diff --git a/keys.c b/keys.c index 9b79389..bcf1a3a 100644 --- a/keys.c +++ b/keys.c @@ -463,3 +463,82 @@ start_command_key (Keys_t * key) run_command (key->command); } + +void +send_key_event (Display* dpy, Keys_t* key) +{ + XKeyEvent k_event; + Window winFocus; + int revert; + XButtonEvent b_event; + Window queryRoot; + Window queryW; + int queryRootX, queryRootY, queryX, queryY; + unsigned int query_mask; + + XGetInputFocus(dpy, &winFocus, &revert); + + if (key->type == BUTTON) { + XQueryPointer(dpy, winFocus, &queryRoot, &queryW, &queryRootX, &queryRootY, &queryX, &queryY, &query_mask); + b_event.display = dpy; + b_event.window = winFocus; + b_event.root = queryRoot; + b_event.subwindow = None; + b_event.time = CurrentTime; + b_event.x = queryX; + b_event.y = queryY; + b_event.x_root = queryRootX; + b_event.y_root = queryRootY; + b_event.same_screen = True; + b_event.button = key->key.button; + b_event.state = key->modifier; + + if (key->event_type == PRESS) + { + b_event.type = ButtonPress; + XSendEvent(dpy, winFocus, True, ButtonPressMask, (XEvent*)&b_event); + } else if (key->event_type == RELEASE) + { + b_event.type = ButtonRelease; + XSendEvent(dpy, winFocus, True, ButtonReleaseMask, (XEvent*)&b_event); + } + XFlush(dpy); + return; + } + + + k_event.display = dpy; + k_event.window = winFocus; + k_event.root = XDefaultRootWindow(dpy); + k_event.subwindow = None; + k_event.time = CurrentTime; + k_event.x = 1; + k_event.y = 1; + k_event.x_root = 1; + k_event.y_root = 1; + k_event.same_screen = True; + + if (key->type == SYM) + { + k_event.keycode = XKeysymToKeycode(dpy, key->key.sym); + } + else + { + k_event.keycode = key->key.code; + } + + k_event.state = key->modifier; + + if (key->event_type == PRESS) + { + k_event.type = KeyPress; + XSendEvent(dpy, winFocus, True, KeyPressMask, (XEvent*)&k_event); + } + else if (key->event_type == RELEASE) + { + k_event.type = KeyRelease; + XSendEvent(dpy, winFocus, True, KeyReleaseMask, (XEvent*)&k_event); + } + XFlush(dpy); + +} \ No newline at end of file diff --git a/keys.h b/keys.h index 5d09801..39e65ee 100644 --- a/keys.h +++ b/keys.h @@ -87,6 +87,7 @@ extern void modifier_to_string (unsigned int modifier, char *str); extern void run_command (char * command); +extern void send_key_event(Display* dpy, Keys_t* key); extern int nb_keys; extern Keys_t *keys; diff --git a/options.c b/options.c index 7257091..ac22e78 100644 --- a/options.c +++ b/options.c @@ -60,6 +60,7 @@ SCM xbindkey_wrapper(SCM key, SCM cmd); SCM xbindkey_function_wrapper(SCM key, SCM fun); SCM remove_xbindkey_wrapper(SCM key); SCM run_command_wrapper (SCM command); +SCM send_key_event_wrapper(SCM key); SCM grab_all_keys_wrapper (void); SCM ungrab_all_keys_wrapper (void); SCM remove_all_keys_wrapper (void); @@ -837,6 +838,7 @@ init_xbk_guile_fns (void) scm_c_define_gsubr("xbindkey", 2, 0, 0, xbindkey_wrapper); scm_c_define_gsubr("xbindkey-function", 2, 0, 0, xbindkey_function_wrapper); scm_c_define_gsubr("remove-xbindkey", 1, 0, 0, remove_xbindkey_wrapper); + scm_c_define_gsubr("send-key-event", 1, 0, 0, send_key_event_wrapper); scm_c_define_gsubr("run-command", 1, 0, 0, run_command_wrapper); scm_c_define_gsubr("grab-all-keys", 0, 0, 0, grab_all_keys_wrapper); scm_c_define_gsubr("ungrab-all-keys", 0, 0, 0, ungrab_all_keys_wrapper); @@ -1101,6 +1103,41 @@ SCM remove_xbindkey_wrapper (SCM key) return SCM_UNSPECIFIED; } +SCM send_key_event_wrapper (SCM key) +{ + Keys_t k; + KeyType_t type = SYM; + EventType_t event_type = PRESS; + KeySym keysym = 0; + KeyCode keycode = 0; + unsigned int button = 0; + unsigned int modifier = 0; + + if (extract_key (key, &type, &event_type, &keysym, &keycode, + &button, &modifier) == SCM_BOOL_F) + { + return SCM_BOOL_F; + } + + if (type == SYM) + { + set_keysym (&k, event_type, keysym, modifier, NULL, NULL); + } + else if (type == BUTTON) + { + set_button (&k, event_type, button, modifier, NULL, NULL); + } + else + { + set_keycode (&k, event_type, keycode, modifier, NULL, NULL); + } + + send_key_event(current_display, &k); + + return SCM_UNSPECIFIED; + +} + SCM run_command_wrapper (SCM command) {