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); void tcp_disconnect(void);
/* xkeymap.c */ /* xkeymap.c */
void xkeymap_init(void); 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); key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
uint16 xkeymap_translate_button(unsigned int button); uint16 xkeymap_translate_button(unsigned int button);
char *get_ksname(uint32 keysym); char *get_ksname(uint32 keysym);
void ensure_remote_modifiers(uint32 ev_time, key_translation tr); void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
void reset_modifier_keys(void); void reset_modifier_keys(unsigned int state);
void rdp_send_scancode(uint32 time, uint16 flags, uint16 scancode); void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
/* xwin.c */ /* xwin.c */
BOOL get_key_state(int keysym); BOOL get_key_state(uint32 keysym, unsigned int state);
BOOL ui_init(void); BOOL ui_init(void);
void ui_deinit(void); void ui_deinit(void);
BOOL ui_create_window(void); BOOL ui_create_window(void);

View File

@ -40,7 +40,7 @@ static key_translation keymap[KEYMAP_SIZE];
static int min_keycode; static int min_keycode;
static uint16 remote_modifier_state = 0; 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 static void
add_to_keymap(char *keyname, uint8 scancode, uint16 modifiers, char *mapname) 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 /* Handles, for example, multi-scancode keypresses (which is not
possible via keymap-files) */ possible via keymap-files) */
BOOL 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) switch (keysym)
{ {
case XK_Break: 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 */ /* toggle full screen */
if (pressed) if (pressed)
@ -471,35 +471,35 @@ ensure_remote_modifiers(uint32 ev_time, key_translation tr)
void void
reset_modifier_keys(void) reset_modifier_keys(unsigned int state)
{ {
/* reset keys */ /* reset keys */
uint32 ev_time; uint32 ev_time;
ev_time = time(NULL); 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); 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); 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); 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); 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); rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LALT);
if (MASK_HAS_BITS(remote_modifier_state, MapRightAltMask) && 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); rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
} }
static void static void
update_modifier_state(uint16 modifiers, BOOL pressed) update_modifier_state(uint8 scancode, BOOL pressed)
{ {
#ifdef WITH_DEBUG_KBD #ifdef WITH_DEBUG_KBD
uint16 old_modifier_state; uint16 old_modifier_state;
@ -507,7 +507,7 @@ update_modifier_state(uint16 modifiers, BOOL pressed)
old_modifier_state = remote_modifier_state; old_modifier_state = remote_modifier_state;
#endif #endif
switch (modifiers) switch (scancode)
{ {
case SCANCODE_CHAR_LSHIFT: case SCANCODE_CHAR_LSHIFT:
MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed); MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
@ -561,7 +561,7 @@ update_modifier_state(uint16 modifiers, BOOL pressed)
/* Send keyboard input */ /* Send keyboard input */
void 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)); update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));

59
xwin.c
View File

