#include "VNConsole.h" #include "vga.h" #include #include 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; //rfbLog("do_key: %c (0x%lx)\n",(char)keySym,keySym); 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) rfbLog("Couldn't reopen device %s!\n",device); } } } } else if(keySym==XK_Control_L || keySym==XK_Control_R) 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) { rfbLog("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) { rfbLog("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 */ console=vcGetConsole(&argc,argv,width,height,&vgaFont,TRUE); for(i=0;i<16;i++) { console->rfbScreen->colourMap.data.bytes[i*3+0]=default_red[color_table[i]]; console->rfbScreen->colourMap.data.bytes[i*3+1]=default_grn[color_table[i]]; console->rfbScreen->colourMap.data.bytes[i*3+2]=default_blu[color_table[i]]; } console->rfbScreen->desktopName=title; console->rfbScreen->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(1) { if(!console->currentlyMarking) { tty_file=fopen(tty_device,"rb"); if(!tty_file) { rfbLog("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;iwidth*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); }