/[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 66 by astrand, Thu Jul 18 18:28:12 2002 UTC revision 183 by astrand, Tue Sep 17 16:57:07 2002 UTC
# Line 25  Line 25 
25  #include <string.h>  #include <string.h>
26  #include <ctype.h>  #include <ctype.h>
27  #include <limits.h>  #include <limits.h>
28    #include <assert.h>
29  #include "rdesktop.h"  #include "rdesktop.h"
30  #include "scancodes.h"  #include "scancodes.h"
31    
# Line 35  Line 36 
36  extern Display *display;  extern Display *display;
37  extern char keymapname[16];  extern char keymapname[16];
38  extern int keylayout;  extern int keylayout;
39    extern BOOL enable_compose;
40    
41  static key_translation keymap[KEYMAP_SIZE];  static key_translation keymap[KEYMAP_SIZE];
42  static unsigned int min_keycode;  static int min_keycode;
43  static uint16 remote_modifier_state = 0;  static uint16 remote_modifier_state = 0;
44    
45    static void update_modifier_state(uint16 modifiers, BOOL pressed);
46    
47  static void  static void
48  add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)  add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)
49  {  {
# Line 52  add_to_keymap(char *keyname, uint8 scanc Line 56  add_to_keymap(char *keyname, uint8 scanc
56                  return;                  return;
57          }          }
58    
59          DEBUG_KBD("Adding translation, keysym=0x%x, scancode=0x%x, "          DEBUG_KBD(("Adding translation, keysym=0x%x, scancode=0x%x, "
60                    "modifiers=0x%x\n", (unsigned int) keysym, scancode,                     "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers));
                   modifiers);  
61    
62          keymap[keysym & KEYMAP_MASK].scancode = scancode;          keymap[keysym & KEYMAP_MASK].scancode = scancode;
63          keymap[keysym & KEYMAP_MASK].modifiers = modifiers;          keymap[keysym & KEYMAP_MASK].modifiers = modifiers;
# Line 116  xkeymap_read(char *mapname) Line 119  xkeymap_read(char *mapname)
119                  if (strncmp(line, "map ", 4) == 0)                  if (strncmp(line, "map ", 4) == 0)
120                  {                  {
121                          keylayout = strtol(line + 4, NULL, 16);                          keylayout = strtol(line + 4, NULL, 16);
122                          DEBUG_KBD("Keylayout 0x%x\n", keylayout);                          DEBUG_KBD(("Keylayout 0x%x\n", keylayout));
123                            continue;
124                    }
125    
126                    /* compose */
127                    if (strncmp(line, "enable_compose", 15) == 0)
128                    {
129                            DEBUG_KBD(("Enabling compose handling\n"));
130                            enable_compose = True;
131                          continue;                          continue;
132                  }                  }
133    
# Line 131  xkeymap_read(char *mapname) Line 142  xkeymap_read(char *mapname)
142                  p = strchr(line, ' ');                  p = strchr(line, ' ');
143                  if (p == NULL)                  if (p == NULL)
144                  {                  {
145                          error("Bad line %d in keymap %s\n", line_num,                          error("Bad line %d in keymap %s\n", line_num, mapname);
                               mapname);  
146                          continue;                          continue;
147                  }                  }
148                  else                  else
# Line 163  xkeymap_read(char *mapname) Line 173  xkeymap_read(char *mapname)
173                          MASK_ADD_BITS(modifiers, MapNumLockMask);                          MASK_ADD_BITS(modifiers, MapNumLockMask);
174                  }                  }
175    
176                    if (strstr(line_rest, "localstate"))
177                    {
178                            MASK_ADD_BITS(modifiers, MapLocalStateMask);
179                    }
180    
181                    if (strstr(line_rest, "inhibit"))
182                    {
183                            MASK_ADD_BITS(modifiers, MapInhibitMask);
184                    }
185    
186                  add_to_keymap(keyname, scancode, modifiers, mapname);                  add_to_keymap(keyname, scancode, modifiers, mapname);
187    
188                  if (strstr(line_rest, "addupper"))                  if (strstr(line_rest, "addupper"))
# Line 183  xkeymap_read(char *mapname) Line 203  xkeymap_read(char *mapname)
203    
204  /* Before connecting and creating UI */  /* Before connecting and creating UI */
205  void  void
206  xkeymap_init1(void)  xkeymap_init(void)
207  {  {
208            unsigned int max_keycode;
209          int i;          int i;
210    
         /* Zeroing keymap */  
         for (i = 0; i < KEYMAP_SIZE; i++)  
         {  
                 keymap[i].scancode = 0;  
                 keymap[i].modifiers = 0;  
         }  
   
211          if (strcmp(keymapname, "none"))          if (strcmp(keymapname, "none"))
         {  
212                  xkeymap_read(keymapname);                  xkeymap_read(keymapname);
         }  
213    
214            XDisplayKeycodes(display, &min_keycode, (int *) &max_keycode);
215  }  }
216    
217  /* After connecting and creating UI */  /* Handles, for example, multi-scancode keypresses (which is not
218  void     possible via keymap-files) */
219  xkeymap_init2(void)  BOOL
220    handle_special_keys(KeySym keysym, uint32 ev_time, BOOL pressed)
221  {  {
222          unsigned int max_keycode;          switch (keysym)
223          XDisplayKeycodes(display, &min_keycode, &max_keycode);          {
224                    case XK_Break:  /* toggle full screen */
225                            if (pressed && (get_key_state(XK_Alt_L) || get_key_state(XK_Alt_R)))
226                            {
227                                    xwin_toggle_fullscreen();
228                                    return True;
229                            }
230                            break;
231    
232                    case XK_Meta_L: /* Windows keys */
233                    case XK_Super_L:
234                    case XK_Hyper_L:
235                    case XK_Meta_R:
236                    case XK_Super_R:
237                    case XK_Hyper_R:
238                            if (pressed)
239                            {
240                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
241                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
242                            }
243                            else
244                            {
245                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
246                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
247                            }
248                            return True;
249                            break;
250            }
251            return False;
252  }  }
253    
254    
255  key_translation  key_translation
256  xkeymap_translate_key(KeySym keysym, unsigned int keycode)  xkeymap_translate_key(KeySym keysym, unsigned int keycode, unsigned int state)
257  {  {
258          key_translation tr = { 0, 0 };          key_translation tr = { 0, 0 };
259    
260          tr = keymap[keysym & KEYMAP_MASK];          tr = keymap[keysym & KEYMAP_MASK];
261    
262            if (tr.modifiers & MapInhibitMask)
263            {
264                    DEBUG_KBD(("Inhibiting key\n"));
265                    tr.scancode = 0;
266                    return tr;
267            }
268    
269            if (tr.modifiers & MapLocalStateMask)
270            {
271                    /* The modifiers to send for this key should be obtained
272                       from the local state. Currently, only shift is implemented. */
273                    if (state & ShiftMask)
274                    {
275                            tr.modifiers = MapLeftShiftMask;
276                    }
277            }
278    
279          if (tr.scancode != 0)          if (tr.scancode != 0)
280          {          {
281                  DEBUG_KBD                  DEBUG_KBD
282                          ("Found key translation, scancode=0x%x, modifiers=0x%x\n",                          (("Found key translation, scancode=0x%x, modifiers=0x%x\n",
283                           tr.scancode, tr.modifiers);                            tr.scancode, tr.modifiers));
284                  return tr;                  return tr;
285          }          }
286    
287          printf("No translation for (keysym 0x%lx, %s)\n", keysym,          fprintf(stderr, "No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym));
                get_ksname(keysym));  
288    
289          /* not in keymap, try to interpret the raw scancode */          /* not in keymap, try to interpret the raw scancode */
290          if ((keycode >= min_keycode) && (keycode <= 0x60))          if ((keycode >= min_keycode) && (keycode <= 0x60))
291          {          {
292                  tr.scancode = keycode - min_keycode;                  tr.scancode = keycode - min_keycode;
293                  printf("Sending guessed scancode 0x%x\n", tr.scancode);  
294                    /* The modifiers to send for this key should be
295                       obtained from the local state. Currently, only
296                       shift is implemented. */
297                    if (state & ShiftMask)
298                    {
299                            tr.modifiers = MapLeftShiftMask;
300                    }
301    
302                    fprintf(stderr, "Sending guessed scancode 0x%x\n", tr.scancode);
303          }          }
304          else          else
305          {          {
306                  printf("No good guess for keycode 0x%x found\n", keycode);                  fprintf(stderr, "No good guess for keycode 0x%x found\n", keycode);
307          }          }
308    
309          return tr;          return tr;
# Line 253  xkeymap_translate_button(unsigned int bu Line 320  xkeymap_translate_button(unsigned int bu
320                          return MOUSE_FLAG_BUTTON3;                          return MOUSE_FLAG_BUTTON3;
321                  case Button3:   /* right */                  case Button3:   /* right */
322                          return MOUSE_FLAG_BUTTON2;                          return MOUSE_FLAG_BUTTON2;
323                    case Button4:   /* wheel up */
324                            return MOUSE_FLAG_BUTTON4;
325                    case Button5:   /* wheel down */
326                            return MOUSE_FLAG_BUTTON5;
327          }          }
328    
329          return 0;          return 0;
# Line 271  get_ksname(KeySym keysym) Line 342  get_ksname(KeySym keysym)
342          return ksname;          return ksname;
343  }  }
344    
 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;  
 }  
