# # Dual-head dual-user patch for xorg-x11 (or multi-head multi-user, if you # prefer that). Based on the work of Miguel Freitas and others. # Look at http://cambuca.ldhs.cetuc.puc-rio.br/multiuser/ for detailed # information on how to use this. # # Modified for xorg-x11-6.8.1 by Jan "Yenya" Kasprzak # # KNOWN BUGS: # - Keyboard LED support is still buggy and unfinished. # - on my setup it destroys font on the text console or something like that. # I have no time to investigate this and I don't use text console on this # box (except for booting). diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Config.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Config.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Config.c 2004-08-16 22:17:51.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Config.c 2004-11-19 21:49:47.000000000 +0100 @@ -1195,6 +1195,16 @@ return FALSE; } #endif + } else if (xf86NameCmp(s, "usbev") == 0) { + xf86Info.kbdProc = xf86KbdProc; + xf86Info.kbdEvents = xf86USBKbdEvents; + xf86Msg(X_CONFIG, "Keyboard: Protocol: usbev\n"); + s = xf86SetStrOption(inputp->commonOptions, "Device", "/dev/input/event0"); + xf86Info.kbdFd = open(s, O_RDWR | O_NONBLOCK | O_EXCL); + if (xf86Info.kbdFd == -1) { + xf86ConfigError("Keyboard device: cannot open \"%s\"", s); + return FALSE; + } } else { xf86ConfigError("\"%s\" is not a valid keyboard protocol name", s); xfree(s); diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Globals.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Globals.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Globals.c 2004-07-06 16:37:47.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Globals.c 2004-11-19 21:49:47.000000000 +0100 @@ -245,3 +245,6 @@ * only to be used when using dlopen() modules for debugging purposes. */ #endif + +Bool xf86NoVTSwitches = FALSE; +Bool xf86NoPCIAccessDisable = FALSE; diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Init.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Init.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Init.c 2004-11-18 22:19:31.000000000 +0100 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Init.c 2004-11-19 21:49:47.000000000 +0100 @@ -1429,6 +1429,28 @@ xf86ProbeOnly = TRUE; return 1; } + if (!strcmp(argv[i],"-delay")) + { + int delay; + + if (!argv[i + 1] || (delay = atoi(argv[i + 1])) <= 0) { + sleep(10); + return 1; + } else { + sleep((unsigned) delay); + return 2; + } + } + if (!strcmp(argv[i],"-novtswitches")) + { + xf86NoVTSwitches = TRUE; + return 1; + } + if (!strcmp(argv[i],"-nopciaccessdisable")) + { + xf86NoPCIAccessDisable = TRUE; + return 1; + } if (!strcmp(argv[i],"-flipPixels")) { xf86FlipPixels = TRUE; diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c 2004-11-18 22:19:29.000000000 +0100 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c 2004-11-19 21:49:47.000000000 +0100 @@ -606,6 +606,9 @@ static void pciIoAccessDisable(void* arg) { + if (xf86NoPCIAccessDisable) + return; + #ifdef DEBUG ErrorF("pciIoAccessDisable: 0x%05lx\n", *(PCITAG *)arg); #endif @@ -628,6 +631,9 @@ static void pciIo_MemAccessDisable(void* arg) { + if (xf86NoPCIAccessDisable) + return; + #ifdef DEBUG ErrorF("pciIo_MemAccessDisable: 0x%05lx\n", *(PCITAG *)arg); #endif @@ -650,6 +656,9 @@ static void pciMemAccessDisable(void* arg) { + if (xf86NoPCIAccessDisable) + return; + #ifdef DEBUG ErrorF("pciMemAccessDisable: 0x%05lx\n", *(PCITAG *)arg); #endif diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Priv.h xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Priv.h --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Priv.h 2004-01-29 09:08:26.000000000 +0100 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Priv.h 2004-11-19 21:49:47.000000000 +0100 @@ -115,6 +115,9 @@ extern RootWinPropPtr *xf86RegisteredPropertiesTable; +extern Bool xf86NoVTSwitches; +extern Bool xf86NoPCIAccessDisable; + #ifndef DEFAULT_VERBOSE #define DEFAULT_VERBOSE 0 #endif diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h 2004-01-29 09:08:26.000000000 +0100 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/common/xf86Privstr.h 2004-11-19 21:49:47.000000000 +0100 @@ -82,6 +82,7 @@ int bell_pitch; int bell_duration; Bool autoRepeat; + int ledsave; unsigned long leds; unsigned long xleds; char * vtinit; diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c 2004-04-23 21:54:08.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c 2004-11-19 21:49:47.000000000 +0100 @@ -121,22 +121,35 @@ FatalError( "xf86OpenConsole: Cannot open /dev/tty0 (%s)\n", strerror(errno)); - if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) || - (xf86Info.vtno == -1)) { - FatalError("xf86OpenConsole: Cannot find a free VT\n"); + + if (xf86NoVTSwitches) { + if (ioctl(fd, VT_GETSTATE, &vts) == 0) + { + xf86Info.vtno = vts.v_active; + } else { + FatalError("xf86OpenConsole: Cannot find the current VT\n"); + } + } else { + if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) || + (xf86Info.vtno == -1)) { + FatalError("xf86OpenConsole: Cannot find a free VT\n"); + } } + close(fd); } #ifdef USE_DEV_FB - fb_dev_name=getenv("FRAMEBUFFER"); - if (!fb_dev_name) - fb_dev_name="/dev/fb0current"; - if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0) - FatalError("xf86OpenConsole: Cannot open %s (%s)\n", - fb_dev_name, strerror(errno)); - if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var)) - FatalError("xf86OpenConsole: Unable to get screen info\n"); + if (!xf86NoVTSwitches) { + fb_dev_name=getenv("FRAMEBUFFER"); + if (!fb_dev_name) + fb_dev_name="/dev/fb0current"; + if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0) + FatalError("xf86OpenConsole: Cannot open %s (%s)\n", + fb_dev_name, strerror(errno)); + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var)) + FatalError("xf86OpenConsole: Unable to get screen info\n"); + } #endif xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno); @@ -167,8 +180,12 @@ "xf86OpenConsole: Could not save ownership of VT\n"); } - /* change ownership of the vt */ - chown(vtname, getuid(), getgid()); + /* humm, not a good idea if we don't really use this vt, chowning it would + probably mess with the first XFree instance. Right? i don't know! */ + if (!xf86NoVTSwitches) { + /* change ownership of the vt */ + chown(vtname, getuid(), getgid()); + } /* * the current VT device we're running on is not "console", we want @@ -213,37 +230,42 @@ { xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); } - SYSCALL(result = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT)); - if (result < 0) - { - FatalError("xf86OpenConsole: VT_GETMODE failed\n"); - } - signal(SIGUSR1, xf86VTRequest); + if (xf86NoVTSwitches) { + close(xf86Info.consoleFd); + } else { + SYSCALL(result = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT)); + if (result < 0) + { + FatalError("xf86OpenConsole: VT_GETMODE failed\n"); + } - VT.mode = VT_PROCESS; - VT.relsig = SIGUSR1; - VT.acqsig = SIGUSR1; - if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0) - { - FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n"); - } - if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) - { - FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n"); - } + signal(SIGUSR1, xf86VTRequest); + + VT.mode = VT_PROCESS; + VT.relsig = SIGUSR1; + VT.acqsig = SIGUSR1; + if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0) + { + FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n"); + } + if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) + { + FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n"); + } - /* we really should have a InitOSInputDevices() function instead - * of Init?$#*&Device(). So I just place it here */ - + /* we really should have a InitOSInputDevices() function instead + * of Init?$#*&Device(). So I just place it here */ + #ifdef USE_DEV_FB - /* copy info to new console */ - var.yoffset=0; - var.xoffset=0; - if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var)) - FatalError("Unable to set screen info\n"); - close(fbfd); + /* copy info to new console */ + var.yoffset=0; + var.xoffset=0; + if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var)) + FatalError("Unable to set screen info\n"); + close(fbfd); #endif + } } else { @@ -251,16 +273,18 @@ /* * now get the VT */ - SYSCALL(result = ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno)); - if (result != 0) - { - xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); - } - SYSCALL(result = - ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno)); - if (result != 0) - { - xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); + if (!xf86NoVTSwitches) { + SYSCALL(result = ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno)); + if (result != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n"); + } + SYSCALL(result = + ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno)); + if (result != 0) + { + xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n"); + } } } return; @@ -275,22 +299,23 @@ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno); ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0); #endif - ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */ - if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) - { - VT.mode = VT_AUTO; - ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */ - } - /* - * Perform a switch back to the active VT when we were started - */ - if (activeVT >= 0) - { - ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT); - activeVT = -1; + if (!xf86NoVTSwitches) { + ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */ + if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) + { + VT.mode = VT_AUTO; + ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */ + } + /* + * Perform a switch back to the active VT when we were started + */ + if (activeVT >= 0) + { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT); + activeVT = -1; + } + close(xf86Info.consoleFd); /* make the vt-manager happy */ } - close(xf86Info.consoleFd); /* make the vt-manager happy */ - restoreVtPerms(); /* restore the permissions */ return; diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c 2004-04-23 21:54:08.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c 2004-11-19 21:49:47.000000000 +0100 @@ -33,12 +33,19 @@ #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" +#include +#include #define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ void xf86SoundKbdBell(int loudness, int pitch, int duration) { + /* i guess it should be safe to beep even on a diferent keyboard (?) */ + /* the beep will be on the system speaker anyway... */ + if (xf86Info.kbdEvents == xf86USBKbdEvents) + return; + if (loudness && pitch) { ioctl(xf86Info.consoleFd, KDMKTONE, @@ -51,7 +58,35 @@ void xf86SetKbdLeds(int leds) { - ioctl(xf86Info.consoleFd, KDSETLED, leds); + struct s_output_event { + struct timeval time; + unsigned short type; + unsigned short code; + unsigned int value; + } output_event; + + fprintf(stderr, "xf86SetKbdLeds(0x%x) called\n", leds); + if (xf86Info.kbdEvents != xf86USBKbdEvents) { + ioctl(xf86Info.consoleFd, KDSETLED, leds); + return; + } + + output_event.type = EV_LED; + output_event.code = LED_NUML; + output_event.value = (leds&(LED_NUM)) ? 1 : 0; + write( xf86Info.kbdFd, (char *)&output_event, sizeof(output_event)); + + output_event.type = EV_LED; + output_event.code = LED_CAPSL; + output_event.value = (leds&(LED_CAP)) ? 1 : 0; + write( xf86Info.kbdFd, (char *)&output_event, sizeof(output_event)); + + output_event.type = EV_LED; + output_event.code = LED_SCROLLL; + output_event.value = (leds&(LED_SCR)) ? 1 : 0; + write( xf86Info.kbdFd, (char *)&output_event, sizeof(output_event)); + + xf86Info.ledsave = leds; } int @@ -59,7 +94,13 @@ { int leds = 0; - ioctl(xf86Info.consoleFd, KDGETLED, &leds); + if (xf86Info.kbdEvents == xf86USBKbdEvents) { + leds = xf86Info.ledsave; + } else { + ioctl(xf86Info.consoleFd, KDGETLED, &leds); + } + + fprintf(stderr, "xf86GetKbdLeds called, returing 0x%x\n", leds); return(leds); } @@ -173,6 +214,10 @@ if (xf86Info.kbdDelay >= 0) delay = xf86Info.kbdDelay; + /* FIXME: just returning so we don't mess with any other keyboards... */ + if (xf86Info.kbdEvents == xf86USBKbdEvents) + return; + if(KDKBDREP_ioctl_ok(rate, delay)) /* m68k? */ return; @@ -223,14 +268,24 @@ void xf86KbdInit() { - ioctl (xf86Info.consoleFd, KDGKBMODE, &kbdtrans); - tcgetattr (xf86Info.consoleFd, &kbdtty); + if (xf86Info.kbdEvents == xf86USBKbdEvents) { + int data; + data=1; + if (ioctl(xf86Info.kbdFd, EVIOCGRAB, &data) == 0) + printf("exclusive access granted"); + } else { + ioctl (xf86Info.consoleFd, KDGKBMODE, &kbdtrans); + tcgetattr (xf86Info.consoleFd, &kbdtty); + } } int xf86KbdOn() { struct termios nTty; + + if (xf86Info.kbdEvents == xf86USBKbdEvents) + return(xf86Info.kbdFd); #ifdef __powerpc__ if (xf86Info.kbdCustomKeycodes) @@ -255,6 +310,9 @@ int xf86KbdOff() { + if (xf86Info.kbdEvents == xf86USBKbdEvents) + return(xf86Info.kbdFd); + ioctl(xf86Info.consoleFd, KDSKBMODE, kbdtrans); tcsetattr(xf86Info.consoleFd, TCSANOW, &kbdtty); return(xf86Info.consoleFd); diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.c 2004-04-23 21:54:08.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.c 2004-11-19 21:49:47.000000000 +0100 @@ -22,11 +22,13 @@ #include "xf86OSKbd.h" #include "atKeynames.h" #include "lnx_kbd.h" +#include #define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ static KbdProtocolRec protocols[] = { {"standard", PROT_STD }, + {"usbev", PROT_USB }, { NULL, PROT_UNKNOWN_KBD } }; @@ -76,6 +78,45 @@ ioctl(pInfo->fd, KDSETLED, real_leds); } +static void +SetUSBKbdLeds(InputInfoPtr pInfo, int leds) +{ + struct s_output_event { + struct timeval time; + unsigned short type; + unsigned short code; + unsigned int value; + } output_event; + int real_leds = 0; + fprintf(stderr, "SetUSBKbdLeds called with leds=0x%x\n", leds); + fprintf(stderr, "CAP=0x%x, NUM=0x%x, SCR=0x%x\n", LED_CAP, LED_NUM, LED_SCR); +#ifdef LED_CAP + if (leds & XLED1) real_leds |= LED_CAP; + if (leds & XLED2) real_leds |= LED_NUM; + if (leds & XLED3) real_leds |= LED_SCR; +#ifdef LED_COMP + if (leds & XLED4) real_leds |= LED_COMP; +#else + if (leds & XLED4) real_leds |= LED_SCR; +#endif +#endif + output_event.type = EV_LED; + output_event.code = LED_NUML; + output_event.value = (leds&(LED_NUM)) ? 1 : 0; + write(pInfo->fd, (char *)&output_event, sizeof(output_event)); + + output_event.type = EV_LED; + output_event.code = LED_CAPSL; + output_event.value = (leds&(LED_CAP)) ? 1 : 0; + write(pInfo->fd, (char *)&output_event, sizeof(output_event)); + + output_event.type = EV_LED; + output_event.code = LED_SCROLLL; + output_event.value = (leds&(LED_SCR)) ? 1 : 0; + write(pInfo->fd, (char *)&output_event, sizeof(output_event)); + + xf86Info.ledsave = leds; +} static int GetKbdLeds(InputInfoPtr pInfo) { @@ -87,6 +128,7 @@ if (real_leds & LED_NUM) leds |= XLED2; if (real_leds & LED_SCR) leds |= XLED3; + fprintf(stderr, "GetKbdLeds called, returing 0x%x\n", leds); return(leds); } @@ -442,6 +484,62 @@ } } +static unsigned short x86_keycodes[256] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90, + 284,285,309,311,312, 91,327,328,329,331,333,335,336,337,338,339, + 367,294,293,286,350, 92,334,512,116,377,109,111,373,347,348,349, + 360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355, + 103,104,105,275,281,272,306,106,274,107,288,364,358,363,362,361, + 291,108,381,290,287,292,279,305,280, 99,112,257,258,113,270,114, + 118,117,125,374,379,259,260,261,262,263,264,265,266,267,268,269, + 271,273,276,277,278,282,283,295,296,297,299,300,301,302,303,307, + 308,310,313,314,315,317,318,319,320,321,322,323,324,325,326,330, + 332,340,341,342,343,344,345,346,356,359,365,368,369,370,371,372 }; + +static void handle_scancode(InputInfoPtr pInfo, int code, int down) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + pKbd->PostEvent(pInfo, code & 0x7f, down); +} + + +static void +usbReadInput(InputInfoPtr pInfo) +{ + struct input_event { + struct timeval time; + unsigned short type; + unsigned short code; + unsigned int value; + } ev; + + int nBytes; + if ((nBytes = read( pInfo->fd, (char *)&ev, sizeof(ev))) > 0) { + if (ev.type == EV_KEY) { + unsigned int keycode = ev.code; + + if (keycode > 255 || !x86_keycodes[keycode]) + return; + + if (keycode == KEY_PAUSE) { + handle_scancode(pInfo, 0xe1, 1); + handle_scancode(pInfo, 0x1d, ev.value); + handle_scancode(pInfo, 0x45, ev.value); + return; + } + if (x86_keycodes[keycode] & 0x100) + handle_scancode(pInfo, 0xe0, 1); + + handle_scancode(pInfo, x86_keycodes[keycode] & 0x7f, ev.value); + } + } +} + static Bool OpenKeyboard(InputInfoPtr pInfo) { @@ -449,6 +547,7 @@ int i; KbdProtocolId prot = PROT_UNKNOWN_KBD; char *s; + int flag = O_RDONLY; s = xf86SetStrOption(pInfo->options, "Protocol", NULL); for (i = 0; protocols[i].name; i++) { @@ -461,6 +560,12 @@ switch (prot) { case PROT_STD: pInfo->read_input = stdReadInput; + pKbd->SetLeds = SetKbdLeds; + break; + case PROT_USB: + pInfo->read_input = usbReadInput; + pKbd->SetLeds = SetUSBKbdLeds; + flag = O_RDWR; break; default: xf86Msg(X_ERROR,"\"%s\" is not a valid keyboard protocol name\n", s); @@ -476,7 +581,7 @@ pInfo->fd = xf86Info.consoleFd; pKbd->isConsole = TRUE; } else { - pInfo->fd = open(s, O_RDONLY | O_NONBLOCK | O_EXCL); + pInfo->fd = open(s, flag | O_NONBLOCK | O_EXCL); if (pInfo->fd == -1) { xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", pInfo->name, s); xfree(s); @@ -501,7 +606,6 @@ pKbd->KbdOn = KbdOn; pKbd->KbdOff = KbdOff; pKbd->Bell = SoundBell; - pKbd->SetLeds = SetKbdLeds; pKbd->GetLeds = GetKbdLeds; pKbd->SetKbdRepeat = SetKbdRepeat; pKbd->KbdGetMapping = KbdGetMapping; diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c 2004-04-23 21:54:12.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c 2004-11-19 21:49:47.000000000 +0100 @@ -25,10 +25,53 @@ */ /* $XConsortium: std_kbdEv.c /main/4 1996/03/11 10:47:33 kaleb $ */ +/* 2001/01/14 Miguel Freitas + * + * USB Keyboard to PC-AT Keyboard HACK + * + * Included routines from Linux Kernel to handle usb keyboard events. + * I don't know if there are any license issues here. Any code written + * by me in this file is under the terms of the GNU General Public + * License as described below. + * +*/ + +/* + * $Id$ + * + * Copyright (c) 1999-2000 Vojtech Pavlik + * + * Input driver to keyboard driver binding. + * + * Sponsored by SuSE + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Should you need to contact me, the author, you can do so either by + * e-mail - mail your message to , or by paper mail: + * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic + */ + + #include "X.h" #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" +#include void xf86KbdEvents() @@ -44,3 +87,68 @@ } } +static unsigned short x86_keycodes[256] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90, + 284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339, + 367,294,293,286,350, 92,334,512,116,377,109,111,373,347,348,349, + 360, 93, 94, 95, 98,376,100,101,357,316,354,304,289,102,351,355, + 103,104,105,275,281,272,306,106,274,107,288,364,358,363,362,361, + 291,108,381,290,287,292,279,305,280, 99,112,257,258,113,270,114, + 118,117,125,374,379,259,260,261,262,263,264,265,266,267,268,269, + 271,273,276,277,278,282,283,295,296,297,299,300,301,302,303,307, + 308,310,313,314,315,317,318,319,320,321,322,323,324,325,326,330, + 332,340,341,342,343,344,345,346,356,359,365,368,369,370,371,372 }; + +static void handle_scancode(unsigned char scancode, int down) +{ + char up_flag = down ? 0 : 0200; + + xf86PostKbdEvent(scancode | up_flag); +} + +static int emulate_raw(unsigned int keycode, int down) +{ + if (keycode > 255 || !x86_keycodes[keycode]) + return -1; + + if (keycode == KEY_PAUSE) { + handle_scancode(0xe1, 1); + handle_scancode(0x1d, down); + handle_scancode(0x45, down); + return 0; + } + + if (x86_keycodes[keycode] & 0x100) + handle_scancode(0xe0, 1); + + handle_scancode(x86_keycodes[keycode] & 0x7f, down); + + if (keycode == KEY_SYSRQ) { + handle_scancode(0xe0, 1); + handle_scancode(0x37, down); + } + + return 0; +} + +void +xf86USBKbdEvents() +{ + struct input_event { + struct timeval time; + unsigned short type; + unsigned short code; + unsigned int value; + } ev; + + int nBytes; + + while ((nBytes = read(xf86Info.kbdFd, (char *)&ev, sizeof(ev))) > 0) + if (ev.type == EV_KEY) + emulate_raw(ev.code, ev.value); +} diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c 2004-04-23 21:54:12.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c 2004-11-19 21:49:47.000000000 +0100 @@ -41,6 +41,9 @@ void xf86VTRequest(int sig) { + if (xf86NoVTSwitches) + return; + signal(sig, (void(*)(int))xf86VTRequest); xf86Info.vtRequestsPending = TRUE; return; @@ -49,12 +52,15 @@ Bool xf86VTSwitchPending() { - return(xf86Info.vtRequestsPending ? TRUE : FALSE); + return(!xf86NoVTSwitches && xf86Info.vtRequestsPending ? TRUE : FALSE); } Bool xf86VTSwitchAway() { + if (xf86NoVTSwitches) + return FALSE; + xf86Info.vtRequestsPending = FALSE; if (ioctl(xf86Info.consoleFd, VT_RELDISP, 1) < 0) { @@ -69,6 +75,9 @@ Bool xf86VTSwitchTo() { + if (xf86NoVTSwitches) + return TRUE; + xf86Info.vtRequestsPending = FALSE; if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0) { diff -uNr xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h --- xorg-x11-6.8.1-rhbuild/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h 2004-04-23 21:54:07.000000000 +0200 +++ xorg-x11-6.8.1/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h 2004-11-19 21:49:47.000000000 +0100 @@ -229,6 +229,7 @@ extern int xf86KbdOn(void); extern int xf86KbdOff(void); extern void xf86KbdEvents(void); +extern void xf86USBKbdEvents(void); #ifdef XQUEUE extern int xf86XqueKbdProc(DeviceIntPtr, int); extern void xf86XqueEvents(void);