/[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 38 by matthewc, Thu Apr 4 12:04:33 2002 UTC revision 197 by astrand, Wed Sep 25 11:07:57 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>
24  #include <stdlib.h>  #include <ctype.h>
25  #include <string.h>  #include <limits.h>
26    #include <time.h>
27  #include "rdesktop.h"  #include "rdesktop.h"
28    #include "scancodes.h"
29    
30  #define KEYMAP_SIZE 4096  #define KEYMAP_SIZE 4096
31  #define KEYMAP_MASK (KEYMAP_SIZE - 1)  #define KEYMAP_MASK (KEYMAP_SIZE - 1)
32    #define KEYMAP_MAX_LINE_LENGTH 80
33    
34    extern Display *display;
35  extern char keymapname[16];  extern char keymapname[16];
36  extern int keylayout;  extern int keylayout;
37    extern BOOL enable_compose;
38    
39  static uint8 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;
42    
43  static BOOL xkeymap_read(char *mapname)  static void update_modifier_state(uint16 modifiers, BOOL pressed);
44    
45    static void
46    add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)
47    {
48            KeySym keysym;
49    
50            keysym = XStringToKeysym(keyname);
51            if (keysym == NoSymbol)
52            {
53                    error("Bad keysym %s in keymap %s\n", keyname, mapname);
54                    return;
55            }
56    
57            DEBUG_KBD(("Adding translation, keysym=0x%x, scancode=0x%x, "
58                       "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers));
59    
60            keymap[keysym & KEYMAP_MASK].scancode = scancode;
61            keymap[keysym & KEYMAP_MASK].modifiers = modifiers;
62    
63            return;
64    }
65    
66    
67    static BOOL
68    xkeymap_read(char *mapname)
69  {  {
70          FILE *fp;          FILE *fp;
71          char line[256], path[256];          char line[KEYMAP_MAX_LINE_LENGTH], path[PATH_MAX];
72            unsigned int line_num = 0;
73            unsigned int line_length = 0;
74          char *keyname, *p;          char *keyname, *p;
75          KeySym keysym;          char *line_rest;
76          unsigned char keycode;          uint8 scancode;
77          unsigned int mapcode = 0;          uint16 modifiers;
78    
79    
80          strcpy(path, KEYMAP_PATH);          strcpy(path, KEYMAP_PATH);
81          strncat(path, mapname, sizeof(path) - sizeof(KEYMAP_PATH));          strncat(path, mapname, sizeof(path) - sizeof(KEYMAP_PATH));
# Line 53  static BOOL xkeymap_read(char *mapname) Line 87  static BOOL xkeymap_read(char *mapname)
87                  return False;                  return False;
88          }          }
89    
90            /* FIXME: More tolerant on white space */
91          while (fgets(line, sizeof(line), fp) != NULL)          while (fgets(line, sizeof(line), fp) != NULL)
92          {          {
93                    line_num++;
94    
95                    /* Replace the \n with \0 */
96                  p = strchr(line, '\n');                  p = strchr(line, '\n');
97                  if (p != NULL)                  if (p != NULL)
98                          *p = 0;                          *p = 0;
99    
100                  keycode = strtol(line, &keyname, 16);                  line_length = strlen(line);
101                  if ((keycode != 0) && (*keyname == ' '))  
102                    /* Completely empty line */
103                    if (strspn(line, " \t\n\r\f\v") == line_length)
104                  {                  {
105                          do                          continue;
106                          {                  }
                                 keyname++;  
                                 p = strchr(keyname, ' ');  
                                 if (p != NULL)  
                                         *p = 0;  
107    
108                                  keysym = XStringToKeysym(keyname);                  /* Include */
109                                  if (keysym == NoSymbol)                  if (strncmp(line, "include ", 8) == 0)
110                                          error("Bad keysym %s in keymap %s\n", keyname, mapname);                  {
111                            if (!xkeymap_read(line + 8))
112                                    return False;
113                            continue;
114                    }
115    
116                                  keymap[keysym & KEYMAP_MASK] = keycode;                  /* map */
117                                  keyname = p;                  if (strncmp(line, "map ", 4) == 0)
118                    {
119                            keylayout = strtol(line + 4, NULL, 16);
120                            DEBUG_KBD(("Keylayout 0x%x\n", keylayout));
121                            continue;
122                    }
123    
124                          } while (keyname != NULL);                  /* compose */
125                    if (strncmp(line, "enable_compose", 15) == 0)
126                    {
127                            DEBUG_KBD(("Enabling compose handling\n"));
128                            enable_compose = True;
129                            continue;
130                  }                  }
131                  else if (strncmp(line, "include ", 8) == 0)  
132                    /* Comment */
133                    if (line[0] == '#')
134                  {                  {
135                          if (!xkeymap_read(line+8))                          continue;
                                 return False;  
136                  }                  }
137                  else if (strncmp(line, "map ", 4) == 0)  
138                    /* Normal line */
139                    keyname = line;
140                    p = strchr(line, ' ');
141                    if (p == NULL)
142                  {                  {
143                          keylayout = strtol(line+4, NULL, 16);                          error("Bad line %d in keymap %s\n", line_num, mapname);
144                            continue;
145                  }                  }
146                  else if (line[0] != '#')                  else
147                    {
148                            *p = 0;
149                    }
150    
151                    /* scancode */
152                    p++;
153                    scancode = strtol(p, &line_rest, 16);
154    
155                    /* flags */
156                    /* FIXME: Should allow case-insensitive flag names.
157                       Fix by using lex+yacc... */
158                    modifiers = 0;
159                    if (strstr(line_rest, "altgr"))
160                    {
161                            MASK_ADD_BITS(modifiers, MapAltGrMask);
162                    }
163    
164                    if (strstr(line_rest, "shift"))
165                    {
166                            MASK_ADD_BITS(modifiers, MapLeftShiftMask);
167                    }
168    
169                    if (strstr(line_rest, "numlock"))
170                  {                  {
171                          error("Malformed line in keymap %s\n", mapname);                          MASK_ADD_BITS(modifiers, MapNumLockMask);
172                    }
173    
174                    if (strstr(line_rest, "localstate"))
175                    {
176                            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);
185    
186                    if (strstr(line_rest, "addupper"))
187                    {
188                            /* Automatically add uppercase key, with same modifiers
189                               plus shift */
190                            for (p = keyname; *p; p++)
191                                    *p = toupper(*p);
192                            MASK_ADD_BITS(modifiers, MapLeftShiftMask);
193                            add_to_keymap(keyname, scancode, modifiers, mapname);
194                  }                  }
195          }          }
196    
# Line 97  static BOOL xkeymap_read(char *mapname) Line 198  static BOOL xkeymap_read(char *mapname)
198          return True;          return True;
199  }  }
200    
201  void xkeymap_init(Display *display)  
202    /* Before connecting and creating UI */
203    void
204    xkeymap_init(void)
205  {  {
206          unsigned int max_keycode;          unsigned int max_keycode;
207    
         XDisplayKeycodes(display, &min_keycode, &max_keycode);  
   
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  uint8 xkeymap_translate_key(KeySym keysym, unsigned int keycode)  /* Handles, for example, multi-scancode keypresses (which is not
215       possible via keymap-files) */
216    BOOL
217    handle_special_keys(uint32 keysym, uint32 ev_time, BOOL pressed)
218  {  {
219          uint8 scancode;          switch (keysym)
220            {
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_Pause:
231                            /* According to MS Keyboard Scan Code
232                               Specification, pressing Pause should result
233                               in E1 1D 45 E1 9D C5. I'm not exactly sure
234                               of how this is supposed to be sent via
235                               RDP. The code below seems to work, but with
236                               the side effect that Left Ctrl stays
237                               down. Therefore, we release it when Pause
238                               is released. */
239                            if (pressed)
240                            {
241                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
242                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0);
243                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x45, 0);
244                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
245                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x9d, 0);
246                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xc5, 0);
247                            }
248                            else
249                            {
250                                    // Release Left Ctrl
251                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d,
252                                                   0);
253                            }
254    
255                            return True;
256                            break;
257    
258                    case XK_Meta_L: /* Windows keys */
259                    case XK_Super_L:
260                    case XK_Hyper_L:
261                    case XK_Meta_R:
262                    case XK_Super_R:
263                    case XK_Hyper_R:
264                            if (pressed)
265                            {
266                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
267                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
268                            }
269                            else
270                            {
271                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
272                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
273                            }
274                            return True;
275                            break;
276            }
277            return False;
278    }
279    
         scancode = keymap[keysym & KEYMAP_MASK];  
         if (scancode != 0)  
                 return scancode;  
