|
|
|
#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;
|
|
|
|
//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)
|
|
|
|
rfbErr("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) {
|
|
|
|
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 */
|
|
|
|
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) {
|
|
|
|
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);
|
|
|
|
}
|