Optimise get_key_state by caching the modifier map and the state
(this can probably still be improved in the future). Only call time(NULL) for the events where it's needed. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@202 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
c6038854b1
commit
b46de1c760
8
proto.h
8
proto.h
@ -63,15 +63,15 @@ BOOL tcp_connect(char *server);
|
||||
void tcp_disconnect(void);
|
||||
/* xkeymap.c */
|
||||
void xkeymap_init(void);
|
||||
BOOL handle_special_keys(uint32 keysym, uint32 ev_time, BOOL pressed);
|
||||
BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed);
|
||||
key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
|
||||
uint16 xkeymap_translate_button(unsigned int button);
|
||||
char *get_ksname(uint32 keysym);
|
||||
void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
|
||||
void reset_modifier_keys(void);
|
||||
void rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode);
|
||||
void reset_modifier_keys(unsigned int state);
|
||||
void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
|
||||
/* xwin.c */
|
||||
BOOL get_key_state(int keysym);
|
||||
BOOL get_key_state(uint32 keysym, unsigned int state);
|
||||
BOOL ui_init(void);
|
||||
void ui_deinit(void);
|
||||
BOOL ui_create_window(void);
|
||||
|
26
xkeymap.c
26
xkeymap.c
@ -40,7 +40,7 @@ static key_translation keymap[KEYMAP_SIZE];
|
||||
static int min_keycode;
|
||||
static uint16 remote_modifier_state = 0;
|
||||
|
||||
static void update_modifier_state(uint16 modifiers, BOOL pressed);
|
||||
static void update_modifier_state(uint8 scancode, BOOL pressed);
|
||||
|
||||
static void
|
||||
add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname)
|
||||
@ -214,12 +214,12 @@ xkeymap_init(void)
|
||||
/* Handles, for example, multi-scancode keypresses (which is not
|
||||
possible via keymap-files) */
|
||||
BOOL
|
||||
handle_special_keys(uint32 keysym, uint32 ev_time, BOOL pressed)
|
||||
handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed)
|
||||
{
|
||||
switch (keysym)
|
||||
{
|
||||
case XK_Break:
|
||||
if (get_key_state(XK_Alt_L) || get_key_state(XK_Alt_R))
|
||||
if (get_key_state(state, XK_Alt_L) || get_key_state(state, XK_Alt_R))
|
||||
{
|
||||
/* toggle full screen */
|
||||
if (pressed)
|
||||
@ -471,35 +471,35 @@ ensure_remote_modifiers(uint32 ev_time, key_translation tr)
|
||||
|
||||
|
||||
void
|
||||
reset_modifier_keys(void)
|
||||
reset_modifier_keys(unsigned int state)
|
||||
{
|
||||
/* reset keys */
|
||||
uint32 ev_time;
|
||||
ev_time = time(NULL);
|
||||
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(XK_Shift_L))
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask) && !get_key_state(state, XK_Shift_L))
|
||||
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
|
||||
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(XK_Shift_R))
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapRightShiftMask) && !get_key_state(state, XK_Shift_R))
|
||||
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
|
||||
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(XK_Control_L))
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapLeftCtrlMask) && !get_key_state(state, XK_Control_L))
|
||||
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
|
||||
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(XK_Control_R))
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapRightCtrlMask) && !get_key_state(state, XK_Control_R))
|
||||
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RCTRL);
|
||||
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(XK_Alt_L))
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapLeftAltMask) && !get_key_state(state, XK_Alt_L))
|
||||
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
|
||||
|
||||
if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) &&
|
||||
!get_key_state(XK_Alt_R) && !get_key_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);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_modifier_state(uint16 modifiers, BOOL pressed)
|
||||
update_modifier_state(uint8 scancode, BOOL pressed)
|
||||
{
|
||||
#ifdef WITH_DEBUG_KBD
|
||||
uint16 old_modifier_state;
|
||||
@ -507,7 +507,7 @@ update_modifier_state(uint16 modifiers, BOOL pressed)
|
||||
old_modifier_state = remote_modifier_state;
|
||||
#endif
|
||||
|
||||
switch (modifiers)
|
||||
switch (scancode)
|
||||
{
|
||||
case SCANCODE_CHAR_LSHIFT:
|
||||
MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
|
||||
@ -561,7 +561,7 @@ update_modifier_state(uint16 modifiers, BOOL pressed)
|
||||
|
||||
/* Send keyboard input */
|
||||
void
|
||||
rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode)
|
||||
rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode)
|
||||
{
|
||||
update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));
|
||||
|
||||
|
59
xwin.c
59
xwin.c
@ -42,6 +42,7 @@ static int depth;
|
||||
static int bpp;
|
||||
static XIM IM;
|
||||
static XIC IC;
|
||||
static XModifierKeymap *mod_map;
|
||||
static Cursor current_cursor;
|
||||
|
||||
/* endianness */
|
||||
@ -183,15 +184,11 @@ translate_colour(uint32 colour)
|
||||
}
|
||||
|
||||
BOOL
|
||||
get_key_state(int keysym)
|
||||
get_key_state(uint32 keysym, unsigned int state)
|
||||
{
|
||||
int keysymMask = 0, modifierpos, key;
|
||||
Window wDummy1, wDummy2;
|
||||
int iDummy3, iDummy4, iDummy5, iDummy6;
|
||||
unsigned int current_state;
|
||||
int modifierpos, key, keysymMask = 0;
|
||||
int offset;
|
||||
|
||||
XModifierKeymap *map = XGetModifierMapping(display);
|
||||
KeyCode keycode = XKeysymToKeycode(display, keysym);
|
||||
|
||||
if (keycode == NoSymbol)
|
||||
@ -199,21 +196,16 @@ get_key_state(int keysym)
|
||||
|
||||
for (modifierpos = 0; modifierpos < 8; modifierpos++)
|
||||
{
|
||||
offset = map->max_keypermod * modifierpos;
|
||||
offset = mod_map->max_keypermod * modifierpos;
|
||||
|
||||
for (key = 0; key < map->max_keypermod; key++)
|
||||
for (key = 0; key < mod_map->max_keypermod; key++)
|
||||
{
|
||||
if (map->modifiermap[offset + key] == keycode)
|
||||
keysymMask = 1 << modifierpos;
|
||||
if (mod_map->modifiermap[offset + key] == keycode)
|
||||
keysymMask |= 1 << modifierpos;
|
||||
}
|
||||
}
|
||||
|
||||
XQueryPointer(display, DefaultRootWindow(display), &wDummy1,
|
||||
&wDummy2, &iDummy3, &iDummy4, &iDummy5, &iDummy6, ¤t_state);
|
||||
|
||||
XFreeModifiermap(map);
|
||||
|
||||
return (current_state & keysymMask) ? True : False;
|
||||
return (state & keysymMask) ? True : False;
|
||||
}
|
||||
|
||||
BOOL
|
||||
@ -286,6 +278,8 @@ ui_init(void)
|
||||
XFillRectangle(display, backstore, gc, 0, 0, width, height);
|
||||
}
|
||||
|
||||
mod_map = XGetModifierMapping(display);
|
||||
|
||||
if (enable_compose)
|
||||
IM = XOpenIM(display, NULL, NULL, NULL);
|
||||
|
||||
@ -299,6 +293,8 @@ ui_deinit(void)
|
||||
if (IM != NULL)
|
||||
XCloseIM(IM);
|
||||
|
||||
XFreeModifierMap(mod_map);
|
||||
|
||||
if (ownbackstore)
|
||||
XFreePixmap(display, backstore);
|
||||
|
||||
@ -425,9 +421,11 @@ xwin_process_events(void)
|
||||
uint16 button, flags;
|
||||
uint32 ev_time;
|
||||
key_translation tr;
|
||||
char *ksname = NULL;
|
||||
char str[256];
|
||||
Status status;
|
||||
unsigned int state;
|
||||
Window wdummy;
|
||||
int dummy;
|
||||
|
||||
while (XPending(display) > 0)
|
||||
{
|
||||
@ -439,7 +437,6 @@ xwin_process_events(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
ev_time = time(NULL);
|
||||
flags = 0;
|
||||
|
||||
switch (xevent.type)
|
||||
@ -466,10 +463,10 @@ xwin_process_events(void)
|
||||
str, sizeof(str), &keysym, NULL);
|
||||
}
|
||||
|
||||
ksname = get_ksname(keysym);
|
||||
DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym, ksname));
|
||||
DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)));
|
||||
|
||||
if (handle_special_keys(keysym, ev_time, True))
|
||||
ev_time = time(NULL);
|
||||
if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
|
||||
break;
|
||||
|
||||
tr = xkeymap_translate_key(keysym,
|
||||
@ -482,15 +479,16 @@ xwin_process_events(void)
|
||||
|
||||
rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
|
||||
break;
|
||||
|
||||
case KeyRelease:
|
||||
XLookupString((XKeyEvent *) & xevent, str,
|
||||
sizeof(str), &keysym, NULL);
|
||||
|
||||
ksname = get_ksname(keysym);
|
||||
DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", keysym,
|
||||
ksname));
|
||||
get_ksname(keysym)));
|
||||
|
||||
if (handle_special_keys(keysym, ev_time, False))
|
||||
ev_time = time(NULL);
|
||||
if (handle_special_keys(keysym, xevent.xkey.state, ev_time, False))
|
||||
break;
|
||||
|
||||
tr = xkeymap_translate_key(keysym,
|
||||
@ -511,17 +509,18 @@ xwin_process_events(void)
|
||||
if (button == 0)
|
||||
break;
|
||||
|
||||
rdp_send_input(ev_time, RDP_INPUT_MOUSE,
|
||||
rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
|
||||
flags | button, xevent.xbutton.x, xevent.xbutton.y);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
rdp_send_input(ev_time, RDP_INPUT_MOUSE,
|
||||
rdp_send_input(time(NULL), RDP_INPUT_MOUSE,
|
||||
MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
reset_modifier_keys();
|
||||
XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
||||
reset_modifier_keys(state);
|
||||
if (grab_keyboard)
|
||||
XGrabKeyboard(display, wnd, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
@ -546,6 +545,12 @@ xwin_process_events(void)
|
||||
if (xevent.xmapping.request == MappingKeyboard
|
||||
|| xevent.xmapping.request == MappingModifier)
|
||||
XRefreshKeyboardMapping(&xevent.xmapping);
|
||||
|
||||
if (xevent.xmapping.request == MappingModifier)
|
||||
{
|
||||
XFreeModifierMap(mod_map);
|
||||
mod_map = XGetModifierMapping(display);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user