280    
281          /* not in keymap, try to interpret the raw scancode */  key_translation
282    xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
283    {
284            key_translation tr = { 0, 0 };
285    
286            tr = keymap[keysym & KEYMAP_MASK];
287    
288            if (tr.modifiers & MapInhibitMask)
289            {
290                    DEBUG_KBD(("Inhibiting key\n"));
291                    tr.scancode = 0;
292                    return tr;
293            }
294    
295            if (tr.modifiers & MapLocalStateMask)
296            {
297                    /* The modifiers to send for this key should be obtained
298                       from the local state. Currently, only shift is implemented. */
299                    if (state & ShiftMask)
300                    {
301                            tr.modifiers = MapLeftShiftMask;
302                    }
303            }
304    
305            if (tr.scancode != 0)
306            {
307                    DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
308                               tr.scancode, tr.modifiers));
309                    return tr;
310            }
311    
312            DEBUG_KBD(("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)));
313    
314            /* not in keymap, try to interpret the raw scancode */
315          if ((keycode >= min_keycode) && (keycode <= 0x60))          if ((keycode >= min_keycode) && (keycode <= 0x60))
316                  return (uint8)(keycode - min_keycode);          {
317                    tr.scancode = keycode - min_keycode;
318    
319                    /* The modifiers to send for this key should be
320                       obtained from the local state. Currently, only
321                       shift is implemented. */
322                    if (state & ShiftMask)
323                    {
324                            tr.modifiers = MapLeftShiftMask;
325                    }
326    
327          switch (keycode)                  DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
328            }
329            else
330          {          {
331                  case 0x61:      /* home */                  DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
                         return 0x47 | 0x80;  
                 case 0x62:      /* up arrow */  
                         return 0x48 | 0x80;  
                 case 0x63:      /* page up */  
                         return 0x49 | 0x80;  
                 case 0x64:      /* left arrow */  
                         return 0x4b | 0x80;  
                 case 0x66:      /* right arrow */  
                         return 0x4d | 0x80;  
                 case 0x67:      /* end */  
                         return 0x4f | 0x80;  
                 case 0x68:      /* down arrow */  
                         return 0x50 | 0x80;  
                 case 0x69:      /* page down */  
                         return 0x51 | 0x80;  
                 case 0x6a:      /* insert */  
                         return 0x52 | 0x80;  
                 case 0x6b:      /* delete */  
                         return 0x53 | 0x80;  
                 case 0x6c:      /* keypad enter */  
                         return 0x1c | 0x80;  
                 case 0x6d:      /* right ctrl */  
                         return 0x1d | 0x80;  
                 case 0x6f:      /* ctrl - print screen */  
                         return 0x37 | 0x80;  
                 case 0x70:      /* keypad '/' */  
                         return 0x35 | 0x80;  
                 case 0x71:      /* right alt */  
                         return 0x38 | 0x80;  
                 case 0x72:      /* ctrl break */  
                         return 0x46 | 0x80;  
                 case 0x73:      /* left window key */  
                         return 0x5b | 0x80;  
                 case 0x74:      /* right window key */  
                         return 0x5c | 0x80;  
                 case 0x75:      /* menu key */  
                         return 0x5d | 0x80;  
332          }          }
333    
334          return 0;          return tr;
335  }  }
336    
337  uint16 xkeymap_translate_button(unsigned int button)  uint16
338    xkeymap_translate_button(unsigned int button)
339  {  {
340          switch (button)          switch (button)
341          {          {
342                  case Button1:   /* left */                  case Button1:   /* left */
343                          return MOUSE_FLAG_BUTTON1;                          return MOUSE_FLAG_BUTTON1;
344                  case Button2:   /* middle */                  case Button2:   /* middle */
345                          return MOUSE_FLAG_BUTTON3;                          return MOUSE_FLAG_BUTTON3;
346                  case Button3:   /* right */                  case Button3:   /* right */
347                          return MOUSE_FLAG_BUTTON2;                          return MOUSE_FLAG_BUTTON2;
348                    case Button4:   /* wheel up */
349                            return MOUSE_FLAG_BUTTON4;
350                    case Button5:   /* wheel down */
351                            return MOUSE_FLAG_BUTTON5;
352          }          }
353    
354          return 0;          return 0;
355  }  }
356    
357    char *
358    get_ksname(uint32 keysym)
359    {
360            char *ksname = NULL;
361    
362            if (keysym == NoSymbol)
363                    ksname = "NoSymbol";
364            else if (!(ksname = XKeysymToString(keysym)))
365                    ksname = "(no name)";
366    
367            return ksname;
368    }
369    
370    
371    void
372    ensure_remote_modifiers(uint32 ev_time, key_translation tr)
373    {
374            /* If this key is a modifier, do nothing */
375            switch (tr.scancode)
376            {
377                    case SCANCODE_CHAR_LSHIFT:
378                    case SCANCODE_CHAR_RSHIFT:
379                    case SCANCODE_CHAR_LCTRL:
380                    case SCANCODE_CHAR_RCTRL:
381                    case SCANCODE_CHAR_LALT:
382                    case SCANCODE_CHAR_RALT:
383                    case SCANCODE_CHAR_LWIN:
384                    case SCANCODE_CHAR_RWIN:
385                    case SCANCODE_CHAR_NUMLOCK:
386                            return;
387                    default:
388                            break;
389            }
390    
391            /* Shift. Left shift and right shift are treated as equal; either is fine. */
392            if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
393                != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
394            {
395                    /* The remote modifier state is not correct */
396                    if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
397                    {
398                            /* Needs left shift. Send down. */
399                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
400                    }
401                    else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
402                    {
403                            /* Needs right shift. Send down. */
404                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
405                    }
406                    else
407                    {
408                            /* Should not use this modifier. Send up for shift currently pressed. */
409                            if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
410                                    /* Left shift is down */
411                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
412                            else
413                                    /* Right shift is down */
414                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
415                    }
416            }
417    
418            /* AltGr */
419            if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)
420                != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask))
421            {
422                    /* The remote modifier state is not correct */
423                    if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
424                    {
425                            /* Needs this modifier. Send down. */
426                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
427                    }
428                    else
429                    {
430                            /* Should not use this modifier. Send up. */
431                            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
432                    }
433            }
434    
435            /* NumLock */
436            if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
437                != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
438            {
439                    /* The remote modifier state is not correct */
440                    uint16 new_remote_state = 0;
441    
442                    if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
443                    {
444                            DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
445                            new_remote_state |= KBD_FLAG_NUMLOCK;
446                    }
447                    else
448                    {
449                            DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
450                    }
451    
452                    rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
453                    update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);
454            }
455    }
456    
457    
458    void
459    reset_modifier_keys(void)
460    {
461            /* reset keys */
462            uint32 ev_time;
463            ev_time = time(NULL);
464    
465            if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(XK_Shift_L))
466                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
467    
468            if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(XK_Shift_R))
469                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
470    
471            if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(XK_Control_L))
472                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
473    
474            if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(XK_Control_R))
475                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
476    
477            if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(XK_Alt_L))
478                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
479    
480            if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
481                !get_key_state(XK_Alt_R) && !get_key_state(XK_Mode_switch))
482                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
483    }
484    
485    
486    static void
487    update_modifier_state(uint16 modifiers, BOOL pressed)
488    {
489    #ifdef WITH_DEBUG_KBD
490            uint16 old_modifier_state;
491    
492            old_modifier_state = remote_modifier_state;
493    #endif
494    
495            switch (modifiers)
496            {
497                    case SCANCODE_CHAR_LSHIFT:
498                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
499                            break;
500                    case SCANCODE_CHAR_RSHIFT:
501                            MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
502                            break;
503                    case SCANCODE_CHAR_LCTRL:
504                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
505                            break;
506                    case SCANCODE_CHAR_RCTRL:
507                            MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
508                            break;
509                    case SCANCODE_CHAR_LALT:
510                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
511                            break;
512                    case SCANCODE_CHAR_RALT:
513                            MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
514                            break;
515                    case SCANCODE_CHAR_LWIN:
516                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
517                            break;
518                    case SCANCODE_CHAR_RWIN:
519                            MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
520                            break;
521                    case SCANCODE_CHAR_NUMLOCK:
522                            /* KeyReleases for NumLocks are sent immediately. Toggle the
523                               modifier state only on Keypress */
524                            if (pressed)
525                            {
526                                    BOOL newNumLockState;
527                                    newNumLockState =
528                                            (MASK_HAS_BITS
529                                             (remote_modifier_state, MapNumLockMask) == False);
530                                    MASK_CHANGE_BIT(remote_modifier_state,
531                                                    MapNumLockMask, newNumLockState);
532                            }
533                            break;
534            }
535    
536    #ifdef WITH_DEBUG_KBD
537            if (old_modifier_state != remote_modifier_state)
538            {
539                    DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n",
540                               old_modifier_state, pressed));
541                    DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state));
542            }
543    #endif
544    
545    }
546    
547    /* Send keyboard input */
548    void
549    rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode)
550    {
551            update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));
552    
553            if (scancode & SCANCODE_EXTENDED)
554            {
555                    DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n",
556                               scancode & ~SCANCODE_EXTENDED, flags));
557                    rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
558                                   scancode & ~SCANCODE_EXTENDED, 0);
559            }
560            else
561            {
562                    DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags));
563                    rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
564            }
565    }

Legend:
Removed from v.38  
changed lines
  Added in v.197

  ViewVC Help
Powered by ViewVC 1.1.26