/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/xkeymap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 297 - (hide annotations)
Tue Jan 28 12:27:28 2003 UTC (21 years, 3 months ago) by matthewc
Original Path: sourceforge.net/trunk/rdesktop/xkeymap.c
File MIME type: text/plain
File size: 15095 byte(s)
Add a warning function, change some errors to warnings, improve a
couple of error messages (not sure whether scewed was meant to be skewed
or screwed :))

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

  ViewVC Help
Powered by ViewVC 1.1.26