summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyojung Jo <hj903.jo@samsung.com>2015-04-23 15:43:11 +0900
committerHyojung Jo <hj903.jo@samsung.com>2015-04-23 15:55:41 +0900
commit3512c416c35405da51837d65f4e8eddec0a3f071 (patch)
tree37a8b8e370917354f4c5bd05f38777aca43fc779
parente54b0ba132352b04d513fcab402e03b02d6439ad (diff)
downloadautotest-3512c416c35405da51837d65f4e8eddec0a3f071.tar.gz
autotest-3512c416c35405da51837d65f4e8eddec0a3f071.tar.bz2
autotest-3512c416c35405da51837d65f4e8eddec0a3f071.zip
Moved event generator/recorder to autotest git repoHEADmaster
Change-Id: I839307dfded8e5462e0fef6c76103b2c5e12bd59 Signed-off-by: Hyojung Jo <hj903.jo@samsung.com>
-rwxr-xr-xeventgenerator/CMakeLists.txt35
-rwxr-xr-xeventgenerator/build.sh9
-rwxr-xr-xeventgenerator/packaging/eventgenerator.spec35
-rwxr-xr-xeventgenerator/src/main.cpp568
-rwxr-xr-xeventrecorder/CMakeLists.txt34
-rwxr-xr-xeventrecorder/build.sh9
-rwxr-xr-xeventrecorder/packaging/eventgenerator.spec35
-rwxr-xr-xeventrecorder/src/main.cpp279
8 files changed, 1004 insertions, 0 deletions
diff --git a/eventgenerator/CMakeLists.txt b/eventgenerator/CMakeLists.txt
new file mode 100755
index 0000000..501580a
--- /dev/null
+++ b/eventgenerator/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 2.8)
+PROJECT(eventgenerator)
+
+SET(EVENTGENERATOR_SRCS
+ ${PROJECT_SOURCE_DIR}/src/main.cpp
+)
+
+SET(EVENTGENERATOR_HEADERS
+ ${PROJECT_SOURCE_DIR}/include
+)
+
+INCLUDE_DIRECTORIES(${EVENTGENERATOR_HEADERS})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(EVENTGENERATOR_PKGS REQUIRED
+ glib-2.0
+ utilX
+ x11
+ gio-2.0
+)
+
+FOREACH (flag ${EVENTGENERATOR_PKGS_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${EXTRA_CFLAGS} -g")
+
+
+ADD_EXECUTABLE(eventgenerator ${EVENTGENERATOR_SRCS})
+TARGET_LINK_LIBRARIES(eventgenerator ${EVENTGENERATOR_PKGS_LDFLAGS} "-ldl" "-lpthread" ${EVENTGENERATOR_PKGS_LIBRARIES})
+INSTALL(TARGETS eventgenerator DESTINATION /opt/usr/apps/${PROJECT_NAME}/bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LOCK_PKGS_LDFLAGS})
diff --git a/eventgenerator/build.sh b/eventgenerator/build.sh
new file mode 100755
index 0000000..91b133a
--- /dev/null
+++ b/eventgenerator/build.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+cp -rf ../eventgenerator ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home/abuild/rpmbuild/BUILD/
+
+sudo chroot ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/ /bin/bash -c "cd /home/abuild/rpmbuild/BUILD/eventgenerator/ && cmake . && make"
+
+sdb root on
+sdb push ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home/abuild/rpmbuild/BUILD/eventgenerator/eventgenerator /home/user/
+
diff --git a/eventgenerator/packaging/eventgenerator.spec b/eventgenerator/packaging/eventgenerator.spec
new file mode 100755
index 0000000..f2fa5f3
--- /dev/null
+++ b/eventgenerator/packaging/eventgenerator.spec
@@ -0,0 +1,35 @@
+Name: eventgenerator
+Summary: eventgenerator
+Version: 0.1
+Release: 1
+Group: Applications/Other
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: x11
+BuildRequires: utilX
+
+%description
+Tizen 3.0 eventgenerator application
+
+%prep
+%setup -q
+
+%build
+export SRC_PWD="$PWD"
+%define _build_dir .build-%{name}
+
+mkdir -p %{_build_dir}
+cd %{_build_dir}
+
+cmake $SRC_PWD -DCMAKE_INSTALL_PREFIX=%{_prefix}
+make %{?jobs:-j%jobs}
+
+%install
+cd %{_build_dir}
+rm -rf %{buildroot}
+%make_install
+
+%files -n lockscreen
+%defattr(-,root,root,-)
+/usr/apps/eventgenerator/bin/*
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;
+}
diff --git a/eventrecorder/CMakeLists.txt b/eventrecorder/CMakeLists.txt
new file mode 100755
index 0000000..9f51b28
--- /dev/null
+++ b/eventrecorder/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 2.8)
+PROJECT(eventrecorder)
+
+SET(EVENTGENERATOR_SRCS
+ ${PROJECT_SOURCE_DIR}/src/main.cpp
+)
+
+SET(EVENTGENERATOR_HEADERS
+ ${PROJECT_SOURCE_DIR}/include
+)
+
+INCLUDE_DIRECTORIES(${EVENTGENERATOR_HEADERS})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(EVENTGENERATOR_PKGS REQUIRED
+ glib-2.0
+ utilX
+ x11
+)
+
+FOREACH (flag ${EVENTGENERATOR_PKGS_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${EXTRA_CFLAGS}")
+
+
+ADD_EXECUTABLE(eventrecorder ${EVENTGENERATOR_SRCS})
+TARGET_LINK_LIBRARIES(eventrecorder ${EVENTGENERATOR_PKGS_LDFLAGS} "-ldl" ${EVENTGENERATOR_PKGS_LIBRARIES})
+INSTALL(TARGETS eventrecorder DESTINATION /opt/usr/apps/${PROJECT_NAME}/bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+
+
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LOCK_PKGS_LDFLAGS})
diff --git a/eventrecorder/build.sh b/eventrecorder/build.sh
new file mode 100755
index 0000000..89104a3
--- /dev/null
+++ b/eventrecorder/build.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+cp -rf ../eventrecorder ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home/abuild/rpmbuild/BUILD/
+
+sudo chroot ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/ /bin/bash -c "cd /home/abuild/rpmbuild/BUILD/eventrecorder/ && cmake . && make"
+
+sdb root on
+sdb push ~/GBS-ROOT/local/BUILD-ROOTS/scratch.armv7l.0/home/abuild/rpmbuild/BUILD/eventrecorder/eventrecorder /home/user/
+
diff --git a/eventrecorder/packaging/eventgenerator.spec b/eventrecorder/packaging/eventgenerator.spec
new file mode 100755
index 0000000..a14a560
--- /dev/null
+++ b/eventrecorder/packaging/eventgenerator.spec
@@ -0,0 +1,35 @@
+Name: eventrecorder
+Summary: eventrecorder
+Version: 0.1
+Release: 1
+Group: Applications/Other
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: x11
+BuildRequires: utilX
+
+%description
+Tizen 3.0 eventrecorder application
+
+%prep
+%setup -q
+
+%build
+export SRC_PWD="$PWD"
+%define _build_dir .build-%{name}
+
+mkdir -p %{_build_dir}
+cd %{_build_dir}
+
+cmake $SRC_PWD -DCMAKE_INSTALL_PREFIX=%{_prefix}
+make %{?jobs:-j%jobs}
+
+%install
+cd %{_build_dir}
+rm -rf %{buildroot}
+%make_install
+
+%files -n lockscreen
+%defattr(-,root,root,-)
+/usr/apps/eventrecorder/bin/*
diff --git a/eventrecorder/src/main.cpp b/eventrecorder/src/main.cpp
new file mode 100755
index 0000000..2169a0e
--- /dev/null
+++ b/eventrecorder/src/main.cpp
@@ -0,0 +1,279 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <signal.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#define INTERVAL_DEFAULT 1000
+
+#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 end;
+
+static XErrorHandler old_handler = (XErrorHandler) 0;
+
+static int _xerror_handler(Display *display, XErrorEvent *theEvent)
+{
+ return 0;
+}
+
+static void _sigint_handler(int signo)
+{
+ printf("Ctrl + C Pressed\n");
+ end = true;
+}
+
+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;
+}
+
+int main(int argc, char *argv[])
+{
+ Display* d;
+ Window root;
+ Window curFocus;
+ Window initFocusWin;
+ KeySym ks;
+ XComposeStatus comp;
+ char buf[17];
+ const char *sym;
+ int len;
+ int revert;
+ static int motionRecord;
+ bool pressed;
+ bool imeInput;
+ unsigned int prevTime, curTime;
+ unsigned int interval;
+ FILE *fp;
+
+ if (argc == 1) {
+ printf("Please enter output file name.\n");
+ printf("Usage: eventrecorder [file name]\n");
+ return -1;
+ }
+
+ fp = fopen(argv[1], "w");
+ if (!fp) {
+ printf("file %s open error\n", argv[1]);
+ return -1;
+ }
+
+ signal(SIGINT, _sigint_handler);
+
+ old_handler = XSetErrorHandler(_xerror_handler);
+
+ d = XOpenDisplay(NULL);
+ root = XDefaultRootWindow(d);
+
+ XGetInputFocus(d, &curFocus, &revert);
+ initFocusWin = curFocus;
+ printf("initFocusWin = 0x%x\n",initFocusWin);
+ printf("=====================================\n");
+ XSelectInput(d, curFocus, KeyPressMask | KeyReleaseMask | SubstructureNotifyMask);
+
+ XAllowEvents(d, AsyncBoth, CurrentTime);
+ XGrabPointer(d, curFocus, 1,
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync,
+ None, None,
+ CurrentTime);
+
+ end = false;
+ motionRecord = 0;
+ prevTime = 0;
+ curTime = 0;
+ interval = 0;
+ imeInput = 0;
+
+ while (1) {
+ XGetInputFocus(d, &curFocus, &revert);
+ XSelectInput(d, curFocus, KeyPressMask | KeyReleaseMask | SubstructureNotifyMask);
+
+ XAllowEvents(d, AsyncBoth, CurrentTime);
+ XGrabPointer(d, curFocus, 1,
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+ GrabModeAsync, GrabModeAsync,
+ None, None,
+ CurrentTime);
+
+ if (end) {
+ printf("EventRecorder is terminated.\n");
+ break;
+ }
+
+ if (!XPending(d))
+ continue;
+
+ XEvent ev;
+ XNextEvent(d, &ev);
+
+ switch (ev.type) {
+ case DestroyNotify:
+ printf("destroyedWin = 0x%x\n", ev.xdestroywindow.event);
+ if(initFocusWin == ev.xdestroywindow.event)
+ end = true;
+ break;
+ // Key Event
+ case KeyPress:
+ if (pressed)
+ continue;
+
+ if (ev.xkey.time == 1)
+ continue;
+
+ len = XLookupString(&ev.xkey, buf, 16, &ks, &comp);
+ sym = XKeysymToString(ks);
+
+ printf("Key Pressed\n");
+ printf("%s\n", sym);
+
+ fprintf(fp, "Key Pressed\n");
+ fprintf(fp, "%s ", sym);
+
+ curTime = ev.xkey.time;
+
+ pressed = true;
+ break;
+ case KeyRelease:
+ if (!pressed)
+ continue;
+
+ if (ev.xkey.time == 1)
+ continue;
+
+ len = XLookupString(&ev.xkey, buf, 16, &ks, &comp);
+ sym = XKeysymToString(ks);
+
+ printf("Key Released\n");
+ printf("%s\n", sym);
+
+ fprintf(fp, "Key Released\n");
+ fprintf(fp, "%s ", sym);
+
+ curTime = ev.xkey.time;
+
+ pressed = false;
+ break;
+ // Mouse Event
+ case MotionNotify:
+ ++motionRecord %= 2;
+ if (!motionRecord) { // Record once in two
+ XSendEvent(d, curFocus, True,
+ PointerMotionMask, (XEvent *)&ev);
+ continue;
+ }
+
+ printf("Mouse Move\n");
+ printf("x: %d, y: %d\n",
+ ev.xmotion.x_root, ev.xmotion.y_root);
+
+ fprintf(fp, "Mouse Move\n");
+ fprintf(fp, "%d %d ",
+ ev.xmotion.x_root, ev.xmotion.y_root);
+
+ curTime = ev.xmotion.time;
+
+ XSendEvent(d, curFocus, True,
+ PointerMotionMask, (XEvent *)&ev);
+
+ break;
+ case ButtonPress:
+ printf("Mouse Pressed\n");
+ printf("x: %d, y: %d\n",
+ ev.xbutton.x_root, ev.xbutton.y_root);
+
+ fprintf(fp, "Mouse Pressed\n");
+ fprintf(fp, "%d %d %d %d ",
+ ev.xbutton.x_root, ev.xbutton.y_root,
+ ev.xbutton.state, ev.xbutton.button);
+
+ curTime = ev.xbutton.time;
+ imeInput = false;
+
+ _get_ime_window();
+
+ if (_check_ime_input(ev.xbutton.x_root,
+ ev.xbutton.y_root)) {
+ imeInput = true;
+
+ ev.xbutton.window = imeWin;
+ XSendEvent(d, imeWin, True,
+ ButtonPressMask, (XEvent *)&ev);
+ } else
+ XSendEvent(d, curFocus, True,
+ ButtonPressMask, (XEvent *)&ev);
+ break;
+ case ButtonRelease:
+ printf("Mouse Released\n");
+ printf("x: %d, y: %d\n",
+ ev.xbutton.x_root, ev.xbutton.y_root);
+
+ fprintf(fp, "Mouse Released\n");
+ fprintf(fp, "%d %d %d %d ",
+ ev.xbutton.x_root, ev.xbutton.y_root,
+ ev.xbutton.state, ev.xbutton.button);
+
+ curTime = ev.xbutton.time;
+
+ if (imeInput) {
+ ev.xbutton.window = imeWin;
+ XSendEvent(d, imeWin, True,
+ ButtonReleaseMask, (XEvent *)&ev);
+ } else
+ XSendEvent(d, curFocus, True,
+ ButtonReleaseMask, (XEvent *)&ev);
+ break;
+ default:
+ break;
+ }
+
+ if (!curTime)
+ continue;
+
+ if (prevTime)
+ interval = curTime - prevTime;
+ else
+ interval = INTERVAL_DEFAULT;
+
+ printf("Time interval: %u\n", interval);
+ printf("=====================================\n");
+ fprintf(fp, "%u\n", interval);
+
+ prevTime = curTime;
+ curTime = 0;
+ }
+
+ if (pressed) {
+ fprintf(fp, "Key Released\n");
+ fprintf(fp, "Escape 120\n");
+ }
+
+ fclose(fp);
+
+ return 0;
+}