/[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 207 by matthewc, Thu Sep 26 14:26:46 2002 UTC revision 449 by astrand, Wed Aug 27 09:42:55 2003 UTC
# Line 12  Line 12 
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #ifdef RDP2VNC
22    #include "vnc/x11stubs.h"
23    #else
24  #include <X11/Xlib.h>  #include <X11/Xlib.h>
25  #define XK_MISCELLANY  #include <X11/keysym.h>
26  #include <X11/keysymdef.h>  #endif
27    
28  #include <ctype.h>  #include <ctype.h>
29  #include <limits.h>  #include <limits.h>
30  #include <time.h>  #include <time.h>
31  #include "rdesktop.h"  #include "rdesktop.h"
32  #include "scancodes.h"  #include "scancodes.h"
33    
34  #define KEYMAP_SIZE 4096  #define KEYMAP_SIZE 0xffff+1
35  #define KEYMAP_MASK (KEYMAP_SIZE - 1)  #define KEYMAP_MASK 0xffff
36  #define KEYMAP_MAX_LINE_LENGTH 80  #define KEYMAP_MAX_LINE_LENGTH 80
37    
38  extern Display *display;  extern Display *display;
39  extern char keymapname[16];  extern char keymapname[16];
40  extern int keylayout;  extern int keylayout;
41  extern BOOL enable_compose;  extern int win_button_size;
42    extern BOOL g_enable_compose;
43    
44  static BOOL keymap_loaded;  static BOOL keymap_loaded;
45  static key_translation keymap[KEYMAP_SIZE];  static key_translation keymap[KEYMAP_SIZE];
46  static int min_keycode;  static int min_keycode;
47  static uint16 remote_modifier_state = 0;  static uint16 remote_modifier_state = 0;
48    static uint16 saved_remote_modifier_state = 0;
49    
50  static void update_modifier_state(uint8 scancode, BOOL pressed);  static void update_modifier_state(uint8 scancode, BOOL pressed);
51    
# Line 51  add_to_keymap(char *keyname, uint8 scanc Line 57  add_to_keymap(char *keyname, uint8 scanc
57          keysym = XStringToKeysym(keyname);          keysym = XStringToKeysym(keyname);
58          if (keysym == NoSymbol)          if (keysym == NoSymbol)
59          {          {
60                  error("Bad keysym %s in keymap %s\n", keyname, mapname);                  DEBUG_KBD(("Bad keysym \"%s\" in keymap %s (ignoring)\n", keyname, mapname));
61                  return;                  return;
62          }          }
63    
# Line 69  static BOOL Line 75  static BOOL
75  xkeymap_read(char *mapname)  xkeymap_read(char *mapname)
76  {  {
77          FILE *fp;          FILE *fp;
78          char line[KEYMAP_MAX_LINE_LENGTH], path[PATH_MAX];          char line[KEYMAP_MAX_LINE_LENGTH];
79            char path[PATH_MAX], inplace_path[PATH_MAX];
80          unsigned int line_num = 0;          unsigned int line_num = 0;
81          unsigned int line_length = 0;          unsigned int line_length = 0;
82          char *keyname, *p;          char *keyname, *p;
# Line 84  xkeymap_read(char *mapname) Line 91  xkeymap_read(char *mapname)
91          fp = fopen(path, "r");          fp = fopen(path, "r");
92          if (fp == NULL)          if (fp == NULL)
93          {          {
94                  error("Failed to open keymap %s\n", path);                  /* in case we are running from the source tree */
95                  return False;                  strcpy(inplace_path, "keymaps/");
96                    strncat(inplace_path, mapname, sizeof(inplace_path) - sizeof("keymaps/"));
97    
98                    fp = fopen(inplace_path, "r");
99                    if (fp == NULL)
100                    {
101                            error("Failed to open keymap %s\n", path);
102                            return False;
103                    }
104          }          }
105    
106          /* FIXME: More tolerant on white space */          /* FIXME: More tolerant on white space */
# Line 126  xkeymap_read(char *mapname) Line 141  xkeymap_read(char *mapname)
141                  if (strncmp(line, "enable_compose", 15) == 0)                  if (strncmp(line, "enable_compose", 15) == 0)
142                  {                  {
143                          DEBUG_KBD(("Enabling compose handling\n"));                          DEBUG_KBD(("Enabling compose handling\n"));
144                          enable_compose = True;                          g_enable_compose = True;
145                          continue;                          continue;
146                  }                  }
147    
# Line 189  xkeymap_read(char *mapname) Line 204  xkeymap_read(char *mapname)
204                          /* Automatically add uppercase key, with same modifiers                          /* Automatically add uppercase key, with same modifiers
205                             plus shift */                             plus shift */
206                          for (p = keyname; *p; p++)                          for (p = keyname; *p; p++)
207                                  *p = toupper(*p);                                  *p = toupper((int) *p);
208                          MASK_ADD_BITS(modifiers, MapLeftShiftMask);                          MASK_ADD_BITS(modifiers, MapLeftShiftMask);
209                          add_to_keymap(keyname, scancode, modifiers, mapname);                          add_to_keymap(keyname, scancode, modifiers, mapname);
210                  }                  }
# Line 205  void Line 220  void
220  xkeymap_init(void)  xkeymap_init(void)
221  {  {
222          unsigned int max_keycode;          unsigned int max_keycode;
223            char *mapname_ptr;
224    
225            /* Make keymapname lowercase */
226            mapname_ptr = keymapname;
227            while (*mapname_ptr)
228            {
229                    *mapname_ptr = tolower((int) *mapname_ptr);
230                    mapname_ptr++;
231            }
232    
233          if (strcmp(keymapname, "none"))          if (strcmp(keymapname, "none"))
234          {          {
# Line 222  handle_special_keys(uint32 keysym, unsig Line 246  handle_special_keys(uint32 keysym, unsig
246  {  {
247          switch (keysym)          switch (keysym)
248          {          {
249                  case XK_Break:                  case XK_Return:
250                          if (get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))                          if ((get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))
251                                && (get_key_state(state, XK_Control_L)
252                                    || get_key_state(state, XK_Control_R)))
253                          {                          {
254                                  /* toggle full screen */                                  /* Ctrl-Alt-Enter: toggle full screen */
255                                  if (pressed)                                  if (pressed)
256                                          xwin_toggle_fullscreen();                                          xwin_toggle_fullscreen();
257                                    return True;
258                          }                          }
259                          else                          break;
260    
261                    case XK_Break:
262                            /* Send Break sequence E0 46 E0 C6 */
263                            if (pressed)
264                          {                          {
265                                  /* Send Break sequence E0 46 E0 C6 */                                  rdp_send_scancode(ev_time, RDP_KEYPRESS,
266                                  if (pressed)                                                    (SCANCODE_EXTENDED | 0x46));
267                                  {                                  rdp_send_scancode(ev_time, RDP_KEYPRESS,
268                                          rdp_send_scancode(ev_time, RDP_KEYPRESS,                                                    (SCANCODE_EXTENDED | 0xc6));
                                                           (SCANCODE_EXTENDED | 0x46));  
                                         rdp_send_scancode(ev_time, RDP_KEYPRESS,  
                                                           (SCANCODE_EXTENDED | 0xc6));  
                                 }  
                                 /* No break sequence */  
269                          }                          }
270                            /* No release sequence */
271                          return True;                          return True;
                         break;  
272    
273                  case XK_Pause:                  case XK_Pause:
274                          /* According to MS Keyboard Scan Code                          /* According to MS Keyboard Scan Code
# Line 267  handle_special_keys(uint32 keysym, unsig Line 291  handle_special_keys(uint32 keysym, unsig
291                          else                          else
292                          {                          {
293                                  /* Release Left Ctrl */                                  /* Release Left Ctrl */
294                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d,                                  rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE,
295                                                 0);                                                 0x1d, 0);
296                          }                          }
   
297                          return True;                          return True;
                         break;  
298    
299                  case XK_Meta_L: /* Windows keys */                  case XK_Meta_L: /* Windows keys */
300                  case XK_Super_L:                  case XK_Super_L:
# Line 291  handle_special_keys(uint32 keysym, unsig Line 313  handle_special_keys(uint32 keysym, unsig
313                                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);                                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
314                          }                          }
315                          return True;                          return True;
316                          break;  
317                    case XK_space:
318                            /* Prevent access to the Windows system menu in single app mode */
319                            if (win_button_size
320                                && (get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R)))
321                                    return True;
322    
323          }          }
324          return False;          return False;
325  }  }
# Line 329  xkeymap_translate_key(uint32 keysym, uns Line 357  xkeymap_translate_key(uint32 keysym, uns
357          }          }
358    
359          if (keymap_loaded)          if (keymap_loaded)
360                  error("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym));                  warning("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym));
361    
362          /* not in keymap, try to interpret the raw scancode */          /* not in keymap, try to interpret the raw scancode */
363          if ((keycode >= min_keycode) && (keycode <= 0x60))          if (((int) keycode >= min_keycode) && (keycode <= 0x60))
364          {          {
365                  tr.scancode = keycode - min_keycode;                  tr.scancode = keycode - min_keycode;
366    
# Line 387  get_ksname(uint32 keysym) Line 415  get_ksname(uint32 keysym)
415          return ksname;          return ksname;
416  }  }
417    
418    void
419    save_remote_modifiers()
420    {
421            saved_remote_modifier_state = remote_modifier_state;
422    }
423    
424    void
425    restore_remote_modifiers(uint32 ev_time)
426    {
427            key_translation dummy;
428    
429            dummy.scancode = 0;
430            dummy.modifiers = saved_remote_modifier_state;
431            ensure_remote_modifiers(ev_time, dummy);
432    }
433    
434  void  void
435  ensure_remote_modifiers(uint32 ev_time, key_translation tr)  ensure_remote_modifiers(uint32 ev_time, key_translation tr)
# Line 408  ensure_remote_modifiers(uint32 ev_time, Line 451  ensure_remote_modifiers(uint32 ev_time,
451                          break;                          break;
452          }          }
453    
454            /* NumLock */
455            if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
456                != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
457            {
458                    /* The remote modifier state is not correct */
459                    uint16 new_remote_state;
460    
461                    if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
462                    {
463                            DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
464                            new_remote_state = KBD_FLAG_NUMLOCK;
465                            remote_modifier_state = MapNumLockMask;
466                    }
467                    else
468                    {
469                            DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
470                            new_remote_state = 0;
471                            remote_modifier_state = 0;
472                    }
473    
474                    rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
475            }
476    
477          /* Shift. Left shift and right shift are treated as equal; either is fine. */          /* Shift. Left shift and right shift are treated as equal; either is fine. */
478          if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)          if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
479              != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))              != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
# Line 452  ensure_remote_modifiers(uint32 ev_time, Line 518  ensure_remote_modifiers(uint32 ev_time,
518                  }                  }
519          }          }
520    
         /* NumLock */  
         if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)  
             != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))  
         {  
                 /* The remote modifier state is not correct */  
                 uint16 new_remote_state = 0;  
   
                 if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))  
                 {  
                         DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));  
                         new_remote_state |= KBD_FLAG_NUMLOCK;  
                 }  
                 else  
                 {  
                         DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));  
                 }  
521    
                 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);  
                 update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);  
         }  
522  }  }
523    
524    
# Line 482  reset_modifier_keys(unsigned int state) Line 529  reset_modifier_keys(unsigned int state)
529          uint32 ev_time;          uint32 ev_time;
530          ev_time = time(NULL);          ev_time = time(NULL);
531    
532          if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(state, XK_Shift_L))          if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask)
533                && !get_key_state(state, XK_Shift_L))
534                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
535    
536          if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(state, XK_Shift_R))          if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask)
537                && !get_key_state(state, XK_Shift_R))
538                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
539    
540          if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(state, XK_Control_L))          if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask)
541                && !get_key_state(state, XK_Control_L))
542                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
543    
544          if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(state, XK_Control_R))          if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask)
545                && !get_key_state(state, XK_Control_R))
546                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);                  rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
547    
548          if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(state, XK_Alt_L))          if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(state, XK_Alt_L))

Legend:
Removed from v.207  
changed lines
  Added in v.449

  ViewVC Help
Powered by ViewVC 1.1.26