Re-worked numlock handling: Keeping remote numlock state in sync with local state

git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@542 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Peter Åstrand 2003-11-03 13:33:35 +00:00
parent bbd2c8f209
commit ee9d0add63
7 changed files with 61 additions and 81 deletions

View File

@ -13,16 +13,10 @@ the plain old interface as well, at least.
There are still some small problems. There are still some small problems.
* NumLock handling: NumLock is switched off when typing a non-numlock * CapsLock: CapsLock changes are never sent to the RDP
key. rdesktop does not know which keys are NumLock-dependent and server. rdesktop does not know which keys that are modified by
not. When you type a numlock-dependent key again, NumLock is CapsLock and which are not. So, the CapsLock indicator in Wordpad
switched on on the server again. The only problem really is that the etc will always be off.
NumLock indicator in Wordpad etc switches on and off when you type.
* CapsLock: CapsLock changes are never sent to the RDP server. This is
a problem of the same type as NumLock: rdesktop does not know which
keys that are modified by CapsLock and which are not. So, the
CapsLock indicator in Wordpad etc will always be off.
Composing/Multi_key is supported. For more information, see: Composing/Multi_key is supported. For more information, see:
@ -71,8 +65,8 @@ scancode value to put into the map file by running:
python -c "print hex(0x80 | 0x52)" python -c "print hex(0x80 | 0x52)"
If flags are "altgr", "shift", "numlock", the scancode sent for this If flags are "altgr", "shift", the scancode sent for this
keysym will be prefix with AltGr, Shift or Numlock. keysym will be prefix with AltGr, or Shift.
If flags include "addupper", an translation for this keysyms uppercase If flags include "addupper", an translation for this keysyms uppercase
name will as well, in addition to the non-uppercase name. Example: name will as well, in addition to the non-uppercase name. Example:

View File

@ -109,44 +109,45 @@ Right 0xcd localstate
# #
# Numpad # Numpad
# #
Num_Lock 0x45
KP_Divide 0xb5 KP_Divide 0xb5
KP_Multiply 0x37 KP_Multiply 0x37
KP_Subtract 0x4a KP_Subtract 0x4a
KP_Add 0x4e KP_Add 0x4e
KP_Enter 0x9c KP_Enter 0x9c
KP_Decimal 0x53 numlock KP_Decimal 0x53
KP_Separator 0x53 numlock KP_Separator 0x53
KP_Delete 0x53 KP_Delete 0x53
KP_0 0x52 numlock KP_0 0x52
KP_Insert 0x52 KP_Insert 0x52
KP_1 0x4f numlock KP_1 0x4f
KP_End 0x4f KP_End 0x4f
KP_2 0x50 numlock KP_2 0x50
KP_Down 0x50 KP_Down 0x50
KP_3 0x51 numlock KP_3 0x51
KP_Next 0x51 KP_Next 0x51
KP_4 0x4b numlock KP_4 0x4b
KP_Left 0x4b KP_Left 0x4b
KP_5 0x4c numlock KP_5 0x4c
KP_Begin 0x4c KP_Begin 0x4c
KP_6 0x4d numlock KP_6 0x4d
KP_Right 0x4d KP_Right 0x4d
KP_7 0x47 numlock KP_7 0x47
KP_Home 0x47 KP_Home 0x47
KP_8 0x48 numlock KP_8 0x48
KP_Up 0x48 KP_Up 0x48
KP_9 0x49 numlock KP_9 0x49
KP_Prior 0x49 KP_Prior 0x49
# #
@ -154,4 +155,3 @@ KP_Prior 0x49
# #
Caps_Lock 0x0 inhibit Caps_Lock 0x0 inhibit
Multi_key 0x0 inhibit Multi_key 0x0 inhibit
Num_Lock 0x0 inhibit

View File

@ -60,7 +60,7 @@ period 0x34
greater 0x34 shift greater 0x34 shift
semicolon 0x35 semicolon 0x35
colon 0x35 shift colon 0x35 shift
comma 0x53 numlock comma 0x53
backslash 0x56 backslash 0x56
bar 0x56 shift bar 0x56 shift
slash 0x73 slash 0x73

13
proto.h
View File

