Keyboard input emulation...

Hi guys,

I’m on Debian 5.0.7 and I want to write a simple C/C++ console application that emulates keyboard keystrokes, without using graphical mode (unable to use XLib stuff: XSendEvent, etc, etc).

The solutions I’ve found on the web involve an X-Server behind, so I need a more basic, low-level way to do that I think, any ideas?

PD: to understand the big picture I found this: http://www.subspacefield.org/~travis/keyboard/index.html, but it wasn’t enough :(

Thanks in advance,
e-milio.
Like a socket type thing???
Why did you have modified this?

"barriehie (2) ... Jan 7, 2011 at 7:59pm
Have to be a bit more specific about 'emulate'. :) If you write chars to /dev/tty it will 'emulate' characters coming from the keyboard but if you call interrupt 16 with the appropriate registers loaded it will actually put a keystroke in the keyboard buffer."

After some extra Google, I’ve found: http://expect-lite.sourceforge.net/expect-lite_simple.html and a simple ping example: http://expect-lite.sourceforge.net/expect-lite_install.html, yet I couldn’t try it, I’m a bit busy with other duties, but I will try it soon...

Thanks for your interest Barrie!
:) After -hours- of getting a 'segmentation fault' with trying to run inline assy to load the keyboard buffer I then thought of emulating the keyboard by using a socket. I don't know what your intent here is but to an application I'm figuring the 'name' of the device sending the data is probably irrelevant; only the receipt of the data is critical, so... I was thinking of falling back on sockets since I couldn't get anything else to work! :( I've got some client/server socket programs that I've gleaned from various places but they would have to be modified to work continuous. I've been meaning to understand those... :)
Don't know what distro you're using but debian has a package

1
2
3
07:38:19 /home/barrie/programming/ $> aptitude search . | grep xvkbd
p   xvkbd                           - software virtual keyboard for X11
07:39:04 /home/barrie/programming/ $>


and startpage turned up this:
[url]http://scripts.top4download.com/kbde/ohiox.html[/url]

HTH
Thanks again Barrie, but I’ve tried with xvkbd before, and as you pasted here it’s part of the X11 scenery.

Finally, I've gotten some time to focus on the issue; I’ve found a simple way to do it, calling directly to the Unix sys API, inspired on Expect code and some other Google searches related to struct termio, ioctl call and so on...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <termio.h>

#define STR_SIZE 256

static const char* EOL_CMD = "\n";
static const char* DEFAULT_CMD = "ls -l";

static bool SetEcho(int dev_tty, bool enable)
{
	struct termio termBuf;
	ioctl(dev_tty, TCGETA, &termBuf);
	if (enable) {
		termBuf.c_lflag |= ECHO; // Enable echo
	} else {
		termBuf.c_lflag &= ~ECHO; // Don't echo
	}
	ioctl(dev_tty, TCSETAW, &termBuf);
	return true;
}

static bool SendCMDToTTY(const char* cmd)
{
	int dev_tty = open("/dev/tty", O_RDWR);
	if (!dev_tty) {
		return false;
	}

	SetEcho(dev_tty, false);
	size_t cmdSize = strlen(cmd);
	for (size_t i = 0; i < cmdSize; i++) {
		ioctl(dev_tty, TIOCSTI, &cmd[i]);
	}
	SetEcho(dev_tty, true);

	close(dev_tty);
	return true;
}

int main(int argc, char* argv[])
{
	char sys_cmd[STR_SIZE];
	memset(sys_cmd, NULL, STR_SIZE);
	for (int i = 1; i < argc; i++) {
		sprintf(sys_cmd, "%s%s%s", sys_cmd, i == 1 ? "" : " ", argv[i]);
	}
	if (argc == 1) {
		sprintf(sys_cmd, "%s", DEFAULT_CMD);
	}
	sprintf(sys_cmd, "%s%s", sys_cmd, EOL_CMD);
	sys_cmd[STR_SIZE - 1] = NULL;

	if (!SendCMDToTTY(sys_cmd)) {
		perror("Error while sending the command to TTY");
	}
	return 0;
}


It’s just a basic example, and it has to be improved with some error checking on system calls, command arguments maybe, etc, etc... but I hope this may help someone else,

Regards,
e-milio.
Glad you got it! I spent the better part of a day messing around with sockets in an attempt to 'emulate' this... :)
Topic archived. No new replies allowed.