/[rdesktop]/sourceforge.net/trunk/rdesktop/xkeymap.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/xkeymap.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 70 by astrand, Sat Jul 27 23:09:32 2002 UTC revision 193 by matthewc, Tue Sep 24 11:14:46 2002 UTC
# Line 19  Line 19 
19  */  */
20    
21  #include <X11/Xlib.h>  #include <X11/Xlib.h>
22  #include <X11/keysym.h>  #define XK_MISCELLANY
23  #include <stdio.h>  #include <X11/keysymdef.h>
 #include <stdlib.h>  
 #include <string.h>  
24  #include <ctype.h>  #include <ctype.h>
25  #include <limits.h>  #include <limits.h>
26    #include <time.h>
27  #include "rdesktop.h"  #include "rdesktop.h"
28  #include "scancodes.h"  #include "scancodes.h"
29    
# Line 38  extern int keylayout; Line 37  extern int keylayout;
37  extern BOOL enable_compose;  extern BOOL enable_compose;
38    
39  static key_translation keymap[KEYMAP_SIZE];  static key_translation keymap[KEYMAP_SIZE];
40  static unsigned int min_keycode;  static int min_keycode;
41  static uint16 remote_modifier_state = 0;  static uint16 remote_modifier_state = 0;
42    
43    static void update_modifier_state(uint16 modifiers, BOOL pressed);
44    
45  static void  static void
46  add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)  add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)
47  {  {
# Line 53  add_to_keymap(char *keyname, uint8 scanc Line 54  add_to_keymap(char *keyname, uint8 scanc
54                  return;                  return;
55          }          }
56    
57          DEBUG_KBD("Adding translation, keysym=0x%x, scancode=0x%x, "          DEBUG_KBD(("Adding translation, keysym=0x%x, scancode=0x%x, "
58                    "modifiers=0x%x\n", (unsigned int) keysym, scancode,                     "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers));
                   modifiers);  
59    
60          keymap[keysym & KEYMAP_MASK].scancode = scancode;          keymap[keysym & KEYMAP_MASK].scancode = scancode;
61          keymap[keysym & KEYMAP_MASK].modifiers = modifiers;          keymap[keysym & KEYMAP_MASK].modifiers = modifiers;
# Line 117  xkeymap_read(char *mapname) Line 117  xkeymap_read(char *mapname)
117                  if (strncmp(line, "map ", 4) == 0)                  if (strncmp(line, "map ", 4) == 0)
118                  {                  {
119                          keylayout = strtol(line + 4, NULL, 16);                          keylayout = strtol(line + 4, NULL, 16);
120                          DEBUG_KBD("Keylayout 0x%x\n", keylayout);                          DEBUG_KBD(("Keylayout 0x%x\n", keylayout));
121                          continue;                          continue;
122                  }                  }
123    
124                  /* compose */                  /* compose */
125                  if (strncmp(line, "enable_compose", 15) == 0)                  if (strncmp(line, "enable_compose", 15) == 0)
126                  {                  {
127                          DEBUG_KBD("Enabling compose handling\n");                          DEBUG_KBD(("Enabling compose handling\n"));
128                          enable_compose = True;                          enable_compose = True;
129                          continue;                          continue;
130                  }                  }
# Line 140  xkeymap_read(char *mapname) Line 140  xkeymap_read(char *mapname)
140                  p = strchr(line, ' ');                  p = strchr(line, ' ');
141                  if (p == NULL)                  if (p == NULL)
142                  {                  {
143                          error("Bad line %d in keymap %s\n", line_num,                          error("Bad line %d in keymap %s\n", line_num, mapname);
                               mapname);  
144                          continue;                          continue;
145                  }                  }
146                  else                  else
# Line 177  xkeymap_read(char *mapname) Line 176  xkeymap_read(char *mapname)
176                          MASK_ADD_BITS(modifiers, MapLocalStateMask);                          MASK_ADD_BITS(modifiers, MapLocalStateMask);
177                  }                  }
178    
179                    if (strstr(line_rest, "inhibit"))
180                    {
181                            MASK_ADD_BITS(modifiers, MapInhibitMask);
182                    }
183    
184                  add_to_keymap(keyname, scancode, modifiers, mapname);                  add_to_keymap(keyname, scancode, modifiers, mapname);
185    
186                  if (strstr(line_rest, "addupper"))                  if (strstr(line_rest, "addupper"))
# Line 197  xkeymap_read(char *mapname) Line 201  xkeymap_read(char *mapname)
201    
202  /* Before connecting and creating UI */  /* Before connecting and creating UI */
203  void  void
204  xkeymap_init1(void)  xkeymap_init(void)
205  {  {
206          int i;          unsigned int max_keycode;
   
         /* Zeroing keymap */  
         for (i = 0; i < KEYMAP_SIZE; i++)  
         {  
                 keymap[i].scancode = 0;  
                 keymap[i].modifiers = 0;  
         }  
207    
208          if (strcmp(keymapname, "none"))          if (strcmp(keymapname, "none"))
         {  
209                  xkeymap_read(keymapname);                  xkeymap_read(keymapname);
         }  
210    
211            XDisplayKeycodes(display, &min_keycode, (int *) &max_keycode);
212  }  }
213    
214  /* After connecting and creating UI */  /* Handles, for example, multi-scancode keypresses (which is not
215  void     possible via keymap-files) */
216  xkeymap_init2(void)  BOOL
217    handle_special_keys(uint32 keysym, uint32 ev_time, BOOL pressed)
218  {  {
219          unsigned int max_keycode;          switch (keysym)
220          XDisplayKeycodes(display, &min_keycode, &max_keycode);          {
221                    case XK_Break:  /* toggle full screen */
222                            if (get_key_state(XK_Alt_L) || get_key_state(XK_Alt_R))
223                            {
224                                    if (pressed)
225                                            xwin_toggle_fullscreen();
226                                    return True;
227                            }
228                            break;
229    
230                    case XK_Meta_L: /* Windows keys */
231                    case XK_Super_L:
232                    case XK_Hyper_L:
233                    case XK_Meta_R:
234                    case XK_Super_R:
235                    case XK_Hyper_R:
236                            if (pressed)
237                            {
238                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
239                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
240                            }
241                            else
242                            {
243                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
244                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
245                            }
246                            return True;
247                            break;
248            }
249            return False;
250  }  }
251    
252    
253  key_translation  key_translation
254  xkeymap_translate_key(KeySym keysym, unsigned int keycode, unsigned int state)  xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
255  {  {
256          key_translation tr = { 0, 0 };          key_translation tr = { 0, 0 };
257    
258          tr = keymap[keysym & KEYMAP_MASK];          tr = keymap[keysym & KEYMAP_MASK];
259    
260            if (tr.modifiers & MapInhibitMask)
261            {
262                    DEBUG_KBD(("Inhibiting key\n"));
263                    tr.scancode = 0;
264                    return tr;
265            }
266    
267          if (tr.modifiers & MapLocalStateMask)          if (tr.modifiers & MapLocalStateMask)
268          {          {
269                  /* The modifiers to send for this key should be obtained                  /* The modifiers to send for this key should be obtained
# Line 243  xkeymap_translate_key(KeySym keysym, uns Line 276  xkeymap_translate_key(KeySym keysym, uns
276    
277          if (tr.scancode != 0)          if (tr.scancode != 0)
278          {          {
279                  DEBUG_KBD                  DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
280                          ("Found key translation, scancode=0x%x, modifiers=0x%x\n",                            tr.scancode, tr.modifiers));
                          tr.scancode, tr.modifiers);  
281                  return tr;                  return tr;
282          }          }
283    
284          printf("No translation for (keysym 0x%lx, %s)\n", keysym,          DEBUG_KBD(("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)));
                get_ksname(keysym));  
285    
286          /* not in keymap, try to interpret the raw scancode */          /* not in keymap, try to interpret the raw scancode */
287          if ((keycode >= min_keycode) && (keycode <= 0x60))          if ((keycode >= min_keycode) && (keycode <= 0x60))
288          {          {
289                  tr.scancode = keycode - min_keycode;                  tr.scancode = keycode - min_keycode;
290                  printf("Sending guessed scancode 0x%x\n", tr.scancode);  
291                    /* The modifiers to send for this key should be
292                       obtained from the local state. Currently, only
293                       shift is implemented. */
294                    if (state & ShiftMask)
295                    {
296                            tr.modifiers = MapLeftShiftMask;
297                    }
298    
299                    DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
300          }          }
301          else          else
302          {          {
303                  printf("No good guess for keycode 0x%x found\n", keycode);                  DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
304          }          }
305    
306          return tr;          return tr;
# Line 287  xkeymap_translate_button(unsigned int bu Line 327  xkeymap_translate_button(unsigned int bu
327  }  }
328    
329  char *  char *
330  get_ksname(KeySym keysym)  get_ksname(uint32 keysym)
331  {  {
332          char *ksname = NULL;          char *ksname = NULL;
333    
# Line 299  get_ksname(KeySym keysym) Line 339  get_ksname(KeySym keysym)
339          return ksname;          return ksname;
340  }  }
341    
 BOOL  
 inhibit_key(KeySym keysym)  
 {  
         switch (keysym)  
         {  
                 case XK_Caps_Lock:  
                         return True;  
                         break;  
                 case XK_Multi_key:  
                         return True;  
                         break;  
                 default:  
                         break;  
         }  
         return False;  
 }  
342    
343  void  void
344  ensure_remote_modifiers(uint32 ev_time, key_translation tr)  ensure_remote_modifiers(uint32 ev_time, key_translation tr)
# Line 336  ensure_remote_modifiers(uint32 ev_time, Line 360  ensure_remote_modifiers(uint32 ev_time,
360                          break;                          break;
361          }          }
362    
363          /* Shift */          /* Shift. Left shift and right shift are treated as equal; either is fine. */
364          if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)          if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
365              != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))              != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
366          {          {
367                  /* The remote modifier state is not correct */                  /* The remote modifier state is not correct */
368                  if (MASK_HAS_BITS(tr.modifiers, MapShiftMask))                  if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
369                  {                  {
370                          /* Needs this modifier. Send down. */                          /* Needs left shift. Send down. */
371                          rdp_send_scancode(ev_time, RDP_KEYPRESS,                          rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
372                                            SCANCODE_CHAR_LSHIFT);                  }
373                    else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
374                    {
375                            /* Needs right shift. Send down. */
376                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
377                  }                  }
378                  else                  else
379                  {                  {
380                          /* Should not use this modifier. Send up. */                          /* Should not use this modifier. Send up for shift currently pressed. */
381                          rdp_send_scancode(ev_time, RDP_KEYRELEASE,                          if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
382                                            SCANCODE_CHAR_LSHIFT);                                  /* Left shift is down */
383                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
384                            else
385                                    /* Right shift is down */
386                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
387                  }                  }
388          }          }
389    
# Line 363  ensure_remote_modifiers(uint32 ev_time, Line 395  ensure_remote_modifiers(uint32 ev_time,
395                  if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))                  if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
396                  {                  {
397                          /* Needs this modifier. Send down. */                          /* Needs this modifier. Send down. */
398                          rdp_send_scancode(ev_time, RDP_KEYPRESS,                          rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
                                           SCANCODE_CHAR_RALT);  
399                  }                  }
400                  else                  else
401                  {                  {
402                          /* Should not use this modifier. Send up. */                          /* Should not use this modifier. Send up. */
403                          rdp_send_scancode(ev_time, RDP_KEYRELEASE,                          rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
                                           SCANCODE_CHAR_RALT);  
404                  }                  }
405          }          }
406    
# Line 379  ensure_remote_modifiers(uint32 ev_time, Line 409  ensure_remote_modifiers(uint32 ev_time,
409              != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))              != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
410          {          {
411                  /* The remote modifier state is not correct */                  /* The remote modifier state is not correct */
412                  DEBUG_KBD("Remote NumLock state is incorrect. Toggling\n");                  uint16 new_remote_state = 0;
413    
414                  if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))                  if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
415                  {                  {
416                          /* Needs this modifier. Toggle */                          DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
417                          rdp_send_scancode(ev_time, RDP_KEYPRESS,                          new_remote_state |= KBD_FLAG_NUMLOCK;
                                           SCANCODE_CHAR_NUMLOCK);  
                         rdp_send_scancode(ev_time, RDP_KEYRELEASE,  
                                           SCANCODE_CHAR_NUMLOCK);  
418                  }                  }
419                  else                  else
420                  {                  {
421                          /* Should not use this modifier. Toggle */                          DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
                         rdp_send_scancode(ev_time, RDP_KEYPRESS,  
                                           SCANCODE_CHAR_NUMLOCK);  
                         rdp_send_scancode(ev_time, RDP_KEYRELEASE,  
                                           SCANCODE_CHAR_NUMLOCK);  
422                  }                  }
423    
424                    rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
425                    update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);
426          }          }
427    }
428    
429    
430    void
431    reset_modifier_keys(void)
432    {
433            /* reset keys */
434            uint32 ev_time;
435            ev_time = time(NULL);
436    
437            if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(XK_Shift_L))
438                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
439    
440            if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(XK_Shift_R))
441                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
442    
443            if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(XK_Control_L))
444                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
445    
446            if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(XK_Control_R))
447                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
448    
449            if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(XK_Alt_L))
450                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
451    
452            if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
453                !get_key_state(XK_Alt_R) && !get_key_state(XK_Mode_switch))
454                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
455  }  }
456    
457    
458  static void  static void
459  update_modifier_state(uint16 modifiers, BOOL pressed)  update_modifier_state(uint16 modifiers, BOOL pressed)
460  {  {
461    #ifdef WITH_DEBUG_KBD
462            uint16 old_modifier_state;
463    
464            old_modifier_state = remote_modifier_state;
465    #endif
466    
         DEBUG_KBD("Before updating modifier_state:0x%x, pressed=0x%x\n",  
                   remote_modifier_state, pressed);  
467          switch (modifiers)          switch (modifiers)
468          {          {
469                  case SCANCODE_CHAR_LSHIFT:                  case SCANCODE_CHAR_LSHIFT:
470                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
                                         MapLeftShiftMask, pressed);  
471                          break;                          break;
472                  case SCANCODE_CHAR_RSHIFT:                  case SCANCODE_CHAR_RSHIFT:
473                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
                                         MapRightShiftMask, pressed);  
474                          break;                          break;
475                  case SCANCODE_CHAR_LCTRL:                  case SCANCODE_CHAR_LCTRL:
476                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
                                         MapLeftCtrlMask, pressed);  
477                          break;                          break;
478                  case SCANCODE_CHAR_RCTRL:                  case SCANCODE_CHAR_RCTRL:
479                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
                                         MapRightCtrlMask, pressed);  
