• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
initBuffer(unsigned char * buffer)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 
SetXCursor(rfbScreenInfoPtr rfbScreen)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 
SetXCursor2(rfbScreenInfoPtr rfbScreen)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 
SetRichCursor(rfbScreenInfoPtr rfbScreen)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 */
SetRichCursor2(rfbScreenInfoPtr rfbScreen)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 
SetAlphaCursor(rfbScreenInfoPtr screen,int mode)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 
doptr(int buttonMask,int x,int y,rfbClientPtr cl)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 
main(int argc,char ** argv)323 int main(int argc,char** argv)
324 {
325 	rfbScreenInfoPtr rfbScreen = rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp);
326         if(!rfbScreen)
327           return 0;
328 
329 	rfbScreen->desktopName = "Cursor Test";
330 	rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
331 	rfbScreen->ptrAddEvent = doptr;
332 
333 	initBuffer((unsigned char*)rfbScreen->frameBuffer);
334 
335 
336 	SetRichCursor(rfbScreen);
337 
338 	/* initialize the server */
339 	rfbInitServer(rfbScreen);
340 
341 	rfbLog("Change cursor shape with left mouse button,\n\t"
342 			"quit with right one (middle button quits server).\n");
343 
344 	/* this is the blocking event loop, i.e. it never returns */
345 	/* 40000 are the microseconds to wait on select(), i.e. 0.04 seconds */
346 	rfbRunEventLoop(rfbScreen,40000,FALSE);
347 
348 	free(rfbScreen->frameBuffer);
349 	rfbScreenCleanup(rfbScreen);
350 
351 	return(0);
352 }
353 
354