add libvncserver
[presencevnc] / libvnc / test / cursortest.c
1 /*
2  * 
3  * This is an example of how to use libvncserver.
4  * 
5  * libvncserver example
6  * Copyright (C) 2005 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>,
7  *              Karl Runge <runge@karlrunge.com>
8  * 
9  *  This is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This software is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this software; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
22  *  USA.
23  */
24
25 #include <rfb/rfb.h>
26
27 static const int bpp=4;
28 static int maxx=800, maxy=600;
29
30 /* This initializes a nice (?) background */
31
32 static void initBuffer(unsigned char* buffer)
33 {
34         int i,j;
35         for(j=0;j<maxy;++j) {
36                 for(i=0;i<maxx;++i) {
37                         buffer[(j*maxx+i)*bpp+0]=(i+j)*128/(maxx+maxy); /* red */
38                         buffer[(j*maxx+i)*bpp+1]=i*128/maxx; /* green */
39                         buffer[(j*maxx+i)*bpp+2]=j*256/maxy; /* blue */
40                 }
41         }
42 }
43
44 /* Example for an XCursor (foreground/background only) */
45
46 static void SetXCursor(rfbScreenInfoPtr rfbScreen)
47 {
48         int width=13,height=11;
49         char cursor[]=
50                 "             "
51                 " xx       xx "
52                 "  xx     xx  "
53                 "   xx   xx   "
54                 "    xx xx    "
55                 "     xxx     "
56                 "    xx xx    "
57                 "   xx   xx   "
58                 "  xx     xx  "
59                 " xx       xx "
60                 "             ",
61              mask[]=
62                 "xxxx     xxxx"
63                 "xxxx     xxxx"
64                 " xxxx   xxxx "
65                 "  xxxx xxxx  "
66                 "   xxxxxxx   "
67                 "    xxxxx    "
68                 "   xxxxxxx   "
69                 "  xxxx xxxx  "
70                 " xxxx   xxxx "
71                 "xxxx     xxxx"
72                 "xxxx     xxxx";
73         rfbCursorPtr c;
74         
75         c=rfbMakeXCursor(width,height,cursor,mask);
76         c->xhot=width/2;c->yhot=height/2;
77
78         rfbSetCursor(rfbScreen, c);
79 }
80
81 static void SetXCursor2(rfbScreenInfoPtr rfbScreen)
82 {
83         int width=13,height=22;
84         char cursor[]=
85                 " xx          "
86                 " x x         "
87                 " x  x        "
88                 " x   x       "
89                 " x    x      "
90                 " x     x     "
91                 " x      x    "
92                 " x       x   "
93                 " x     xx x  "
94                 " x x   x xxx "
95                 " x xx  x   x "
96                 " xx x   x    "
97                 " xx  x  x    "
98                 " x    x  x   "
99                 " x    x  x   "
100                 "       x  x  "
101                 "        x  x "
102                 "        x  x "
103                 "         xx  "
104                 "             "
105                 "             ",
106              mask[]=
107                 "xxx          "
108                 "xxxx         "
109                 "xxxxx        "
110                 "xxxxxx       "
111                 "xxxxxxx      "
112                 "xxxxxxxx     "
113                 "xxxxxxxxx    "
114                 "xxxxxxxxxx   "
115                 "xxxxxxxxxxx  "
116                 "xxxxxxxxxxxx "
117                 "xxxxxxxxxxxxx"
118                 "xxxxxxxxxxxxx"
119                 "xxxxxxxxxx  x"
120                 "xxxxxxxxxx   "
121                 "xxx  xxxxxx  "
122                 "xxx  xxxxxx  "
123                 "xx    xxxxxx "
124                 "       xxxxx "
125                 "       xxxxxx"
126                 "        xxxxx"
127                 "         xxx "
128                 "             ";
129         rfbCursorPtr c;
130         
131         c=rfbMakeXCursor(width,height,cursor,mask);
132         c->xhot=0;c->yhot=0;
133
134         rfbSetCursor(rfbScreen, c);
135 }
136
137 /* Example for a rich cursor (full-colour) */
138
139 static void SetRichCursor(rfbScreenInfoPtr rfbScreen)
140 {
141         int i,j,w=32,h=32;
142         /* runge */
143         /*  rfbCursorPtr c = rfbScreen->cursor; */
144         rfbCursorPtr c;
145         char bitmap[]=
146                 "                                "
147                 "              xxxxxx            "
148                 "       xxxxxxxxxxxxxxxxx        "
149                 "      xxxxxxxxxxxxxxxxxxxxxx    "
150                 "    xxxxx  xxxxxxxx  xxxxxxxx   "
151                 "   xxxxxxxxxxxxxxxxxxxxxxxxxxx  "
152                 "  xxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
153                 "  xxxxx   xxxxxxxxxxx   xxxxxxx "
154                 "  xxxx     xxxxxxxxx     xxxxxx "
155                 "  xxxxx   xxxxxxxxxxx   xxxxxxx "
156                 " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
157                 " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
158                 " xxxxxxxxxxxx  xxxxxxxxxxxxxxx  "
159                 " xxxxxxxxxxxxxxxxxxxxxxxxxxxx   "
160                 " xxxxxxxxxxxxxxxxxxxxxxxxxxxx   "
161                 " xxxxxxxxxxx   xxxxxxxxxxxxxx   "
162                 " xxxxxxxxxx     xxxxxxxxxxxx    "
163                 "  xxxxxxxxx      xxxxxxxxx      "
164                 "   xxxxxxxxxx   xxxxxxxxx       "
165                 "      xxxxxxxxxxxxxxxxxxx       "
166                 "       xxxxxxxxxxxxxxxxxxx      "
167                 "         xxxxxxxxxxxxxxxxxxx    "
168                 "             xxxxxxxxxxxxxxxxx  "
169                 "                xxxxxxxxxxxxxxx "
170                 "   xxxx           xxxxxxxxxxxxx "
171                 "  xx   x            xxxxxxxxxxx "
172                 "  xxx               xxxxxxxxxxx "
173                 "  xxxx             xxxxxxxxxxx  "
174                 "   xxxxxx       xxxxxxxxxxxx    "
175                 "    xxxxxxxxxxxxxxxxxxxxxx      "
176                 "      xxxxxxxxxxxxxxxx          "
177                 "                                ";
178
179         c=rfbMakeXCursor(w,h,bitmap,bitmap);
180         c->xhot = 16; c->yhot = 24;
181
182         c->richSource = (char*)malloc(w*h*bpp);
183         for(j=0;j<h;j++) {
184                 for(i=0;i<w;i++) {
185                         c->richSource[j*w*bpp+i*bpp+0]=i*0xff/w;
186                         c->richSource[j*w*bpp+i*bpp+1]=(i+j)*0xff/(w+h);
187                         c->richSource[j*w*bpp+i*bpp+2]=j*0xff/h;
188                         c->richSource[j*w*bpp+i*bpp+3]=0;
189                 }
190         }
191         rfbSetCursor(rfbScreen, c);
192 }
193
194 /* runge */
195 static void SetRichCursor2(rfbScreenInfoPtr rfbScreen)
196 {
197         int i,j,w=17,h=16;
198         /*  rfbCursorPtr c = rfbScreen->cursor; */
199         rfbCursorPtr c;
200         char bitmap[]=
201                 "                 "
202                 "xxxx             "
203                 "xxxxxxxx         "
204                 "xxxxxxxxxxxx    x"
205                 "xxx  xxxxxxxx   x"
206                 "xxxxxxxxxxxxxx  x"
207                 "xxxxxxxxxxxxxxx x"
208                 "xxxxx   xxxxxxx x"
209                 "xxxx     xxxxxx x"
210                 "xxxxx   xxxxxxx x"
211                 "xxxxxxxxxxxxxxx x"
212                 "xxxxxxxxxxxxxxx x"
213                 "xxxxxxxxxxxxxx  x"
214                 "xxxxxxxxxxxxx   x"
215                 "xxxxxxxxxxxxx   x"
216                 "xxxxxxxxxxxxx   x";
217         /*  c=rfbScreen->cursor = rfbMakeXCursor(w,h,bitmap,bitmap); */
218         c=rfbMakeXCursor(w,h,bitmap,bitmap);
219         c->xhot = 5; c->yhot = 7;
220
221         c->richSource = (char*)malloc(w*h*bpp);
222         for(j=0;j<h;j++) {
223                 for(i=0;i<w;i++) {
224                         c->richSource[j*w*bpp+i*bpp+0]=0xff;
225                         c->richSource[j*w*bpp+i*bpp+1]=0x00;
226                         c->richSource[j*w*bpp+i*bpp+2]=0x7f;
227                         c->richSource[j*w*bpp+i*bpp+3]=0;
228                 }
229         }
230         rfbSetCursor(rfbScreen, c);
231 }
232
233 /* alpha channel */
234
235 static void SetAlphaCursor(rfbScreenInfoPtr screen,int mode)
236 {
237         int i,j;
238         rfbCursorPtr c = screen->cursor;
239         int maskStride=(c->width+7)/8;
240
241         if(!c)
242                 return;
243
244         if(c->alphaSource) {
245                 free(c->alphaSource);
246                 c->alphaSource=NULL;
247         }
248
249         if(mode==0)
250                 return;
251
252         c->alphaSource = (unsigned char*)malloc(c->width*c->height);
253
254         for(j=0;j<c->height;j++)
255                 for(i=0;i<c->width;i++) {
256                         unsigned char value=0x100*i/c->width;
257                         rfbBool masked=(c->mask[(i/8)+maskStride*j]<<(i&7))&0x80;
258                         c->alphaSource[i+c->width*j]=(masked?(mode==1?value:0xff-value):0);
259                 }
260         if(c->cleanupMask)
261                 free(c->mask);
262         c->mask=rfbMakeMaskFromAlphaSource(c->width,c->height,c->alphaSource);
263         c->cleanupMask=TRUE;
264 }
265
266 /* Here the pointer events are handled */
267
268 static void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
269 {
270         static int oldButtonMask=0;
271         static int counter=0;
272
273         if((oldButtonMask&1)==0 && (buttonMask&1)==1) {
274                 switch(++counter) {
275                 case 7:
276                         SetRichCursor(cl->screen);
277                         SetAlphaCursor(cl->screen,2);
278                         break;
279                 case 6:
280                         SetRichCursor(cl->screen);
281                         SetAlphaCursor(cl->screen,1);
282                         break;
283                 case 5:
284                         SetRichCursor2(cl->screen);
285                         SetAlphaCursor(cl->screen,0);
286                         break;
287                 case 4:
288                         SetXCursor(cl->screen);
289                         break;
290                 case 3:
291                         SetRichCursor2(cl->screen);
292                         SetAlphaCursor(cl->screen,2);
293                         break;
294                 case 2:
295                         SetXCursor(cl->screen);
296                         SetAlphaCursor(cl->screen,2);
297                         break;
298                 case 1:
299                         SetXCursor2(cl->screen);
300                         SetAlphaCursor(cl->screen,0);
301                         break;
302                 default:
303                         SetRichCursor(cl->screen);
304                         counter=0;
305                 }
306         }
307         if(buttonMask&2) {
308                 rfbScreenCleanup(cl->screen);
309                 exit(0);
310         }
311
312         if(buttonMask&4)
313                 rfbCloseClient(cl);
314
315
316         oldButtonMask=buttonMask;
317
318         rfbDefaultPtrAddEvent(buttonMask,x,y,cl);
319 }
320
321 /* Initialization */
322
323 int main(int argc,char** argv)
324 {
325         rfbScreenInfoPtr rfbScreen =
326                 rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp);
327         rfbScreen->desktopName = "Cursor Test";
328         rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
329         rfbScreen->ptrAddEvent = doptr;
330
331         initBuffer((unsigned char*)rfbScreen->frameBuffer);
332
333
334         SetRichCursor(rfbScreen);
335
336         /* initialize the server */
337         rfbInitServer(rfbScreen);
338
339         rfbLog("Change cursor shape with left mouse button,\n\t"
340                         "quit with right one (middle button quits server).\n");
341
342         /* this is the blocking event loop, i.e. it never returns */
343         /* 40000 are the microseconds to wait on select(), i.e. 0.04 seconds */
344         rfbRunEventLoop(rfbScreen,40000,FALSE);
345
346         free(rfbScreen->frameBuffer);
347         rfbScreenCleanup(rfbScreen);
348
349         return(0);
350 }
351