/[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 1035 by astrand, Fri Dec 30 20:32:06 2005 UTC revision 1405 by jsorg71, Thu May 3 04:53:39 2007 UTC
# Line 2  Line 2 
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X keyboard mapping     User interface services - X keyboard mapping
4    
5     Copyright (C) Matthew Chapman 1999-2005     Copyright (C) Matthew Chapman 1999-2007
6     Copyright (C) Peter Astrand <peter@cendio.se> 2003     Copyright (C) Peter Astrand <astrand@cendio.se> 2003-2007
7      
8     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.     (at your option) any later version.
12      
13     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# Line 46  extern int g_keyboard_type; Line 46  extern int g_keyboard_type;
46  extern int g_keyboard_subtype;  extern int g_keyboard_subtype;
47  extern int g_keyboard_functionkeys;  extern int g_keyboard_functionkeys;
48  extern int g_win_button_size;  extern int g_win_button_size;
49  extern BOOL g_enable_compose;  extern RD_BOOL g_enable_compose;
50  extern BOOL g_use_rdp5;  extern RD_BOOL g_use_rdp5;
51  extern BOOL g_numlock_sync;  extern RD_BOOL g_numlock_sync;
52    
53  static BOOL keymap_loaded;  static RD_BOOL keymap_loaded;
54  static key_translation *keymap[KEYMAP_SIZE];  static key_translation *keymap[KEYMAP_SIZE];
55  static int min_keycode;  static int min_keycode;
56  static uint16 remote_modifier_state = 0;  static uint16 remote_modifier_state = 0;
57  static uint16 saved_remote_modifier_state = 0;  static uint16 saved_remote_modifier_state = 0;
58    
59  static void update_modifier_state(uint8 scancode, BOOL pressed);  static void update_modifier_state(uint8 scancode, RD_BOOL pressed);
60    
61  /* Free key_translation structure, including linked list */  /* Free key_translation structure, including linked list */
62  static void  static void
# Line 159  add_sequence(char *rest, char *mapname) Line 159  add_sequence(char *rest, char *mapname)
159          DEBUG_KBD(("\n"));          DEBUG_KBD(("\n"));
160  }  }
161    
162  BOOL  RD_BOOL
163  xkeymap_from_locale(const char *locale)  xkeymap_from_locale(const char *locale)
164  {  {
165          char *str, *ptr;          char *str, *ptr;
# Line 206  xkeymap_from_locale(const char *locale) Line 206  xkeymap_from_locale(const char *locale)
206          {          {
207                  fclose(fp);                  fclose(fp);
208                  STRNCPY(g_keymapname, str, sizeof(g_keymapname));                  STRNCPY(g_keymapname, str, sizeof(g_keymapname));
209                    xfree(str);
210                  return True;                  return True;
211          }          }
212    
213            xfree(str);
214          return False;          return False;
215  }  }
216    
# Line 273  xkeymap_open(const char *filename) Line 275  xkeymap_open(const char *filename)
275          return NULL;          return NULL;
276  }  }
277    
278  static BOOL  static RD_BOOL
279  xkeymap_read(char *mapname)  xkeymap_read(char *mapname)
280  {  {
281          FILE *fp;          FILE *fp;
# Line 453  xkeymap_init(void) Line 455  xkeymap_init(void)
455  }  }
456    
457  static void  static void
458  send_winkey(uint32 ev_time, BOOL pressed, BOOL leftkey)  send_winkey(uint32 ev_time, RD_BOOL pressed, RD_BOOL leftkey)
459  {  {
460          uint8 winkey;          uint8 winkey;
461    
# Line 502  reset_winkey(uint32 ev_time) Line 504  reset_winkey(uint32 ev_time)
504  }  }
505    
506  /* Handle special key combinations */  /* Handle special key combinations */
507  BOOL  RD_BOOL
508  handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed)  handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, RD_BOOL pressed)
509  {  {
510          switch (keysym)          switch (keysym)
511          {          {
# Line 589  handle_special_keys(uint32 keysym, unsig Line 591  handle_special_keys(uint32 keysym, unsig
591                          /* Inhibit */                          /* Inhibit */
592                          return True;                          return True;
593                          break;                          break;
594                    case XK_Overlay1_Enable:
595                            /* Toggle SeamlessRDP */
596                            if (pressed)
597                                    ui_seamless_toggle();
598                            break;
599    
600          }          }
601          return False;          return False;
# Line 607  xkeymap_translate_key(uint32 keysym, uns Line 614  xkeymap_translate_key(uint32 keysym, uns
614                  tr = *ptr;                  tr = *ptr;
615                  if (tr.seq_keysym == 0) /* Normal scancode translation */                  if (tr.seq_keysym == 0) /* Normal scancode translation */
616                  {                  {
617                          if (tr.modifiers & MapInhibitMask)                          if (MASK_HAS_BITS(tr.modifiers, MapInhibitMask))
618                          {                          {
619                                  DEBUG_KBD(("Inhibiting key\n"));                                  DEBUG_KBD(("Inhibiting key\n"));
620                                  tr.scancode = 0;                                  tr.scancode = 0;
621                                  return tr;                                  return tr;
622                          }                          }
623    
624                          if (tr.modifiers & MapLocalStateMask)                          if (MASK_HAS_BITS(tr.modifiers, MapLocalStateMask))
625                          {                          {
626                                  /* The modifiers to send for this key should be obtained                                  /* The modifiers to send for this key should be obtained
627                                     from the local state. Currently, only shift is implemented. */                                     from the local state. Currently, only shift is implemented. */
628                                  if (state & ShiftMask)                                  if (MASK_HAS_BITS(state, ShiftMask))
629                                  {                                  {
630                                          tr.modifiers = MapLeftShiftMask;                                          tr.modifiers = MapLeftShiftMask;
631                                  }                                  }
632                          }                          }
633    
634                          if ((tr.modifiers & MapLeftShiftMask)                          /* Windows interprets CapsLock+Ctrl+key
635                              && ((remote_modifier_state & MapLeftCtrlMask)                             differently from Shift+Ctrl+key. Since we
636                                  || (remote_modifier_state & MapRightCtrlMask))                             are simulating CapsLock with Shifts, things
637                              && get_key_state(state, XK_Caps_Lock))                             like Ctrl+f with CapsLock on breaks. To
638                               solve this, we are releasing Shift if Ctrl
639                               is on, but only if Shift isn't physically pressed. */
640                            if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
641                                && MASK_HAS_BITS(remote_modifier_state, MapCtrlMask)
642                                && !MASK_HAS_BITS(state, ShiftMask))
643                          {                          {
644                                  DEBUG_KBD(("CapsLock + Ctrl pressed, releasing LeftShift\n"));                                  DEBUG_KBD(("Non-physical Shift + Ctrl pressed, releasing Shift\n"));
645                                  tr.modifiers ^= MapLeftShiftMask;                                  MASK_REMOVE_BITS(tr.modifiers, MapShiftMask);
646                          }                          }
647    
648                          DEBUG_KBD(("Found scancode translation, scancode=0x%x, modifiers=0x%x\n",                          DEBUG_KBD(("Found scancode translation, scancode=0x%x, modifiers=0x%x\n",
# Line 651  xkeymap_translate_key(uint32 keysym, uns Line 663  xkeymap_translate_key(uint32 keysym, uns
663                          /* The modifiers to send for this key should be                          /* The modifiers to send for this key should be
664                             obtained from the local state. Currently, only                             obtained from the local state. Currently, only
665                             shift is implemented. */                             shift is implemented. */
666                          if (state & ShiftMask)                          if (MASK_HAS_BITS(state, ShiftMask))
667                          {                          {
668                                  tr.modifiers = MapLeftShiftMask;                                  tr.modifiers = MapLeftShiftMask;
669                          }                          }
# Line 667  xkeymap_translate_key(uint32 keysym, uns Line 679  xkeymap_translate_key(uint32 keysym, uns
679          return tr;          return tr;
680  }  }
681    
682    static RD_BOOL
683    is_modifier(uint8 scancode)
684    {
685            switch (scancode)
686            {
687                    case SCANCODE_CHAR_LSHIFT:
688                    case SCANCODE_CHAR_RSHIFT:
689                    case SCANCODE_CHAR_LCTRL:
690                    case SCANCODE_CHAR_RCTRL:
691                    case SCANCODE_CHAR_LALT:
692                    case SCANCODE_CHAR_RALT:
693                    case SCANCODE_CHAR_LWIN:
694                    case SCANCODE_CHAR_RWIN:
695                    case SCANCODE_CHAR_NUMLOCK:
696                            return True;
697                    default:
698                            break;
699            }
700            return False;
701    }
702    
703    static void
704    save_remote_modifiers_if_modifier(uint8 scancode)
705    {
706            if (!is_modifier(scancode))
707                    return;
708    
709            saved_remote_modifier_state = remote_modifier_state;
710    }
711    
712  void  void
713  xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time,  xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time,
714                    BOOL pressed, uint8 nesting)                    RD_BOOL pressed, uint8 nesting)
715  {  {
716          key_translation tr, *ptr;          key_translation tr, *ptr;
717          tr = xkeymap_translate_key(keysym, keycode, state);          tr = xkeymap_translate_key(keysym, keycode, state);
# Line 685  xkeymap_send_keys(uint32 keysym, unsigne Line 727  xkeymap_send_keys(uint32 keysym, unsigne
727                          save_remote_modifiers(tr.scancode);                          save_remote_modifiers(tr.scancode);
728                          ensure_remote_modifiers(ev_time, tr);                          ensure_remote_modifiers(ev_time, tr);
729                          rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);                          rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
                         restore_remote_modifiers(ev_time, tr.scancode);  
730                  }                  }
731                  else                  else
732                  {                  {
733                          rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);                          rdp_send_scancode(ev_time, RDP_KEYRELEASE, tr.scancode);
734                            restore_remote_modifiers(ev_time, tr.scancode);
735                            save_remote_modifiers_if_modifier(tr.scancode);
736                  }                  }
737                  return;                  return;
738          }          }
# Line 750  get_ksname(uint32 keysym) Line 793  get_ksname(uint32 keysym)
793          return ksname;          return ksname;
794  }  }
795    
 static BOOL  
 is_modifier(uint8 scancode)  
 {  
         switch (scancode)  
         {  
                 case SCANCODE_CHAR_LSHIFT:  
                 case SCANCODE_CHAR_RSHIFT:  
                 case SCANCODE_CHAR_LCTRL:  
                 case SCANCODE_CHAR_RCTRL:  
                 case SCANCODE_CHAR_LALT:  
                 case SCANCODE_CHAR_RALT:  
                 case SCANCODE_CHAR_LWIN:  
                 case SCANCODE_CHAR_RWIN:  
                 case SCANCODE_CHAR_NUMLOCK:  
                         return True;  
                 default:  
                         break;  
         }  
         return False;  
 }  
   
