--- evdev.c.orig 2005-09-20 20:15:15.000000000 +0900 +++ evdev.c 2005-09-21 18:59:42.000000000 +0900 @@ -36,6 +36,7 @@ * twice. */ #include +#include #include #include @@ -49,6 +50,10 @@ #include +#ifdef XFreeXDGA +#include +#endif + /* 2.4 compatibility */ #ifndef EVIOCGRAB #define EVIOCGRAB _IOW('E', 0x90, int) @@ -79,6 +84,8 @@ #define MODEFLAG 8 #define COMPOSEFLAG 16 +#define MAX_BUTTON_COUNT 32 + typedef struct { int kernel24; } EvdevRec, *EvdevPtr; @@ -88,6 +95,33 @@ static int wheel_left_button = 6; static int wheel_right_button = 7; +static int vtSwitchEnabled = 1; + +static int +IsModifierPressed(KeyClassRec *keyc, int keymask) +{ + return (keyc->state & (keymask)) == (keymask); +} + +static void +DoTerminate() +{ +#ifdef XFreeDGA + DGAShutDown(); +#endif + GiveUp (0); +} + +static void +DoSwitchScreen (int vtno) +{ + int fd = open("/dev/console", O_WRONLY); + if (fd < 0 || ioctl(fd, VT_ACTIVATE, (void*)(size_t) vtno) < 0) { + ErrorF("Failed to switch consoles (%s)\n", strerror(errno)); + } + close(fd); +} + static void PostButtonClicks(InputInfoPtr pInfo, int button, int count) { @@ -100,6 +134,67 @@ } static void +EvdevProcessKeyEvent(InputInfoPtr pInfo, int keycode, int pressed) +{ + +#ifdef XKB + + /* Process special action key bindings. */ + /* FIXME Action key bindings should not be hardcoded here */ + KeyClassRec *keyc = pInfo->dev->key; + + /* Actin key bindings are disabled while screen saver is running */ + /* I'm not sure if this is correct, so please remove it if it's wrong */ + + if (!xf86inSuspend && + !(IsModifierPressed(keyc, ShiftMask)) && + ((IsModifierPressed(keyc, ControlMask | AltMask)) || + (IsModifierPressed(keyc, ControlMask | AltLangMask)))) { + + switch (keycode) { + case KEY_BACKSPACE: + DoTerminate(); + return; + + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + case KEY_F11: + case KEY_F12: + if (vtSwitchEnabled) { + int vtno; + + /* keycodes for F11 and F12 are a bit strange */ + if (keycode != KEY_F11 && keycode != KEY_F12) + vtno = keycode - KEY_F1 + 1; + else + vtno = keycode - KEY_F11 + 11; + + DoSwitchScreen (vtno); + return; + } + break; + + default: + break; + } + + } + +#endif /*XKB*/ + + xf86PostKeyboardEvent(pInfo->dev, keycode + MIN_KEYCODE, pressed); + +} + +static void EvdevReadInput(InputInfoPtr pInfo) { struct input_event ev; @@ -109,8 +204,8 @@ dx = 0; dy = 0; - while (xf86WaitForInput (pInfo->fd, 0) > 0) { - len = read(pInfo->fd, &ev, sizeof ev); + while (pInfo->fd > 0 && xf86WaitForInput (pInfo->fd, 0) > 0) { + len = read(pInfo->fd, &ev, sizeof(ev)); if (len != sizeof ev) { /* The kernel promises that we always only read a complete * event, so len != sizeof ev is an error. */ @@ -157,7 +252,7 @@ case BTN_RIGHT: case BTN_MIDDLE: xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 1, - value, 0, 0); + value, 0, 0); break; case BTN_SIDE: @@ -166,12 +261,11 @@ case BTN_BACK: case BTN_TASK: xf86PostButtonEvent(pInfo->dev, 0, ev.code - BTN_LEFT + 5, - value, 0, 0); + value, 0, 0); break; default: - xf86PostKeyboardEvent(pInfo->dev, - ev.code + MIN_KEYCODE, value); + EvdevProcessKeyEvent (pInfo, ev.code, value); } break; @@ -196,139 +290,241 @@ * probably don't. The easiest is to remap the event keycodes. */ static KeySym map[] = { - /* 0x00 */ NoSymbol, NoSymbol, - /* 0x01 */ XK_Escape, NoSymbol, - /* 0x02 */ XK_1, XK_exclam, - /* 0x03 */ XK_2, XK_at, - /* 0x04 */ XK_3, XK_numbersign, - /* 0x05 */ XK_4, XK_dollar, - /* 0x06 */ XK_5, XK_percent, - /* 0x07 */ XK_6, XK_asciicircum, - /* 0x08 */ XK_7, XK_ampersand, - /* 0x09 */ XK_8, XK_asterisk, - /* 0x0a */ XK_9, XK_parenleft, - /* 0x0b */ XK_0, XK_parenright, - /* 0x0c */ XK_minus, XK_underscore, - /* 0x0d */ XK_equal, XK_plus, - /* 0x0e */ XK_BackSpace, NoSymbol, - /* 0x0f */ XK_Tab, XK_ISO_Left_Tab, - /* 0x10 */ XK_Q, NoSymbol, - /* 0x11 */ XK_W, NoSymbol, - /* 0x12 */ XK_E, NoSymbol, - /* 0x13 */ XK_R, NoSymbol, - /* 0x14 */ XK_T, NoSymbol, - /* 0x15 */ XK_Y, NoSymbol, - /* 0x16 */ XK_U, NoSymbol, - /* 0x17 */ XK_I, NoSymbol, - /* 0x18 */ XK_O, NoSymbol, - /* 0x19 */ XK_P, NoSymbol, - /* 0x1a */ XK_bracketleft, XK_braceleft, - /* 0x1b */ XK_bracketright,XK_braceright, - /* 0x1c */ XK_Return, NoSymbol, - /* 0x1d */ XK_Control_L, NoSymbol, - /* 0x1e */ XK_A, NoSymbol, - /* 0x1f */ XK_S, NoSymbol, - /* 0x20 */ XK_D, NoSymbol, - /* 0x21 */ XK_F, NoSymbol, - /* 0x22 */ XK_G, NoSymbol, - /* 0x23 */ XK_H, NoSymbol, - /* 0x24 */ XK_J, NoSymbol, - /* 0x25 */ XK_K, NoSymbol, - /* 0x26 */ XK_L, NoSymbol, - /* 0x27 */ XK_semicolon, XK_colon, - /* 0x28 */ XK_quoteright, XK_quotedbl, - /* 0x29 */ XK_quoteleft, XK_asciitilde, - /* 0x2a */ XK_Shift_L, NoSymbol, - /* 0x2b */ XK_backslash, XK_bar, - /* 0x2c */ XK_Z, NoSymbol, - /* 0x2d */ XK_X, NoSymbol, - /* 0x2e */ XK_C, NoSymbol, - /* 0x2f */ XK_V, NoSymbol, - /* 0x30 */ XK_B, NoSymbol, - /* 0x31 */ XK_N, NoSymbol, - /* 0x32 */ XK_M, NoSymbol, - /* 0x33 */ XK_comma, XK_less, - /* 0x34 */ XK_period, XK_greater, - /* 0x35 */ XK_slash, XK_question, - /* 0x36 */ XK_Shift_R, NoSymbol, - /* 0x37 */ XK_KP_Multiply, NoSymbol, - /* 0x38 */ XK_Alt_L, XK_Meta_L, - /* 0x39 */ XK_space, NoSymbol, - /* 0x3a */ XK_Caps_Lock, NoSymbol, - /* 0x3b */ XK_F1, NoSymbol, - /* 0x3c */ XK_F2, NoSymbol, - /* 0x3d */ XK_F3, NoSymbol, - /* 0x3e */ XK_F4, NoSymbol, - /* 0x3f */ XK_F5, NoSymbol, - /* 0x40 */ XK_F6, NoSymbol, - /* 0x41 */ XK_F7, NoSymbol, - /* 0x42 */ XK_F8, NoSymbol, - /* 0x43 */ XK_F9, NoSymbol, - /* 0x44 */ XK_F10, NoSymbol, - /* 0x45 */ XK_Num_Lock, NoSymbol, - /* 0x46 */ XK_Scroll_Lock, NoSymbol, + /* 0x00 */ NoSymbol, NoSymbol, + /* 0x01 */ XK_Escape, NoSymbol, + /* 0x02 */ XK_1, XK_exclam, + /* 0x03 */ XK_2, XK_at, + /* 0x04 */ XK_3, XK_numbersign, + /* 0x05 */ XK_4, XK_dollar, + /* 0x06 */ XK_5, XK_percent, + /* 0x07 */ XK_6, XK_asciicircum, + /* 0x08 */ XK_7, XK_ampersand, + /* 0x09 */ XK_8, XK_asterisk, + /* 0x0a */ XK_9, XK_parenleft, + /* 0x0b */ XK_0, XK_parenright, + /* 0x0c */ XK_minus, XK_underscore, + /* 0x0d */ XK_equal, XK_plus, + /* 0x0e */ XK_BackSpace, NoSymbol, + /* 0x0f */ XK_Tab, XK_ISO_Left_Tab, + /* 0x10 */ XK_Q, NoSymbol, + /* 0x11 */ XK_W, NoSymbol, + /* 0x12 */ XK_E, NoSymbol, + /* 0x13 */ XK_R, NoSymbol, + /* 0x14 */ XK_T, NoSymbol, + /* 0x15 */ XK_Y, NoSymbol, + /* 0x16 */ XK_U, NoSymbol, + /* 0x17 */ XK_I, NoSymbol, + /* 0x18 */ XK_O, NoSymbol, + /* 0x19 */ XK_P, NoSymbol, + /* 0x1a */ XK_bracketleft, XK_braceleft, + /* 0x1b */ XK_bracketright, XK_braceright, + /* 0x1c */ XK_Return, NoSymbol, + /* 0x1d */ XK_Control_L, NoSymbol, + /* 0x1e */ XK_A, NoSymbol, + /* 0x1f */ XK_S, NoSymbol, + /* 0x20 */ XK_D, NoSymbol, + /* 0x21 */ XK_F, NoSymbol, + /* 0x22 */ XK_G, NoSymbol, + /* 0x23 */ XK_H, NoSymbol, + /* 0x24 */ XK_J, NoSymbol, + /* 0x25 */ XK_K, NoSymbol, + /* 0x26 */ XK_L, NoSymbol, + /* 0x27 */ XK_semicolon, XK_colon, + /* 0x28 */ XK_quoteright, XK_quotedbl, + /* 0x29 */ XK_quoteleft, XK_asciitilde, + /* 0x2a */ XK_Shift_L, NoSymbol, + /* 0x2b */ XK_backslash, XK_bar, + /* 0x2c */ XK_Z, NoSymbol, + /* 0x2d */ XK_X, NoSymbol, + /* 0x2e */ XK_C, NoSymbol, + /* 0x2f */ XK_V, NoSymbol, + /* 0x30 */ XK_B, NoSymbol, + /* 0x31 */ XK_N, NoSymbol, + /* 0x32 */ XK_M, NoSymbol, + /* 0x33 */ XK_comma, XK_less, + /* 0x34 */ XK_period, XK_greater, + /* 0x35 */ XK_slash, XK_question, + /* 0x36 */ XK_Shift_R, NoSymbol, + /* 0x37 */ XK_KP_Multiply, NoSymbol, + /* 0x38 */ XK_Alt_L, XK_Meta_L, + /* 0x39 */ XK_space, NoSymbol, + /* 0x3a */ XK_Caps_Lock, NoSymbol, + /* 0x3b */ XK_F1, NoSymbol, + /* 0x3c */ XK_F2, NoSymbol, + /* 0x3d */ XK_F3, NoSymbol, + /* 0x3e */ XK_F4, NoSymbol, + /* 0x3f */ XK_F5, NoSymbol, + /* 0x40 */ XK_F6, NoSymbol, + /* 0x41 */ XK_F7, NoSymbol, + /* 0x42 */ XK_F8, NoSymbol, + /* 0x43 */ XK_F9, NoSymbol, + /* 0x44 */ XK_F10, NoSymbol, + /* 0x45 */ XK_Num_Lock, NoSymbol, + /* 0x46 */ XK_Scroll_Lock, NoSymbol, + /* These KP keys should have the KP_7 keysyms in the numlock * modifer... ? */ - /* 0x47 */ XK_KP_Home, XK_KP_7, - /* 0x48 */ XK_KP_Up, XK_KP_8, - /* 0x49 */ XK_KP_Prior, XK_KP_9, - /* 0x4a */ XK_KP_Subtract, NoSymbol, - /* 0x4b */ XK_KP_Left, XK_KP_4, - /* 0x4c */ XK_KP_Begin, XK_KP_5, - /* 0x4d */ XK_KP_Right, XK_KP_6, - /* 0x4e */ XK_KP_Add, NoSymbol, - /* 0x4f */ XK_KP_End, XK_KP_1, - /* 0x50 */ XK_KP_Down, XK_KP_2, - /* 0x51 */ XK_KP_Next, XK_KP_3, - /* 0x52 */ XK_KP_Insert, XK_KP_0, - /* 0x53 */ XK_KP_Delete, XK_KP_Decimal, - /* 0x54 */ NoSymbol, NoSymbol, - /* 0x55 */ XK_F13, NoSymbol, - /* 0x56 */ XK_less, XK_greater, - /* 0x57 */ XK_F11, NoSymbol, - /* 0x58 */ XK_F12, NoSymbol, - /* 0x59 */ XK_F14, NoSymbol, - /* 0x5a */ XK_F15, NoSymbol, - /* 0x5b */ XK_F16, NoSymbol, - /* 0x5c */ XK_F17, NoSymbol, - /* 0x5d */ XK_F18, NoSymbol, - /* 0x5e */ XK_F19, NoSymbol, - /* 0x5f */ XK_F20, NoSymbol, - /* 0x60 */ XK_KP_Enter, NoSymbol, - /* 0x61 */ XK_Control_R, NoSymbol, - /* 0x62 */ XK_KP_Divide, NoSymbol, - /* 0x63 */ XK_Print, XK_Sys_Req, - /* 0x64 */ XK_Alt_R, XK_Meta_R, - /* 0x65 */ NoSymbol, NoSymbol, /* KEY_LINEFEED */ - /* 0x66 */ XK_Home, NoSymbol, - /* 0x67 */ XK_Up, NoSymbol, - /* 0x68 */ XK_Prior, NoSymbol, - /* 0x69 */ XK_Left, NoSymbol, - /* 0x6a */ XK_Right, NoSymbol, - /* 0x6b */ XK_End, NoSymbol, - /* 0x6c */ XK_Down, NoSymbol, - /* 0x6d */ XK_Next, NoSymbol, - /* 0x6e */ XK_Insert, NoSymbol, - /* 0x6f */ XK_Delete, NoSymbol, - /* 0x6f */ NoSymbol, NoSymbol, /* KEY_MACRO */ - /* 0x70 */ NoSymbol, NoSymbol, - /* 0x71 */ NoSymbol, NoSymbol, - /* 0x72 */ NoSymbol, NoSymbol, - /* 0x73 */ NoSymbol, NoSymbol, - /* 0x74 */ NoSymbol, NoSymbol, - /* 0x75 */ XK_KP_Equal, NoSymbol, - /* 0x76 */ NoSymbol, NoSymbol, - /* 0x77 */ NoSymbol, NoSymbol, - /* 0x78 */ XK_F21, NoSymbol, - /* 0x79 */ XK_F22, NoSymbol, - /* 0x7a */ XK_F23, NoSymbol, - /* 0x7b */ XK_F24, NoSymbol, - /* 0x7c */ XK_KP_Separator, NoSymbol, - /* 0x7d */ XK_Meta_L, NoSymbol, - /* 0x7e */ XK_Meta_R, NoSymbol, - /* 0x7f */ XK_Multi_key, NoSymbol, + /* 0x47 */ XK_KP_Home, XK_KP_7, + /* 0x48 */ XK_KP_Up, XK_KP_8, + /* 0x49 */ XK_KP_Prior, XK_KP_9, + /* 0x4a */ XK_KP_Subtract, NoSymbol, + /* 0x4b */ XK_KP_Left, XK_KP_4, + /* 0x4c */ XK_KP_Begin, XK_KP_5, + /* 0x4d */ XK_KP_Right, XK_KP_6, + /* 0x4e */ XK_KP_Add, NoSymbol, + /* 0x4f */ XK_KP_End, XK_KP_1, + /* 0x50 */ XK_KP_Down, XK_KP_2, + /* 0x51 */ XK_KP_Next, XK_KP_3, + /* 0x52 */ XK_KP_Insert, XK_KP_0, + /* 0x53 */ XK_KP_Delete, XK_KP_Decimal, + /* 0x54 */ NoSymbol, NoSymbol, + /* 0x55 */ XK_Zenkaku_Hankaku, NoSymbol, + /* 0x56 */ NoSymbol, NoSymbol, /* KEY_102ND */ + /* 0x57 */ XK_F11, NoSymbol, + /* 0x58 */ XK_F12, NoSymbol, + /* 0x59 */ XK_Romaji, NoSymbol, + /* 0x5a */ XK_Katakana, NoSymbol, + /* 0x5b */ XK_Hiragana, NoSymbol, + /* 0x5c */ XK_Henkan_Mode, NoSymbol, + /* 0x5d */ XK_Hiragana_Katakana, NoSymbol, + /* 0x5e */ XK_Muhenkan, NoSymbol, + /* 0x5f */ NoSymbol, NoSymbol, /* KEY_KPJPCOMMA */ + /* 0x60 */ XK_KP_Enter, NoSymbol, + /* 0x61 */ XK_Control_R, NoSymbol, + /* 0x62 */ XK_KP_Divide, NoSymbol, + /* 0x63 */ XK_Print, XK_Sys_Req, + /* 0x64 */ XK_Alt_R, XK_Meta_R, + /* 0x65 */ NoSymbol, NoSymbol, /* KEY_LINEFEED */ + /* 0x66 */ XK_Home, NoSymbol, + /* 0x67 */ XK_Up, NoSymbol, + /* 0x68 */ XK_Prior, NoSymbol, + /* 0x69 */ XK_Left, NoSymbol, + /* 0x6a */ XK_Right, NoSymbol, + /* 0x6b */ XK_End, NoSymbol, + /* 0x6c */ XK_Down, NoSymbol, + /* 0x6d */ XK_Next, NoSymbol, + /* 0x6e */ XK_Insert, NoSymbol, + /* 0x6f */ XK_Delete, NoSymbol, + /* 0x70 */ NoSymbol, NoSymbol, /* KEY_MACRO */ + + /* 0x71 */ XF86XK_AudioMute, NoSymbol, + /* 0x72 */ XF86XK_AudioLowerVolume, NoSymbol, + /* 0x73 */ XF86XK_AudioRaiseVolume, NoSymbol, + /* 0x74 */ XF86XK_PowerOff, NoSymbol, + /* 0x75 */ XK_KP_Equal, NoSymbol, + /* 0x76 */ NoSymbol, NoSymbol, /* KEY_KPPLUSMINUS */ + /* 0x77 */ XK_Pause, NoSymbol, + /* 0x78 */ NoSymbol, NoSymbol, + /* 0x79 */ XK_KP_Separator, NoSymbol, + /* 0x7a */ XK_Hangul, NoSymbol, + /* 0x7b */ XK_Hangul_Hanja, NoSymbol, + /* 0x7c */ XK_yen, NoSymbol, + /* 0x7d */ XK_Meta_L, NoSymbol, + /* 0x7e */ XK_Meta_R, NoSymbol, + /* 0x7f */ XK_Multi_key, NoSymbol, + + /* 0x80 */ XF86XK_Stop, NoSymbol, + /* 0x81 */ XK_Redo, NoSymbol, + /* 0x82 */ NoSymbol, NoSymbol, /* KEY_PROPS */ + /* 0x83 */ XK_Undo, NoSymbol, + /* 0x84 */ NoSymbol, NoSymbol, /* KEY_FRONT */ + /* 0x85 */ XF86XK_Copy, NoSymbol, + /* 0x86 */ XF86XK_Open, NoSymbol, + /* 0x87 */ XF86XK_Paste, NoSymbol, + /* 0x88 */ XK_Find, NoSymbol, + /* 0x89 */ XF86XK_Cut, NoSymbol, + /* 0x8a */ XK_Help, NoSymbol, + /* 0x8b */ XK_Menu, NoSymbol, + /* 0x8c */ XF86XK_Calculator, NoSymbol, + /* 0x8d */ NoSymbol, NoSymbol, /* KEY_SETUP */ + /* 0x8e */ XF86XK_Sleep, NoSymbol, + /* 0x8f */ XF86XK_WakeUp, NoSymbol, + /* 0x90 */ NoSymbol, NoSymbol, /* KEY_FILE */ + /* 0x91 */ XF86XK_Send, NoSymbol, + /* 0x92 */ NoSymbol, NoSymbol, /* KEY_DELETEFILE */ + /* 0x93 */ XF86XK_Xfer, NoSymbol, + /* 0x94 */ XF86XK_Launch0, NoSymbol, + /* 0x95 */ XF86XK_Launch1, NoSymbol, + /* 0x96 */ XF86XK_WWW, NoSymbol, + /* 0x97 */ XF86XK_DOS, NoSymbol, + /* 0x98 */ NoSymbol, NoSymbol, /* KEY_COFFE */ + /* 0x99 */ NoSymbol, NoSymbol, /* KEY_DIRECTION */ + /* 0x9a */ XF86XK_RotateWindows, NoSymbol, + /* 0x9b */ XF86XK_Mail, NoSymbol, + /* 0x9c */ NoSymbol, NoSymbol, /* KEY_BOOKMARKS */ + /* 0x9d */ XF86XK_MyComputer, NoSymbol, + /* 0x9e */ XF86XK_Back, NoSymbol, + /* 0x9f */ XF86XK_Forward, NoSymbol, + /* 0xa0 */ NoSymbol, NoSymbol, /* KEY_CLOSECD */ + /* 0xa1 */ XF86XK_Eject, NoSymbol, + /* 0xa2 */ NoSymbol, NoSymbol, /* KEY_EJECTCLOSECD */ + /* 0xa3 */ XF86XK_AudioNext, NoSymbol, + /* 0xa4 */ XF86XK_AudioPause, NoSymbol, + /* 0xa5 */ XF86XK_AudioPrev, NoSymbol, + /* 0xa6 */ XF86XK_AudioStop, NoSymbol, + /* 0xa7 */ XF86XK_AudioRecord, NoSymbol, + /* 0xa8 */ XF86XK_AudioRewind, NoSymbol, + /* 0xa9 */ NoSymbol, NoSymbol, + /* 0xaa */ XK_ISO_Level3_Shift, NoSymbol, /* KEY_ISO */ + /* 0xab */ NoSymbol, NoSymbol, /* KEY_CONFIG */ + /* 0xac */ XF86XK_HomePage, NoSymbol, + /* 0xad */ XF86XK_Refresh, NoSymbol, + /* 0xae */ NoSymbol, NoSymbol, /* KEY_EXIT */ + /* 0xaf */ NoSymbol, NoSymbol, /* KEY_MOVE */ + /* 0xb0 */ NoSymbol, NoSymbol, /* KEY_EDIT */ + /* 0xb1 */ XF86XK_ScrollUp, NoSymbol, + /* 0xb2 */ XF86XK_ScrollDown, NoSymbol, + /* 0xb3 */ NoSymbol, NoSymbol, /* KEY_KPLEFTPAREN */ + /* 0xb4 */ NoSymbol, NoSymbol, /* KEY_KPRIGHTPAREN */ + /* 0xb5 */ NoSymbol, NoSymbol, + /* 0xb6 */ NoSymbol, NoSymbol, + + /* 0xb7 */ XK_F13, NoSymbol, + /* 0xb8 */ XK_F14, NoSymbol, + /* 0xb9 */ XK_F15, NoSymbol, + /* 0xba */ XK_F16, NoSymbol, + /* 0xbb */ XK_F17, NoSymbol, + /* 0xbc */ XK_F18, NoSymbol, + /* 0xbd */ XK_F19, NoSymbol, + /* 0xbe */ XK_F20, NoSymbol, + /* 0xbf */ XK_F21, NoSymbol, + /* 0xc0 */ XK_F22, NoSymbol, + /* 0xc1 */ XK_F23, NoSymbol, + /* 0xc2 */ XK_F24, NoSymbol, + /* 0xc3 */ NoSymbol, NoSymbol, + /* 0xc4 */ NoSymbol, NoSymbol, + /* 0xc5 */ NoSymbol, NoSymbol, + /* 0xc6 */ NoSymbol, NoSymbol, + /* 0xc7 */ NoSymbol, NoSymbol, + /* 0xc8 */ XF86XK_AudioPlay, NoSymbol, /* KEY_PLAYCD */ + /* 0xc9 */ XF86XK_AudioPause, NoSymbol, /* KEY_PAUSECD */ + /* 0xca */ XF86XK_Launch2, NoSymbol, /* KEY_PROG3 */ + /* 0xcb */ XF86XK_Launch3, NoSymbol, /* KEY_PROG4 */ + /* 0xcc */ XF86XK_Sleep, NoSymbol, + /* 0xcd */ XF86XK_Close, NoSymbol, + /* 0xce */ XF86XK_AudioPlay, NoSymbol, /* KEY_PLAY */ + /* 0xcf */ NoSymbol, NoSymbol, /* KEY_FASTFORWARD */ + /* 0xd0 */ NoSymbol, NoSymbol, /* KEY_BASSBOOST */ + /* 0xd1 */ XK_Print, NoSymbol, + /* 0xd2 */ NoSymbol, NoSymbol, /* KEY_HP */ + /* 0xd3 */ XF86XK_WebCam, NoSymbol, /* KEY_CAMERA */ + /* 0xd4 */ XF86XK_Music, NoSymbol, + /* 0xd5 */ XK_question, NoSymbol, + /* 0xd6 */ XF86XK_Mail, NoSymbol, + /* 0xd7 */ XF86XK_Messenger, NoSymbol, + /* 0xd8 */ XF86XK_Search, NoSymbol, + /* 0xd9 */ NoSymbol, NoSymbol, /* KEY_CONNECT */ + /* 0xda */ XF86XK_Finance, NoSymbol, + /* 0xdb */ NoSymbol, NoSymbol, /* KEY_SPORT */ + /* 0xdc */ XF86XK_Shop, NoSymbol, + /* 0xdd */ NoSymbol, NoSymbol, /* KEY_ALTERASE */ + /* 0xde */ XK_Cancel, NoSymbol, + /* 0xdf */ NoSymbol, NoSymbol, /* KEY_BRIGHTNESSDOWN */ + /* 0xe0 */ NoSymbol, NoSymbol, /* KEY_BRIGHTNESSUP */ + /* 0xe1 */ XF86XK_AudioMedia, NoSymbol /* KEY_MEDIA */ }; + static void EvdevKbdBell(int percent, DeviceIntPtr dev, pointer ctrl, int unused) { @@ -360,6 +556,39 @@ write(pInfo->fd, ev, sizeof ev); } +static void +EvdevResetDevice(InputInfoPtr pInfo) +{ +} + +static void +EvdevOpenDevice(InputInfoPtr pInfo) +{ + if (pInfo->fd < 0) { + const char *device + = xf86CheckStrOption(pInfo->conf_idev->commonOptions, + "Device", NULL); + if (!device) { + xf86Msg(X_ERROR, "%s: No device specified.\n", pInfo->name); + return; + } + + xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device); + do { + pInfo->fd = open(device, O_RDWR, 0); + } while(pInfo->fd < 0 && errno == EINTR); + } +} + +static void +EvdevCloseDevice(InputInfoPtr pInfo) +{ + if (pInfo->fd > 0) { + close(pInfo->fd); + pInfo->fd = -1; + } +} + static int EvdevAddKeyClass(DeviceIntPtr device) { @@ -391,7 +620,7 @@ pInfo = device->public.devicePrivate; /* Compute the modifier map */ - memset(modMap, 0, sizeof modMap); + memset(modMap, 0, sizeof(modMap)); for (i = 0; i < ArrayLength(map) / GLYPHS_PER_KEY; i++) { sym = map[i * GLYPHS_PER_KEY]; @@ -428,8 +657,8 @@ pInfo = device->public.devicePrivate; if (!InitValuatorClassDeviceStruct(device, 2, - miPointerGetMotionEvents, - miPointerGetMotionBufferSize(), 0)) + miPointerGetMotionEvents, + miPointerGetMotionBufferSize(), 0)) return !Success; /* X valuator */ @@ -450,23 +679,34 @@ static int EvdevAddButtonClass(DeviceIntPtr device) { - CARD8 map[32]; + CARD8 map[MAX_BUTTON_COUNT + 1]; InputInfoPtr pInfo; + int buttonCount = MAX_BUTTON_COUNT; int i; + const char *buttons = NULL; pInfo = device->public.devicePrivate; /* FIXME: count number of actual buttons */ - for (i = 0; i < ArrayLength(map); i++) + for (i = 0; i < ArrayLength(map); i++) { map[i] = i; + } /* Linux reports BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, which should map * to buttons 1, 2 and 3, so swap 2 and 3 in the map */ map[2] = 3; map[3] = 2; - if (!InitButtonClassDeviceStruct(device, ArrayLength(map), map)) + buttons = xf86CheckStrOption(pInfo->conf_idev->commonOptions, + "Buttons", NULL); + if (buttons) { + int newButtonCount = atoi(buttons); + if (0 < newButtonCount && newButtonCount <= MAX_BUTTON_COUNT) + buttonCount = newButtonCount; + } + + if (!InitButtonClassDeviceStruct(device, buttonCount, map)) return !Success; pInfo->flags |= XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; @@ -477,58 +717,83 @@ static int EvdevInit(DeviceIntPtr device) { - InputInfoPtr pInfo; - - pInfo = device->public.devicePrivate; + InputInfoPtr pInfo = device->public.devicePrivate; + + EvdevOpenDevice(pInfo); /* FIXME: This doesn't add buttons for keyboards with * scrollwheels. */ if (pInfo->flags & XI86_KEYBOARD_CAPABLE) { - EvdevAddKeyClass(device); + EvdevAddKeyClass(device); } if (pInfo->flags & XI86_POINTER_CAPABLE) { - EvdevAddButtonClass(device); - EvdevAddRelClass(device); + EvdevAddButtonClass(device); + EvdevAddRelClass(device); } + EvdevCloseDevice(pInfo); + return Success; } +static void +EvdevOpen(DeviceIntPtr device) +{ + InputInfoPtr pInfo = device->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + + EvdevResetDevice(pInfo); + EvdevOpenDevice(pInfo); + + if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) { + xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name, + strerror(errno)); + } + xf86AddEnabledDevice(pInfo); + device->public.on = TRUE; +} + +static void +EvdevClose(DeviceIntPtr device) +{ + InputInfoPtr pInfo = device->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + + if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)0)) { + xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name, + strerror(errno)); + } + xf86RemoveEnabledDevice(pInfo); + device->public.on = FALSE; + + EvdevCloseDevice(pInfo); +} + static int EvdevProc(DeviceIntPtr device, int what) { InputInfoPtr pInfo; - EvdevPtr pEvdev; pInfo = device->public.devicePrivate; - pEvdev = pInfo->private; - switch (what) - { + switch (what) { case DEVICE_INIT: - return EvdevInit(device); + return EvdevInit(device); case DEVICE_ON: - if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) - xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name, - strerror(errno)); - xf86AddEnabledDevice(pInfo); - device->public.on = TRUE; - break; + EvdevOpen(device); + break; case DEVICE_OFF: - if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)0)) - xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name, - strerror(errno)); - xf86RemoveEnabledDevice(pInfo); - device->public.on = FALSE; - break; + EvdevClose(device); + break; case DEVICE_CLOSE: - xf86Msg(X_INFO, "%s: Close\n", pInfo->name); - break; + EvdevClose(device); + xf86Msg(X_INFO, "%s: Close\n", pInfo->name); + break; } return Success; @@ -629,7 +894,6 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) { InputInfoPtr pInfo; - MessageType deviceFrom = X_CONFIG; const char *device; EvdevPtr pEvdev; @@ -653,7 +917,8 @@ pInfo->private_flags = 0; pInfo->always_core_feedback = 0; pInfo->conf_idev = dev; - + pInfo->fd = -1; + if (!(pEvdev = xcalloc(sizeof(*pEvdev), 1))) return pInfo; pInfo->private = pEvdev; @@ -667,14 +932,12 @@ xfree(pEvdev); return pInfo; } - - xf86Msg(deviceFrom, "%s: Device: \"%s\"\n", pInfo->name, device); - do { - pInfo->fd = open(device, O_RDWR, 0); - } - while (pInfo->fd < 0 && errno == EINTR); + EvdevOpenDevice(pInfo); + if (pInfo->fd < 0) { + const char *device = xf86CheckStrOption(pInfo->conf_idev->commonOptions, + "Device", NULL); xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", device); xfree(pEvdev); return pInfo; @@ -683,6 +946,8 @@ if (EvdevProbe(pInfo)) xfree(pEvdev); + EvdevCloseDevice(pInfo); + return pInfo; }