345    
346  void  void
347  ensure_remote_modifiers(uint32 ev_time, key_translation tr)  ensure_remote_modifiers(uint32 ev_time, key_translation tr)
# Line 308  ensure_remote_modifiers(uint32 ev_time, Line 363  ensure_remote_modifiers(uint32 ev_time,
363                          break;                          break;
364          }          }
365    
366          /* Shift */          /* Shift. Left shift and right shift are treated as equal; either is fine. */
367          if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)          if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
368              != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))              != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
369          {          {
370                  /* The remote modifier state is not correct */                  /* The remote modifier state is not correct */
371                  if (MASK_HAS_BITS(tr.modifiers, MapShiftMask))                  if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
372                  {                  {
373                          /* Needs this modifier. Send down. */                          /* Needs left shift. Send down. */
374                          rdp_send_scancode(ev_time, RDP_KEYPRESS,                          rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
375                                            SCANCODE_CHAR_LSHIFT);                  }
376                    else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
377                    {
378                            /* Needs right shift. Send down. */
379                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
380                  }                  }
381                  else                  else
382                  {                  {
383                          /* Should not use this modifier. Send up. */                          /* Should not use this modifier. Send up for shift currently pressed. */
384                          rdp_send_scancode(ev_time, RDP_KEYRELEASE,                          if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
385                                            SCANCODE_CHAR_LSHIFT);                                  /* Left shift is down */
386                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
387                            else
388                            {
389                                    assert(MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask));
390                                    /* Right shift is down */
391                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
392                            }
393    
394                  }                  }
395          }          }
396    
# Line 335  ensure_remote_modifiers(uint32 ev_time, Line 402  ensure_remote_modifiers(uint32 ev_time,
402                  if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))                  if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
403                  {                  {
404                          /* Needs this modifier. Send down. */                          /* Needs this modifier. Send down. */
405                          rdp_send_scancode(ev_time, RDP_KEYPRESS,                          rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
                                           SCANCODE_CHAR_RALT);  
406                  }                  }
407                  else                  else
408                  {                  {
409                          /* Should not use this modifier. Send up. */                          /* Should not use this modifier. Send up. */
410                          rdp_send_scancode(ev_time, RDP_KEYRELEASE,                          rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
                                           SCANCODE_CHAR_RALT);  
411                  }                  }
412          }          }
413    
# Line 351  ensure_remote_modifiers(uint32 ev_time, Line 416  ensure_remote_modifiers(uint32 ev_time,
416              != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))              != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
417          {          {
418                  /* The remote modifier state is not correct */                  /* The remote modifier state is not correct */
419                  DEBUG_KBD("Remote NumLock state is incorrect. Toggling\n");                  uint16 new_remote_state = 0;
420    
421                  if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))                  if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
422                  {                  {
423                          /* Needs this modifier. Toggle */                          DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
424                          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);  
425                  }                  }
426                  else                  else
427                  {                  {
428                          /* 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);  
429                  }                  }
430    
431                    rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
432                    update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);
433          }          }
434    }
435    
436    
437    void
438    reset_modifier_keys()
439    {
440            /* reset keys */
441            uint32 ev_time;
442            ev_time = time(NULL);
443    
444            if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(XK_Shift_L))
445                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
446    
447            if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(XK_Shift_R))
448                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
449    
450            if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(XK_Control_L))
451                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
452    
453            if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(XK_Control_R))
454                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
455    
456            if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(XK_Alt_L))
457                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
458    
459            if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
460                !get_key_state(XK_Alt_R) && !get_key_state(XK_Mode_switch))
461                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
462  }  }
463    
464    
465  static void  static void
466  update_modifier_state(uint16 modifiers, BOOL pressed)  update_modifier_state(uint16 modifiers, BOOL pressed)
467  {  {
468    #ifdef WITH_DEBUG_KBD
469            uint16 old_modifier_state;
470    
471            old_modifier_state = remote_modifier_state;
472    #endif
473    
         DEBUG_KBD("Before updating modifier_state:0x%x, pressed=0x%x\n",  
                   remote_modifier_state, pressed);  
474          switch (modifiers)          switch (modifiers)
475          {          {
476                  case SCANCODE_CHAR_LSHIFT:                  case SCANCODE_CHAR_LSHIFT:
477                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
                                         MapLeftShiftMask, pressed);  
478                          break;                          break;
479                  case SCANCODE_CHAR_RSHIFT:                  case SCANCODE_CHAR_RSHIFT:
480                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
                                         MapRightShiftMask, pressed);  
481                          break;                          break;
482                  case SCANCODE_CHAR_LCTRL:                  case SCANCODE_CHAR_LCTRL:
483                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
                                         MapLeftCtrlMask, pressed);  
484                          break;                          break;
485                  case SCANCODE_CHAR_RCTRL:                  case SCANCODE_CHAR_RCTRL:
486                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
                                         MapRightCtrlMask, pressed);  