@ -59,21 +59,21 @@ void unimpl(char *format, ...);
void hexdump(unsigned char *p, int len); void hexdump(unsigned char *p, int len);
int load_licence(unsigned char **data); int load_licence(unsigned char **data);
void save_licence(unsigned char *data, int length); void save_licence(unsigned char *data, int length);
/* rdp5.c */
void rdp5_process(STREAM s, BOOL encryption);
/* rdp.c */ /* rdp.c */
void rdp_out_unistr(STREAM s, char *string, int len); void rdp_out_unistr(STREAM s, char *string, int len);
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
uint16 param2); uint16 param2);
void process_null_system_pointer_pdu(STREAM s);
void process_colour_pointer_pdu(STREAM s); void process_colour_pointer_pdu(STREAM s);
void process_cached_pointer_pdu(STREAM s); void process_cached_pointer_pdu(STREAM s);
void process_system_pointer_pdu(STREAM s);
void process_bitmap_updates(STREAM s); void process_bitmap_updates(STREAM s);
void process_palette(STREAM s); void process_palette(STREAM s);
BOOL rdp_main_loop(void); BOOL rdp_main_loop(void);
BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command, BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory); char *directory);
void rdp_disconnect(void); void rdp_disconnect(void);
/* rdp5.c */
void rdp5_process(STREAM s, BOOL encryption);
/* rdpdr.c */ /* rdpdr.c */
void rdpdr_send_connect(void); void rdpdr_send_connect(void);
void rdpdr_send_name(void); void rdpdr_send_name(void);
@ -86,6 +86,7 @@ STREAM rdpsnd_init_packet(uint16 type, uint16 size);
void rdpsnd_send(STREAM s); void rdpsnd_send(STREAM s);
void rdpsnd_send_completion(uint16 tick, uint8 packet_index); void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
void rdpsnd_process_negotiate(STREAM in); void rdpsnd_process_negotiate(STREAM in);
void rdpsnd_process_unknown6(STREAM in);
void rdpsnd_process(STREAM s); void rdpsnd_process(STREAM s);
BOOL rdpsnd_init(void); BOOL rdpsnd_init(void);
/* rdpsnd_oss.c */ /* rdpsnd_oss.c */
@ -93,9 +94,9 @@ BOOL wave_out_open(void);
void wave_out_close(void); void wave_out_close(void);
BOOL wave_out_format_supported(WAVEFORMATEX * pwfx); BOOL wave_out_format_supported(WAVEFORMATEX * pwfx);
BOOL wave_out_set_format(WAVEFORMATEX * pwfx); BOOL wave_out_set_format(WAVEFORMATEX * pwfx);
void wave_out_volume(uint16 left, uint16 right);
void wave_out_write(STREAM s, uint16 tick, uint8 index); void wave_out_write(STREAM s, uint16 tick, uint8 index);
void wave_out_play(void); void wave_out_play(void);
void wave_out_volume(uint16 left, uint16 right);
/* secure.c */ /* secure.c */
void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt); void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2); void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);
@ -132,7 +133,9 @@ char *get_ksname(uint32 keysym);
void save_remote_modifiers(uint8 scancode); void save_remote_modifiers(uint8 scancode);
void restore_remote_modifiers(uint32 ev_time, uint8 scancode); void restore_remote_modifiers(uint32 ev_time, uint8 scancode);
void ensure_remote_modifiers(uint32 ev_time, key_translation tr); void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
void reset_modifier_keys(unsigned int state); unsigned int read_keyboard_state(void);
uint16 ui_get_numlock_state(unsigned int state);
void reset_modifier_keys(void);
void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode); void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
/* xwin.c */ /* xwin.c */
BOOL get_key_state(unsigned int state, uint32 keysym); BOOL get_key_state(unsigned int state, uint32 keysym);

2
rdp.c
View File

@ -600,7 +600,7 @@ process_demand_active(STREAM s)
rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */ rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
rdp_recv(&type); /* RDP_CTL_COOPERATE */ rdp_recv(&type); /* RDP_CTL_COOPERATE */
rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */ rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0); rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
rdp_send_fonts(1); rdp_send_fonts(1);
rdp_send_fonts(2); rdp_send_fonts(2);
rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */ rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */

View File

