"Fossies" - the Fresh Open Source Software Archive

Member "xorgxrdp-0.2.10/xrdpkeyb/rdpKeyboard.c" (12 Dec 2018, 26193 Bytes) of package /linux/misc/xorgxrdp-0.2.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rdpKeyboard.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.2.8_vs_0.2.9.

    1 /*
    2 Copyright 2013-2017 Jay Sorg
    3 
    4 Permission to use, copy, modify, distribute, and sell this software and its
    5 documentation for any purpose is hereby granted without fee, provided that
    6 the above copyright notice appear in all copies and that both that
    7 copyright notice and this permission notice appear in supporting
    8 documentation.
    9 
   10 The above copyright notice and this permission notice shall be included in
   11 all copies or substantial portions of the Software.
   12 
   13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
   16 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
   17 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   18 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   19 
   20 xrdp keyboard module
   21 
   22 */
   23 
   24 #if defined(HAVE_CONFIG_H)
   25 #include "config_ac.h"
   26 #endif
   27 
   28 #include <stdio.h>
   29 #include <stdlib.h>
   30 #include <string.h>
   31 
   32 /* this should be before all X11 .h files */
   33 #include <xorg-server.h>
   34 #include <xorgVersion.h>
   35 
   36 /* all driver need this */
   37 #include <xf86.h>
   38 #include <xf86_OSproc.h>
   39 
   40 #include <xf86Xinput.h>
   41 
   42 #include <mipointer.h>
   43 #include <fb.h>
   44 #include <micmap.h>
   45 #include <mi.h>
   46 
   47 #include <xkbsrv.h>
   48 
   49 #include <X11/keysym.h>
   50 
   51 #include "rdp.h"
   52 #include "rdpInput.h"
   53 #include "rdpDraw.h"
   54 #include "rdpMisc.h"
   55 
   56 /******************************************************************************/
   57 #define LOG_LEVEL 1
   58 #define LLOGLN(_level, _args) \
   59     do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
   60 
   61 #define MIN_KEY_CODE 8
   62 #define MAX_KEY_CODE 255
   63 #define NO_OF_KEYS ((MAX_KEY_CODE - MIN_KEY_CODE) + 1)
   64 #define GLYPHS_PER_KEY 2
   65 /* control */
   66 #define CONTROL_L_KEY_CODE 37
   67 #define CONTROL_R_KEY_CODE 109
   68 /* shift */
   69 #define SHIFT_L_KEY_CODE 50
   70 #define SHIFT_R_KEY_CODE 62
   71 /* win keys */
   72 #define SUPER_L_KEY_CODE 115
   73 #define SUPER_R_KEY_CODE 116
   74 /* alt */
   75 #define ALT_L_KEY_CODE 64
   76 #define ALT_R_KEY_CODE 113
   77 /* caps lock */
   78 #define CAPS_LOCK_KEY_CODE 66
   79 /* num lock */
   80 #define NUM_LOCK_KEY_CODE 77
   81 
   82 #define N_PREDEFINED_KEYS \
   83     (sizeof(g_kbdMap) / (sizeof(KeySym) * GLYPHS_PER_KEY))
   84 
   85 static char g_base_str[] = "base";
   86 static char g_pc104_str[] = "pc104";
   87 static char g_us_str[] = "us";
   88 static char g_empty_str[] = "";
   89 static char g_Keyboard_str[] = "Keyboard";
   90 
   91 static char g_xrdp_keyb_name[] = XRDP_KEYB_NAME;
   92 
   93 static KeySym g_kbdMap[] =
   94 {
   95     NoSymbol,        NoSymbol,        /* 8 */
   96     XK_Escape,       NoSymbol,        /* 9 */
   97     XK_1,            XK_exclam,       /* 10 */
   98     XK_2,            XK_at,
   99     XK_3,            XK_numbersign,
  100     XK_4,            XK_dollar,
  101     XK_5,            XK_percent,
  102     XK_6,            XK_asciicircum,
  103     XK_7,            XK_ampersand,
  104     XK_8,            XK_asterisk,
  105     XK_9,            XK_parenleft,
  106     XK_0,            XK_parenright,
  107     XK_minus,        XK_underscore,   /* 20 */
  108     XK_equal,        XK_plus,
  109     XK_BackSpace,    NoSymbol,
  110     XK_Tab,          XK_ISO_Left_Tab,
  111     XK_Q,            NoSymbol,
  112     XK_W,            NoSymbol,
  113     XK_E,            NoSymbol,
  114     XK_R,            NoSymbol,
  115     XK_T,            NoSymbol,
  116     XK_Y,            NoSymbol,
  117     XK_U,            NoSymbol,        /* 30 */
  118     XK_I,            NoSymbol,
  119     XK_O,            NoSymbol,
  120     XK_P,            NoSymbol,
  121     XK_bracketleft,  XK_braceleft,
  122     XK_bracketright, XK_braceright,
  123     XK_Return,       NoSymbol,
  124     XK_Control_L,    NoSymbol,
  125     XK_A,            NoSymbol,
  126     XK_S,            NoSymbol,
  127     XK_D,            NoSymbol,        /* 40 */
  128     XK_F,            NoSymbol,
  129     XK_G,            NoSymbol,
  130     XK_H,            NoSymbol,
  131     XK_J,            NoSymbol,
  132     XK_K,            NoSymbol,
  133     XK_L,            NoSymbol,
  134     XK_semicolon,    XK_colon,
  135     XK_apostrophe,   XK_quotedbl,
  136     XK_grave,        XK_asciitilde,
  137     XK_Shift_L,      NoSymbol,        /* 50 */
  138     XK_backslash,    XK_bar,
  139     XK_Z,            NoSymbol,
  140     XK_X,            NoSymbol,
  141     XK_C,            NoSymbol,
  142     XK_V,            NoSymbol,
  143     XK_B,            NoSymbol,
  144     XK_N,            NoSymbol,
  145     XK_M,            NoSymbol,
  146     XK_comma,        XK_less,
  147     XK_period,       XK_greater,      /* 60 */
  148     XK_slash,        XK_question,
  149     XK_Shift_R,      NoSymbol,
  150     XK_KP_Multiply,  NoSymbol,
  151     XK_Alt_L,        NoSymbol,
  152     XK_space,        NoSymbol,
  153     XK_Caps_Lock,    NoSymbol,
  154     XK_F1,           NoSymbol,
  155     XK_F2,           NoSymbol,
  156     XK_F3,           NoSymbol,
  157     XK_F4,           NoSymbol,        /* 70 */
  158     XK_F5,           NoSymbol,
  159     XK_F6,           NoSymbol,
  160     XK_F7,           NoSymbol,
  161     XK_F8,           NoSymbol,
  162     XK_F9,           NoSymbol,
  163     XK_F10,          NoSymbol,
  164     XK_Num_Lock,     NoSymbol,
  165     XK_Scroll_Lock,  NoSymbol,
  166     XK_KP_Home,      XK_KP_7,
  167     XK_KP_Up,        XK_KP_8,         /* 80 */
  168     XK_KP_Prior,     XK_KP_9,
  169     XK_KP_Subtract,  NoSymbol,
  170     XK_KP_Left,      XK_KP_4,
  171     XK_KP_Begin,     XK_KP_5,
  172     XK_KP_Right,     XK_KP_6,
  173     XK_KP_Add,       NoSymbol,
  174     XK_KP_End,       XK_KP_1,
  175     XK_KP_Down,      XK_KP_2,
  176     XK_KP_Next,      XK_KP_3,
  177     XK_KP_Insert,    XK_KP_0,         /* 90 */
  178     XK_KP_Delete,    XK_KP_Decimal,
  179     NoSymbol,        NoSymbol,
  180     NoSymbol,        NoSymbol,
  181     NoSymbol,        NoSymbol,
  182     XK_F11,          NoSymbol,
  183     XK_F12,          NoSymbol,
  184     XK_Home,         NoSymbol,
  185     XK_Up,           NoSymbol,
  186     XK_Prior,        NoSymbol,
  187     XK_Left,         NoSymbol,        /* 100 */
  188     XK_Print,        NoSymbol,
  189     XK_Right,        NoSymbol,
  190     XK_End,          NoSymbol,
  191     XK_Down,         NoSymbol,
  192     XK_Next,         NoSymbol,
  193     XK_Insert,       NoSymbol,
  194     XK_Delete,       NoSymbol,
  195     XK_KP_Enter,     NoSymbol,
  196     XK_Control_R,    NoSymbol,
  197     XK_Pause,        NoSymbol,        /* 110 */
  198     XK_Print,        NoSymbol,
  199     XK_KP_Divide,    NoSymbol,
  200     XK_Alt_R,        NoSymbol,
  201     NoSymbol,        NoSymbol,
  202     XK_Super_L,      NoSymbol,
  203     XK_Super_R,      NoSymbol,
  204     XK_Menu,         NoSymbol,
  205     NoSymbol,        NoSymbol,
  206     NoSymbol,        NoSymbol,
  207     NoSymbol,        NoSymbol,        /* 120 */
  208     NoSymbol,        NoSymbol
  209 };
  210 
  211 static int
  212 rdpLoadLayout(rdpKeyboard *keyboard, struct xrdp_client_info *client_info);
  213 
  214 /******************************************************************************/
  215 static void
  216 rdpEnqueueKey(DeviceIntPtr device, int type, int scancode)
  217 {
  218     if (type == KeyPress)
  219     {
  220         xf86PostKeyboardEvent(device, scancode, TRUE);
  221     }
  222     else
  223     {
  224         xf86PostKeyboardEvent(device, scancode, FALSE);
  225     }
  226 }
  227 
  228 /******************************************************************************/
  229 static void
  230 sendDownUpKeyEvent(DeviceIntPtr device, int type, int x_scancode)
  231 {
  232     /* need this cause rdp and X11 repeats are different */
  233     /* if type is keydown, send keyup + keydown */
  234     if (type == KeyPress)
  235     {
  236         rdpEnqueueKey(device, KeyRelease, x_scancode);
  237         rdpEnqueueKey(device, KeyPress, x_scancode);
  238     }
  239     else
  240     {
  241         rdpEnqueueKey(device, KeyRelease, x_scancode);
  242     }
  243 }
  244 
  245 /******************************************************************************/
  246 static void
  247 check_keysa(rdpKeyboard *keyboard)
  248 {
  249     if (keyboard->ctrl_down != 0)
  250     {
  251         rdpEnqueueKey(keyboard->device, KeyRelease, keyboard->ctrl_down);
  252         keyboard->ctrl_down = 0;
  253     }
  254 
  255     if (keyboard->alt_down != 0)
  256     {
  257         rdpEnqueueKey(keyboard->device, KeyRelease, keyboard->alt_down);
  258         keyboard->alt_down = 0;
  259     }
  260 
  261     if (keyboard->shift_down != 0)
  262     {
  263         rdpEnqueueKey(keyboard->device, KeyRelease, keyboard->shift_down);
  264         keyboard->shift_down = 0;
  265     }
  266 }
  267 
  268 /**
  269  * @param down   - true for KeyDown events, false otherwise
  270  * @param param1 - ASCII code of pressed key
  271  * @param param2 -
  272  * @param param3 - scancode of pressed key
  273  * @param param4 -
  274  ******************************************************************************/
  275 static void
  276 KbdAddEvent(rdpKeyboard *keyboard, int down, int param1, int param2,
  277             int param3, int param4)
  278 {
  279     int rdp_scancode;
  280     int x_scancode;
  281     int is_ext;
  282     int is_spe;
  283     int type;
  284 
  285     type = down ? KeyPress : KeyRelease;
  286     rdp_scancode = param3;
  287     is_ext = param4 & 256; /* 0x100 */
  288     is_spe = param4 & 512; /* 0x200 */
  289     x_scancode = 0;
  290 
  291     switch (rdp_scancode)
  292     {
  293         case 58: /* caps lock             */
  294         case 42: /* left shift            */
  295         case 54: /* right shift           */
  296         case 70: /* scroll lock           */
  297             x_scancode = rdp_scancode + MIN_KEY_CODE;
  298 
  299             if (x_scancode > 0)
  300             {
  301                 rdpEnqueueKey(keyboard->device, type, x_scancode);
  302             }
  303 
  304             break;
  305 
  306         case 56: /* left - right alt button */
  307 
  308             if (is_ext)
  309             {
  310                 x_scancode = 113; /* right alt button */
  311             }
  312             else
  313             {
  314                 x_scancode = 64;  /* left alt button   */
  315             }
  316 
  317             rdpEnqueueKey(keyboard->device, type, x_scancode);
  318             break;
  319 
  320         case 15: /* tab */
  321 
  322             if (!down && !keyboard->tab_down)
  323             {
  324                 /* leave x_scancode 0 here, we don't want the tab key up */
  325                 check_keysa(keyboard);
  326             }
  327             else
  328             {
  329                 sendDownUpKeyEvent(keyboard->device, type, 23);
  330             }
  331 
  332             keyboard->tab_down = down;
  333             break;
  334 
  335         case 29: /* left or right ctrl */
  336 
  337             /* this is to handle special case with pause key sending control first */
  338             if (is_spe)
  339             {
  340                 if (down)
  341                 {
  342                     keyboard->pause_spe = 1;
  343                     /* leave x_scancode 0 here, we don't want the control key down */
  344                 }
  345             }
  346             else
  347             {
  348                 x_scancode = is_ext ? 109 : 37;
  349                 keyboard->ctrl_down = down ? x_scancode : 0;
  350                 rdpEnqueueKey(keyboard->device, type, x_scancode);
  351             }
  352 
  353             break;
  354 
  355         case 69: /* Pause or Num Lock */
  356 
  357             if (keyboard->pause_spe)
  358             {
  359                 x_scancode = 110;
  360 
  361                 if (!down)
  362                 {
  363                     keyboard->pause_spe = 0;
  364                 }
  365             }
  366             else
  367             {
  368                 x_scancode = keyboard->ctrl_down ? 110 : 77;
  369             }
  370 
  371             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  372             break;
  373 
  374         case 28: /* Enter or Return */
  375             x_scancode = is_ext ? 108 : 36;
  376             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  377             break;
  378 
  379         case 53: /* / */
  380             x_scancode = is_ext ? 112 : 61;
  381             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  382             break;
  383 
  384         case 55: /* * on KP or Print Screen */
  385             x_scancode = is_ext ? 111 : 63;
  386             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  387             break;
  388 
  389         case 71: /* 7 or Home */
  390             x_scancode = is_ext ? 97 : 79;
  391             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  392             break;
  393 
  394         case 72: /* 8 or Up */
  395             x_scancode = is_ext ? 98 : 80;
  396             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  397             break;
  398 
  399         case 73: /* 9 or PgUp */
  400             x_scancode = is_ext ? 99 : 81;
  401             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  402             break;
  403 
  404         case 75: /* 4 or Left */
  405             x_scancode = is_ext ? 100 : 83;
  406             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  407             break;
  408 
  409         case 77: /* 6 or Right */
  410             x_scancode = is_ext ? 102 : 85;
  411             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  412             break;
  413 
  414         case 79: /* 1 or End */
  415             x_scancode = is_ext ? 103 : 87;
  416             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  417             break;
  418 
  419         case 80: /* 2 or Down */
  420             x_scancode = is_ext ? 104 : 88;
  421             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  422             break;
  423 
  424         case 81: /* 3 or PgDn */
  425             x_scancode = is_ext ? 105 : 89;
  426             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  427             break;
  428 
  429         case 82: /* 0 or Insert */
  430             x_scancode = is_ext ? 106 : 90;
  431             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  432             break;
  433 
  434         case 83: /* . or Delete */
  435             x_scancode = is_ext ? 107 : 91;
  436             sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  437             break;
  438 
  439         case 91: /* left win key */
  440             rdpEnqueueKey(keyboard->device, type, 115);
  441             break;
  442 
  443         case 92: /* right win key */
  444             rdpEnqueueKey(keyboard->device, type, 116);
  445             break;
  446 
  447         case 93: /* menu key */
  448             rdpEnqueueKey(keyboard->device, type, 117);
  449             break;
  450 
  451         case 89: /* left meta */
  452             rdpEnqueueKey(keyboard->device, type, 156);
  453             break;
  454 
  455         case 90: /* right meta */
  456             rdpEnqueueKey(keyboard->device, type, 156);
  457             break;
  458 
  459         case 115: /* "/ ?" on br keyboard */
  460             sendDownUpKeyEvent(keyboard->device, type, 211);
  461             break;
  462 
  463         case 126: /* . on br keypad */
  464             sendDownUpKeyEvent(keyboard->device, type, 134);
  465             break;
  466 
  467         default:
  468             x_scancode = rdp_scancode + MIN_KEY_CODE;
  469 
  470             if (x_scancode > 0)
  471             {
  472                 sendDownUpKeyEvent(keyboard->device, type, x_scancode);
  473             }
  474 
  475             break;
  476     }
  477 }
  478 
  479 /******************************************************************************/
  480 /* notes -
  481      scroll lock doesn't seem to be a modifier in X
  482 */
  483 static void
  484 KbdSync(rdpKeyboard *keyboard, int param1)
  485 {
  486     int xkb_state;
  487 
  488     xkb_state = XkbStateFieldFromRec(&(keyboard->device->key->xkbInfo->state));
  489 
  490     if ((!(xkb_state & 0x02)) != (!(param1 & 4))) /* caps lock */
  491     {
  492         LLOGLN(0, ("KbdSync: toggling caps lock"));
  493         KbdAddEvent(keyboard, 1, 58, 0, 58, 0);
  494         KbdAddEvent(keyboard, 0, 58, 49152, 58, 49152);
  495     }
  496 
  497     if ((!(xkb_state & 0x10)) != (!(param1 & 2))) /* num lock */
  498     {
  499         LLOGLN(0, ("KbdSync: toggling num lock"));
  500         KbdAddEvent(keyboard, 1, 69, 0, 69, 0);
  501         KbdAddEvent(keyboard, 0, 69, 49152, 69, 49152);
  502     }
  503 
  504     if ((!(keyboard->scroll_lock_down)) != (!(param1 & 1))) /* scroll lock */
  505     {
  506         LLOGLN(0, ("KbdSync: toggling scroll lock"));
  507         KbdAddEvent(keyboard, 1, 70, 0, 70, 0);
  508         KbdAddEvent(keyboard, 0, 70, 49152, 70, 49152);
  509     }
  510 }
  511 
  512 /******************************************************************************/
  513 static int
  514 rdpInputKeyboard(rdpPtr dev, int msg, long param1, long param2,
  515                  long param3, long param4)
  516 {
  517     rdpKeyboard *keyboard;
  518 
  519     keyboard = &(dev->keyboard);
  520     LLOGLN(10, ("rdpInputKeyboard:"));
  521     switch (msg)
  522     {
  523         case 15: /* key down */
  524         case 16: /* key up */
  525             KbdAddEvent(keyboard, msg == 15, param1, param2, param3, param4);
  526             break;
  527         case 17: /* from RDP_INPUT_SYNCHRONIZE */
  528             KbdSync(keyboard, param1);
  529             break;
  530         case 18:
  531             rdpLoadLayout(keyboard, (struct xrdp_client_info *) param1);
  532             break;
  533 
  534     }
  535     return 0;
  536 }
  537 
  538 /******************************************************************************/
  539 void
  540 rdpkeybDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap)
  541 {
  542     int i;
  543 
  544     LLOGLN(0, ("rdpkeybDeviceInit:"));
  545     LLOGLN(10, ("  MAP_LENGTH %d GLYPHS_PER_KEY %d N_PREDEFINED_KEYS %d",
  546            MAP_LENGTH, GLYPHS_PER_KEY, (int) N_PREDEFINED_KEYS));
  547 
  548     for (i = 0; i < MAP_LENGTH; i++)
  549     {
  550         pModMap[i] = NoSymbol;
  551     }
  552 
  553     pModMap[SHIFT_L_KEY_CODE] = ShiftMask;
  554     pModMap[SHIFT_R_KEY_CODE] = ShiftMask;
  555     pModMap[CAPS_LOCK_KEY_CODE] = LockMask;
  556     pModMap[CONTROL_L_KEY_CODE] = ControlMask;
  557     pModMap[CONTROL_R_KEY_CODE] = ControlMask;
  558     pModMap[ALT_L_KEY_CODE] = Mod1Mask;
  559     pModMap[ALT_R_KEY_CODE] = Mod1Mask;
  560     pModMap[NUM_LOCK_KEY_CODE] = Mod2Mask;
  561     pModMap[SUPER_L_KEY_CODE] = Mod4Mask;
  562     pModMap[SUPER_R_KEY_CODE] = Mod4Mask;
  563     pKeySyms->minKeyCode = MIN_KEY_CODE;
  564     pKeySyms->maxKeyCode = MAX_KEY_CODE;
  565     pKeySyms->mapWidth = GLYPHS_PER_KEY;
  566     pKeySyms->map = g_new0(KeySym, MAP_LENGTH * GLYPHS_PER_KEY);
  567     if (pKeySyms->map == 0)
  568     {
  569         LLOGLN(0, ("rdpkeybDeviceInit: out of memory"));
  570         exit(1);
  571     }
  572 
  573     for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++)
  574     {
  575         pKeySyms->map[i] = NoSymbol;
  576     }
  577 
  578     for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++)
  579     {
  580         pKeySyms->map[i] = g_kbdMap[i];
  581     }
  582 }
  583 
  584 /******************************************************************************/
  585 static void
  586 rdpkeybDeviceOn(void)
  587 {
  588     LLOGLN(0, ("rdpkeybDeviceOn:"));
  589 }
  590 
  591 /******************************************************************************/
  592 static void
  593 rdpkeybDeviceOff(void)
  594 {
  595     LLOGLN(0, ("rdpkeybDeviceOff:"));
  596 }
  597 
  598 /******************************************************************************/
  599 static void
  600 rdpkeybBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
  601 {
  602     LLOGLN(0, ("rdpkeybBell:"));
  603 }
  604 
  605 /******************************************************************************/
  606 static CARD32
  607 rdpInDeferredRepeatCallback(OsTimerPtr timer, CARD32 now, pointer arg)
  608 {
  609     DeviceIntPtr pDev;
  610     DeviceIntPtr it;
  611     Bool found;
  612 
  613     LLOGLN(0, ("rdpInDeferredRepeatCallback:"));
  614     TimerFree(timer);
  615     pDev = (DeviceIntPtr) arg;
  616     found = FALSE;
  617     it = inputInfo.devices;
  618     while (it != NULL)
  619     {
  620         if (it == pDev)
  621         {
  622             found = TRUE;
  623             break;
  624         }
  625         it = it->next;
  626     }
  627     if (found)
  628     {
  629         XkbSetRepeatKeys(pDev, -1, AutoRepeatModeOff);
  630     }
  631     return 0;
  632 }
  633 
  634 /******************************************************************************/
  635 static void
  636 rdpkeybChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
  637 {
  638     XkbControlsPtr ctrls;
  639 
  640     LLOGLN(0, ("rdpkeybChangeKeyboardControl:"));
  641     ctrls = 0;
  642     if (pDev != 0)
  643     {
  644         if (pDev->key != 0)
  645         {
  646             if (pDev->key->xkbInfo != 0)
  647             {
  648                 if (pDev->key->xkbInfo->desc != 0)
  649                 {
  650                     if (pDev->key->xkbInfo->desc->ctrls != 0)
  651                     {
  652                         ctrls = pDev->key->xkbInfo->desc->ctrls;
  653                     }
  654                 }
  655             }
  656         }
  657     }
  658     if (ctrls != 0)
  659     {
  660         if (ctrls->enabled_ctrls & XkbRepeatKeysMask)
  661         {
  662             LLOGLN(0, ("rdpkeybChangeKeyboardControl: autoRepeat on"));
  663             /* schedule to turn off the autorepeat after 100 ms so any app
  664              * polling it will be happy it's on */
  665             TimerSet(NULL, 0, 100, rdpInDeferredRepeatCallback, pDev);
  666         }
  667         else
  668         {
  669             LLOGLN(0, ("rdpkeybChangeKeyboardControl: autoRepeat off"));
  670         }
  671     }
  672 }
  673 
  674 /******************************************************************************/
  675 static int
  676 rdpkeybControl(DeviceIntPtr device, int what)
  677 {
  678     KeySymsRec keySyms;
  679     CARD8 modMap[MAP_LENGTH];
  680     DevicePtr pDev;
  681     XkbRMLVOSet set;
  682     rdpPtr dev;
  683 
  684     LLOGLN(0, ("rdpkeybControl: what %d", what));
  685     pDev = (DevicePtr)device;
  686 
  687     switch (what)
  688     {
  689         case DEVICE_INIT:
  690             rdpkeybDeviceInit(device, &keySyms, modMap);
  691             memset(&set, 0, sizeof(set));
  692             set.rules = g_base_str;
  693             set.model = g_pc104_str;
  694             set.layout = g_us_str;
  695             set.variant = g_empty_str;
  696             set.options = g_empty_str;
  697             InitKeyboardDeviceStruct(device, &set, rdpkeybBell,
  698                                      rdpkeybChangeKeyboardControl);
  699             dev = rdpGetDevFromScreen(NULL);
  700             dev->keyboard.device = device;
  701             rdpRegisterInputCallback(0, rdpInputKeyboard);
  702             break;
  703         case DEVICE_ON:
  704             pDev->on = 1;
  705             rdpkeybDeviceOn();
  706             break;
  707         case DEVICE_OFF:
  708             pDev->on = 0;
  709             rdpkeybDeviceOff();
  710             break;
  711         case DEVICE_CLOSE:
  712             if (pDev->on)
  713             {
  714                 rdpkeybDeviceOff();
  715             }
  716             break;
  717     }
  718     return Success;
  719 }
  720 
  721 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 1, 0)
  722 
  723 /* debian 6
  724    ubuntu 10.04 */
  725 
  726 /******************************************************************************/
  727 static InputInfoPtr
  728 rdpkeybPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
  729 {
  730     InputInfoPtr info;
  731 
  732     LLOGLN(0, ("rdpkeybPreInit: drv %p dev %p, flags 0x%x",
  733            drv, dev, flags));
  734     info = xf86AllocateInput(drv, 0);
  735     info->name = dev->identifier;
  736     info->device_control = rdpkeybControl;
  737     info->flags = XI86_CONFIGURED | XI86_ALWAYS_CORE | XI86_SEND_DRAG_EVENTS |
  738                   XI86_CORE_KEYBOARD | XI86_KEYBOARD_CAPABLE;
  739     info->type_name = "Keyboard";
  740     info->fd = -1;
  741     info->conf_idev = dev;
  742 
  743     return info;
  744 }
  745 
  746 #else
  747 
  748 /* debian 7
  749    ubuntu 12.04 */
  750 
  751 /******************************************************************************/
  752 static int
  753 rdpkeybPreInit(InputDriverPtr drv, InputInfoPtr info, int flags)
  754 {
  755     LLOGLN(0, ("rdpkeybPreInit: drv %p info %p, flags 0x%x",
  756            drv, info, flags));
  757     info->device_control = rdpkeybControl;
  758     info->type_name = g_Keyboard_str;
  759 
  760     return 0;
  761 }
  762 
  763 #endif
  764 
  765 /******************************************************************************/
  766 static void
  767 rdpkeybUnInit(InputDriverPtr drv, InputInfoPtr info, int flags)
  768 {
  769     LLOGLN(0, ("rdpkeybUnInit: drv %p info %p, flags 0x%x",
  770            drv, info, flags));
  771     rdpUnregisterInputCallback(rdpInputKeyboard);
  772 }
  773 
  774 /******************************************************************************/
  775 static InputDriverRec rdpkeyb =
  776 {
  777     PACKAGE_VERSION_MAJOR,  /* version   */
  778     g_xrdp_keyb_name,       /* name      */
  779     NULL,                   /* identify  */
  780     rdpkeybPreInit,         /* preinit   */
  781     rdpkeybUnInit,          /* uninit    */
  782     NULL,                   /* module    */
  783     0                       /* ref count */
  784 };
  785 
  786 /******************************************************************************/
  787 static pointer
  788 rdpkeybPlug(pointer module, pointer options, int *errmaj, int *errmin)
  789 {
  790     LLOGLN(0, ("rdpkeybPlug:"));
  791     xf86AddInputDriver(&rdpkeyb, module, 0);
  792     return module;
  793 }
  794 
  795 /******************************************************************************/
  796 static void
  797 rdpkeybUnplug(pointer p)
  798 {
  799     LLOGLN(0, ("rdpkeybUnplug:"));
  800 }
  801 
  802 /******************************************************************************/
  803 static int
  804 reload_xkb(DeviceIntPtr keyboard, XkbRMLVOSet *set)
  805 {
  806     XkbSrvInfoPtr xkbi;
  807     XkbDescPtr xkb;
  808     KeySymsPtr keySyms;
  809     KeyCode first_key;
  810     CARD8 num_keys;
  811     DeviceIntPtr pDev;
  812 
  813     /* free some stuff so we can call InitKeyboardDeviceStruct again */
  814     xkbi = keyboard->key->xkbInfo;
  815     xkb = xkbi->desc;
  816     XkbFreeKeyboard(xkb, 0, TRUE);
  817     free(xkbi);
  818     keyboard->key->xkbInfo = NULL;
  819     free(keyboard->kbdfeed);
  820     keyboard->kbdfeed = NULL;
  821     free(keyboard->key);
  822     keyboard->key = NULL;
  823 
  824     /* init keyboard and reload the map */
  825     if (!InitKeyboardDeviceStruct(keyboard, set, rdpkeybBell,
  826                                   rdpkeybChangeKeyboardControl))
  827     {
  828         LLOGLN(0, ("rdpLoadLayout: InitKeyboardDeviceStruct failed"));
  829         return 1;
  830     }
  831 
  832     /* notify the X11 clients eg. X_ChangeKeyboardMapping */
  833     keySyms = XkbGetCoreMap(keyboard);
  834     if (keySyms)
  835     {
  836         first_key = keySyms->minKeyCode;
  837         num_keys = (keySyms->maxKeyCode - keySyms->minKeyCode) + 1;
  838         XkbApplyMappingChange(keyboard, keySyms, first_key, num_keys,
  839                               NULL, serverClient);
  840         for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
  841         {
  842             if ((pDev->coreEvents || pDev == keyboard) && pDev->key)
  843             {
  844                 XkbApplyMappingChange(pDev, keySyms, first_key, num_keys,
  845                                       NULL, serverClient);
  846             }
  847         }
  848         free(keySyms->map);
  849         free(keySyms);
  850     }
  851     else
  852     {
  853         return 1;
  854     }
  855     return 0;
  856 }
  857 
  858 /******************************************************************************/
  859 static int
  860 rdpLoadLayout(rdpKeyboard *keyboard, struct xrdp_client_info *client_info)
  861 {
  862     XkbRMLVOSet set;
  863 
  864     int keylayout = client_info->keylayout;
  865 
  866     LLOGLN(0, ("rdpLoadLayout: keylayout 0x%8.8x variant %s display %s",
  867                keylayout, client_info->variant, display));
  868     memset(&set, 0, sizeof(set));
  869     set.rules = g_base_str;
  870 
  871     set.model = g_pc104_str;
  872     set.layout = g_us_str;
  873     set.variant = g_empty_str;
  874     set.options = g_empty_str;
  875 
  876     if (strlen(client_info->model) > 0)
  877     {
  878         set.model = client_info->model;
  879     }
  880     if (strlen(client_info->variant) > 0)
  881     {
  882         set.variant = client_info->variant;
  883     }
  884     if (strlen(client_info->layout) > 0)
  885     {
  886         set.layout = client_info->layout;
  887     }
  888     if (strlen(client_info->options) > 0)
  889     {
  890         set.options = client_info->options;
  891     }
  892 
  893     reload_xkb(keyboard->device, &set);
  894     reload_xkb(inputInfo.keyboard, &set);
  895 
  896     return 0;
  897 }
  898 
  899 /******************************************************************************/
  900 static XF86ModuleVersionInfo rdpkeybVersionRec =
  901 {
  902     XRDP_KEYB_NAME,
  903     MODULEVENDORSTRING,
  904     MODINFOSTRING1,
  905     MODINFOSTRING2,
  906     XORG_VERSION_CURRENT,
  907     PACKAGE_VERSION_MAJOR,
  908     PACKAGE_VERSION_MINOR,
  909     PACKAGE_VERSION_PATCHLEVEL,
  910     ABI_CLASS_XINPUT,
  911     ABI_XINPUT_VERSION,
  912     MOD_CLASS_XINPUT,
  913     { 0, 0, 0, 0 }
  914 };
  915 
  916 /******************************************************************************/
  917 _X_EXPORT XF86ModuleData xrdpkeybModuleData =
  918 {
  919     &rdpkeybVersionRec,
  920     rdpkeybPlug,
  921     rdpkeybUnplug
  922 };