796  void  void
797  save_remote_modifiers(uint8 scancode)  save_remote_modifiers(uint8 scancode)
798  {  {
# Line 944  reset_modifier_keys() Line 966  reset_modifier_keys()
966    
967    
968  static void  static void
969  update_modifier_state(uint8 scancode, BOOL pressed)  update_modifier_state(uint8 scancode, RD_BOOL pressed)
970  {  {
971  #ifdef WITH_DEBUG_KBD  #ifdef WITH_DEBUG_KBD
972          uint16 old_modifier_state;          uint16 old_modifier_state;
# Line 983  update_modifier_state(uint8 scancode, BO Line 1005  update_modifier_state(uint8 scancode, BO
1005                             modifier state only on Keypress */                             modifier state only on Keypress */
1006                          if (pressed && !g_numlock_sync)                          if (pressed && !g_numlock_sync)
1007                          {                          {
1008                                  BOOL newNumLockState;                                  RD_BOOL newNumLockState;
1009                                  newNumLockState =                                  newNumLockState =
1010                                          (MASK_HAS_BITS                                          (MASK_HAS_BITS
1011                                           (remote_modifier_state, MapNumLockMask) == False);                                           (remote_modifier_state, MapNumLockMask) == False);

Legend:
Removed from v.1035  
changed lines
  Added in v.1405

  ViewVC Help
Powered by ViewVC 1.1.26