/[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 470 - (hide annotations)
Mon Sep 15 08:03:30 2003 UTC (20 years, 8 months ago) by astrand
File MIME type: text/plain
File size: 16580 byte(s)
Kbd fix: Shift was always reset after press

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

  ViewVC Help
Powered by ViewVC 1.1.26