[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