/[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 548 - (hide annotations)
Tue Nov 11 14:01:31 2003 UTC (20 years, 6 months ago) by astrand
File MIME type: text/plain
File size: 16234 byte(s)
Resetting Windows key state in reset_modifiers

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 548 static void
280     reset_winkey(uint32 ev_time)
281     {
282     if (g_use_rdp5)
283     {
284     /* For some reason, it seems to suffice to release
285     *either* the left or right winkey. */
286     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LWIN);
287     }
288     }
289    
290 astrand 118 /* Handles, for example, multi-scancode keypresses (which is not
291     possible via keymap-files) */
292     BOOL
293 matthewc 203 handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed)
294 astrand 118 {
295     switch (keysym)
296     {
297 matthewc 244 case XK_Return:
298 matthewc 212 if ((get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))
299 astrand 226 && (get_key_state(state, XK_Control_L)
300     || get_key_state(state, XK_Control_R)))
301 astrand 118 {
302 matthewc 244 /* Ctrl-Alt-Enter: toggle full screen */
303 matthewc 193 if (pressed)
304     xwin_toggle_fullscreen();
305 matthewc 244 return True;
306     }
307     break;
308 astrand 199
309 matthewc 244 case XK_Break:
310     /* Send Break sequence E0 46 E0 C6 */
311     if (pressed)
312     {
313     rdp_send_scancode(ev_time, RDP_KEYPRESS,
314     (SCANCODE_EXTENDED | 0x46));
315     rdp_send_scancode(ev_time, RDP_KEYPRESS,
316     (SCANCODE_EXTENDED | 0xc6));
317 astrand 118 }
318 matthewc 244 /* No release sequence */
319     return True;
320    
321     case XK_Pause:
322     /* According to MS Keyboard Scan Code
323     Specification, pressing Pause should result
324     in E1 1D 45 E1 9D C5. I'm not exactly sure
325     of how this is supposed to be sent via
326     RDP. The code below seems to work, but with
327     the side effect that Left Ctrl stays
328     down. Therefore, we release it when Pause
329     is released. */
330     if (pressed)
331 astrand 199 {
332 astrand 260 rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
333     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0);
334     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x45, 0);
335     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
336     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x9d, 0);
337     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xc5, 0);
338 astrand 199 }
339 matthewc 244 else
340 astrand 197 {
341 matthewc 244 /* Release Left Ctrl */
342     rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE,
343     0x1d, 0);
344 astrand 197 }
345     return True;
346    
347 astrand 118 case XK_Meta_L: /* Windows keys */
348     case XK_Super_L:
349     case XK_Hyper_L:
350 astrand 452 send_winkey(ev_time, pressed, True);
351     return True;
352    
353 astrand 118 case XK_Meta_R:
354     case XK_Super_R:
355     case XK_Hyper_R:
356 astrand 452 send_winkey(ev_time, pressed, False);
357 astrand 118 return True;
358 astrand 331
359     case XK_space:
360     /* Prevent access to the Windows system menu in single app mode */
361 jsorg71 450 if (g_win_button_size
362 astrand 331 && (get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R)))
363     return True;
364    
365 astrand 118 }
366     return False;
367     }
368    
369    
370 astrand 66 key_translation
371 matthewc 190 xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
372 astrand 66 {
373     key_translation tr = { 0, 0 };
374    
375     tr = keymap[keysym & KEYMAP_MASK];
376    
377 astrand 116 if (tr.modifiers & MapInhibitMask)
378     {
379     DEBUG_KBD(("Inhibiting key\n"));
380     tr.scancode = 0;
381     return tr;
382     }
383    
384 astrand 69 if (tr.modifiers & MapLocalStateMask)
385     {
386     /* The modifiers to send for this key should be obtained
387     from the local state. Currently, only shift is implemented. */
388     if (state & ShiftMask)
389     {
390     tr.modifiers = MapLeftShiftMask;
391     }
392     }
393    
394 astrand 66 if (tr.scancode != 0)
395 matthewc 50 {
396 matthewc 190 DEBUG_KBD(("Found key translation, scancode=0x%x, modifiers=0x%x\n",
397 astrand 197 tr.scancode, tr.modifiers));
398 astrand 66 return tr;
399 matthewc 50 }
400    
401 matthewc 205 if (keymap_loaded)
402 matthewc 297 warning("No translation for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym));
403 astrand 66
404 matthewc 38 /* not in keymap, try to interpret the raw scancode */
405 forsberg 414 if (((int) keycode >= min_keycode) && (keycode <= 0x60))
406 matthewc 38 {
407 astrand 66 tr.scancode = keycode - min_keycode;
408 astrand 165
409     /* The modifiers to send for this key should be
410     obtained from the local state. Currently, only
411     shift is implemented. */
412     if (state & ShiftMask)
413     {
414     tr.modifiers = MapLeftShiftMask;
415     }
416    
417 matthewc 190 DEBUG_KBD(("Sending guessed scancode 0x%x\n", tr.scancode));
418 matthewc 38 }
419 astrand 66 else
420     {
421 matthewc 190 DEBUG_KBD(("No good guess for keycode 0x%x found\n", keycode));
422 astrand 66 }
423 matthewc 38
424 astrand 66 return tr;
425 matthewc 38 }
426    
427 astrand 64 uint16
428     xkeymap_translate_button(unsigned int button)
429 matthewc 38 {
430     switch (button)
431     {
432 astrand 64 case Button1: /* left */
433 matthewc 38 return MOUSE_FLAG_BUTTON1;
434 astrand 64 case Button2: /* middle */
435 matthewc 38 return MOUSE_FLAG_BUTTON3;
436 astrand 64 case Button3: /* right */
437 matthewc 38 return MOUSE_FLAG_BUTTON2;
438 jsorg71 67 case Button4: /* wheel up */
439     return MOUSE_FLAG_BUTTON4;
440     case Button5: /* wheel down */
441     return MOUSE_FLAG_BUTTON5;
442 matthewc 38 }
443    
444     return 0;
445     }
446 astrand 66
447     char *
448 matthewc 190 get_ksname(uint32 keysym)
449 astrand 66 {
450     char *ksname = NULL;
451    
452     if (keysym == NoSymbol)
453     ksname = "NoSymbol";
454     else if (!(ksname = XKeysymToString(keysym)))
455     ksname = "(no name)";
456    
457     return ksname;
458     }
459    
460 astrand 470 static BOOL
461     is_modifier(uint8 scancode)
462     {
463     switch (scancode)
464     {
465     case SCANCODE_CHAR_LSHIFT:
466     case SCANCODE_CHAR_RSHIFT:
467     case SCANCODE_CHAR_LCTRL:
468     case SCANCODE_CHAR_RCTRL:
469     case SCANCODE_CHAR_LALT:
470     case SCANCODE_CHAR_RALT:
471     case SCANCODE_CHAR_LWIN:
472     case SCANCODE_CHAR_RWIN:
473     case SCANCODE_CHAR_NUMLOCK:
474     return True;
475     default:
476     break;
477     }
478     return False;
479     }
480    
481 astrand 449 void
482 astrand 470 save_remote_modifiers(uint8 scancode)
483 astrand 449 {
484 astrand 470 if (is_modifier(scancode))
485     return;
486    
487 astrand 449 saved_remote_modifier_state = remote_modifier_state;
488     }
489 astrand 66
490     void
491 astrand 470 restore_remote_modifiers(uint32 ev_time, uint8 scancode)
492 astrand 449 {
493     key_translation dummy;
494    
495 astrand 470 if (is_modifier(scancode))
496     return;
497    
498 astrand 449 dummy.scancode = 0;
499     dummy.modifiers = saved_remote_modifier_state;
500     ensure_remote_modifiers(ev_time, dummy);
501     }
502    
503     void
504 astrand 66 ensure_remote_modifiers(uint32 ev_time, key_translation tr)
505     {
506     /* If this key is a modifier, do nothing */
507 astrand 470 if (is_modifier(tr.scancode))
508     return;
509 astrand 66
510 astrand 183 /* Shift. Left shift and right shift are treated as equal; either is fine. */
511 astrand 66 if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
512     != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
513     {
514     /* The remote modifier state is not correct */
515 astrand 183 if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
516 astrand 66 {
517 astrand 183 /* Needs left shift. Send down. */
518 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
519 astrand 66 }
520 astrand 183 else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
521     {
522     /* Needs right shift. Send down. */
523     rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
524     }
525 astrand 66 else
526     {
527 astrand 183 /* Should not use this modifier. Send up for shift currently pressed. */
528     if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
529     /* Left shift is down */
530     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
531     else
532     /* Right shift is down */
533     rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
534 astrand 66 }
535     }
536    
537     /* AltGr */
538     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)
539     != MASK_HAS_BITS(remote_modifier_state, MapAltGrMask))
540     {
541     /* The remote modifier state is not correct */
542     if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
543     {
544     /* Needs this modifier. Send down. */
545 astrand 82 rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
546 astrand 66 }
547     else
548     {
549     /* Should not use this modifier. Send up. */
550 astrand 82 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
551 astrand 66 }
552     }
553    
554 astrand 115
555 astrand 66 }
556    
557    
558 astrand 543 unsigned int
559     read_keyboard_state()
560     {
561     unsigned int state;
562     Window wdummy;
563     int dummy;
564    
565     XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
566     return state;
567     }
568    
569    
570     uint16
571     ui_get_numlock_state(unsigned int state)
572     {
573     uint16 numlock_state = 0;
574    
575     if (get_key_state(state, XK_Num_Lock))
576     numlock_state = KBD_FLAG_NUMLOCK;
577    
578     return numlock_state;
579     }
580    
581    
582 astrand 170 void
583 astrand 543 reset_modifier_keys()
584 astrand 170 {
585 astrand 543 unsigned int state = read_keyboard_state();
586    
587 astrand 170 /* reset keys */
588     uint32 ev_time;
589     ev_time = time(NULL);
590    
591 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask)
592     && !get_key_state(state, XK_Shift_L))
593 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
594    
595 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask)
596     && !get_key_state(state, XK_Shift_R))
597 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
598    
599 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask)
600     && !get_key_state(state, XK_Control_L))
601 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
602    
603 astrand 226 if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask)
604     && !get_key_state(state, XK_Control_R))
605 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
606    
607 matthewc 203 if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(state, XK_Alt_L))
608 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
609    
610     if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
611 matthewc 203 !get_key_state(state, XK_Alt_R) && !get_key_state(state, XK_Mode_switch))
612 astrand 170 rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
613 astrand 543
614 astrand 548 reset_winkey(ev_time);
615    
616 astrand 543 rdp_send_input(ev_time, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(state), 0);
617 astrand 170 }
618    
619    
620 astrand 66 static void
621 matthewc 203 update_modifier_state(uint8 scancode, BOOL pressed)
622 astrand 66 {
623 astrand 113 #ifdef WITH_DEBUG_KBD
624     uint16 old_modifier_state;
625 astrand 66
626 astrand 113 old_modifier_state = remote_modifier_state;
627     #endif
628    
629 matthewc 203 switch (scancode)
630 astrand 66 {
631     case SCANCODE_CHAR_LSHIFT:
632 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
633 astrand 66 break;
634     case SCANCODE_CHAR_RSHIFT:
635 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
636 astrand 66 break;
637     case SCANCODE_CHAR_LCTRL:
638 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
639 astrand 66 break;
640     case SCANCODE_CHAR_RCTRL:
641 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
642 astrand 66 break;
643     case SCANCODE_CHAR_LALT:
644 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
645 astrand 66 break;
646     case SCANCODE_CHAR_RALT:
647 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
648 astrand 66 break;
649     case SCANCODE_CHAR_LWIN:
650 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
651 astrand 66 break;
652     case SCANCODE_CHAR_RWIN:
653 astrand 82 MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
654 astrand 66 break;
655     }
656    
657 astrand 113 #ifdef WITH_DEBUG_KBD
658     if (old_modifier_state != remote_modifier_state)
659     {
660     DEBUG_KBD(("Before updating modifier_state:0x%x, pressed=0x%x\n",
661     old_modifier_state, pressed));
662     DEBUG_KBD(("After updating modifier_state:0x%x\n", remote_modifier_state));
663     }
664     #endif
665    
666 astrand 66 }
667    
668     /* Send keyboard input */
669     void
670 matthewc 203 rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode)
671 astrand 66 {
672     update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));
673    
674     if (scancode & SCANCODE_EXTENDED)
675     {
676 astrand 84 DEBUG_KBD(("Sending extended scancode=0x%x, flags=0x%x\n",
677     scancode & ~SCANCODE_EXTENDED, flags));
678 astrand 66 rdp_send_input(time, RDP_INPUT_SCANCODE, flags | KBD_FLAG_EXT,
679     scancode & ~SCANCODE_EXTENDED, 0);
680     }
681     else
682     {
683 astrand 85 DEBUG_KBD(("Sending scancode=0x%x, flags=0x%x\n", scancode, flags));
684     rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
685 astrand 66 }
686     }

  ViewVC Help
Powered by ViewVC 1.1.26