# Kdrive evdev support patch, posted by Ander Conselvan de Oliveira at # http://lists.freedesktop.org/archives/xorg/2005-December/011635.html Upstream-Status: Pending Signed-off-by: Yu Ke diff -u -r --exclude=CVS --exclude=Makefile --exclude='*.o' --exclude=ephyr --exclude='*.Po' xserver.original/hw/kdrive/linux/evdev.c xserver/hw/kdrive/linux/evdev.c --- xserver.original/hw/kdrive/linux/evdev.c 2005-12-16 10:36:05.000000000 -0200 +++ xserver/hw/kdrive/linux/evdev.c 2005-12-16 10:40:51.077410192 -0200 @@ -31,9 +31,11 @@ #include #include #include +#include #include "inputstr.h" #include "scrnintstr.h" #include "kdrive.h" +#include "kkeymap.h" #define NUM_EVENTS 128 #define ABS_UNSET -65535 @@ -105,9 +107,10 @@ { KdMouseInfo *mi = closure; Kevdev *ke = mi->driver; - int i; + int i, j; struct input_event events[NUM_EVENTS]; int n; + int flags; n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event)); if (n <= 0) @@ -115,22 +118,64 @@ n /= sizeof (struct input_event); for (i = 0; i < n; i++) { + flags = KD_MOUSE_DELTA | kdMouseInfo->buttonState; switch (events[i].type) { case EV_SYN: break; case EV_KEY: - EvdevMotion (mi); - ASSIGNBIT(ke->key,events[i].code, events[i].value); - if (events[i].code < 0x100) - ErrorF ("key %d %d\n", events[i].code, events[i].value); - else - ErrorF ("key 0x%x %d\n", events[i].code, events[i].value); + if (events[i].code >= BTN_MOUSE && events[i].code < BTN_JOYSTICK) { + switch (events[i].code) { + case BTN_LEFT: + if (events[i].value == 1) + flags |= KD_BUTTON_1; + else + flags &= ~KD_BUTTON_1; + break; + case BTN_MIDDLE: + if (events[i].value == 1) + flags |= KD_BUTTON_2; + else + flags &= ~KD_BUTTON_2; + break; + case BTN_RIGHT: + if (events[i].value == 1) + flags |= KD_BUTTON_3; + else + flags &= ~KD_BUTTON_3; + break; + default: + /* Unknow button */ + break; + } + KdEnqueueMouseEvent (kdMouseInfo, flags, 0, 0); + } break; case EV_REL: - ke->rel[events[i].code] += events[i].value; + if (events[i].code == REL_X) { + KdEnqueueMouseEvent (kdMouseInfo, flags, events[i].value, 0); + } + else if (events[i].code == REL_Y) { + KdEnqueueMouseEvent (kdMouseInfo, flags, 0, events[i].value); + } + else if (events[i].code == REL_WHEEL) { + for (j = 0; j < abs (events[i].value); j++) { + if (events[i].value > 0) + flags |= KD_BUTTON_4; + else + flags |= KD_BUTTON_5; + + KdEnqueueMouseEvent (kdMouseInfo, flags, 0, 0); + + if (events[i].value > 0) + flags &= ~KD_BUTTON_4; + else + flags &= ~KD_BUTTON_5; + + KdEnqueueMouseEvent (kdMouseInfo, flags, 0, 0); + } /* events[i].code == REL_WHEEL */ + } break; case EV_ABS: - ke->abs[events[i].code] = events[i].value; break; } } @@ -173,6 +218,12 @@ fd = open (kdefaultEvdev[i], 2); if (fd >= 0) { + if (ioctl (fd, EVIOCGRAB, 1) < 0) + { + close (fd); + continue; + } + mi->name = KdSaveString (kdefaultEvdev[i]); break; } @@ -287,7 +338,319 @@ EvdevFini, }; -#if 0 +/* Keyboard */ + +int kbd_fd = -1; +int EvdevInputType = 0; + +KeySym evdevKeymap[(194 - 1 + 1) * 2] = { +/* These are directly mapped from DOS scanset 0 */ +/* 1 8 */ XK_Escape, NoSymbol, +/* 2 9 */ XK_1, XK_exclam, +/* 3 10 */ XK_2, XK_at, +/* 4 11 */ XK_3, XK_numbersign, +/* 5 12 */ XK_4, XK_dollar, +/* 6 13 */ XK_5, XK_percent, +/* 7 14 */ XK_6, XK_asciicircum, +/* 8 15 */ XK_7, XK_ampersand, +/* 9 16 */ XK_8, XK_asterisk, +/* 10 17 */ XK_9, XK_parenleft, +/* 11 18 */ XK_0, XK_parenright, +/* 12 19 */ XK_minus, XK_underscore, +/* 13 20 */ XK_equal, XK_plus, +/* 14 21 */ XK_BackSpace, NoSymbol, +/* 15 22 */ XK_Tab, NoSymbol, +/* 16 23 */ XK_Q, NoSymbol, +/* 17 24 */ XK_W, NoSymbol, +/* 18 25 */ XK_E, NoSymbol, +/* 19 26 */ XK_R, NoSymbol, +/* 20 27 */ XK_T, NoSymbol, +/* 21 28 */ XK_Y, NoSymbol, +/* 22 29 */ XK_U, NoSymbol, +/* 23 30 */ XK_I, NoSymbol, +/* 24 31 */ XK_O, NoSymbol, +/* 25 32 */ XK_P, NoSymbol, +/* 26 33 */ XK_bracketleft, XK_braceleft, +/* 27 34 */ XK_bracketright, XK_braceright, +/* 28 35 */ XK_Return, NoSymbol, +/* 29 36 */ XK_Control_L, NoSymbol, +/* 30 37 */ XK_A, NoSymbol, +/* 31 38 */ XK_S, NoSymbol, +/* 32 39 */ XK_D, NoSymbol, +/* 33 40 */ XK_F, NoSymbol, +/* 34 41 */ XK_G, NoSymbol, +/* 35 42 */ XK_H, NoSymbol, +/* 36 43 */ XK_J, NoSymbol, +/* 37 44 */ XK_K, NoSymbol, +/* 38 45 */ XK_L, NoSymbol, +/* 39 46 */ XK_semicolon, XK_colon, +/* 40 47 */ XK_apostrophe, XK_quotedbl, +/* 41 48 */ XK_grave, XK_asciitilde, +/* 42 49 */ XK_Shift_L, NoSymbol, +/* 43 50 */ XK_backslash, XK_bar, +/* 44 51 */ XK_Z, NoSymbol, +/* 45 52 */ XK_X, NoSymbol, +/* 46 53 */ XK_C, NoSymbol, +/* 47 54 */ XK_V, NoSymbol, +/* 48 55 */ XK_B, NoSymbol, +/* 49 56 */ XK_N, NoSymbol, +/* 50 57 */ XK_M, NoSymbol, +/* 51 58 */ XK_comma, XK_less, +/* 52 59 */ XK_period, XK_greater, +/* 53 60 */ XK_slash, XK_question, +/* 54 61 */ XK_Shift_R, NoSymbol, +/* 55 62 */ XK_KP_Multiply, NoSymbol, +/* 56 63 */ XK_Alt_L, XK_Meta_L, +/* 57 64 */ XK_space, NoSymbol, +/* 58 65 */ XK_Caps_Lock, NoSymbol, +/* 59 66 */ XK_F1, NoSymbol, +/* 60 67 */ XK_F2, NoSymbol, +/* 61 68 */ XK_F3, NoSymbol, +/* 62 69 */ XK_F4, NoSymbol, +/* 63 70 */ XK_F5, NoSymbol, +/* 64 71 */ XK_F6, NoSymbol, +/* 65 72 */ XK_F7, NoSymbol, +/* 66 73 */ XK_F8, NoSymbol, +/* 67 74 */ XK_F9, NoSymbol, +/* 68 75 */ XK_F10, NoSymbol, +/* 69 76 */ XK_Break, XK_Pause, +/* 70 77 */ XK_Scroll_Lock, NoSymbol, +/* 71 78 */ XK_KP_Home, XK_KP_7, +/* 72 79 */ XK_KP_Up, XK_KP_8, +/* 73 80 */ XK_KP_Page_Up, XK_KP_9, +/* 74 81 */ XK_KP_Subtract, NoSymbol, +/* 75 82 */ XK_KP_Left, XK_KP_4, +/* 76 83 */ XK_KP_5, NoSymbol, +/* 77 84 */ XK_KP_Right, XK_KP_6, +/* 78 85 */ XK_KP_Add, NoSymbol, +/* 79 86 */ XK_KP_End, XK_KP_1, +/* 80 87 */ XK_KP_Down, XK_KP_2, +/* 81 88 */ XK_KP_Page_Down, XK_KP_3, +/* 82 89 */ XK_KP_Insert, XK_KP_0, +/* 83 90 */ XK_KP_Delete, XK_KP_Decimal, +/* 84 91 */ NoSymbol, NoSymbol, +/* 85 92 */ NoSymbol, NoSymbol, +/* 86 93 */ NoSymbol, NoSymbol, +/* 87 94 */ XK_F11, NoSymbol, +/* 88 95 */ XK_F12, NoSymbol, + +/* These are remapped from the extended set (using ExtendMap) */ + +/* 89 96 */ XK_Control_R, NoSymbol, +/* 90 97 */ XK_KP_Enter, NoSymbol, +/* 91 98 */ XK_KP_Divide, NoSymbol, +/* 92 99 */ XK_Sys_Req, XK_Print, +/* 93 100 */ XK_Alt_R, XK_Meta_R, +/* 94 101 */ XK_Num_Lock, NoSymbol, +/* 95 102 */ XK_Home, NoSymbol, +/* 96 103 */ XK_Up, NoSymbol, +/* 97 104 */ XK_Page_Up, NoSymbol, +/* 98 105 */ XK_Left, NoSymbol, +/* 99 106 */ XK_Right, NoSymbol, +/* 100 107 */ XK_End, NoSymbol, +/* 101 108 */ XK_Down, NoSymbol, +/* 102 109 */ XK_Page_Down, NoSymbol, +/* 103 110 */ XK_Insert, NoSymbol, +/* 104 111 */ XK_Delete, NoSymbol, +/* 105 112 */ XK_Super_L, NoSymbol, +/* 106 113 */ XK_Super_R, NoSymbol, +/* 107 114 */ XK_Menu, NoSymbol, +/* 108 115 */ NoSymbol, NoSymbol, +/* 109 116 */ NoSymbol, NoSymbol, +/* 110 117 */ NoSymbol, NoSymbol, +/* 111 118 */ NoSymbol, NoSymbol, +/* 112 119 */ NoSymbol, NoSymbol, + +/* 113 120 */ NoSymbol, NoSymbol, +/* 114 121 */ NoSymbol, NoSymbol, +/* 115 122 */ NoSymbol, NoSymbol, +/* 116 123 */ NoSymbol, NoSymbol, +/* 117 124 */ NoSymbol, NoSymbol, +/* 118 125 */ NoSymbol, NoSymbol, +/* 119 126 */ NoSymbol, NoSymbol, +/* 120 127 */ NoSymbol, NoSymbol, +/* 121 128 */ NoSymbol, NoSymbol, +/* 122 129 */ NoSymbol, NoSymbol, +/* 123 130 */ NoSymbol, NoSymbol, +/* 124 131 */ NoSymbol, NoSymbol, +/* 125 132 */ NoSymbol, NoSymbol, +/* 126 133 */ NoSymbol, NoSymbol, +/* 127 134 */ NoSymbol, NoSymbol, +/* 128 135 */ NoSymbol, NoSymbol, +/* 129 136 */ NoSymbol, NoSymbol, +/* 130 137 */ NoSymbol, NoSymbol, +/* 131 138 */ NoSymbol, NoSymbol, +/* 132 139 */ NoSymbol, NoSymbol, +/* 133 140 */ NoSymbol, NoSymbol, +/* 134 141 */ NoSymbol, NoSymbol, +/* 135 142 */ NoSymbol, NoSymbol, +/* 136 143 */ NoSymbol, NoSymbol, +/* 137 144 */ NoSymbol, NoSymbol, +/* 138 145 */ NoSymbol, NoSymbol, +/* 139 146 */ NoSymbol, NoSymbol, +/* 140 147 */ NoSymbol, NoSymbol, +/* 141 148 */ NoSymbol, NoSymbol, +/* 142 149 */ NoSymbol, NoSymbol, +/* 143 150 */ NoSymbol, NoSymbol, +/* 144 151 */ NoSymbol, NoSymbol, +/* 145 152 */ NoSymbol, NoSymbol, +/* 146 153 */ NoSymbol, NoSymbol, +/* 147 154 */ NoSymbol, NoSymbol, +/* 148 155 */ NoSymbol, NoSymbol, +/* 149 156 */ NoSymbol, NoSymbol, +/* 150 157 */ NoSymbol, NoSymbol, +/* 151 158 */ NoSymbol, NoSymbol, +/* 152 159 */ NoSymbol, NoSymbol, +/* 153 160 */ NoSymbol, NoSymbol, +/* 154 161 */ NoSymbol, NoSymbol, +/* 155 162 */ NoSymbol, NoSymbol, +/* 156 163 */ NoSymbol, NoSymbol, +/* 157 164 */ NoSymbol, NoSymbol, +/* 158 165 */ NoSymbol, NoSymbol, +/* 159 166 */ NoSymbol, NoSymbol, +/* 160 167 */ NoSymbol, NoSymbol, +/* 161 168 */ NoSymbol, NoSymbol, +/* 162 169 */ NoSymbol, NoSymbol, +/* 163 170 */ NoSymbol, NoSymbol, +/* 164 171 */ NoSymbol, NoSymbol, +/* 165 172 */ NoSymbol, NoSymbol, +/* 166 173 */ NoSymbol, NoSymbol, +/* 167 174 */ NoSymbol, NoSymbol, +/* 168 175 */ NoSymbol, NoSymbol, +/* 169 176 */ NoSymbol, NoSymbol, +/* 170 177 */ NoSymbol, NoSymbol, +/* 171 178 */ NoSymbol, NoSymbol, +/* 172 179 */ NoSymbol, NoSymbol, +/* 173 180 */ NoSymbol, NoSymbol, +/* 174 181 */ NoSymbol, NoSymbol, +/* 175 182 */ NoSymbol, NoSymbol, +/* 176 183 */ NoSymbol, NoSymbol, +/* 177 184 */ NoSymbol, NoSymbol, +/* 178 185 */ NoSymbol, NoSymbol, +/* 179 186 */ NoSymbol, NoSymbol, +/* 180 187 */ NoSymbol, NoSymbol, +/* 181 188 */ NoSymbol, NoSymbol, +/* 182 189 */ NoSymbol, NoSymbol, +/* 183 190 */ NoSymbol, NoSymbol, +/* 184 191 */ NoSymbol, NoSymbol, +/* 185 192 */ NoSymbol, NoSymbol, +/* 186 193 */ NoSymbol, NoSymbol, +/* 187 194 */ NoSymbol, NoSymbol, +/* 188 195 */ NoSymbol, NoSymbol, +/* 189 196 */ NoSymbol, NoSymbol, +/* 190 197 */ NoSymbol, NoSymbol, +/* 191 198 */ NoSymbol, NoSymbol, +/* 192 199 */ NoSymbol, NoSymbol, +/* 193 200 */ NoSymbol, NoSymbol, +/* 194 201 */ NoSymbol, NoSymbol, +}; + +static void +EvdevKbdRead (int fd, void *closure) +{ + int i, n; + struct input_event events[NUM_EVENTS]; + + n = read (fd, &events, NUM_EVENTS * sizeof (struct input_event)); + if (n <= 0) + return; + + n /= sizeof (struct input_event); + + for (i = 0; i < n; i++) + { + if (events[i].type == EV_KEY) + KdEnqueueKeyboardEvent (events[i].code, !events[i].value); + } +} + +static void +EvdevKbdLoad (void) +{ + kdMinScanCode = 0; + kdMaxScanCode = 193; + kdKeymapWidth = 2; + memcpy (kdKeymap, evdevKeymap, sizeof (evdevKeymap)); +} + +static int +EvdevKbdInit (void) +{ + int fd, i; + + if (!EvdevInputType) + EvdevInputType = KdAllocInputType (); + + if (!kdKeyboard) + { + for (i = 0; i < NUM_DEFAULT_EVDEV; i++) + { + fd = open (kdefaultEvdev[i], 2); + if (fd >= 0) + { + kdKeyboard = KdSaveString (kdefaultEvdev[i]); + break; + } + } + } + else + { + fd = open (kdKeyboard, O_RDWR); + if (fd < 0) + return FALSE; + } + + if (ioctl (fd, EVIOCGRAB, 1) < 0) + { + close (fd); + return FALSE; + } + + if (!KdRegisterFd (EvdevInputType, fd, EvdevKbdRead, NULL)) + return FALSE; + + kbd_fd = fd; + return TRUE; +} + +static void +EvdevKbdFini (void) +{ +} + +static void +EvdevKbdLeds (int leds) +{ + struct input_event event; + + memset(&event, 0, sizeof(event)); + + event.type = EV_LED; + event.code = LED_CAPSL; + event.value = leds & (1 << 0) ? 1 : 0; + write(kbd_fd, (char *) &event, sizeof(event)); + + event.type = EV_LED; + event.code = LED_NUML; + event.value = leds & (1 << 1) ? 1 : 0; + write(kbd_fd, (char *) &event, sizeof(event)); + + event.type = EV_LED; + event.code = LED_SCROLLL; + event.value = leds & (1 << 2) ? 1 : 0; + write(kbd_fd, (char *) &event, sizeof(event)); + + event.type = EV_LED; + event.code = LED_COMPOSE; + event.value = leds & (1 << 3) ? 1 : 0; + write(kbd_fd, (char *) &event, sizeof(event)); +} + +static void +EvdevKbdBell (int volume, int frequency, int duration) +{ +} + KdKeyboardFuncs LinuxEvdevKeyboardFuncs = { EvdevKbdLoad, EvdevKbdInit, @@ -296,4 +659,4 @@ EvdevKbdFini, 0, }; -#endif + diff -u -r --exclude=CVS --exclude=Makefile --exclude='*.o' --exclude=ephyr --exclude='*.Po' xserver.original/hw/kdrive/src/kdrive.c xserver/hw/kdrive/src/kdrive.c --- xserver.original/hw/kdrive/src/kdrive.c 2005-12-16 10:36:07.000000000 -0200 +++ xserver/hw/kdrive/src/kdrive.c 2005-12-16 10:37:09.000000000 -0200 @@ -73,6 +73,7 @@ Bool kdEnabled; int kdSubpixelOrder; int kdVirtualTerminal = -1; +char *kdKeyboard = 0; Bool kdSwitchPending; char *kdSwitchCmd; DDXPointRec kdOrigin; @@ -795,6 +796,14 @@ UseMsg (); return 2; } + if (!strcmp (argv[i], "-keyboard")) + { + if ((i+1) < argc) + kdKeyboard = argv[i+1]; + else + UseMsg (); + return 2; + } if (!strcmp (argv[i], "-rgba")) { if ((i+1) < argc) diff -u -r --exclude=CVS --exclude=Makefile --exclude='*.o' --exclude=ephyr --exclude='*.Po' xserver.original/hw/kdrive/src/kdrive.h xserver/hw/kdrive/src/kdrive.h --- xserver.original/hw/kdrive/src/kdrive.h 2005-12-16 10:36:07.000000000 -0200 +++ xserver/hw/kdrive/src/kdrive.h 2005-12-16 10:37:09.000000000 -0200 @@ -416,6 +416,7 @@ extern Bool kdDisableZaphod; extern Bool kdDontZap; extern int kdVirtualTerminal; +extern char *kdKeyboard; extern char *kdSwitchCmd; extern KdOsFuncs *kdOsFuncs; @@ -769,7 +770,7 @@ ProcessInputEvents (void); extern KdMouseFuncs LinuxMouseFuncs; -extern KdMouseFuncs LinuxEvdevFuncs; +extern KdMouseFuncs LinuxEvdevMouseFuncs; extern KdMouseFuncs Ps2MouseFuncs; extern KdMouseFuncs BusMouseFuncs; extern KdMouseFuncs MsMouseFuncs; @@ -777,6 +778,7 @@ extern KdMouseFuncs TsFuncs; #endif extern KdKeyboardFuncs LinuxKeyboardFuncs; +extern KdKeyboardFuncs LinuxEvdevKeyboardFuncs; extern KdOsFuncs LinuxFuncs; extern KdMouseFuncs VxWorksMouseFuncs; diff -u -r --exclude=CVS --exclude=Makefile --exclude='*.o' --exclude=ephyr --exclude='*.Po' xserver.original/hw/kdrive/src/kinput.c xserver/hw/kdrive/src/kinput.c --- xserver.original/hw/kdrive/src/kinput.c 2005-12-16 10:36:07.000000000 -0200 +++ xserver/hw/kdrive/src/kinput.c 2005-12-16 10:37:09.000000000 -0200 @@ -1300,6 +1300,7 @@ xE.u.u.type = KeyPress; xE.u.u.detail = key_code; +#ifndef XKB switch (KEYCOL1(key_code)) { case XK_Num_Lock: @@ -1313,6 +1314,7 @@ else xE.u.u.type = KeyPress; } +#endif /* * Check pressed keys which are already down