| #include <rfb/keysym.h> |
| #include "VNConsole.h" |
| #include "vga.h" |
| #include <fcntl.h> |
| #include <sys/ioctl.h> |
| |
| static int tty=2; |
| static int tty_inject_device; |
| |
| void do_key(rfbBool down,rfbKeySym keySym,rfbClientPtr cl) |
| { |
| static char isControl=0; |
| |
| if(down) { |
| /* if(keySym==XK_Escape) |
| rfbCloseClient(cl); |
| else */ if(keySym==XK_Control_L || keySym==XK_Control_R) |
| isControl++; |
| else if(tty_inject_device>=0) { |
| if(keySym==XK_Escape) |
| keySym=27; |
| if(isControl) { |
| if(keySym>='a' && keySym<='z') |
| keySym-='a'-1; |
| else if(keySym>='A' && keySym<='Z') |
| keySym-='A'-1; |
| else |
| keySym=0xffff; |
| } |
| |
| if(keySym==XK_Tab) |
| keySym='\t'; |
| else if(keySym==XK_Return) |
| keySym='\r'; |
| else if(keySym==XK_BackSpace) |
| keySym=8; |
| else if(keySym==XK_Home || keySym==XK_KP_Home) |
| keySym=1; |
| else if(keySym==XK_End || keySym==XK_KP_End) |
| keySym=5; |
| else if(keySym==XK_Up || keySym==XK_KP_Up) |
| keySym=16; |
| else if(keySym==XK_Down || keySym==XK_KP_Down) |
| keySym=14; |
| else if(keySym==XK_Right || keySym==XK_KP_Right) |
| keySym=6; |
| else if(keySym==XK_Left || keySym==XK_KP_Left) |
| keySym=2; |
| |
| if(keySym<0x100) { |
| int ret; |
| ret=ioctl(tty_inject_device,TIOCSTI,&keySym); |
| if(ret<0) { |
| static char device[64]; |
| close(tty_inject_device); |
| sprintf(device,"/dev/tty%d",tty); |
| tty_inject_device=open(device,O_WRONLY); |
| ret=ioctl(tty_inject_device,TIOCSTI,&keySym); |
| if(ret<0) |
| rfbErr("Couldn't reopen device %s!\n",device); |
| } |
| } |
| } |
| } else if(keySym==XK_Control_L || keySym==XK_Control_R) |
| if(isControl>0) |
| isControl--; |
| } |
| |
| /* these colours are from linux kernel drivers/char/console.c */ |
| unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, |
| 8,12,10,14, 9,13,11,15 }; |
| /* the default colour table, for VGA+ colour systems */ |
| int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa, |
| 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff}; |
| int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, |
| 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff}; |
| int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, |
| 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; |
| |
| int main(int argc,char **argv) |
| { |
| int width=80,height=25; |
| char *buffer; |
| vncConsolePtr console; |
| char tty_device[64],title[128]; |
| int i; |
| FILE* tty_file; |
| struct winsize dimensions; |
| |
| if(argc>1) { |
| if((tty=atoi(argv[1]))<1) { |
| rfbErr("Usage: %s [tty_number [vnc args]]\n",argv[0]); |
| exit(1); |
| } else { |
| argv++; |
| argc--; |
| } |
| } |
| |
| /* getopt goes here! */ |
| |
| sprintf(tty_device,"/dev/tty%d",tty); |
| if((tty_inject_device=open(tty_device,O_WRONLY))<0) { |
| rfbErr("Couldn't open tty device %s!\n",tty_device); |
| exit(1); |
| } |
| rfbLog("Using device %s.\n",tty_device); |
| |
| if(ioctl(tty_inject_device,TIOCGWINSZ,&dimensions)>=0) { |
| width=dimensions.ws_col; |
| height=dimensions.ws_row; |
| } |
| |
| sprintf(title,"LinuxVNC: /dev/tty%d",tty); |
| |
| /* console init */ |
| if(!(console=vcGetConsole(&argc,argv,width,height,&vgaFont,TRUE))) |
| exit(1); |
| |
| for(i=0;i<16;i++) { |
| console->screen->colourMap.data.bytes[i*3+0]=default_red[color_table[i]]; |
| console->screen->colourMap.data.bytes[i*3+1]=default_grn[color_table[i]]; |
| console->screen->colourMap.data.bytes[i*3+2]=default_blu[color_table[i]]; |
| } |
| console->screen->desktopName=title; |
| console->screen->kbdAddEvent=do_key; |
| console->selectTimeOut=100000; |
| console->wrapBottomToTop=TRUE; |
| #ifdef USE_OLD_VCS |
| buffer=malloc(width*height); |
| console->cursorActive=FALSE; |
| #else |
| buffer=malloc(width*height*2+4); |
| console->cursorActive=TRUE; |
| #endif |
| /* memcpy(buffer,console->screenBuffer,width*height); */ |
| |
| #ifdef USE_OLD_VCS |
| sprintf(tty_device,"/dev/vcs%d",tty); |
| #else |
| sprintf(tty_device,"/dev/vcsa%d",tty); |
| #endif |
| |
| while(rfbIsActive(console->screen)) { |
| if(!console->currentlyMarking) { |
| tty_file=fopen(tty_device,"rb"); |
| if(!tty_file) { |
| rfbErr("cannot open device \"%s\"\n", |
| tty_device); |
| exit(1); |
| } |
| #ifdef USE_OLD_VCS |
| fread(buffer,width,height,tty_file); |
| #else |
| fread(buffer,width*height*2+4,1,tty_file); |
| vcHideCursor(console); |
| #endif |
| fclose(tty_file); |
| |
| for(i=0;i<console->width*console->height;i++) { |
| if |
| #ifdef USE_OLD_VCS |
| (buffer[i]!=console->screenBuffer[i]) |
| #else |
| (buffer[4+2*i]!=console->screenBuffer[i] || |
| buffer[5+2*i]!=console->attributeBuffer[i]) |
| #endif |
| { |
| console->x=(i%console->width); |
| console->y=(i/console->width); |
| /* |
| rfbLog("changes: %d,%d (%d!=%d || %d!=%d)\n", |
| console->x,console->y, |
| buffer[4+2*i],console->screenBuffer[i], |
| buffer[5+2*i],console->attributeBuffer[i]); |
| */ |
| |
| #ifdef USE_OLD_VCS |
| vcPutChar(console,buffer[i]); |
| #else |
| vcPutCharColour(console,buffer[4+i*2],buffer[5+i*2]&0x7,buffer[5+i*2]>>4); |
| #endif |
| } |
| } |
| console->x=buffer[2]; |
| console->y=buffer[3]; |
| } |
| vcProcessEvents(console); |
| } |
| return(0); |
| } |