@ -38,6 +38,7 @@
#define KEYMAP_MAX_LINE_LENGTH 80 #define KEYMAP_MAX_LINE_LENGTH 80
extern Display *g_display; extern Display *g_display;
extern Window g_wnd;
extern char keymapname[16]; extern char keymapname[16];
extern int keylayout; extern int keylayout;
extern int g_win_button_size; extern int g_win_button_size;
@ -185,11 +186,6 @@ xkeymap_read(char *mapname)
MASK_ADD_BITS(modifiers, MapLeftShiftMask); MASK_ADD_BITS(modifiers, MapLeftShiftMask);
} }
if (strstr(line_rest, "numlock"))
{
MASK_ADD_BITS(modifiers, MapNumLockMask);
}
if (strstr(line_rest, "localstate")) if (strstr(line_rest, "localstate"))
{ {
MASK_ADD_BITS(modifiers, MapLocalStateMask); MASK_ADD_BITS(modifiers, MapLocalStateMask);
@ -500,29 +496,6 @@ ensure_remote_modifiers(uint32 ev_time, key_translation tr)
if (is_modifier(tr.scancode)) if (is_modifier(tr.scancode))
return; return;
/* NumLock */
if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
!= MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
{
/* The remote modifier state is not correct */
uint16 new_remote_state;
if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
{
DEBUG_KBD(("Remote NumLock state is incorrect, activating NumLock.\n"));
new_remote_state = KBD_FLAG_NUMLOCK;
remote_modifier_state = MapNumLockMask;
}
else
{
DEBUG_KBD(("Remote NumLock state is incorrect, deactivating NumLock.\n"));
new_remote_state = 0;
remote_modifier_state = 0;
}
rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
}
/* Shift. Left shift and right shift are treated as equal; either is fine. */ /* Shift. Left shift and right shift are treated as equal; either is fine. */
if (MASK_HAS_BITS(tr.modifiers, MapShiftMask) if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
!= MASK_HAS_BITS(remote_modifier_state, MapShiftMask)) != MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
@ -571,9 +544,35 @@ ensure_remote_modifiers(uint32 ev_time, key_translation tr)
} }
void unsigned int
reset_modifier_keys(unsigned int state) read_keyboard_state()
{ {
unsigned int state;
Window wdummy;
int dummy;
XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
return state;
}
uint16
ui_get_numlock_state(unsigned int state)
{
uint16 numlock_state = 0;
if (get_key_state(state, XK_Num_Lock))
numlock_state = KBD_FLAG_NUMLOCK;
return numlock_state;
}
void
reset_modifier_keys()
{
unsigned int state = read_keyboard_state();
/* reset keys */ /* reset keys */
uint32 ev_time; uint32 ev_time;
ev_time = time(NULL); ev_time = time(NULL);
@ -600,6 +599,8 @@ reset_modifier_keys(unsigned int state)
if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) && if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
!get_key_state(state, XK_Alt_R) && !get_key_state(state, XK_Mode_switch)) !get_key_state(state, XK_Alt_R) && !get_key_state(state, XK_Mode_switch))
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT); rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
rdp_send_input(ev_time, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(state), 0);
} }
@ -638,19 +639,6 @@ update_modifier_state(uint8 scancode, BOOL pressed)
case SCANCODE_CHAR_RWIN: case SCANCODE_CHAR_RWIN:
MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed); MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
break; break;
case SCANCODE_CHAR_NUMLOCK:
/* KeyReleases for NumLocks are sent immediately. Toggle the
modifier state only on Keypress */
if (pressed)
{
BOOL newNumLockState;
newNumLockState =
(MASK_HAS_BITS
(remote_modifier_state, MapNumLockMask) == False);
MASK_CHANGE_BIT(remote_modifier_state,
MapNumLockMask, newNumLockState);
}
break;
} }
#ifdef WITH_DEBUG_KBD #ifdef WITH_DEBUG_KBD

7
xwin.c
View File

@ -988,9 +988,6 @@ xwin_process_events(void)
key_translation tr; key_translation tr;
char str[256]; char str[256];
Status status; Status status;
unsigned int state;
Window wdummy;
int dummy;
while (XPending(g_display) > 0) while (XPending(g_display) > 0)
{ {
@ -1163,9 +1160,7 @@ xwin_process_events(void)
if (xevent.xfocus.mode == NotifyGrab) if (xevent.xfocus.mode == NotifyGrab)
break; break;
g_focused = True; g_focused = True;
XQueryPointer(g_display, g_wnd, &wdummy, &wdummy, &dummy, &dummy, reset_modifier_keys();
&dummy, &dummy, &state);
reset_modifier_keys(state);
if (g_grab_keyboard && g_mouse_in_wnd) if (g_grab_keyboard && g_mouse_in_wnd)
XGrabKeyboard(g_display, g_wnd, True, XGrabKeyboard(g_display, g_wnd, True,
GrabModeAsync, GrabModeAsync, CurrentTime); GrabModeAsync, GrabModeAsync, CurrentTime);