/[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

Contents of /sourceforge.net/trunk/rdesktop/xkeymap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 810 - (show annotations)
Sun Jan 23 19:29:31 2005 UTC (19 years, 4 months ago) by stargo
File MIME type: text/plain
File size: 18021 byte(s)
Don't send shift when CapsLock is on and Ctrl is pressed, too.
Fixes 858618 and 1069927

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

  ViewVC Help
Powered by ViewVC 1.1.26