/[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 50 by matthewc, Sat Apr 20 09:41:03 2002 UTC revision 199 by astrand, Wed Sep 25 11:17:59 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>
 #include <string.h>  
25  #include <limits.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;  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[PATH_MAX], path[PATH_MAX];          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            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 54  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;
136                                  return False;                  }
137    
138                    /* Normal line */
139                    keyname = line;
140                    p = strchr(line, ' ');
141                    if (p == NULL)
142                    {
143                            error("Bad line %d in keymap %s\n", line_num, mapname);
144                            continue;
145                    }
146                    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                            MASK_ADD_BITS(modifiers, MapNumLockMask);
172                  }                  }
173                  else if (strncmp(line, "map ", 4) == 0)  
174                    if (strstr(line_rest, "localstate"))
175                  {                  {
176                          keylayout = strtol(line+4, NULL, 16);                          MASK_ADD_BITS(modifiers, MapLocalStateMask);
177                  }                  }
178                  else if (line[0] != '#')  
179                    if (strstr(line_rest, "inhibit"))
180                  {                  {
181                          error("Malformed line in keymap %s\n", mapname);                          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 98  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(void)  
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(unsigned int keysym, unsigned int keycode, uint16 *flags)  /* 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:
222                            if (get_key_state(XK_Alt_L) || get_key_state(XK_Alt_R))
223                            {
224                                    /* toggle full screen */
225                                    if (pressed)
226                                            xwin_toggle_fullscreen();
227    
228          scancode = keymap[keysym & KEYMAP_MASK];                          }
229          if (scancode != 0)                          else
230                            {
231                                    /* Send Break sequence E0 46 E0 C6 */
232                                    if (pressed)
233                                    {
234                                            rdp_send_scancode(ev_time, RDP_KEYPRESS,
235                                                              (SCANCODE_EXTENDED | 0x46));
236                                            rdp_send_scancode(ev_time, RDP_KEYPRESS,
237                                                              (SCANCODE_EXTENDED | 0xc6));
238                                    }
239                                    /* No break sequence */
240                            }
241    
242                            return True;
243                            break;
244    
245                    case XK_Pause:
246                            /* According to MS Keyboard Scan Code
247                               Specification, pressing Pause should result
248                               in E1 1D 45 E1 9D C5. I'm not exactly sure
249                               of how this is supposed to be sent via
250                               RDP. The code below seems to work, but with
251                               the side effect that Left Ctrl stays
252                               down. Therefore, we release it when Pause
253                               is released. */
254                            if (pressed)
255                            {
256                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
257                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0);
258                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x45, 0);
259                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
260                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x9d, 0);
261                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xc5, 0);
262                            }
263                            else
264                            {
265                                    // Release Left Ctrl
266                                    rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d,
267                                                   0);
268                            }
269    
270                            return True;
271                            break;
272    
273                    case XK_Meta_L: /* Windows keys */
274                    case XK_Super_L:
275                    case XK_Hyper_L:
276                    case XK_Meta_R:
277                    case XK_Super_R:
278                    case XK_Hyper_R:
279                            if (pressed)
280                            {
281                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
282                                    rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
283                            }
284                            else
285                            {
286                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
287                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
288                            }
289                            return True;
290                            break;
291            }
292            return False;
293    }
294    
295    
296    key_translation
297    xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
298    {
299            key_translation tr = { 0, 0 };
300    
301            tr = keymap[keysym & KEYMAP_MASK];
302    
303            if (tr.modifiers & MapInhibitMask)
304          {          {
305                  if (scancode & 0x80)                  DEBUG_KBD(("Inhibiting key\n"));
306                          *flags |= KBD_FLAG_EXT;                  tr.scancode = 0;
307                    return tr;
308            }
309    
310                  return (scancode & 0x7f);          if (tr.modifiers & MapLocalStateMask)
311            {
312                    /* The modifiers to send for this key should be obtained
313                       from the local state. Currently, only shift is implemented. */
314                    if (state & ShiftMask)
315                    {
316                            tr.modifiers = MapLeftShiftMask;
317                    }
318          }          }
319    
320          /* not in keymap, try to interpret the raw scancode */          if (tr.scancode != 0)
321            {
322                    DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
323                               tr.scancode, tr.modifiers));
324                    return tr;
325            }
326    
327            DEBUG_KBD(("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)));
328    
329            /* not in keymap, try to interpret the raw scancode */
330          if ((keycode >= min_keycode) && (keycode <= 0x60))          if ((keycode >= min_keycode) && (keycode <= 0x60))
331                  return (uint8)(keycode - min_keycode);          {
332                    tr.scancode = keycode - min_keycode;
333    
334          *flags |= KBD_FLAG_EXT;                  /* The modifiers to send for this key should be
335                       obtained from the local state. Currently, only
336                       shift is implemented. */
337                    if (state & ShiftMask)
338                    {
339                            tr.modifiers = MapLeftShiftMask;
340                    }
341    
342          switch (keycode)                  DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
343            }
344            else
345          {          {
346                  case 0x61:      /* home */                  DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
                         return 0x47;  
                 case 0x62:      /* up arrow */  
                         return 0x48;  
                 case 0x63:      /* page up */  
                         return 0x49;  
                 case 0x64:      /* left arrow */  
                         return 0x4b;  
                 case 0x66:      /* right arrow */  
                         return 0x4d;  
                 case 0x67:      /* end */  
                         return 0x4f;  
                 case 0x68:      /* down arrow */  
                         return 0x50;  
                 case 0x69:      /* page down */  
                         return 0x51;  
                 case 0x6a:      /* insert */  
                         return 0x52;  
                 case 0x6b:      /* delete */  
                         return 0x53;  
                 case 0x6c:      /* keypad enter */  
                         return 0x1c;  
                 case 0x6d:      /* right ctrl */  
                         return 0x1d;  
                 case 0x6f:      /* ctrl - print screen */  
                         return 0x37;  
                 case 0x70:      /* keypad '/' */  
                         return 0x35;  
                 case 0x71:      /* right alt */  
                         return 0x38;  
                 case 0x72:      /* ctrl break */  
                         return 0x46;  
                 case 0x73:      /* left window key */  
                         return 0x5b;  
                 case 0x74:      /* right window key */  
                         return 0x5c;  
                 case 0x75:      /* menu key */  
                         return 0x5d;  
347          }          }
348    
349          return 0;          return tr;
350  }  }
351    
352  uint16 xkeymap_translate_button(unsigned int button)  uint16
353    xkeymap_translate_button(unsigned int button)
354  {  {
355          switch (button)          switch (button)
356          {          {
357                  case Button1:   /* left */                  case Button1:   /* left */
358                          return MOUSE_FLAG_BUTTON1;                          return MOUSE_FLAG_BUTTON1;
359                  case Button2:   /* middle */                  case Button2:   /* middle */
360                          return MOUSE_FLAG_BUTTON3;                          return MOUSE_FLAG_BUTTON3;
361                  case Button3:   /* right */                  case Button3:   /* right */
362                          return MOUSE_FLAG_BUTTON2;                          return MOUSE_FLAG_BUTTON2;
363                    case Button4:   /* wheel up */
364                            return MOUSE_FLAG_BUTTON4;
365                    case Button5:   /* wheel down */
366                            return MOUSE_FLAG_BUTTON5;
367          }          }
368    
369          return 0;          return 0;
370  }  }
371    
372    char *
373    get_ksname(uint32 keysym)
374    {
375            char *ksname = NULL;
376    
377            if (keysym == NoSymbol)
378                    ksname = "NoSymbol";
379            else if (!(ksname = XKeysymToString(keysym)))
380                    ksname = "(no name)";
381    
382            return ksname;
383    }
384    
385    
386    void
387    ensure_remote_modifiers(uint32 ev_time, key_translation tr)
388    {
389            /* If this key is a modifier, do nothing */
390            switch (tr.scancode)
391            {
392                    case SCANCODE_CHAR_LSHIFT:
393                    case SCANCODE_CHAR_RSHIFT:
394                    case SCANCODE_CHAR_LCTRL:
395                    case SCANCODE_CHAR_RCTRL:
396                    case SCANCODE_CHAR_LALT:
397                    case SCANCODE_CHAR_RALT:
398                    case SCANCODE_CHAR_LWIN:
399                    case SCANCODE_CHAR_RWIN:
400                    case SCANCODE_CHAR_NUMLOCK:
401                            return;
402                    default:
403                            break;
404            }
405    
406            /* Shift. Left shift and right shift are treated as equal; either is fine. */
407            if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
408                != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
409            {
410                    /* The remote modifier state is not correct */
411                    if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
412                    {
413                            /* Needs left shift. Send down. */
414                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
415                    }
416                    else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
417                    {
418                            /* Needs right shift. Send down. */
419                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
420                    }
421                    else
422                    {
423                            /* Should not use this modifier. Send up for shift currently pressed. */
424                            if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
425                                    /* Left shift is down */
426                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
427                            else
428                                    /* Right shift is down */
429                                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
430                    }
431            }
432    
433            /* AltGr */
434            if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)
435                != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask))
436            {
437                    /* The remote modifier state is not correct */
438                    if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
439                    {
440                            /* Needs this modifier. Send down. */
441                            rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
442                    }
443                    else
444                    {
445                            /* Should not use this modifier. Send up. */
446                            rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
447                    }
448            }
449    
450            /* NumLock */
451            if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
452                != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
453            {
454                    /* The remote modifier state is not correct */
455                    uint16 new_remote_state = 0;
456    
457                    if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
458                    {
459                            DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
460                            new_remote_state |= KBD_FLAG_NUMLOCK;
461                    }
462                    else
463                    {
464                            DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
465                    }
466    
467                    rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
468                    update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);
469            }
470    }
471    
472    
473    void
474    reset_modifier_keys(void)
475    {
476            /* reset keys */
477            uint32 ev_time;
478            ev_time = time(NULL);
479    
480            if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(XK_Shift_L))
481                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
482    
483            if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(XK_Shift_R))
484                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
485    
486            if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(XK_Control_L))
487                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
488    
489            if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(XK_Control_R))
490                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
491    
492            if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(XK_Alt_L))
493                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
494    
495            if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
496                !get_key_state(XK_Alt_R) && !get_key_state(XK_Mode_switch))
497                    rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
498    }
499    
500    
501    static void
502    update_modifier_state(uint16 modifiers, BOOL pressed)
503    {
504    #ifdef WITH_DEBUG_KBD
505            uint16 old_modifier_state;
506    
507            old_modifier_state = remote_modifier_state;
508    #endif
509    
510            switch (modifiers)
511            {
512                    case SCANCODE_CHAR_LSHIFT:
513                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
514                            break;
515                    case SCANCODE_CHAR_RSHIFT:
516                            MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
517                            break;
518                    case SCANCODE_CHAR_LCTRL:
519                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
520                            break;
521                    case SCANCODE_CHAR_RCTRL:
522                            MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
523                            break;
524                    case SCANCODE_CHAR_LALT:
525                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
526                            break;
527                    case SCANCODE_CHAR_RALT:
528                            MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
529                            break;
530                    case SCANCODE_CHAR_LWIN:
531                            MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
532                            break;
533                    case SCANCODE_CHAR_RWIN:
534                            MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
535                            break;
536                    case SCANCODE_CHAR_NUMLOCK:
537                            /* KeyReleases for NumLocks are sent immediately. Toggle the
538                               modifier state only on Keypress */
539                            if (pressed)
540                            {
541                                    BOOL newNumLockState;
542                                    newNumLockState =
543                                            (MASK_HAS_BITS
544                                             (remote_modifier_state, MapNumLockMask) == False);
545                                    MASK_CHANGE_BIT(remote_modifier_state,
546                                                    MapNumLockMask, newNumLockState);
547                            }
548                            break;
549            }
550    
551    #ifdef WITH_DEBUG_KBD
552            if (old_modifier_state != remote_modifier_state)
553            {
554                    DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n",
555                               old_modifier_state, pressed));
556                    DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state));
557            }
558    #endif
559    
560    }
561    
562    /* Send keyboard input */
563    void
564    rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode)
565    {
566            update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));
567    
568            if (scancode & SCANCODE_EXTENDED)
569            {
570                    DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n",
571                               scancode & ~SCANCODE_EXTENDED, flags));
572                    rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
573                                   scancode & ~SCANCODE_EXTENDED, 0);
574            }
575            else
576            {
577                    DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags));
578                    rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
579            }
580    }

Legend:
Removed from v.50  
changed lines
  Added in v.199

  ViewVC Help
Powered by ViewVC 1.1.26