Add feature 85117: [liboscar/icq] password changing support for ICQ.
[kdenetwork.git] / krfb / libvncserver / example.c
blob1cdda701d2a81cb5b56ef29733fc1d6a9e54a899
1 /*
2 *
3 * This is an example of how to use libvncserver.
4 *
5 * libvncserver example
6 * Copyright (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
7 *
8 * This is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This software is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this software; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA.
24 #ifdef WIN32
25 #define sleep Sleep
26 #else
27 #include <unistd.h>
28 #endif
30 #ifdef __IRIX__
31 #include <netdb.h>
32 #endif
34 #include "rfb.h"
35 #include "keysym.h"
37 const int maxx=640, maxy=480, bpp=4;
38 /* TODO: odd maxx doesn't work (vncviewer bug) */
40 /* This initializes a nice (?) background */
42 void initBuffer(unsigned char* buffer)
44 int i,j;
45 for(j=0;j<maxy;++j) {
46 for(i=0;i<maxx;++i) {
47 buffer[(j*maxx+i)*bpp+0]=(i+j)*128/(maxx+maxy); /* red */
48 buffer[(j*maxx+i)*bpp+1]=i*128/maxx; /* green */
49 buffer[(j*maxx+i)*bpp+2]=j*256/maxy; /* blue */
51 buffer[j*maxx*bpp+0]=0xff;
52 buffer[j*maxx*bpp+1]=0xff;
53 buffer[j*maxx*bpp+2]=0xff;
54 buffer[j*maxx*bpp+3]=0xff;
58 /* Here we create a structure so that every client has it's own pointer */
60 typedef struct ClientData {
61 Bool oldButton;
62 int oldx,oldy;
63 } ClientData;
65 void clientgone(rfbClientPtr cl)
67 free(cl->clientData);
70 enum rfbNewClientAction newclient(rfbClientPtr cl)
72 cl->clientData = (void*)calloc(sizeof(ClientData),1);
73 cl->clientGoneHook = clientgone;
74 return RFB_CLIENT_ACCEPT;
77 /* aux function to draw a line */
79 void drawline(unsigned char* buffer,int rowstride,int bpp,int x1,int y1,int x2,int y2)
81 int i,j;
82 i=x1-x2; j=y1-y2;
83 if(i==0 && j==0) {
84 for(i=0;i<bpp;i++)
85 buffer[y1*rowstride+x1*bpp+i]=0xff;
86 return;
88 if(i<0) i=-i;
89 if(j<0) j=-j;
90 if(i<j) {
91 if(y1>y2) { i=y2; y2=y1; y1=i; i=x2; x2=x1; x1=i; }
92 if(y2==y1) { if(y2>0) y1--; else y2++; }
93 for(j=y1;j<=y2;j++)
94 for(i=0;i<bpp;i++)
95 buffer[j*rowstride+(x1+(j-y1)*(x2-x1)/(y2-y1))*bpp+i]=0xff;
96 } else {
97 if(x1>x2) { i=y2; y2=y1; y1=i; i=x2; x2=x1; x1=i; }
98 for(i=x1;i<=x2;i++)
99 for(j=0;j<bpp;j++)
100 buffer[(y1+(i-x1)*(y2-y1)/(x2-x1))*rowstride+i*bpp+j]=0xff;
104 /* Here the pointer events are handled */
106 void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
108 ClientData* cd=cl->clientData;
110 if(cl->screen->cursorIsDrawn)
111 rfbUndrawCursor(cl->screen);
113 if(x>=0 && y>=0 && x<maxx && y<maxy) {
114 if(buttonMask) {
115 int i,j,x1,x2,y1,y2;
117 if(cd->oldButton==buttonMask) { /* draw a line */
118 drawline(cl->screen->frameBuffer,cl->screen->paddedWidthInBytes,bpp,
119 x,y,cd->oldx,cd->oldy);
120 rfbMarkRectAsModified(cl->screen,x,y,cd->oldx,cd->oldy);
121 } else { /* draw a point (diameter depends on button) */
122 int w=cl->screen->paddedWidthInBytes;
123 x1=x-buttonMask; if(x1<0) x1=0;
124 x2=x+buttonMask; if(x2>maxx) x2=maxx;
125 y1=y-buttonMask; if(y1<0) y1=0;
126 y2=y+buttonMask; if(y2>maxy) y2=maxy;
128 for(i=x1*bpp;i<x2*bpp;i++)
129 for(j=y1;j<y2;j++)
130 cl->screen->frameBuffer[j*w+i]=(char)0xff;
131 rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1);
134 /* we could get a selection like that:
135 rfbGotXCutText(cl->screen,"Hallo",5);
137 } else
138 cd->oldButton=0;
140 cd->oldx=x; cd->oldy=y; cd->oldButton=buttonMask;
142 defaultPtrAddEvent(buttonMask,x,y,cl);
145 /* aux function to draw a character to x, y */
147 #include "radon.h"
149 /* Here the key events are handled */
151 void dokey(Bool down,KeySym key,rfbClientPtr cl)
153 if(down) {
154 if(key==XK_Escape)
155 rfbCloseClient(cl);
156 else if(key==XK_Page_Up) {
157 if(cl->screen->cursorIsDrawn)
158 rfbUndrawCursor(cl->screen);
159 initBuffer(cl->screen->frameBuffer);
160 rfbMarkRectAsModified(cl->screen,0,0,maxx,maxy);
161 } else if(key>=' ' && key<0x100) {
162 ClientData* cd=cl->clientData;
163 int x1=cd->oldx,y1=cd->oldy,x2,y2;
164 if(cl->screen->cursorIsDrawn)
165 rfbUndrawCursor(cl->screen);
166 cd->oldx+=rfbDrawChar(cl->screen,&radonFont,cd->oldx,cd->oldy,(char)key,0x00ffffff);
167 rfbFontBBox(&radonFont,(char)key,&x1,&y1,&x2,&y2);
168 rfbMarkRectAsModified(cl->screen,x1,y1,x2-1,y2-1);
173 /* Example for an XCursor (foreground/background only) */
175 int exampleXCursorWidth=9,exampleXCursorHeight=7;
176 char exampleXCursor[]=
178 " xx xx "
179 " xx xx "
180 " xxx "
181 " xx xx "
182 " xx xx "
183 " ";
185 /* Example for a rich cursor (full-colour) */
187 void MakeRichCursor(rfbScreenInfoPtr rfbScreen)
189 int i,j,w=32,h=32;
190 rfbCursorPtr c = rfbScreen->cursor;
191 char bitmap[]=
193 " xxxxxx "
194 " xxxxxxxxxxxxxxxxx "
195 " xxxxxxxxxxxxxxxxxxxxxx "
196 " xxxxx xxxxxxxx xxxxxxxx "
197 " xxxxxxxxxxxxxxxxxxxxxxxxxxx "
198 " xxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
199 " xxxxx xxxxxxxxxxx xxxxxxx "
200 " xxxx xxxxxxxxx xxxxxx "
201 " xxxxx xxxxxxxxxxx xxxxxxx "
202 " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
203 " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
204 " xxxxxxxxxxxx xxxxxxxxxxxxxxx "
205 " xxxxxxxxxxxxxxxxxxxxxxxxxxxx "
206 " xxxxxxxxxxxxxxxxxxxxxxxxxxxx "
207 " xxxxxxxxxxx xxxxxxxxxxxxxx "
208 " xxxxxxxxxx xxxxxxxxxxxx "
209 " xxxxxxxxx xxxxxxxxx "
210 " xxxxxxxxxx xxxxxxxxx "
211 " xxxxxxxxxxxxxxxxxxx "
212 " xxxxxxxxxxxxxxxxxxx "
213 " xxxxxxxxxxxxxxxxxxx "
214 " xxxxxxxxxxxxxxxxx "
215 " xxxxxxxxxxxxxxx "
216 " xxxx xxxxxxxxxxxxx "
217 " xx x xxxxxxxxxxx "
218 " xxx xxxxxxxxxxx "
219 " xxxx xxxxxxxxxxx "
220 " xxxxxx xxxxxxxxxxxx "
221 " xxxxxxxxxxxxxxxxxxxxxx "
222 " xxxxxxxxxxxxxxxx "
223 " ";
224 c=rfbScreen->cursor = rfbMakeXCursor(w,h,bitmap,bitmap);
225 c->xhot = 16; c->yhot = 24;
227 c->richSource = malloc(w*h*bpp);
228 for(j=0;j<h;j++) {
229 for(i=0;i<w;i++) {
230 c->richSource[j*w*bpp+i*bpp+0]=i*0xff/w;
231 c->richSource[j*w*bpp+i*bpp+1]=(i+j)*0xff/(w+h);
232 c->richSource[j*w*bpp+i*bpp+2]=j*0xff/h;
233 c->richSource[j*w*bpp+i*bpp+3]=0;
238 /* Initialization */
240 int main(int argc,char** argv)
242 rfbScreenInfoPtr rfbScreen =
243 rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp);
244 rfbScreen->desktopName = "LibVNCServer Example";
245 rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp);
246 rfbScreen->rfbAlwaysShared = TRUE;
247 rfbScreen->ptrAddEvent = doptr;
248 rfbScreen->kbdAddEvent = dokey;
249 rfbScreen->newClientHook = newclient;
250 rfbScreen->httpDir = "./classes";
252 initBuffer(rfbScreen->frameBuffer);
253 rfbDrawString(rfbScreen,&radonFont,20,100,"Hello, World!",0xffffff);
255 /* This call creates a mask and then a cursor: */
256 /* rfbScreen->defaultCursor =
257 rfbMakeXCursor(exampleCursorWidth,exampleCursorHeight,exampleCursor,0);
260 MakeRichCursor(rfbScreen);
262 /* initialize the server */
263 rfbInitServer(rfbScreen);
265 #ifndef BACKGROUND_LOOP_TEST
266 /* this is the blocking event loop, i.e. it never returns */
267 /* 40000 are the microseconds, i.e. 0.04 seconds */
268 rfbRunEventLoop(rfbScreen,40000,FALSE);
269 #elif !defined(HAVE_PTHREADS)
270 #error "I need pthreads for that."
271 #endif
273 /* this is the non-blocking event loop; a background thread is started */
274 rfbRunEventLoop(rfbScreen,-1,TRUE);
275 /* now we could do some cool things like rendering */
276 while(1) sleep(5); /* render(); */
278 return(0);