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:
parent
bbd2c8f209
commit
ee9d0add63
@ -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:
|
||||||
|
@ -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
|
|
||||||
|
@ -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
13
proto.h
@ -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
2
rdp.c
@ -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 */
|
||||||
|
74
xkeymap.c
74
xkeymap.c
@ -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
7
xwin.c
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user