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:
Matt Chapman 2002-09-26 14:04:30 +00:00
parent c6038854b1
commit b46de1c760
3 changed files with 49 additions and 44 deletions

View File

@ -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);

View File

@ -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
View File

@ -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, &current_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;
}