487                          break;                          break;
488                  case SCANCODE_CHAR_LALT:                  case SCANCODE_CHAR_LALT:
489                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
                                         pressed);  
490                          break;                          break;
491                  case SCANCODE_CHAR_RALT:                  case SCANCODE_CHAR_RALT:
492                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
                                         MapRightAltMask, pressed);  
493                          break;                          break;
494                  case SCANCODE_CHAR_LWIN:                  case SCANCODE_CHAR_LWIN:
495                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask,                          MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
                                         pressed);  
496                          break;                          break;
497                  case SCANCODE_CHAR_RWIN:                  case SCANCODE_CHAR_RWIN:
498                          MASK_CHANGE_BIT(remote_modifier_state,                          MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
                                         MapRightWinMask, pressed);  
499                          break;                          break;
500                  case SCANCODE_CHAR_NUMLOCK:                  case SCANCODE_CHAR_NUMLOCK:
501                          /* KeyReleases for NumLocks are sent immediately. Toggle the                          /* KeyReleases for NumLocks are sent immediately. Toggle the
# Line 421  update_modifier_state(uint16 modifiers, Line 505  update_modifier_state(uint16 modifiers,
505                                  BOOL newNumLockState;                                  BOOL newNumLockState;
506                                  newNumLockState =                                  newNumLockState =
507                                          (MASK_HAS_BITS                                          (MASK_HAS_BITS
508                                           (remote_modifier_state,                                           (remote_modifier_state, MapNumLockMask) == False);
                                           MapNumLockMask) == False);  
509                                  MASK_CHANGE_BIT(remote_modifier_state,                                  MASK_CHANGE_BIT(remote_modifier_state,
510                                                  MapNumLockMask,                                                  MapNumLockMask, newNumLockState);
                                                 newNumLockState);  
511                          }                          }
512                          break;                          break;
513          }          }
514          DEBUG_KBD("After updating modifier_state:0x%x\n",  
515                    remote_modifier_state);  #ifdef WITH_DEBUG_KBD
516            if (old_modifier_state != remote_modifier_state)
517            {
518                    DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n",
519                               old_modifier_state, pressed));
520                    DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state));
521            }
522    #endif
523    
524  }  }
525    
# Line 442  rdp_send_scancode(uint32 time, uint16 fl Line 531  rdp_send_scancode(uint32 time, uint16 fl
531    
532          if (scancode & SCANCODE_EXTENDED)          if (scancode & SCANCODE_EXTENDED)
533          {          {
534                  DEBUG_KBD("Sending extended scancode=0x%x, flags=0x%x\n",                  DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n",
535                            scancode & ~SCANCODE_EXTENDED, flags);                             scancode & ~SCANCODE_EXTENDED, flags));
536                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
537                                 scancode & ~SCANCODE_EXTENDED, 0);                                 scancode & ~SCANCODE_EXTENDED, 0);
538          }          }
539          else          else
540          {          {
541                  DEBUG_KBD("Sending scancode=0x%x, flags=0x%x\n", scancode,                  DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags));
                           flags);  
542                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);                  rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
543          }          }
544  }  }

Legend:
Removed from v.66  
changed lines
  Added in v.183

  ViewVC Help
Powered by ViewVC 1.1.26