/[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 227 - (hide annotations)
Fri Oct 11 09:38:49 2002 UTC (21 years, 7 months ago) by astrand
File MIME type: text/plain
File size: 15219 byte(s)
Eliminating GCC warning message.

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

  ViewVC Help
Powered by ViewVC 1.1.26