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.
* NumLock handling: NumLock is switched off when typing a non-numlock
key. rdesktop does not know which keys are NumLock-dependent and
not. When you type a numlock-dependent key again, NumLock is
switched on on the server again. The only problem really is that the
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.
* CapsLock: CapsLock changes are never sent to the RDP
server. 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:
@ -71,8 +65,8 @@ scancode value to put into the map file by running:
python -c "print hex(0x80 | 0x52)"
If flags are "altgr", "shift", "numlock", the scancode sent for this
keysym will be prefix with AltGr, Shift or Numlock.
If flags are "altgr", "shift", the scancode sent for this
keysym will be prefix with AltGr, or Shift.
If flags include "addupper", an translation for this keysyms uppercase
name will as well, in addition to the non-uppercase name. Example:

View File

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

View File

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

13
proto.h
View File

@ -59,21 +59,21 @@ void unimpl(char *format, ...);
void hexdump(unsigned char *p, int len);
int load_licence(unsigned char **data);
void save_licence(unsigned char *data, int length);
/* rdp5.c */
void rdp5_process(STREAM s, BOOL encryption);
/* rdp.c */
void rdp_out_unistr(STREAM s, char *string, int len);
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
uint16 param2);
void process_null_system_pointer_pdu(STREAM s);
void process_colour_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_palette(STREAM s);
BOOL rdp_main_loop(void);
BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory);
void rdp_disconnect(void);
/* rdp5.c */
void rdp5_process(STREAM s, BOOL encryption);
/* rdpdr.c */
void rdpdr_send_connect(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_completion(uint16 tick, uint8 packet_index);
void rdpsnd_process_negotiate(STREAM in);
void rdpsnd_process_unknown6(STREAM in);
void rdpsnd_process(STREAM s);
BOOL rdpsnd_init(void);
/* rdpsnd_oss.c */
@ -93,9 +94,9 @@ BOOL wave_out_open(void);
void wave_out_close(void);
BOOL wave_out_format_supported(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_play(void);
void wave_out_volume(uint16 left, uint16 right);
/* secure.c */
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);
@ -132,7 +133,9 @@ char *get_ksname(uint32 keysym);
void save_remote_modifiers(uint8 scancode);
void restore_remote_modifiers(uint32 ev_time, uint8 scancode);
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);
/* xwin.c */
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_CTL_COOPERATE */
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(2);
rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */

View File

@ -38,6 +38,7 @@
#define KEYMAP_MAX_LINE_LENGTH 80
extern Display *g_display;
extern Window g_wnd;
extern char keymapname[16];
extern int keylayout;
extern int g_win_button_size;
@ -185,11 +186,6 @@ xkeymap_read(char *mapname)
MASK_ADD_BITS(modifiers, MapLeftShiftMask);
}
if (strstr(line_rest, "numlock"))
{
MASK_ADD_BITS(modifiers, MapNumLockMask);
}
if (strstr(line_rest, "localstate"))
{
MASK_ADD_BITS(modifiers, MapLocalStateMask);
@ -500,29 +496,6 @@ ensure_remote_modifiers(uint32 ev_time, key_translation tr)
if (is_modifier(tr.scancode))
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. */
if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
!= MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
@ -571,9 +544,35 @@ ensure_remote_modifiers(uint32 ev_time, key_translation tr)
}
void
reset_modifier_keys(unsigned int state)
unsigned int
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 */
uint32 ev_time;
ev_time = time(NULL);
@ -600,6 +599,8 @@ reset_modifier_keys(unsigned int state)
if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
!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_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:
MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
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

7
xwin.c
View File

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