/[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 331 - (hide annotations)
Tue Feb 18 13:44:27 2003 UTC (21 years, 3 months ago) by astrand
File MIME type: text/plain
File size: 15399 byte(s)
Prevent access to sys menu in single app mode

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

  ViewVC Help
Powered by ViewVC 1.1.26