/[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 244 - (hide annotations)
Thu Oct 24 08:48:51 2002 UTC (21 years, 7 months ago) by matthewc
File MIME type: text/plain
File size: 15170 byte(s)
Change fullscreen toggle key to Ctrl-Alt-Enter.

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 astrand 227 {
223     *mapname_ptr = tolower(*mapname_ptr);
224     mapname_ptr++;
225     }
226 astrand 225
227 matthewc 38 if (strcmp(keymapname, "none"))
228 matthewc 205 {
229     if (xkeymap_read(keymapname))
230     keymap_loaded = True;
231     }
232 astrand 66
233 astrand 77 XDisplayKeycodes(display, &min_keycode, (int *) &max_keycode);
234 astrand 66 }
235 matthewc 38
236 astrand 118 /* Handles, for example, multi-scancode keypresses (which is not
237     possible via keymap-files) */
238     BOOL
239 matthewc 203 handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed)
240 astrand 118 {
241     switch (keysym)
242     {
243 matthewc 244 case XK_Return:
244 matthewc 212 if ((get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))
245 astrand 226 && (get_key_state(state, XK_Control_L)
246     || get_key_state(state, XK_Control_R)))
247 astrand 118 {
248 matthewc 244 /* Ctrl-Alt-Enter: toggle full screen */
249 matthewc 193 if (pressed)
250     xwin_toggle_fullscreen();
251 matthewc 244 return True;
252     }
253     break;
254 astrand 199
255 matthewc 244 case XK_Break:
256     /* Send Break sequence E0 46 E0 C6 */
257     if (pressed)
258     {
259     rdp_send_scancode(ev_time, RDP_KEYPRESS,
260     (SCANCODE_EXTENDED | 0x46));
261     rdp_send_scancode(ev_time, RDP_KEYPRESS,
262     (SCANCODE_EXTENDED | 0xc6));
263 astrand 118 }
264 matthewc 244 /* No release sequence */
265     return True;
266    
267     case XK_Pause:
268     /* According to MS Keyboard Scan Code
269     Specification, pressing Pause should result
270     in E1 1D 45 E1 9D C5. I'm not exactly sure
271     of how this is supposed to be sent via
272     RDP. The code below seems to work, but with
273     the side effect that Left Ctrl stays
274     down. Therefore, we release it when Pause
275     is released. */
276     if (pressed)
277 astrand 199 {
278 matthewc 244 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
279     0xe1, 0);
280     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
281     0x1d, 0);
282     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
283     0x45, 0);
284     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
285     0xe1, 0);
286     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
287     0x9d, 0);
288     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS,
289     0xc5, 0);
290 astrand 199 }
291 matthewc 244 else
292 astrand 197 {
293 matthewc 244 /* Release Left Ctrl */
294     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE,
295     0x1d, 0);
296 astrand 197 }
297     return True;
298    
299 astrand 118 case XK_Meta_L: /* Windows keys */
300     case XK_Super_L:
301     case XK_Hyper_L:
302     case XK_Meta_R:
303     case XK_Super_R:
304     case XK_Hyper_R:
305     if (pressed)
306     {
307     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
308     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
309     }
310     else
311     {
312     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
313     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
314     }
315     return True;
316     }
317     return False;
318     }
319    
320    
321 astrand 66 key_translation
322 matthewc 190 xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
323 astrand 66 {
324     key_translation tr = { 0, 0 };
325    
326     tr = keymap[keysym & KEYMAP_MASK];
327    
328 astrand 116 if (tr.modifiers & MapInhibitMask)
329     {
330     DEBUG_KBD(("Inhibiting key\n"));
331     tr.scancode = 0;
332     return tr;
333     }
334    
335 astrand 69 if (tr.modifiers & MapLocalStateMask)
336     {
337     /* The modifiers to send for this key should be obtained
338     from the local state. Currently, only shift is implemented. */
339     if (state & ShiftMask)
340     {
341     tr.modifiers = MapLeftShiftMask;
342     }
343     }
344    
345 astrand 66 if (tr.scancode != 0)
346 matthewc 50 {
347 matthewc 190 DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
348 astrand 197 tr.scancode, tr.modifiers));
349 astrand 66 return tr;
350 matthewc 50 }
351    
352 matthewc 205 if (keymap_loaded)
353     error("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym));
354 astrand 66
355 matthewc 38 /* not in keymap, try to interpret the raw scancode */
356     if ((keycode >= min_keycode) && (keycode <= 0x60))
357     {
358 astrand 66 tr.scancode = keycode - min_keycode;
359 astrand 165
360     /* The modifiers to send for this key should be
361     obtained from the local state. Currently, only
362     shift is implemented. */
363     if (state & ShiftMask)
364     {
365     tr.modifiers = MapLeftShiftMask;
366     }
367    
368 matthewc 190 DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
369 matthewc 38 }
370 astrand 66 else
371     {
372 matthewc 190 DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
373 astrand 66 }
374 matthewc 38
375 astrand 66 return tr;
376 matthewc 38 }
377    
378 astrand 64 uint16
379     xkeymap_translate_button(unsigned int button)
380 matthewc 38 {
381     switch (button)
382     {
383 astrand 64 case Button1: /* left */
384 matthewc 38 return MOUSE_FLAG_BUTTON1;
385 astrand 64 case Button2: /* middle */
386 matthewc 38 return MOUSE_FLAG_BUTTON3;
387 astrand 64 case Button3: /* right */
388 matthewc 38 return MOUSE_FLAG_BUTTON2;
389 jsorg71 67 case Button4: /* wheel up */
390     return MOUSE_FLAG_BUTTON4;
391     case Button5: /* wheel down */
392     return MOUSE_FLAG_BUTTON5;
393 matthewc 38 }
394    
395     return 0;
396     }
397 astrand 66
398     char *
399 matthewc 190 get_ksname(uint32 keysym)
400 astrand 66 {
401     char *ksname = NULL;
402    
403     if (keysym == NoSymbol)
404     ksname = "NoSymbol";
405     else if (!(ksname = XKeysymToString(keysym)))
406     ksname = "(no name)";
407    
408     return ksname;
409     }
410    
411    
412     void
413     ensure_remote_modifiers(uint32 ev_time, key_translation tr)
414     {
415     /* If this key is a modifier, do nothing */
416     switch (tr.scancode)
417     {
418     case SCANCODE_CHAR_LSHIFT:
419     case SCANCODE_CHAR_RSHIFT:
420     case SCANCODE_CHAR_LCTRL:
421     case SCANCODE_CHAR_RCTRL:
422     case SCANCODE_CHAR_LALT:
423     case SCANCODE_CHAR_RALT:
424     case SCANCODE_CHAR_LWIN:
425     case SCANCODE_CHAR_RWIN:
426     case SCANCODE_CHAR_NUMLOCK:
427     return;
428     default:
429     break;
430     }
431    
432 astrand 183 /* Shift. Left shift and right shift are treated as equal; either is fine. */
433 astrand 66 if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
434     != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
435     {
436     /* The remote modifier state is not correct */
437 astrand 183 if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
438 astrand 66 {
439 astrand 183 /* Needs left shift. Send down. */
440 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
441 astrand 66 }
442 astrand 183 else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
443     {
444     /* Needs right shift. Send down. */
445     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
446     }
447 astrand 66 else
448     {
449 astrand 183 /* Should not use this modifier. Send up for shift currently pressed. */
450     if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
451     /* Left shift is down */
452     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
453     else
454     /* Right shift is down */
455     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
456 astrand 66 }
457     }
458    
459     /* AltGr */
460     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)
461     != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask))
462     {
463     /* The remote modifier state is not correct */
464     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
465     {
466     /* Needs this modifier. Send down. */
467 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
468 astrand 66 }
469     else
470     {
471     /* Should not use this modifier. Send up. */
472 astrand 82 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
473 astrand 66 }
474     }
475    
476     /* NumLock */
477     if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
478     != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
479     {
480     /* The remote modifier state is not correct */
481 astrand 115 uint16 new_remote_state = 0;
482    
483 astrand 66 if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
484     {
485 astrand 115 DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
486     new_remote_state |= KBD_FLAG_NUMLOCK;
487 astrand 66 }
488     else
489     {
490 astrand 115 DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
491 astrand 66 }
492 astrand 115
493     rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
494     update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);
495 astrand 66 }
496     }
497    
498    
499 astrand 170 void
500 matthewc 203 reset_modifier_keys(unsigned int state)
501 astrand 170 {
502     /* reset keys */
503     uint32 ev_time;
504     ev_time = time(NULL);
505    
506 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask)
507     && !get_key_state(state, XK_Shift_L))
508 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
509    
510 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask)
511     && !get_key_state(state, XK_Shift_R))
512 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
513    
514 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask)
515     && !get_key_state(state, XK_Control_L))
516 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
517    
518 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask)
519     && !get_key_state(state, XK_Control_R))
520 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
521    
522 matthewc 203 if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(state, XK_Alt_L))
523 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
524    
525     if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
526 matthewc 203 !get_key_state(state, XK_Alt_R) && !get_key_state(state, XK_Mode_switch))
527 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
528     }
529    
530    
531 astrand 66 static void
532 matthewc 203 update_modifier_state(uint8 scancode, BOOL pressed)
533 astrand 66 {
534 astrand 113 #ifdef WITH_DEBUG_KBD
535     uint16 old_modifier_state;
536 astrand 66
537 astrand 113 old_modifier_state = remote_modifier_state;
538     #endif
539    
540 matthewc 203 switch (scancode)
541 astrand 66 {
542     case SCANCODE_CHAR_LSHIFT:
543 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
544 astrand 66 break;
545     case SCANCODE_CHAR_RSHIFT:
546 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
547 astrand 66 break;
548     case SCANCODE_CHAR_LCTRL:
549 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
550 astrand 66 break;
551     case SCANCODE_CHAR_RCTRL:
552 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
553 astrand 66 break;
554     case SCANCODE_CHAR_LALT:
555 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
556 astrand 66 break;
557     case SCANCODE_CHAR_RALT:
558 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
559 astrand 66 break;
560     case SCANCODE_CHAR_LWIN:
561 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
562 astrand 66 break;
563     case SCANCODE_CHAR_RWIN:
564 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
565 astrand 66 break;
566     case SCANCODE_CHAR_NUMLOCK:
567     /* KeyReleases for NumLocks are sent immediately. Toggle the
568     modifier state only on Keypress */
569     if (pressed)
570     {
571     BOOL newNumLockState;
572     newNumLockState =
573     (MASK_HAS_BITS
574 astrand 82 (remote_modifier_state, MapNumLockMask) == False);
575 astrand 66 MASK_CHANGE_BIT(remote_modifier_state,
576 astrand 82 MapNumLockMask, newNumLockState);
577 astrand 66 }
578     break;
579     }
580    
581 astrand 113 #ifdef WITH_DEBUG_KBD
582     if (old_modifier_state != remote_modifier_state)
583     {
584     DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n",
585     old_modifier_state, pressed));
586     DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state));
587     }
588     #endif
589    
590 astrand 66 }
591    
592     /* Send keyboard input */
593     void
594 matthewc 203 rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode)
595 astrand 66 {
596     update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));
597    
598     if (scancode & SCANCODE_EXTENDED)
599     {
600 astrand 84 DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n",
601     scancode & ~SCANCODE_EXTENDED, flags));
602 astrand 66 rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
603     scancode & ~SCANCODE_EXTENDED, 0);
604     }
605     else
606     {
607 astrand 85 DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags));
608     rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
609 astrand 66 }
610     }

  ViewVC Help
Powered by ViewVC 1.1.26