/[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

Annotation of /sourceforge.net/trunk/rdesktop/xkeymap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 226 - (hide annotations)
Fri Oct 11 09:37:48 2002 UTC (21 years, 7 months ago) by astrand
File MIME type: text/plain
File size: 15198 byte(s)
Indent fixes.

1 matthewc 38 /*
2     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X keyboard mapping
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 matthewc 38
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include <X11/Xlib.h>
22 matthewc 190 #define XK_MISCELLANY
23     #include <X11/keysymdef.h>
24 astrand 66 #include <ctype.h>
25 matthewc 39 #include <limits.h>
26 matthewc 190 #include <time.h>
27 matthewc 38 #include "rdesktop.h"
28 astrand 66 #include "scancodes.h"
29 matthewc 38
30     #define KEYMAP_SIZE 4096
31     #define KEYMAP_MASK (KEYMAP_SIZE - 1)
32 astrand 66 #define KEYMAP_MAX_LINE_LENGTH 80
33 matthewc 38
34 matthewc 50 extern Display *display;
35 matthewc 38 extern char keymapname[16];
36     extern int keylayout;
37 astrand 70 extern BOOL enable_compose;
38 matthewc 38
39 matthewc 205 static BOOL keymap_loaded;
40 astrand 66 static key_translation keymap[KEYMAP_SIZE];
41 astrand 73 static int min_keycode;
42 astrand 66 static uint16 remote_modifier_state = 0;
43 matthewc 38
44 matthewc 203 static void update_modifier_state(uint8 scancode, BOOL pressed);
45 astrand 115
46 astrand 66 static void
47     add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)
48     {
49     KeySym keysym;
50    
51     keysym = XStringToKeysym(keyname);
52     if (keysym == NoSymbol)
53     {
54     error("Bad keysym %s in keymap %s\n", keyname, mapname);
55     return;
56     }
57    
58 astrand 84 DEBUG_KBD(("Adding translation, keysym=0x%x, scancode=0x%x, "
59     "modifiers=0x%x\n", (unsigned int) keysym, scancode, modifiers));
60 astrand 66
61     keymap[keysym & KEYMAP_MASK].scancode = scancode;
62     keymap[keysym & KEYMAP_MASK].modifiers = modifiers;
63    
64     return;
65     }
66    
67    
68 astrand 64 static BOOL
69     xkeymap_read(char *mapname)
70 matthewc 38 {
71     FILE *fp;
72 matthewc 216 char line[KEYMAP_MAX_LINE_LENGTH];
73     char path[PATH_MAX], inplace_path[PATH_MAX];
74 astrand 66 unsigned int line_num = 0;
75     unsigned int line_length = 0;
76 matthewc 38 char *keyname, *p;
77 astrand 66 char *line_rest;
78     uint8 scancode;
79     uint16 modifiers;
80 matthewc 38
81 astrand 66
82 matthewc 38 strcpy(path, KEYMAP_PATH);
83     strncat(path, mapname, sizeof(path) - sizeof(KEYMAP_PATH));
84    
85     fp = fopen(path, "r");
86     if (fp == NULL)
87     {
88 matthewc 216 /* in case we are running from the source tree */
89     strcpy(inplace_path, "keymaps/");
90     strncat(inplace_path, mapname, sizeof(inplace_path) - sizeof("keymaps/"));
91    
92     fp = fopen(inplace_path, "r");
93     if (fp == NULL)
94     {
95     error("Failed to open keymap %s\n", path);
96     return False;
97     }
98 matthewc 38 }
99    
100 astrand 66 /* FIXME: More tolerant on white space */
101 matthewc 38 while (fgets(line, sizeof(line), fp) != NULL)
102     {
103 astrand 66 line_num++;
104    
105     /* Replace the \n with \0 */
106 matthewc 38 p = strchr(line, '\n');
107     if (p != NULL)
108     *p = 0;
109    
110 astrand 66 line_length = strlen(line);
111    
112     /* Completely empty line */
113     if (strspn(line, " \t\n\r\f\v") == line_length)
114 matthewc 38 {
115 astrand 66 continue;
116     }
117 matthewc 38
118 astrand 66 /* Include */
119     if (strncmp(line, "include ", 8) == 0)
120 matthewc 38 {
121 astrand 64 if (!xkeymap_read(line + 8))
122 matthewc 38 return False;
123 astrand 66 continue;
124 matthewc 38 }
125 astrand 66
126     /* map */
127     if (strncmp(line, "map ", 4) == 0)
128 matthewc 38 {
129 astrand 64 keylayout = strtol(line + 4, NULL, 16);
130 astrand 84 DEBUG_KBD(("Keylayout 0x%x\n", keylayout));
131 astrand 66 continue;
132 matthewc 38 }
133 astrand 66
134 astrand 70 /* compose */
135     if (strncmp(line, "enable_compose", 15) == 0)
136     {
137 astrand 84 DEBUG_KBD(("Enabling compose handling\n"));
138 astrand 70 enable_compose = True;
139     continue;
140     }
141    
142 astrand 66 /* Comment */
143     if (line[0] == '#')
144 matthewc 38 {
145 astrand 66 continue;
146 matthewc 38 }
147 astrand 66
148     /* Normal line */
149     keyname = line;
150     p = strchr(line, ' ');
151     if (p == NULL)
152     {
153 astrand 82 error("Bad line %d in keymap %s\n", line_num, mapname);
154 astrand 66 continue;
155     }
156     else
157     {
158     *p = 0;
159     }
160    
161     /* scancode */
162     p++;
163     scancode = strtol(p, &line_rest, 16);
164    
165     /* flags */
166     /* FIXME: Should allow case-insensitive flag names.
167     Fix by using lex+yacc... */
168     modifiers = 0;
169     if (strstr(line_rest, "altgr"))
170     {
171     MASK_ADD_BITS(modifiers, MapAltGrMask);
172     }
173    
174     if (strstr(line_rest, "shift"))
175     {
176     MASK_ADD_BITS(modifiers, MapLeftShiftMask);
177     }
178    
179     if (strstr(line_rest, "numlock"))
180     {
181     MASK_ADD_BITS(modifiers, MapNumLockMask);
182     }
183    
184 astrand 69 if (strstr(line_rest, "localstate"))
185     {
186     MASK_ADD_BITS(modifiers, MapLocalStateMask);
187     }
188    
189 astrand 116 if (strstr(line_rest, "inhibit"))
190     {
191     MASK_ADD_BITS(modifiers, MapInhibitMask);
192     }
193    
194 astrand 66 add_to_keymap(keyname, scancode, modifiers, mapname);
195    
196     if (strstr(line_rest, "addupper"))
197     {
198     /* Automatically add uppercase key, with same modifiers
199     plus shift */
200     for (p = keyname; *p; p++)
201     *p = toupper(*p);
202     MASK_ADD_BITS(modifiers, MapLeftShiftMask);
203     add_to_keymap(keyname, scancode, modifiers, mapname);
204     }
205 matthewc 38 }
206    
207     fclose(fp);
208     return True;
209     }
210    
211 astrand 66
212     /* Before connecting and creating UI */
213 astrand 64 void
214 matthewc 121 xkeymap_init(void)
215 matthewc 38 {
216 matthewc 121 unsigned int max_keycode;
217 astrand 225 char *mapname_ptr;
218 matthewc 38
219 astrand 225 /* Make keymapname lowercase */
220     mapname_ptr = keymapname;
221 astrand 226 while (*mapname_ptr)
222     *mapname_ptr++ = tolower(*mapname_ptr);
223 astrand 225
224 matthewc 38 if (strcmp(keymapname, "none"))
225 matthewc 205 {
226     if (xkeymap_read(keymapname))
227     keymap_loaded = True;
228     }
229 astrand 66
230 astrand 77 XDisplayKeycodes(display, &min_keycode, (int *) &max_keycode);
231 astrand 66 }
232 matthewc 38
233 astrand 118 /* Handles, for example, multi-scancode keypresses (which is not
234     possible via keymap-files) */
235     BOOL
236 matthewc 203 handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed)
237 astrand 118 {
238     switch (keysym)
239     {
240 astrand 199 case XK_Break:
241 matthewc 212 case XK_Pause:
242     if ((get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))
243 astrand 226 && (get_key_state(state, XK_Control_L)
244     || get_key_state(state, XK_Control_R)))
245 astrand 118 {
246 matthewc 212 /* Ctrl-Alt-Break: toggle full screen */
247 matthewc 193 if (pressed)
248     xwin_toggle_fullscreen();
249 astrand 199
250 astrand 118 }
251 matthewc 212 else if (keysym == XK_Break)
252 astrand 199 {
253     /* Send Break sequence E0 46 E0 C6 */
254     if (pressed)
255     {
256     rdp_send_scancode(ev_time, RDP_KEYPRESS,
257     (SCANCODE_EXTENDED | 0x46));
258     rdp_send_scancode(ev_time, RDP_KEYPRESS,
259     (SCANCODE_EXTENDED | 0xc6));
260     }
261     /* No break sequence */
262     }
263 astrand 226 else /* XK_Pause */
264 astrand 197 {
265 matthewc 212 /* According to MS Keyboard Scan Code
266     Specification, pressing Pause should result
267     in E1 1D 45 E1 9D C5. I'm not exactly sure
268     of how this is supposed to be sent via
269     RDP. The code below seems to work, but with
270     the side effect that Left Ctrl stays
271     down. Therefore, we release it when Pause
272     is released. */
273     if (pressed)
274     {
275 astrand 226 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
276     0xe1, 0);
277     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
278     0x1d, 0);
279     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
280     0x45, 0);
281     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
282     0xe1, 0);
283     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
284     0x9d, 0);
285     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
286     0xc5, 0);
287 matthewc 212 }
288     else
289     {
290     /* Release Left Ctrl */
291 astrand 226 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE,
292     0x1d, 0);
293 matthewc 212 }
294 astrand 197 }
295     return True;
296    
297 astrand 118 case XK_Meta_L: /* Windows keys */
298     case XK_Super_L:
299     case XK_Hyper_L:
300     case XK_Meta_R:
301     case XK_Super_R:
302     case XK_Hyper_R:
303     if (pressed)
304     {
305     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
306     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
307     }
308     else
309     {
310     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
311     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
312     }
313     return True;
314     }
315     return False;
316     }
317    
318    
319 astrand 66 key_translation
320 matthewc 190 xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
321 astrand 66 {
322     key_translation tr = { 0, 0 };
323    
324     tr = keymap[keysym & KEYMAP_MASK];
325    
326 astrand 116 if (tr.modifiers & MapInhibitMask)
327     {
328     DEBUG_KBD(("Inhibiting key\n"));
329     tr.scancode = 0;
330     return tr;
331     }
332    
333 astrand 69 if (tr.modifiers & MapLocalStateMask)
334     {
335     /* The modifiers to send for this key should be obtained
336     from the local state. Currently, only shift is implemented. */
337     if (state & ShiftMask)
338     {
339     tr.modifiers = MapLeftShiftMask;
340     }
341     }
342    
343 astrand 66 if (tr.scancode != 0)
344 matthewc 50 {
345 matthewc 190 DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
346 astrand 197 tr.scancode, tr.modifiers));
347 astrand 66 return tr;
348 matthewc 50 }
349    
350 matthewc 205 if (keymap_loaded)
351     error("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym));
352 astrand 66
353 matthewc 38 /* not in keymap, try to interpret the raw scancode */
354     if ((keycode >= min_keycode) && (keycode <= 0x60))
355     {
356 astrand 66 tr.scancode = keycode - min_keycode;
357 astrand 165
358     /* The modifiers to send for this key should be
359     obtained from the local state. Currently, only
360     shift is implemented. */
361     if (state & ShiftMask)
362     {
363     tr.modifiers = MapLeftShiftMask;
364     }
365    
366 matthewc 190 DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
367 matthewc 38 }
368 astrand 66 else
369     {
370 matthewc 190 DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
371 astrand 66 }
372 matthewc 38
373 astrand 66 return tr;
374 matthewc 38 }
375    
376 astrand 64 uint16
377     xkeymap_translate_button(unsigned int button)
378 matthewc 38 {
379     switch (button)
380     {
381 astrand 64 case Button1: /* left */
382 matthewc 38 return MOUSE_FLAG_BUTTON1;
383 astrand 64 case Button2: /* middle */
384 matthewc 38 return MOUSE_FLAG_BUTTON3;
385 astrand 64 case Button3: /* right */
386 matthewc 38 return MOUSE_FLAG_BUTTON2;
387 jsorg71 67 case Button4: /* wheel up */
388     return MOUSE_FLAG_BUTTON4;
389     case Button5: /* wheel down */
390     return MOUSE_FLAG_BUTTON5;
391 matthewc 38 }
392    
393     return 0;
394     }
395 astrand 66
396     char *
397 matthewc 190 get_ksname(uint32 keysym)
398 astrand 66 {
399     char *ksname = NULL;
400    
401     if (keysym == NoSymbol)
402     ksname = "NoSymbol";
403     else if (!(ksname = XKeysymToString(keysym)))
404     ksname = "(no name)";
405    
406     return ksname;
407     }
408    
409    
410     void
411     ensure_remote_modifiers(uint32 ev_time, key_translation tr)
412     {
413     /* If this key is a modifier, do nothing */
414     switch (tr.scancode)
415     {
416     case SCANCODE_CHAR_LSHIFT:
417     case SCANCODE_CHAR_RSHIFT:
418     case SCANCODE_CHAR_LCTRL:
419     case SCANCODE_CHAR_RCTRL:
420     case SCANCODE_CHAR_LALT:
421     case SCANCODE_CHAR_RALT:
422     case SCANCODE_CHAR_LWIN:
423     case SCANCODE_CHAR_RWIN:
424     case SCANCODE_CHAR_NUMLOCK:
425     return;
426     default:
427     break;
428     }
429    
430 astrand 183 /* Shift. Left shift and right shift are treated as equal; either is fine. */
431 astrand 66 if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
432     != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
433     {
434     /* The remote modifier state is not correct */
435 astrand 183 if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
436 astrand 66 {
437 astrand 183 /* Needs left shift. Send down. */
438 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
439 astrand 66 }
440 astrand 183 else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
441     {
442     /* Needs right shift. Send down. */
443     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
444     }
445 astrand 66 else
446     {
447 astrand 183 /* Should not use this modifier. Send up for shift currently pressed. */
448     if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
449     /* Left shift is down */
450     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
451     else
452     /* Right shift is down */
453     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
454 astrand 66 }
455     }
456    
457     /* AltGr */
458     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)
459     != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask))
460     {
461     /* The remote modifier state is not correct */
462     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
463     {
464     /* Needs this modifier. Send down. */
465 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
466 astrand 66 }
467     else
468     {
469     /* Should not use this modifier. Send up. */
470 astrand 82 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
471 astrand 66 }
472     }
473    
474     /* NumLock */
475     if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
476     != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
477     {
478     /* The remote modifier state is not correct */
479 astrand 115 uint16 new_remote_state = 0;
480    
481 astrand 66 if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
482     {
483 astrand 115 DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
484     new_remote_state |= KBD_FLAG_NUMLOCK;
485 astrand 66 }
486     else
487     {
488 astrand 115 DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
489 astrand 66 }
490 astrand 115
491     rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
492     update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);
493 astrand 66 }
494     }
495    
496    
497 astrand 170 void
498 matthewc 203 reset_modifier_keys(unsigned int state)
499 astrand 170 {
500     /* reset keys */
501     uint32 ev_time;
502     ev_time = time(NULL);
503    
504 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask)
505     && !get_key_state(state, XK_Shift_L))
506 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
507    
508 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask)
509     && !get_key_state(state, XK_Shift_R))
510 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
511    
512 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask)
513     && !get_key_state(state, XK_Control_L))
514 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
515    
516 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask)
517     && !get_key_state(state, XK_Control_R))
518 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
519    
520 matthewc 203 if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(state, XK_Alt_L))
521 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
522    
523     if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
524 matthewc 203 !get_key_state(state, XK_Alt_R) && !get_key_state(state, XK_Mode_switch))
525 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
526     }
527    
528    
529 astrand 66 static void
530 matthewc 203 update_modifier_state(uint8 scancode, BOOL pressed)
531 astrand 66 {
532 astrand 113 #ifdef WITH_DEBUG_KBD
533     uint16 old_modifier_state;
534 astrand 66
535 astrand 113 old_modifier_state = remote_modifier_state;
536     #endif
537    
538 matthewc 203 switch (scancode)
539 astrand 66 {
540     case SCANCODE_CHAR_LSHIFT:
541 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
542 astrand 66 break;
543     case SCANCODE_CHAR_RSHIFT:
544 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
545 astrand 66 break;
546     case SCANCODE_CHAR_LCTRL:
547 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
548 astrand 66 break;
549     case SCANCODE_CHAR_RCTRL:
550 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
551 astrand 66 break;
552     case SCANCODE_CHAR_LALT:
553 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
554 astrand 66 break;
555     case SCANCODE_CHAR_RALT:
556 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
557 astrand 66 break;
558     case SCANCODE_CHAR_LWIN:
559 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
560 astrand 66 break;
561     case SCANCODE_CHAR_RWIN:
562 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
563 astrand 66 break;
564     case SCANCODE_CHAR_NUMLOCK:
565     /* KeyReleases for NumLocks are sent immediately. Toggle the
566     modifier state only on Keypress */
567     if (pressed)
568     {
569     BOOL newNumLockState;
570     newNumLockState =
571     (MASK_HAS_BITS
572 astrand 82 (remote_modifier_state, MapNumLockMask) == False);
573 astrand 66 MASK_CHANGE_BIT(remote_modifier_state,
574 astrand 82 MapNumLockMask, newNumLockState);
575 astrand 66 }
576     break;
577     }
578    
579 astrand 113 #ifdef WITH_DEBUG_KBD
580     if (old_modifier_state != remote_modifier_state)
581     {
582     DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n",
583     old_modifier_state, pressed));
584     DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state));
585     }
586     #endif
587    
588 astrand 66 }
589    
590     /* Send keyboard input */
591     void
592 matthewc 203 rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode)
593 astrand 66 {
594     update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));
595    
596     if (scancode & SCANCODE_EXTENDED)
597     {
598 astrand 84 DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n",
599     scancode & ~SCANCODE_EXTENDED, flags));
600 astrand 66 rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
601     scancode & ~SCANCODE_EXTENDED, 0);
602     }
603     else
604     {
605 astrand 85 DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags));
606     rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
607 astrand 66 }
608     }

  ViewVC Help
Powered by ViewVC 1.1.26