Home | History | Annotate | Download | only in test
      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 (at) gmx.de>,
      7  * 		Karl Runge <runge (at) 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 = 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