2 #include <rfb/keysym.h>
7 unsigned char colourMap16[16*3]={
8 /* 0 black #000000 */ 0x00,0x00,0x00,
9 /* 1 maroon #800000 */ 0x80,0x00,0x00,
10 /* 2 green #008000 */ 0x00,0x80,0x00,
11 /* 3 khaki #808000 */ 0x80,0x80,0x00,
12 /* 4 navy #000080 */ 0x00,0x00,0x80,
13 /* 5 purple #800080 */ 0x80,0x00,0x80,
14 /* 6 aqua-green #008080 */ 0x00,0x80,0x80,
15 /* 7 light grey #c0c0c0 */ 0xc0,0xc0,0xc0,
16 /* 8 dark grey #808080 */ 0x80,0x80,0x80,
17 /* 9 red #ff0000 */ 0xff,0x00,0x00,
18 /* a light green #00ff00 */ 0x00,0xff,0x00,
19 /* b yellow #ffff00 */ 0xff,0xff,0x00,
20 /* c blue #0000ff */ 0x00,0x00,0xff,
21 /* d pink #ff00ff */ 0xff,0x00,0xff,
22 /* e light blue #00ffff */ 0x00,0xff,0xff,
23 /* f white #ffffff */ 0xff,0xff,0xff
26 void MakeColourMap16(vncConsolePtr c)
28 rfbColourMap* colourMap=&(c->screen->colourMap);
30 free(colourMap->data.bytes);
31 colourMap->data.bytes=malloc(16*3);
32 memcpy(colourMap->data.bytes,colourMap16,16*3);
34 colourMap->is16=FALSE;
35 c->screen->serverFormat.trueColour=FALSE;
38 void vcDrawOrHideCursor(vncConsolePtr c)
40 int i,j,w=c->screen->paddedWidthInBytes;
41 char *b=c->screen->frameBuffer+c->y*c->cHeight*w+c->x*c->cWidth;
42 for(j=c->cy1;j<c->cy2;j++)
43 for(i=c->cx1;i<c->cx2;i++)
45 rfbMarkRectAsModified(c->screen,
46 c->x*c->cWidth+c->cx1,c->y*c->cHeight+c->cy1,
47 c->x*c->cWidth+c->cx2,c->y*c->cHeight+c->cy2);
48 c->cursorIsDrawn=c->cursorIsDrawn?FALSE:TRUE;
51 void vcDrawCursor(vncConsolePtr c)
53 if(c->cursorActive && c->y<c->height && c->x<c->width) {
54 /* rfbLog("DrawCursor: %d,%d\n",c->x,c->y); */
55 vcDrawOrHideCursor(c);
59 void vcHideCursor(vncConsolePtr c)
61 if(c->currentlyMarking)
63 vcDrawOrHideCursor(c);
66 void vcMakeSureCursorIsDrawn(rfbClientPtr cl)
68 vncConsolePtr c=(vncConsolePtr)cl->screen->screenData;
69 if(!c->dontDrawCursor)
73 vncConsolePtr vcGetConsole(int *argc,char **argv,
74 int width,int height,rfbFontDataPtr font
75 #ifdef USE_ATTRIBUTE_BUFFER
76 ,rfbBool withAttributes
80 vncConsolePtr c=(vncConsolePtr)malloc(sizeof(vncConsole));
85 c->screenBuffer=(char*)malloc(width*height);
86 memset(c->screenBuffer,' ',width*height);
87 #ifdef USE_ATTRIBUTE_BUFFER
89 c->attributeBuffer=(char*)malloc(width*height);
90 memset(c->attributeBuffer,0x07,width*height);
92 c->attributeBuffer=NULL;
96 c->wrapBottomToTop=FALSE;
98 c->cursorIsDrawn=FALSE;
99 c->dontDrawCursor=FALSE;
100 c->inputBuffer=(char*)malloc(1024);
104 c->selectTimeOut=40000; /* 40 ms */
107 c->wasRightButtonDown=FALSE;
108 c->currentlyMarking=FALSE;
110 rfbWholeFontBBox(font,&c->xhot,&c->cHeight,&c->cWidth,&c->yhot);
112 c->cHeight=-c->cHeight-c->yhot;
116 c->cx2=c->cWidth*7/8;
117 c->cy2=c->cHeight-1-c->yhot+c->cHeight/16;
118 if(c->cy2>=c->cHeight)
120 c->cy1=c->cy2-c->cHeight/8;
125 rfbGetScreen(argc,argv,c->cWidth*c->width,c->cHeight*c->height,8,1,1);
126 c->screen->screenData=(void*)c;
127 c->screen->displayHook=vcMakeSureCursorIsDrawn;
128 c->screen->frameBuffer=
129 (char*)malloc(c->screen->width*c->screen->height);
130 memset(c->screen->frameBuffer,c->backColour,
131 c->screen->width*c->screen->height);
132 c->screen->kbdAddEvent=vcKbdAddEventProc;
133 c->screen->ptrAddEvent=vcPtrAddEventProc;
134 c->screen->setXCutText=vcSetXCutTextProc;
140 rfbInitServer(c->screen);
145 #include <rfb/rfbregion.h>
147 /* before using this function, hide the cursor */
148 void vcScroll(vncConsolePtr c,int lineCount)
151 rfbScreenInfoPtr s=c->screen;
156 /* rfbLog("begin scroll\n"); */
158 c->dontDrawCursor=TRUE;
160 if(lineCount>=c->height || lineCount<=-c->height) {
162 } else if(lineCount>0) {
163 y1=s->height-lineCount*c->cHeight; y2=s->height;
164 rfbDoCopyRect(s,0,0,s->width,y1,0,-lineCount*c->cHeight);
165 memmove(c->screenBuffer,
166 c->screenBuffer+(c->height-lineCount)*c->width,
167 (c->height-lineCount)*c->width);
168 #ifdef USE_ATTRIBUTE_BUFFER
169 if(c->attributeBuffer)
170 memmove(c->attributeBuffer,
171 c->attributeBuffer+(c->height-lineCount)*c->width,
172 (c->height-lineCount)*c->width);
175 y1=0; y2=-lineCount*c->cHeight;
176 rfbDoCopyRect(s,0,y2,s->width,s->height,0,-lineCount*c->cHeight);
177 memmove(c->screenBuffer-lineCount*c->width,
179 (c->height+lineCount)*c->width);
180 #ifdef USE_ATTRIBUTE_BUFFER
181 if(c->attributeBuffer)
182 memmove(c->attributeBuffer-lineCount*c->width,
184 (c->height+lineCount)*c->width);
188 c->dontDrawCursor=FALSE;
189 memset(s->frameBuffer+y1*s->width,c->backColour,(y2-y1)*s->width);
190 rfbMarkRectAsModified(s,0,y1-c->cHeight,s->width,y2);
191 memset(c->screenBuffer+y1/c->cHeight*c->width,' ',
192 (y2-y1)/c->cHeight*c->width);
193 #ifdef USE_ATTRIBUTE_BUFFER
194 if(c->attributeBuffer)
195 memset(c->attributeBuffer+y1/c->cHeight*c->width,0x07,
196 (y2-y1)/c->cHeight*c->width);
198 /* rfbLog("end scroll\n"); */
201 void vcCheckCoordinates(vncConsolePtr c)
207 if(c->y>=c->height) {
208 if(c->wrapBottomToTop)
211 vcScroll(c,c->y+1-c->height);
217 void vcPutChar(vncConsolePtr c,unsigned char ch)
219 #ifdef USE_ATTRIBUTE_BUFFER
220 if(c->attributeBuffer) {
221 unsigned char colour=c->attributeBuffer[c->x+c->y*c->width];
222 vcPutCharColour(c,ch,colour&0x7,colour>>4);
225 vcPutCharColour(c,ch,c->foreColour,c->backColour);
228 void vcPutCharColour(vncConsolePtr c,unsigned char ch,unsigned char foreColour,unsigned char backColour)
230 rfbScreenInfoPtr s=c->screen;
239 case 8: /* BackSpace */
246 case 10: /* return */
249 vcCheckCoordinates(c);
251 case 9: /* tabulator */
257 rfbLog("putchar of unknown character: %c(%d).\n",ch,ch);
261 #ifdef USE_ATTRIBUTE_BUFFER
262 if(c->attributeBuffer)
263 c->attributeBuffer[c->x+c->y*c->width]=foreColour|(backColour<<4);
267 for(j=y+c->cHeight-1;j>=y;j--)
268 memset(s->frameBuffer+j*s->width+x,backColour,c->cWidth);
269 rfbDrawChar(s,c->font,
270 x-c->xhot+(c->cWidth-rfbWidthOfChar(c->font,ch))/2,
271 y+c->cHeight-c->yhot-1,
273 c->screenBuffer[c->y*c->width+c->x]=ch;
275 rfbMarkRectAsModified(s,x,y-c->cHeight+1,x+c->cWidth,y+c->cHeight+1);
276 vcCheckCoordinates(c);
280 void vcPrint(vncConsolePtr c,unsigned char* str)
288 void vcPrintColour(vncConsolePtr c,unsigned char* str,unsigned char foreColour,unsigned char backColour)
291 vcPutCharColour(c,*str,foreColour,backColour);
296 void vcPrintF(vncConsolePtr c,char* format,...)
300 va_start(args, format);
301 vsprintf(buf, format, args);
306 void vcPrintFColour(vncConsolePtr c,unsigned char foreColour,unsigned char backColour,char* format,...)
310 va_start(args, format);
311 vsprintf(buf, format, args);
312 vcPrintColour(c,buf,foreColour,backColour);
316 char vcGetCh(vncConsolePtr c)
318 if(c->inputCount>0) {
320 ch=c->inputBuffer[0];
323 memmove(c->inputBuffer,c->inputBuffer+1,c->inputCount);
329 char vcGetChar(vncConsolePtr c)
331 while(rfbIsActive(c->screen) && c->inputCount==0)
336 char *vcGetString(vncConsolePtr c,char *buffer,int bufferSize)
338 char *bufferBackup=c->inputBuffer;
339 int i,count=bufferSize-1;
341 if(count>c->inputCount)
343 for(i=1;i<count && bufferBackup[i-1]!='\n';i++);
344 if(i<count || i==bufferSize-1) {
345 memcpy(buffer,bufferBackup,i);
348 memmove(bufferBackup,bufferBackup+i+2,c->inputCount);
351 memcpy(buffer,bufferBackup,c->inputCount);
353 c->inputSize=bufferSize;
354 c->inputBuffer=buffer;
355 while(rfbIsActive(c->screen)
356 && c->inputCount<bufferSize-1 && buffer[c->inputCount-1]!='\n')
358 buffer[c->inputCount]=0;
359 c->inputBuffer=bufferBackup;
365 void vcKbdAddEventProc(rfbBool down,rfbKeySym keySym,rfbClientPtr cl)
367 vncConsolePtr c=(vncConsolePtr)cl->screen->screenData;
369 if(c->inputCount<c->inputSize) {
370 if(keySym<0 || keySym>0xff) {
371 if(keySym==XK_Return) keySym='\n';
372 else if(keySym==XK_BackSpace) keySym=8;
373 else if(keySym==XK_Tab) keySym=9;
381 c->inputBuffer[c->inputCount++]=(char)keySym;
383 vcPutChar(c,(unsigned char)keySym);
389 void vcPtrAddEventProc(int buttonMask,int x,int y,rfbClientPtr cl)
391 vncConsolePtr c=(vncConsolePtr)cl->screen->screenData;
393 if(c->wasRightButtonDown) {
394 if((buttonMask&4)==0) {
397 for(s=c->selection;*s;s++) {
398 c->screen->kbdAddEvent(1,*s,cl);
399 c->screen->kbdAddEvent(0,*s,cl);
402 c->wasRightButtonDown=0;
404 } else if(buttonMask&4)
405 c->wasRightButtonDown=1;
408 int cx=x/c->cWidth,cy=y/c->cHeight,pos;
409 if(cx<0) cx=0; else if(cx>=c->width) cx=c->width-1;
410 if(cy<0) cy=0; else if(cy>=c->height) cy=c->height-1;
414 if(!c->currentlyMarking) {
415 c->currentlyMarking=TRUE;
418 vcToggleMarkCell(c,pos);
420 DEBUG(rfbLog("markStart: %d, markEnd: %d, pos: %d\n",
421 c->markStart,c->markEnd,pos));
422 if(c->markEnd!=pos) {
424 cx=c->markEnd; cy=pos;
426 cx=pos; cy=c->markEnd;
428 if(cx<c->markStart) {
434 vcToggleMarkCell(c,cx);
440 } else if(c->currentlyMarking) {
442 if(c->markStart<c->markEnd) {
443 i=c->markStart; j=c->markEnd+1;
445 i=c->markEnd; j=c->markStart;
447 if(c->selection) free(c->selection);
448 c->selection=(char*)malloc(j-i+1);
449 memcpy(c->selection,c->screenBuffer+i,j-i);
452 rfbGotXCutText(c->screen,c->selection,j-i);
454 rfbDefaultPtrAddEvent(buttonMask,x,y,cl);
457 void vcSetXCutTextProc(char* str,int len, struct _rfbClientRec* cl)
459 vncConsolePtr c=(vncConsolePtr)cl->screen->screenData;
461 if(c->selection) free(c->selection);
462 c->selection=(char*)malloc(len+1);
463 memcpy(c->selection,str,len);
467 void vcToggleMarkCell(vncConsolePtr c,int pos)
469 int x=(pos%c->width)*c->cWidth,
470 y=(pos/c->width)*c->cHeight;
472 rfbScreenInfoPtr s=c->screen;
473 char *b=s->frameBuffer+y*s->width+x;
474 for(j=0;j<c->cHeight;j++)
475 for(i=0;i<c->cWidth;i++)
476 b[j*s->width+i]^=0x0f;
477 rfbMarkRectAsModified(c->screen,x,y,x+c->cWidth,y+c->cHeight);
480 void vcUnmark(vncConsolePtr c)
483 c->currentlyMarking=FALSE;
484 if(c->markStart<c->markEnd) {
485 i=c->markStart; j=c->markEnd+1;
487 i=c->markEnd; j=c->markStart;
490 vcToggleMarkCell(c,i);
493 void vcProcessEvents(vncConsolePtr c)
495 rfbProcessEvents(c->screen,c->selectTimeOut);