add libvncserver
[presencevnc] / libvnc / vncterm / LinuxVNC.c
1 #include <rfb/keysym.h>
2 #include "VNConsole.h"
3 #include "vga.h"
4 #include <fcntl.h>
5 #include <sys/ioctl.h>
6
7 static int tty=2;
8 static int tty_inject_device;
9
10 void do_key(rfbBool down,rfbKeySym keySym,rfbClientPtr cl)
11 {
12   static char isControl=0;
13
14   if(down) {
15     /* if(keySym==XK_Escape)
16       rfbCloseClient(cl);
17     else */ if(keySym==XK_Control_L || keySym==XK_Control_R)
18       isControl++;
19     else if(tty_inject_device>=0) {
20       if(keySym==XK_Escape)
21         keySym=27;
22       if(isControl) {
23         if(keySym>='a' && keySym<='z')
24           keySym-='a'-1;
25         else if(keySym>='A' && keySym<='Z')
26           keySym-='A'-1;
27         else
28           keySym=0xffff;
29       }
30
31       if(keySym==XK_Tab)
32         keySym='\t';
33       else if(keySym==XK_Return)
34         keySym='\r';
35       else if(keySym==XK_BackSpace)
36         keySym=8;
37       else if(keySym==XK_Home || keySym==XK_KP_Home)
38         keySym=1;
39       else if(keySym==XK_End || keySym==XK_KP_End)
40         keySym=5;
41       else if(keySym==XK_Up || keySym==XK_KP_Up)
42         keySym=16;
43       else if(keySym==XK_Down || keySym==XK_KP_Down)
44         keySym=14;
45       else if(keySym==XK_Right || keySym==XK_KP_Right)
46         keySym=6;
47       else if(keySym==XK_Left || keySym==XK_KP_Left)
48         keySym=2;
49
50       if(keySym<0x100) {
51         int ret;
52         ret=ioctl(tty_inject_device,TIOCSTI,&keySym);
53         if(ret<0) {
54           static char device[64];
55           close(tty_inject_device);
56           sprintf(device,"/dev/tty%d",tty);
57           tty_inject_device=open(device,O_WRONLY);
58           ret=ioctl(tty_inject_device,TIOCSTI,&keySym);
59           if(ret<0)
60             rfbErr("Couldn't reopen device %s!\n",device);
61         }
62       }
63     }
64   } else if(keySym==XK_Control_L || keySym==XK_Control_R)
65     isControl--;
66 }
67
68 /* these colours are from linux kernel drivers/char/console.c */
69 unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
70                                        8,12,10,14, 9,13,11,15 };
71 /* the default colour table, for VGA+ colour systems */
72 int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
73     0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
74 int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
75     0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
76 int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
77     0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
78
79 int main(int argc,char **argv)
80 {
81   int width=80,height=25;
82   char *buffer;
83   vncConsolePtr console;
84   char tty_device[64],title[128];
85   int i;
86   FILE* tty_file;
87   struct winsize dimensions;
88
89   if(argc>1) {
90     if((tty=atoi(argv[1]))<1) {
91       rfbErr("Usage: %s [tty_number [vnc args]]\n",argv[0]);
92       exit(1);
93     } else {
94       argv++;
95       argc--;
96     }
97   }
98
99   /* getopt goes here! */
100
101   sprintf(tty_device,"/dev/tty%d",tty);
102   if((tty_inject_device=open(tty_device,O_WRONLY))<0) {
103     rfbErr("Couldn't open tty device %s!\n",tty_device);
104     exit(1);
105   }
106   rfbLog("Using device %s.\n",tty_device);
107
108   if(ioctl(tty_inject_device,TIOCGWINSZ,&dimensions)>=0) {
109     width=dimensions.ws_col;
110     height=dimensions.ws_row;
111   }
112
113   sprintf(title,"LinuxVNC: /dev/tty%d",tty);
114
115   /* console init */
116   console=vcGetConsole(&argc,argv,width,height,&vgaFont,TRUE);
117   for(i=0;i<16;i++) {
118     console->screen->colourMap.data.bytes[i*3+0]=default_red[color_table[i]];
119     console->screen->colourMap.data.bytes[i*3+1]=default_grn[color_table[i]];
120     console->screen->colourMap.data.bytes[i*3+2]=default_blu[color_table[i]];
121   }
122   console->screen->desktopName=title;
123   console->screen->kbdAddEvent=do_key;
124   console->selectTimeOut=100000;
125   console->wrapBottomToTop=TRUE;
126 #ifdef USE_OLD_VCS
127   buffer=malloc(width*height);
128   console->cursorActive=FALSE;
129 #else
130   buffer=malloc(width*height*2+4);
131   console->cursorActive=TRUE;
132 #endif
133   /* memcpy(buffer,console->screenBuffer,width*height); */
134
135 #ifdef USE_OLD_VCS
136   sprintf(tty_device,"/dev/vcs%d",tty);
137 #else
138   sprintf(tty_device,"/dev/vcsa%d",tty);
139 #endif
140
141   while(rfbIsActive(console->screen)) {
142     if(!console->currentlyMarking) {
143       tty_file=fopen(tty_device,"rb");
144       if(!tty_file) {
145         rfbErr("cannot open device \"%s\"\n",
146                 tty_device);
147         exit(1);
148       }
149 #ifdef USE_OLD_VCS
150       fread(buffer,width,height,tty_file);
151 #else
152       fread(buffer,width*height*2+4,1,tty_file);
153       vcHideCursor(console);
154 #endif
155       fclose(tty_file);
156
157       for(i=0;i<console->width*console->height;i++) {
158         if
159 #ifdef USE_OLD_VCS
160          (buffer[i]!=console->screenBuffer[i])
161 #else
162          (buffer[4+2*i]!=console->screenBuffer[i] ||
163           buffer[5+2*i]!=console->attributeBuffer[i])
164 #endif
165           {
166             console->x=(i%console->width);
167             console->y=(i/console->width);
168             /*
169               rfbLog("changes: %d,%d (%d!=%d || %d!=%d)\n",
170               console->x,console->y,
171               buffer[4+2*i],console->screenBuffer[i],
172               buffer[5+2*i],console->attributeBuffer[i]);
173             */
174             
175 #ifdef USE_OLD_VCS
176             vcPutChar(console,buffer[i]);
177 #else
178             vcPutCharColour(console,buffer[4+i*2],buffer[5+i*2]&0x7,buffer[5+i*2]>>4);
179 #endif
180           }
181       }
182       console->x=buffer[2];
183       console->y=buffer[3];
184     }
185     vcProcessEvents(console);
186   }
187   return(0);
188 }