Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Emulating key/mouse presses

Sun Apr 07, 2013 6:48 pm

I want to make a program that, among others, makes the computer think a key's been pressed. Googull has not helped at all (I want it to be pressed AND HELD DOWN, I've only found worthwhile documentation on simply pressing without holding down the key and this horrible thing), and this place is my Plan B if I come across something I don't know how to do (Plan A being Google).

User avatar
jojopi
Posts: 3233
Joined: Tue Oct 11, 2011 8:38 pm

Re: Emulating key/mouse presses

Sun Apr 07, 2013 8:03 pm

What is the application that you are trying to fool, and is there not a better way to control it than by faking input? It simply makes no sense to hold a key down without regard to what programs are running.

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Sun Apr 07, 2013 8:37 pm

http://gallery.earthtools.ca/download/ventctl.tar

i used this program many years ago to do something similar, it has 2 parts

first part opens /dev/input/x, and sniffs the keyboard for a hotkey like shift (remove this code)
the second part uses x11 api's to find the ventrilo window, and fake the A key being pushed or released (reuse this code)

that would work for any X11 (gui) app you wanted to poke keys at

its basicaly just this

Code: Select all

display = XOpenDisplay(0);
window = XDefaultRootWindow(display);
windowVentrilo = find_window(display, window, VENTRILO);
unsigned int simulatekey = XKeysymToKeycode(display, SIMULATEKEY);
...
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *) &event);
or
XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *) &event);

XFlush(display);
oh, and this is the python forum, *facepalm*, could still be usefull

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Mon Apr 08, 2013 6:40 am

cleverca22 wrote:http://gallery.earthtools.ca/download/ventctl.tar

i used this program many years ago to do something similar, it has 2 parts

first part opens /dev/input/x, and sniffs the keyboard for a hotkey like shift (remove this code)
the second part uses x11 api's to find the ventrilo window, and fake the A key being pushed or released (reuse this code)

that would work for any X11 (gui) app you wanted to poke keys at

its basicaly just this

Code: Select all

display = XOpenDisplay(0);
window = XDefaultRootWindow(display);
windowVentrilo = find_window(display, window, VENTRILO);
unsigned int simulatekey = XKeysymToKeycode(display, SIMULATEKEY);
...
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *) &event);
or
XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *) &event);

XFlush(display);
oh, and this is the python forum, *facepalm*, could still be usefull
Hang on, is that C or something? Just guessing that because of all the semicolons. I think I might keep this in mind in case I ever learn any C.

Also my first priority with OS support for this program is getting it to work on Windows (yeah I know this is the Pi forum but yeah)

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Mon Apr 08, 2013 7:36 pm

I found I hadn't used the right Google search terms. >.<

Code: Select all

import win32api#forget this and die
win32api.keybd_event(keycode, 0, 0, 0)#down
win32api.keybd_event(keycode, 0, 2, 0)#up
This only works for Windows, so I feel we should keep this thread open in case someone finds a way to do it on other osses (that word has to be a thing).

User avatar
jojopi
Posts: 3233
Joined: Tue Oct 11, 2011 8:38 pm

Re: Emulating key/mouse presses

Mon Apr 08, 2013 9:50 pm

Mario-Fan wrote:This only works for Windows, so I feel we should keep this thread open in case someone finds a way to do it on other osses (that word has to be a thing).
The best method depends not only on the operating system but also on the program to be fooled. For instance, spoofing X events to a specific window or storing input to a specific terminal is much safer than spoofing kernel input events. But each of these only works with the right type of application.

Also, on Linux you typically have the source code for everything, so hacking remote control into an existing program is technically much easier. And there is redirection and LD_PRELOAD.

Most importantly though, nobody ever wants to "press and hold a key, with no regard to what the user is doing at the time" (except perhaps if they are writing anti-social malware). Almost always they want to "do the thing that application Z will do for me, but the only way I know to tell it is to hold a key".

Making some assumptions and concealing your real intention may get you a worse solution than asking your actual problem. Or none at all.

User avatar
aTao
Posts: 1093
Joined: Wed Dec 12, 2012 10:41 am
Location: Howlin Eigg

Re: Emulating key/mouse presses

Mon Apr 08, 2013 10:03 pm

*Dons flame proof coat*
Java has a "Robot" class which will do exactly that, it can read a bitmap of the screen and generate and send keyboard and mouse events to any open window.
>)))'><'(((<

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Tue Apr 09, 2013 3:48 am

the c code may be usefull as a hint, to point out what functions to use in a python lib (if one exists), and it could also be used for making your own python lib, or a simple c program that takes orders from python
jojopi wrote: Most importantly though, nobody ever wants to "press and hold a key, with no regard to what the user is doing at the time" (except perhaps if they are writing anti-social malware). Almost always they want to "do the thing that application Z will do for me, but the only way I know to tell it is to hold a key".
i can see it being usefull to turn the GPIO inputs into a keyboard (with a limited number of keys)
need to send separate push and release events, so holding a real button still works right

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Tue Apr 09, 2013 6:42 am

jojopi wrote:
Mario-Fan wrote:Making some assumptions and concealing your real intention may get you a worse solution than asking your actual problem. Or none at all.
Since you seem to ask, I'm making a thing that basically does netplay on games where the only multiplayer mode is on the same machine. For lack of a better name, I'm calling it "Local Netplay."
EDIT: I found out that the method I found isn't actually the best one. :?
EDIT 2: I found another thing that looks more promising. http://mail.python.org/pipermail/tutor/ ... 50042.html
EDIT 3: And now to attempt to understand how it works. :|

forumisto
Posts: 386
Joined: Fri Mar 16, 2012 8:41 am

Re: Emulating key/mouse presses

Tue Apr 09, 2013 10:30 am

In the X environment, you can use the Robot class of Java

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Sat Apr 13, 2013 6:37 am

http://www.raspberrypi.org/phpBB3/viewt ... 48#p219638

this code looks like it may also be of use

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Sat Apr 13, 2013 6:51 pm

cleverca22 wrote:http://gallery.earthtools.ca/download/ventctl.tar

i used this program many years ago to do something similar, it has 2 parts

first part opens /dev/input/x, and sniffs the keyboard for a hotkey like shift (remove this code)
the second part uses x11 api's to find the ventrilo window, and fake the A key being pushed or released (reuse this code)

that would work for any X11 (gui) app you wanted to poke keys at

its basicaly just this

Code: Select all

display = XOpenDisplay(0);
window = XDefaultRootWindow(display);
windowVentrilo = find_window(display, window, VENTRILO);
unsigned int simulatekey = XKeysymToKeycode(display, SIMULATEKEY);
...
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *) &event);
or
XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *) &event);

