/[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 450 - (hide annotations)
Wed Aug 27 22:51:33 2003 UTC (20 years, 9 months ago) by jsorg71
File MIME type: text/plain
File size: 15768 byte(s)
more g_ prefix for global vars

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

  ViewVC Help
Powered by ViewVC 1.1.26