[openbox] Sending fake input events
Gary Scharf
gscharf at getwellnetwork.com
Wed Dec 27 10:38:03 EST 2006
FWIW, we use this to good effect.
Note that the window to which you intend the send the event must have focus.
--------------------------------------------------[begin code]--------------------------------------
/*
* XSendKey -
*
* C program to send a key event to an X window specified by its handle.
*
* Usage:
* xsendkey windowId keysym
*
* Compilation (provided the linker can find libX11, or use -L/path_to_Xlibs):
* (g)cc xsendkey.c -o xsendkey -lX11
*
* Copyright 1997 Alex Safonov, safo... at cs.umn.edu.
*
* Based on the code posted to comp.windows.x by Kevin Lyda
* (k... at parsley.faxinter.com), whose question inspired me to write this.
*
* This code can be freely distributed and modified provided that this whole
* statement is unchanged and distributed with it.
*
* NO WARRANTY: use at your own risk. If you compile this program and it
* burns your monitor and crashes your hard disk heads, you can't sue me.
*
* $Id: xsendkey.c,v 1.2 2006/10/06 01:10:21 rcavanaugh Exp $
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/cursorfont.h>
#include <X11/Xos.h>
#include <X11/keysym.h>
#define BUFLEN 64
int isModifier(KeySym k) {
switch (k) {
case XK_Shift_L:
case XK_Shift_R:
case XK_Control_L:
case XK_Control_R:
case XK_Caps_Lock:
case XK_Shift_Lock:
case XK_Meta_L:
case XK_Meta_R:
case XK_Alt_L:
case XK_Alt_R:
case XK_Super_L:
case XK_Super_R:
case XK_Hyper_L:
case XK_Hyper_R:
return -1;
default:
break;
}
return 0;
}
int getModifierMask(KeySym k) {
switch (k) {
case XK_Shift_L:
case XK_Shift_R:
return ShiftMask;
case XK_Control_L:
case XK_Control_R:
return ControlMask;
case XK_Alt_L:
case XK_Alt_R:
return Mod1Mask;
case XK_Caps_Lock:
case XK_Shift_Lock:
case XK_Meta_L:
case XK_Meta_R:
case XK_Super_L:
case XK_Super_R:
case XK_Hyper_L:
case XK_Hyper_R:
default:
break;
}
return 0;
}
int main(int argc, char* argv[]) {
Display *display;
Window window;
int xerr;
XEvent xkey;
char ksBuf[BUFLEN];
KeySym keysym;
int statemask = 0;
if (argc != 3) {
fprintf(stderr, "Usage: %s windowId keySym\n", argv[0]);
exit(2);
}
if (sscanf(argv[1], "%lx", &window) != 1) {
fprintf(stderr, "Invalid windowId %s\n", argv[1]);
exit(2);
}
if ((display = XOpenDisplay(":0")) == NULL) {
printf("failed to open display\n");
exit(2);
}
char sepchar[2]=" +";
char *curkey = strtok(argv[2], sepchar);
do {
keysym = XStringToKeysym(curkey);
if (keysym == NoSymbol) {
fprintf(stderr, "Invalid keysym %s\n", curkey);
XCloseDisplay(display);
exit(2);
} else {
if(isModifier(keysym) == -1) {
xkey.xkey.state = getModifierMask(keysym);
} else {
xkey.xkey.keycode = XKeysymToKeycode(display, keysym);
}
}
} while( ( curkey = strtok(NULL, sepchar)) != NULL ) ;
xkey.xkey.state |= statemask;
xkey.type = KeyPress;
xkey.xkey.type = KeyPress;
xkey.xkey.display = display;
xkey.xkey.window = window;
xkey.xkey.subwindow = None;
xkey.xkey.x = xkey.xkey.y = xkey.xkey.x_root = xkey.xkey.y_root = 0;
xkey.xkey.same_screen = True;
xkey.xkey.root = DefaultRootWindow(display);
if ((xerr = XSendEvent(display, window, 0, False, &xkey)) == 0) {
printf("%s: failed to send (return code %d).\n", argv[0], xerr);
exit(1);
}
xkey.type = KeyRelease;
xkey.xkey.type = KeyRelease;
if ((xerr = XSendEvent(display, window, 0, False, &xkey)) == 0) {
printf("%s: failed to send (return code %d).\n", argv[0], xerr);
exit(1);
}
XFlush(display);
XCloseDisplay(display);
}
--------------------------------------------------[end code]-----------------------------------------
________________________________
From: Mikael Magnusson [mailto:mangosoft at comhem.se]
Sent: Fri 12/22/2006 8:32 PM
To: openbox at icculus.org
Subject: Re: [openbox] Sending fake input events
On Fri, 22 Dec 2006, Kre?imir ?pes wrote:
> I'm using different keyboard shortcuts for copy\paste and since many
> apps have C-c & C-v hardcoded, I was thinking of faking input events.
>
> eg. when I press C-u, openbox or X catches it and translates to C-c.
>
> I have accomplished this by writing a small C program that uses the Xtst
> extension, but it's not performing too well;
>
> Is there a different (better) way to address this issue?
>
> Also, I'd like to use this oppertunity to ask if anyone knows how to
> send fake char events? I need to use some non ascii chars and I dont
> like switching between keyboard layouts to be able to use them;
You can use the ~/.XCompose file for this. (note both the X and the C is
big). An example entry is
include "%L" # this always goes on the first line
<Multi_key> <e> <u> <r> : "result string goes here"
--
Mikael Magnusson
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/ms-tnef
Size: 13252 bytes
Desc: not available
URL: <http://icculus.org/pipermail/openbox/attachments/20061227/afbdbccc/attachment.bin>
More information about the openbox
mailing list