XFlush(display);
oh, and this is the python forum, *facepalm*, could still be usefull
I just remembered that you can run C code in Python. So I can use this, but I have little to no knowledge of C (I can barely read basic programs since both Lua and Python are based off it) and don't really know what to do.

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Sun Apr 14, 2013 7:36 am

how do you run c code in python?, if i had an example i could make the above code work in it

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Sun Apr 14, 2013 7:50 am

cleverca22 wrote:how do you run c code in python?, if i had an example i could make the above code work in it
Supposedly all you have to do is import it, but I don't seem to be able to import the code right away. I think you need to #include <Python.h> first, according to this.

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Sun Apr 14, 2013 10:13 am

ive always been wanting to try out that part of python

https://github.com/cleverca22/xorg

the code in this repo will find any window that has 'Event' in the title bar (like xev, or just edit it to the name of your text editor for testing)

then it will simply send these keys, a, space, b, c, and backspace
each one is a separate press and release call, so you can hold it if you need to

most of the error checking is missing, and it doesn't send proper python exceptions, but it works

(i only tested it on my laptop, but it shouldnt be any different on a pi)

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Sun Apr 14, 2013 11:13 am

cleverca22 wrote:ive always been wanting to try out that part of python

https://github.com/cleverca22/xorg

the code in this repo will find any window that has 'Event' in the title bar (like xev, or just edit it to the name of your text editor for testing)

then it will simply send these keys, a, space, b, c, and backspace
each one is a separate press and release call, so you can hold it if you need to

most of the error checking is missing, and it doesn't send proper python exceptions, but it works

(i only tested it on my laptop, but it shouldnt be any different on a pi)
This will probably do the job, thanks. :D
One question though.
Image
Does this mean I have to compile it on the Pi itself?

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Sun Apr 14, 2013 11:33 am

yeah, its using Xorg headers, which simply wont exist on the windows pc, and if you did manage to compile it on windows, it would become a windows-only lib

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Mon Apr 15, 2013 3:03 pm

cleverca22 wrote:yeah, its using Xorg headers, which simply wont exist on the windows pc, and if you did manage to compile it on windows, it would become a windows-only lib
By the way, does this work on other Linux desktop environments like GNOME?

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Mon Apr 15, 2013 3:31 pm

yep, i was testing it on firefox and gedit, it should work on ANY x program, but i noticed it doesnt work on xterm

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Mon Apr 15, 2013 3:40 pm

cleverca22 wrote:yep, i was testing it on firefox and gedit, it should work on ANY x program, but i noticed it doesnt work on xterm
I mean, LXDE is a desktop environment. Does it work on GNOME, which is also a desktop environment?

User avatar
jojopi
Posts: 3233
Joined: Tue Oct 11, 2011 8:38 pm

Re: Emulating key/mouse presses

Mon Apr 15, 2013 4:11 pm

cleverca22 wrote:yep, i was testing it on firefox and gedit, it should work on ANY x program, but i noticed it doesnt work on xterm
For xterm you will need Ctrl+LeftClick "Allow SendEvents", or the corresponding resource.

It is actually not uncommon for clients to ignore synthetic events. One solution is LD_PRELOAD: http://www.semicomplete.com/blog/tags/xsendevent

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Mon Apr 15, 2013 4:51 pm

ahhh, nice

and that must mean synergy uses something else, because its never run into that issue with xterm

Mario-Fan
Posts: 32
Joined: Fri Dec 28, 2012 2:34 pm

Re: Emulating key/mouse presses

Tue Apr 16, 2013 3:31 pm

So I tried the stuff out. I downloaded python-dev and ran the command.

Code: Select all

Mario-Fan@raspberrypi ~/Local Netplay $ python setup.py build
running build
running build_ext
building 'xorg' extension
creating build
creating build/temp.linux-armv6l-2.7
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c xorg.c -o build/temp.linux-armv6l-2.7/xorg.o
xorg.c:2:22: fatal error: X11/Xlib.h: No such file or directory
compilation terminated.
error: command 'gcc' failed with exit status 1
Mario-Fan@raspberrypi ~/Local Netplay $ 

User avatar
PeterO
Posts: 5829
Joined: Sun Jul 22, 2012 4:14 pm

Re: Emulating key/mouse presses

Tue Apr 16, 2013 3:38 pm

Can't really investigate this now, but you should be able to write to the files in /dev/input/ to feed events into the input streams.
I've only read from them so far to pick up keyboard press/release events and mouse motion events for some openGL ES applications. A quick google suggests they can be written to as well.

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

cleverca22
Posts: 581
Joined: Sat Aug 18, 2012 2:33 pm

Re: Emulating key/mouse presses

Tue Apr 16, 2013 4:26 pm

looks like it also requires libx11-dev to be installed

Return to “Python”