/[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 326 - (hide annotations)
Wed Feb 12 09:56:13 2003 UTC (21 years, 3 months ago) by astrand
File MIME type: text/plain
File size: 15168 byte(s)
Only reports "bad keysym" if DEBUG_KBD.

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 astrand 326 DEBUG_KBD(("Bad keysym \"%s\" in keymap %s (ignoring)\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 astrand 318 *p = toupper((int) *p);
202 astrand 66 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 astrand 318 *mapname_ptr = tolower((int) *mapname_ptr);
224 astrand 227 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 310 /* NumLock */
427     if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
428     != MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
429     {
430     /* The remote modifier state is not correct */
431     uint16 new_remote_state;
432    
433     if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
434     {
435     DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
436     new_remote_state = KBD_FLAG_NUMLOCK;
437     remote_modifier_state = MapNumLockMask;
438     }
439     else
440     {
441     DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
442     new_remote_state = 0;
443     remote_modifier_state = 0;
444     }
445    
446     rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
447     }
448    
449 astrand 183 /* Shift. Left shift and right shift are treated as equal; either is fine. */
450 astrand 66 if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
451     != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
452     {
453     /* The remote modifier state is not correct */
454 astrand 183 if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
455 astrand 66 {
456 astrand 183 /* Needs left shift. Send down. */
457 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
458 astrand 66 }
459 astrand 183 else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
460     {
461     /* Needs right shift. Send down. */
462     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
463     }
464 astrand 66 else
465     {
466 astrand 183 /* Should not use this modifier. Send up for shift currently pressed. */
467     if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
468     /* Left shift is down */
469     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
470     else
471     /* Right shift is down */
472     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
473 astrand 66 }
474     }
475    
476     /* AltGr */
477     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)
478     != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask))
479     {
480     /* The remote modifier state is not correct */
481     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
482     {
483     /* Needs this modifier. Send down. */
484 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
485 astrand 66 }
486     else
487     {
488     /* Should not use this modifier. Send up. */
489 astrand 82 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
490 astrand 66 }
491     }
492    
493 astrand 115
494 astrand 66 }
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