@ -42,6 +42,7 @@ static int depth;
static int bpp; static int bpp;
static XIM IM; static XIM IM;
static XIC IC; static XIC IC;
static XModifierKeymap *mod_map;
static Cursor current_cursor; static Cursor current_cursor;
/* endianness */ /* endianness */
@ -183,15 +184,11 @@ translate_colour(uint32 colour)
} }
BOOL BOOL
get_key_state(int keysym) get_key_state(uint32 keysym, unsigned int state)
{ {
int keysymMask = 0, modifierpos, key; int modifierpos, key, keysymMask = 0;
Window wDummy1, wDummy2;
int iDummy3, iDummy4, iDummy5, iDummy6;
unsigned int current_state;
int offset; int offset;
XModifierKeymap *map = XGetModifierMapping(display);
KeyCode keycode = XKeysymToKeycode(display, keysym); KeyCode keycode = XKeysymToKeycode(display, keysym);
if (keycode == NoSymbol) if (keycode == NoSymbol)
@ -199,21 +196,16 @@ get_key_state(int keysym)
for (modifierpos = 0; modifierpos < 8; modifierpos++) 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) if (mod_map->modifiermap[offset + key] == keycode)
keysymMask = 1 << modifierpos; keysymMask |= 1 << modifierpos;
} }
} }
XQueryPointer(display, DefaultRootWindow(display), &wDummy1, return (state & keysymMask) ? True : False;
&wDummy2, &iDummy3, &iDummy4, &iDummy5, &iDummy6, &current_state);
XFreeModifiermap(map);
return (current_state & keysymMask) ? True : False;
} }
BOOL BOOL
@ -286,6 +278,8 @@ ui_init(void)
XFillRectangle(display, backstore, gc, 0, 0, width, height); XFillRectangle(display, backstore, gc, 0, 0, width, height);
} }
mod_map = XGetModifierMapping(display);
if (enable_compose) if (enable_compose)
IM = XOpenIM(display, NULL, NULL, NULL); IM = XOpenIM(display, NULL, NULL, NULL);
@ -299,6 +293,8 @@ ui_deinit(void)
if (IM != NULL) if (IM != NULL)
XCloseIM(IM); XCloseIM(IM);
XFreeModifierMap(mod_map);
if (ownbackstore) if (ownbackstore)
XFreePixmap(display, backstore); XFreePixmap(display, backstore);
@ -425,9 +421,11 @@ xwin_process_events(void)
uint16 button, flags; uint16 button, flags;
uint32 ev_time; uint32 ev_time;
key_translation tr; key_translation tr;
char *ksname = NULL;
char str[256]; char str[256];
Status status; Status status;
unsigned int state;
Window wdummy;
int dummy;
while (XPending(display) > 0) while (XPending(display) > 0)
{ {
@ -439,7 +437,6 @@ xwin_process_events(void)
continue; continue;
} }
ev_time = time(NULL);
flags = 0; flags = 0;
switch (xevent.type) switch (xevent.type)
@ -466,10 +463,10 @@ xwin_process_events(void)
str, sizeof(str), &keysym, NULL); str, sizeof(str), &keysym, NULL);
} }
ksname = get_ksname(keysym); DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym, get_ksname(keysym)));
DEBUG_KBD(("KeyPress for (keysym 0x%lx, %s)\n", keysym, ksname));
if (handle_special_keys(keysym, ev_time, True)) ev_time = time(NULL);
if (handle_special_keys(keysym, xevent.xkey.state, ev_time, True))
break; break;
tr = xkeymap_translate_key(keysym, tr = xkeymap_translate_key(keysym,
@ -482,15 +479,16 @@ xwin_process_events(void)
rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode); rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
break; break;
case KeyRelease: case KeyRelease:
XLookupString((XKeyEvent *) & xevent, str, XLookupString((XKeyEvent *) & xevent, str,
sizeof(str), &keysym, NULL); sizeof(str), &keysym, NULL);
ksname = get_ksname(keysym);
DEBUG_KBD(("\nKeyRelease for (keysym 0x%lx, %s)\n", 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; break;
tr = xkeymap_translate_key(keysym, tr = xkeymap_translate_key(keysym,
@ -511,17 +509,18 @@ xwin_process_events(void)
if (button == 0) if (button == 0)
break; 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); flags | button, xevent.xbutton.x, xevent.xbutton.y);
break; break;
case MotionNotify: 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); MOUSE_FLAG_MOVE, xevent.xmotion.x, xevent.xmotion.y);
break; break;
case FocusIn: case FocusIn:
reset_modifier_keys(); XQueryPointer(display, wnd, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
reset_modifier_keys(state);
if (grab_keyboard) if (grab_keyboard)
XGrabKeyboard(display, wnd, True, XGrabKeyboard(display, wnd, True,
GrabModeAsync, GrabModeAsync, CurrentTime); GrabModeAsync, GrabModeAsync, CurrentTime);
@ -546,6 +545,12 @@ xwin_process_events(void)
if (xevent.xmapping.request == MappingKeyboard if (xevent.xmapping.request == MappingKeyboard
|| xevent.xmapping.request == MappingModifier) || xevent.xmapping.request == MappingModifier)
XRefreshKeyboardMapping(&xevent.xmapping); XRefreshKeyboardMapping(&xevent.xmapping);
if (xevent.xmapping.request == MappingModifier)
{
XFreeModifierMap(mod_map);
mod_map = XGetModifierMapping(display);
}
break; break;
} }