3 * This is an example of how to use libvncserver.
6 * Copyright (C) 2005 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>,
7 * Karl Runge <runge@karlrunge.com>
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.
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.
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,
27 static const int bpp=4;
28 static int maxx=800, maxy=600;
30 /* This initializes a nice (?) background */
32 static void initBuffer(unsigned char* buffer)
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 */
44 /* Example for an XCursor (foreground/background only) */
46 static void SetXCursor(rfbScreenInfoPtr rfbScreen)
48 int width=13,height=11;
75 c=rfbMakeXCursor(width,height,cursor,mask);
76 c->xhot=width/2;c->yhot=height/2;
78 rfbSetCursor(rfbScreen, c);
81 static void SetXCursor2(rfbScreenInfoPtr rfbScreen)
83 int width=13,height=22;
131 c=rfbMakeXCursor(width,height,cursor,mask);
134 rfbSetCursor(rfbScreen, c);
137 /* Example for a rich cursor (full-colour) */
139 static void SetRichCursor(rfbScreenInfoPtr rfbScreen)
143 /* rfbCursorPtr c = rfbScreen->cursor; */
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 "
170 " xxxx xxxxxxxxxxxxx "
174 " xxxxxx xxxxxxxxxxxx "
175 " xxxxxxxxxxxxxxxxxxxxxx "
179 c=rfbMakeXCursor(w,h,bitmap,bitmap);
180 c->xhot = 16; c->yhot = 24;
182 c->richSource = (char*)malloc(w*h*bpp);
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;
191 rfbSetCursor(rfbScreen, c);
195 static void SetRichCursor2(rfbScreenInfoPtr rfbScreen)
198 /* rfbCursorPtr c = rfbScreen->cursor; */
217 /* c=rfbScreen->cursor = rfbMakeXCursor(w,h,bitmap,bitmap); */
218 c=rfbMakeXCursor(w,h,bitmap,bitmap);
219 c->xhot = 5; c->yhot = 7;
221 c->richSource = (char*)malloc(w*h*bpp);
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;
230 rfbSetCursor(rfbScreen, c);
235 static void SetAlphaCursor(rfbScreenInfoPtr screen,int mode)
238 rfbCursorPtr c = screen->cursor;
239 int maskStride=(c->width+7)/8;
245 free(c->alphaSource);
252 c->alphaSource = (unsigned char*)malloc(c->width*c->height);
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);
262 c->mask=rfbMakeMaskFromAlphaSource(c->width,c->height,c->alphaSource);
266 /* Here the pointer events are handled */
268 static void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
270 static int oldButtonMask=0;
271 static int counter=0;
273 if((oldButtonMask&1)==0 && (buttonMask&1)==1) {
276 SetRichCursor(cl->screen);
277 SetAlphaCursor(cl->screen,2);
280 SetRichCursor(cl->screen);
281 SetAlphaCursor(cl->screen,1);
284 SetRichCursor2(cl->screen);
285 SetAlphaCursor(cl->screen,0);
288 SetXCursor(cl->screen);
291 SetRichCursor2(cl->screen);
292 SetAlphaCursor(cl->screen,2);
295 SetXCursor(cl->screen);
296 SetAlphaCursor(cl->screen,2);
299 SetXCursor2(cl->screen);
300 SetAlphaCursor(cl->screen,0);
303 SetRichCursor(cl->screen);
308 rfbScreenCleanup(cl->screen);
316 oldButtonMask=buttonMask;
318 rfbDefaultPtrAddEvent(buttonMask,x,y,cl);
323 int main(int argc,char** argv)
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;
331 initBuffer((unsigned char*)rfbScreen->frameBuffer);
334 SetRichCursor(rfbScreen);
336 /* initialize the server */
337 rfbInitServer(rfbScreen);
339 rfbLog("Change cursor shape with left mouse button,\n\t"
340 "quit with right one (middle button quits server).\n");
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);
346 free(rfbScreen->frameBuffer);
347 rfbScreenCleanup(rfbScreen);