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