/[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 543 - (hide annotations)
Mon Nov 3 13:33:35 2003 UTC (20 years, 7 months ago) by astrand
File MIME type: text/plain
File size: 15980 byte(s)
Re-worked numlock handling: Keeping remote numlock state in sync with local state

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

  ViewVC Help
Powered by ViewVC 1.1.26