diff options
Diffstat (limited to 'eventgenerator/src/main.cpp')
-rwxr-xr-x | eventgenerator/src/main.cpp | 568 |
1 files changed, 568 insertions, 0 deletions
diff --git a/eventgenerator/src/main.cpp b/eventgenerator/src/main.cpp new file mode 100755 index 0000000..8246386 --- /dev/null +++ b/eventgenerator/src/main.cpp @@ -0,0 +1,568 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <string> +#include <iostream> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <iostream> +#include <list> +#include <sys/time.h> +#include <unistd.h> +#include <utilX.h> +#include <glib.h> +#include <gerror.h> +#include <gio/gio.h> + +#define DEVICED_PATH_USBHOST "/Org/Tizen/System/DeviceD/Usbhost" +#define DEVICED_INTERFACE_USBHOST "org.tizen.system.deviced.Usbhost" + +#define SIGNAL_USBHOST_CHANGED "ChangedDevice" + +#define MAX_STR_SIZE 256 + +#define COMMAND_GET_IME_WINDOW_ID "xinfo -topwins 2>&1 | grep 'Tizen Keyboard' | awk '{ if ($9 > 0) print $3,$4,$5,$8,$9; else print 0,0,0,0,0}'" + +Window imeWin; +int ime_x, ime_y, ime_w, ime_h; +bool imeInput; +bool end; +GDBusConnection *conn; +GDBusProxy *proxy; +GError *error; + +using namespace std; + +class CKeyEventGenerator { +private: + unsigned long m_RootId; + Display *m_Display; + +public: + CKeyEventGenerator(); + virtual ~CKeyEventGenerator() {} + +public: + void GenerateKeyPressEvent(char *keyname); + void GenerateKeyReleaseEvent(char *keyname); + void GenerateMouseMoveEvent(int x, int y); + void GenerateMousePressEvent(int x, int y, int state, int button); + void GenerateMouseReleaseEvent(int x, int y, int state, int button); +}; + +static void _get_ime_window(void) +{ + FILE *fp; + char str[256]; + + fp = popen(COMMAND_GET_IME_WINDOW_ID, "r"); + if (!fp) { + printf("popen error\n"); + return; + } + + fscanf(fp, "%s %d %d %d %d\n", str, &ime_w, &ime_h, &ime_x, &ime_y); + imeWin = strtol(str, NULL, 16); + + pclose(fp); +} + +static bool _check_ime_input(int x, int y) +{ + if (imeWin && (x > ime_x && x < ime_x + ime_w) + && (y > ime_y && y < ime_y + ime_h)) + return true; + else + return false; +} + +CKeyEventGenerator::CKeyEventGenerator() { + m_Display = XOpenDisplay(0); + m_RootId = XDefaultRootWindow(m_Display); + printf("root: 0x%x\n", m_RootId); +} + +void CKeyEventGenerator::GenerateKeyPressEvent(char *keyname) +{ + XEvent xev; + Window root = (Window)m_RootId; + Display *dpy = m_Display; + Window win; + int revert; + + XGetInputFocus(dpy, &win, &revert); + + xev.xkey.display = dpy; + xev.xkey.window = win; + xev.xkey.root = root; + xev.xkey.subwindow = None; + xev.xkey.time = CurrentTime; + xev.xkey.x = 1; + xev.xkey.y = 1; + xev.xkey.x_root = 540; + xev.xkey.y_root = 960; + xev.xkey.keycode = XKeysymToKeycode(m_Display, XStringToKeysym(keyname)); + xev.xkey.same_screen = 1; + xev.xkey.state = 0; + xev.xkey.type = KeyPress; + + XSendEvent(dpy, win, True, KeyPressMask | KeyReleaseMask, &xev); + XFlush(dpy); +} + + +void CKeyEventGenerator::GenerateKeyReleaseEvent(char *keyname) +{ + XEvent xev; + Window root = (Window)m_RootId; + Display *dpy = m_Display; + Window win; + int revert; + + XGetInputFocus(dpy, &win, &revert); + + xev.xkey.display = dpy; + xev.xkey.window = win; + xev.xkey.root = root; + xev.xkey.subwindow = None; + xev.xkey.time = CurrentTime; + xev.xkey.x = 1; + xev.xkey.y = 1; + xev.xkey.x_root = 540; + xev.xkey.y_root = 960; + xev.xkey.keycode = XKeysymToKeycode(m_Display, XStringToKeysym(keyname)); + xev.xkey.same_screen = 1; + xev.xkey.state = 0; + xev.xkey.type = KeyRelease; + + XSendEvent(dpy, win, True, KeyPressMask | KeyReleaseMask, &xev); + XFlush(dpy); +} + + +void CKeyEventGenerator::GenerateMouseMoveEvent(int x, int y) +{ + XEvent xev; + Window root = (Window)m_RootId; + Display *dpy = m_Display; + Window win; + int revert; + + XGetInputFocus(dpy, &win, &revert); + + xev.xmotion.window = win; + xev.xmotion.root = root; + xev.xmotion.subwindow = None; + xev.xmotion.time = CurrentTime; + xev.xmotion.x = x; + xev.xmotion.y = y; + xev.xmotion.x_root = x; + xev.xmotion.y_root = y; + xev.xmotion.state = 0; + xev.xmotion.is_hint = 0; + xev.xmotion.same_screen = 1; + xev.xmotion.type = MotionNotify; + + XSendEvent(dpy, win, True, PointerMotionMask, &xev); + XFlush(dpy); +} + + +void CKeyEventGenerator::GenerateMousePressEvent(int x, int y, int state, int button) +{ + XEvent xev; + Window root = (Window)m_RootId; + Display *dpy = m_Display; + Window win; + int revert; + + _get_ime_window(); + + if (_check_ime_input(x, y)) { + imeInput = true; + win = imeWin; + } else + XGetInputFocus(dpy, &win, &revert); + + xev.xbutton.window = win; + xev.xbutton.root = root; + xev.xbutton.subwindow = None; + xev.xbutton.time = CurrentTime; + xev.xbutton.x = x; + xev.xbutton.y = y; + xev.xbutton.x_root = x; + xev.xbutton.y_root = y; + xev.xbutton.state = state; + xev.xbutton.button = button; + xev.xbutton.same_screen = 1; + xev.xbutton.type = ButtonPress; + + XSendEvent(dpy, win, True, ButtonPressMask, &xev); + XFlush(dpy); +} + + +void CKeyEventGenerator::GenerateMouseReleaseEvent(int x, int y, int state, int button) +{ + XEvent xev; + Window root = (Window)m_RootId; + Display *dpy = m_Display; + Window win; + int revert; + + if (imeInput) + win = imeWin; + else + XGetInputFocus(dpy, &win, &revert); + + xev.xbutton.window = win; + xev.xbutton.root = root; + xev.xbutton.subwindow = None; + xev.xbutton.time = CurrentTime; + xev.xbutton.x = x; + xev.xbutton.y = y; + xev.xbutton.x_root = x; + xev.xbutton.y_root = y; + xev.xbutton.state = state; + xev.xbutton.button = button; + xev.xbutton.same_screen = 1; + xev.xbutton.type = ButtonRelease; + + XSendEvent(dpy, win, True, ButtonReleaseMask, &xev); + XFlush(dpy); +} + + +static void *_check_event(void *data) +{ + Display *dpy; + Window win; + int revert; + bool event; + + dpy = XOpenDisplay(0); + XGetInputFocus(dpy, &win, &revert); + XSelectInput(dpy, win, KeyPressMask | KeyReleaseMask); + + XAllowEvents(dpy, AsyncBoth, CurrentTime); + XGrabPointer(dpy, win, 1, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, + None, None, + CurrentTime); + + event = false; + while (1) { + if (end) + pthread_exit(NULL); + + if (!XPending(dpy)) + continue; + + XEvent ev; + XNextEvent(dpy, &ev); + + switch (ev.type) { + case KeyPress: + if (imeInput) + break; + + if (ev.xkey.time > 1) + event = true; + break; + case KeyRelease: + if (imeInput) { + imeInput = false; + break; + } + + if (ev.xkey.time > 1) + event = true; + break; + case MotionNotify: + if (ev.xmotion.time) + event = true; + break; + case ButtonPress: + case ButtonRelease: + if (ev.xbutton.time) + event = true; + break; + default: + break; + } + + if (event) + break; + } + + + end = true; + + pthread_exit(NULL); +} + +static bool _usb_initialize(void) +{ + conn = NULL; + proxy = NULL; + error = NULL; + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (!conn) { + printf("get connection failed\n"); + g_error_free(error); + return false; + } + + return true; +} + +static void _usb_finalize(void) +{ + g_object_unref(conn); +} + +static void _usb_connect(const char *name, const char *serial) +{ + GVariant *param; + int r; + + param = g_variant_new("(isiiiiisss)", 1, "devpath", 0x08, + 0, 0, 0, 0, "manufacturer", name, serial); + + r = g_dbus_connection_emit_signal(conn, NULL, DEVICED_PATH_USBHOST, + DEVICED_INTERFACE_USBHOST, + SIGNAL_USBHOST_CHANGED, + param, &error); + + if (!r) { + printf("connect signal (%s, %s) emit failed\n", name, serial); + g_error_free(error); + } +} + +static void _usb_disconnect(const char *name, const char *serial) +{ + GVariant *param; + int r; + + param = g_variant_new("(isiiiiisss)", 0, "devpath", 0x08, + 0, 0, 0, 0, "manufacturer", name, serial); + + r = g_dbus_connection_emit_signal(conn, NULL, DEVICED_PATH_USBHOST, + DEVICED_INTERFACE_USBHOST, + SIGNAL_USBHOST_CHANGED, + param, &error); + + if (!r) { + printf("disconnect signal (%s, %s) emit failed\n", name, serial); + g_error_free(error); + } +} + +static bool _run_command(const char *command) +{ + int ret; + + ret = system(command); + + if (ret) { + printf("Exit status: %d\n", ret); + return false; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + CKeyEventGenerator *keygen = new CKeyEventGenerator; + char file[MAX_STR_SIZE]; + char dev[MAX_STR_SIZE], str[MAX_STR_SIZE]; + char op[MAX_STR_SIZE], sym[MAX_STR_SIZE]; + char name[MAX_STR_SIZE], serial[MAX_STR_SIZE]; + unsigned int time; + int r; + pthread_t thread_id; + FILE *fp_list, *fp; + + if (argc == 1) { + printf("Please enter input file name.\n"); + printf("Usage: eventgenerator [file name]\n"); + return -1; + } + + fp_list = fopen(argv[1], "r"); + if (!fp_list) { + printf("file %s open error\n", argv[1]); + return -1; + } + + if (!_usb_initialize()) { + printf("Usb init failed\n"); + return -1; + } + + thread_id = 0; + + r = pthread_create(&thread_id, NULL, _check_event, (void *)NULL); + if (r != 0) { + printf("pthread create failed\n"); + return -1; + } + + end = false; + + unsigned int interval; + int x = 0, y = 0; + int state = 0, button = 0; + int move_offset = 10000; + int button_offset = 100000; + int usb_offset = 100000; + int command_interval = 500000; + + printf("========================\n"); + while (1) { + if (fscanf(fp_list, "%s\n", file) == EOF) + break; + + printf("****************************************\n"); + printf("Testcase file: %s\n", file); + printf("****************************************\n"); + + fp = fopen(file, "r"); + if (!fp) { + printf("file %s open error\n", file); + fclose(fp_list); + return -1; + } + + while (1) { + if (end) { + printf("User input is detected.\n" + "Eventgenerator is terminated.\n"); + break; + } + + if (fscanf(fp, "%s", dev) == EOF) + break; + + if (dev[0] == '#') { + fgets(str, MAX_STR_SIZE, fp); + printf("%s%s", dev, str); + printf("========================\n"); + continue; + } + + if (!strcmp(dev, "Command")) { + fscanf(fp, "\n"); + fgets(str, MAX_STR_SIZE, fp); + + if (!_run_command(str)) { + printf("Execute command failed.\n"); + break; + } + + printf("%s\n%s", dev, str); + + usleep(command_interval); + + printf("Time for sleep: %u ms\n", command_interval / 1000); + printf("========================\n"); + } else if (!strcmp(dev, "Key")) { + fscanf(fp, "%s\n", op); + printf("%s %s\n", dev, op); + + fscanf(fp, "%s %u\n", sym, &interval); + + printf("%s\n", sym); + printf("Time for sleep: %u ms\n", interval); + + usleep(interval * 1000 + button_offset); + + if (!strcmp(op, "Pressed")) + keygen->GenerateKeyPressEvent(sym); + else if (!strcmp(op, "Released")) + keygen->GenerateKeyReleaseEvent(sym); + + printf("Send Event\n"); + printf("========================\n"); + } else if (!strcmp(dev, "Mouse")) { + fscanf(fp, "%s\n", op); + printf("%s %s\n", dev, op); + + if (!strcmp(op, "Move")) { + fscanf(fp, "%d %d %u\n", &x, &y, &interval); + + printf("x: %d, y: %d\n", x, y); + printf("Time for sleep: %u ms\n", interval); + + usleep(interval * 1000 + move_offset); + keygen->GenerateMouseMoveEvent(x, y); + } else if (!strcmp(op, "Pressed")) { + fscanf(fp, "%d %d %d %d %u\n", &x, &y, &state, &button, &interval); + + printf("x: %d, y: %d\n", x, y); + printf("Time for sleep: %u ms\n", interval); + + usleep(interval * 1000 + button_offset); + keygen->GenerateMousePressEvent(x, y, state, button); + } else if (!strcmp(op, "Released")) { + fscanf(fp, "%d %d %d %d %u\n", &x, &y, &state, &button, &interval); + + printf("x: %d, y: %d\n", x, y); + printf("Time for sleep: %u ms\n", interval); + + usleep(interval * 1000 + button_offset); + keygen->GenerateMouseReleaseEvent(x, y, state, button); + } + + printf("Send Event\n"); + printf("========================\n"); + } else if (!strcmp(dev, "Usb")) { + fscanf(fp, "%s\n", op); + printf("%s %s\n", dev, op); + + fscanf(fp, "%s %s %u\n", name, serial, &interval); + printf("name: %s, serial: %s\n", name, serial); + printf("Time for sleep: %u ms\n", interval); + + usleep(interval * 1000 + usb_offset); + + if (!strcmp(op, "Connect")) { + _usb_connect(name, serial); + } else if (!strcmp(op, "Disconnect")) { + _usb_disconnect(name, serial); + } + + printf("Send Signal\n"); + printf("========================\n"); + } + } + + if (end) + break; + + printf("****************************************\n"); + printf("Test %s complete.\n", file); + printf("****************************************\n"); + + fclose(fp); + } + + if (!end) { + end = true; + + pthread_join(thread_id, (void **)&r); + } + + _usb_finalize(); + + fclose(fp_list); + + delete keygen; + + return 0; +} |