480                          break;                          break;
481                  case SCANCODE_CHAR_LALT:                  case SCANCODE_CHAR_LALT:
482                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
                                         pressed);  
483                          break;                          break;
484                  case SCANCODE_CHAR_RALT:                  case SCANCODE_CHAR_RALT:
485                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
                                         MapRightAltMask, pressed);  
486                          break;                          break;
487                  case SCANCODE_CHAR_LWIN:                  case SCANCODE_CHAR_LWIN:
488                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
                                         pressed);  
489                          break;                          break;
490                  case SCANCODE_CHAR_RWIN:                  case SCANCODE_CHAR_RWIN:
491                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
                                         MapRightWinMask, pressed);  
492                          break;                          break;
493                  case SCANCODE_CHAR_NUMLOCK:                  case SCANCODE_CHAR_NUMLOCK:
494                          /* KeyReleases for NumLocks are sent immediately. Toggle the                          /* KeyReleases for NumLocks are sent immediately. Toggle the
# Line 449  update_modifier_state(uint16 modifiers, Line 498  update_modifier_state(uint16 modifiers,
498                                  BOOL newNumLockState;                                  BOOL newNumLockState;
499                                  newNumLockState =                                  newNumLockState =
500                                          (MASK_HAS_BITS                                          (MASK_HAS_BITS
501                                           (remote_modifier_state,                                           (remote_modifier_state, MapNumLockMask) == False);
                                           MapNumLockMask) == False);  
502                                  MASK_CHANGE_BIT(remote_modifier_state,                                  MASK_CHANGE_BIT(remote_modifier_state,
503                                                  MapNumLockMask,                                                  MapNumLockMask, newNumLockState);
                                                 newNumLockState);  
504                          }                          }
505                          break;                          break;
506          }          }
507          DEBUG_KBD("After updating modifier_state:0x%x\n",  
508                    remote_modifier_state);  #ifdef WITH_DEBUG_KBD
509            if (old_modifier_state != remote_modifier_state)
510            {
511                    DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n",
512                               old_modifier_state, pressed));
513                    DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state));
514            }
515    #endif
516    
517  }  }
518    
# Line 470  rdp_send_scancode(uint32 time, uint16 fl Line 524  rdp_send_scancode(uint32 time, uint16 fl
524    
525          if (scancode & SCANCODE_EXTENDED)          if (scancode & SCANCODE_EXTENDED)
526          {          {
527                  DEBUG_KBD("Sending extended scancode=0x%x, flags=0x%x\n",                  DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n",
528                            scancode & ~SCANCODE_EXTENDED, flags);                             scancode & ~SCANCODE_EXTENDED, flags));
529                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
530                                 scancode & ~SCANCODE_EXTENDED, 0);                                 scancode & ~SCANCODE_EXTENDED, 0);
531          }          }
532          else          else
533          {          {
534                  DEBUG_KBD("Sending scancode=0x%x, flags=0x%x\n", scancode,                  DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags));
                           flags);  
535                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
536          }          }
537  }  }

Legend:
Removed from v.70  
changed lines
  Added in v.193

  ViewVC Help
Powered by ViewVC 1.1.26