e_info_client_screen_recorder_run(argc, argv);
}
+static void
+_e_info_client_inputgen_usage(void)
+{
+ printf(" If you want to generate input events, follow below steps\n");
+ printf(" \tinit_device -> generate events (keygen) -> deinit_device\n");
+ printf("\n\n");
+ printf(" enlightenment_info -init_device\n");
+ printf(" \t--node: open a device node (ex> /dev/input/event1)\n");
+ printf(" \t--type: create a device by given type (keyboard/mouse/touch)\n");
+ printf(" \t\tyou can select one or more types, but currently only keyboard type is supported\n");
+ printf(" \t--name: device name want to create. used with --type option (default: E_Info_Device)\n");
+ printf("\n");
+ printf(" you need to choice either node or type to init device\n");
+ printf(" example> enlightenment_info -init_device --node=/dev/input/event1\n");
+ printf(" enlightenment_info -init_device --type=keyboard/mouse --name=Test_Device\n");
+ printf(" enlightenment_info -init_device --type=keyboard\n");
+ printf("\n\n");
+ printf(" enlightenment_info -deinit_device\n");
+ printf(" example> enlightenment_info -deinit_device\n");
+ printf("\n\n");
+ printf(" enlightenment_info -keygen\n");
+ printf(" \t--name: keyname want to generate\n");
+ printf(" \t--code: X keycode want to generate\n");
+ printf(" \t--state: key event state want to generate [press/down/1] [release/up/0] (default: Press/Release pair)\n");
+ printf("\n");
+ printf(" you need to choice either name or code to generate key events\n");
+ printf(" example> enlightenment_info -keygen --name=XF86Back\n");
+ printf(" enlightenment_info -keygen --code=166 --state=down\n");
+ printf(" enlightenment_info -keygen --name=XF86Back --state=0\n");
+ printf("\n");
+}
+
+static void
+_e_info_client_cb_init_device(const Eldbus_Message *msg)
+{
+ const char *errname = NULL, *errtext = NULL;
+ char *result = NULL;
+
+ EINA_SAFETY_ON_TRUE_GOTO(eldbus_message_error_get(msg, &errname, &errtext), err);
+
+ EINA_SAFETY_ON_FALSE_GOTO(eldbus_message_arguments_get(msg, "s", &result), err);
+
+ if (strncmp(result, E_INFO_INPUT_RESULT_NONE, sizeof(E_INFO_INPUT_RESULT_NONE)))
+ printf("Init_device Failed: %s\n", result);
+
+ return;
+
+err:
+ if(errname || errtext)
+ printf("errname : %s, errmsg : %s\n", errname, errtext);
+ else
+ printf("Error occurred in _e_info_client_cb_init_device\n");
+}
+
+void
+_e_info_client_proc_init_device(int argc, char **argv)
+{
+ char name[80] = {0, }, node[20] = {0, };
+ unsigned int type = 0x0;
+ char *tmp = NULL, *buf = NULL, *buf_ptr = NULL;
+ int i;
+
+ if (argc < 3)
+ {
+ _e_info_client_inputgen_usage();
+ return;
+ }
+
+ for (i = 2; i < argc; i++)
+ {
+ if (!strncmp(argv[i], "--node=", sizeof("--node=") - 1))
+ {
+ tmp = argv[i] + sizeof("--node=") - 1;
+ strncpy(node, tmp, strlen(tmp));
+ type = 0x0;
+ break;
+ }
+ else if (!strncmp(argv[i], "--type=", sizeof("--type=") - 1))
+ {
+ tmp = argv[i] + sizeof("--type=") - 1;
+ buf = strtok_r(tmp, "/", &buf_ptr);
+ if (!buf)
+ {
+ printf("Please insert correct device type. keyboard/mouse/touch.\n");
+ return;
+ }
+ while (buf)
+ {
+ if (!strncmp(buf, "mouse", sizeof("mouse")))
+ {
+ type |= E_INPUT_SEAT_POINTER;
+ }
+ else if (!strncmp(buf, "touch", sizeof("touch")))
+ {
+ type |= E_INPUT_SEAT_TOUCH;
+ }
+ else if (!strncmp(buf, "keyboard", sizeof("keyboard")))
+ {
+ type |= E_INPUT_SEAT_KEYBOARD;
+ }
+ else
+ {
+ printf("Please insert valid device type. keyboard/mouse/touch.\n");
+ break;
+ }
+ buf = strtok_r(NULL, "/", &buf_ptr);
+ }
+ }
+ else if (!strncmp(argv[i], "--name=", sizeof("--name=") - 1))
+ {
+ tmp = argv[i] + sizeof("--name=") - 1;
+ strncpy(name, tmp, strlen(tmp));
+ }
+ else
+ {
+ _e_info_client_inputgen_usage();
+ return;
+ }
+ }
+
+ if (!type && node[0] == '\0')
+ {
+ printf("Please insert either node or type\n");
+ return;
+ }
+ else if (type && node[0] != '\0')
+ {
+ printf("Please insert only one between node and type\n");
+ return;
+ }
+
+ if (type)
+ {
+ if (name[0] == '\0')
+ snprintf(name, sizeof("E_Info_Device"), "E_Info_Device");
+ }
+ else
+ {
+ snprintf(name, sizeof(node), "%s", node);
+ }
+
+ if (!_e_info_client_eldbus_message_with_args("init_device", _e_info_client_cb_init_device, "us", type, name))
+ return;
+}
+
+void
+_e_info_client_proc_deinit_device(int argc, char **argv)
+{
+ if (!_e_info_client_eldbus_message("deinit_device", NULL))
+ return;
+}
+
+static void
+_e_info_client_cb_keygen(const Eldbus_Message *msg)
+{
+ const char *errname = NULL, *errtext = NULL;
+ char *result = NULL;
+
+ EINA_SAFETY_ON_TRUE_GOTO(eldbus_message_error_get(msg, &errname, &errtext), err);
+
+ EINA_SAFETY_ON_FALSE_GOTO(eldbus_message_arguments_get(msg, "s", &result), err);
+
+ if (strncmp(result, E_INFO_INPUT_RESULT_NONE, sizeof(E_INFO_INPUT_RESULT_NONE)))
+ printf("Keygen Failed: %s\n", result);
+
+ return;
+
+err:
+ if(errname || errtext)
+ printf("errname : %s, errmsg : %s\n", errname, errtext);
+ else
+ printf("Error occurred in _e_info_client_cb_keygen\n");
+}
+
+void
+_e_info_client_proc_keygen(int argc, char **argv)
+{
+ char name[16] = {0, };
+ int state = E_INFO_KEY_STATE_ALL, code = 0, i;
+ char *tmp = NULL;
+
+ if (argc < 3)
+ {
+ _e_info_client_inputgen_usage();
+ return;
+ }
+
+ for (i = 2; i < argc; i++)
+ {
+ if (!strncmp(argv[i], "--name=", sizeof("--name=") - 1))
+ {
+ tmp = argv[i] + sizeof("--name=") - 1;
+ strncpy(name, tmp, strlen(tmp));
+ }
+ else if (!strncmp(argv[i], "--code=", sizeof("--code=") - 1))
+ {
+ tmp = argv[i] + sizeof("--code=") - 1;
+ code = atoi(tmp);
+ }
+ else if (!strncmp(argv[i], "--state=", sizeof("--state=") - 1))
+ {
+ tmp = argv[i] + sizeof("--state=") - 1;
+ if (!strncmp(tmp, "press", sizeof("press")) ||
+ !strncmp(tmp, "down", sizeof("down")) ||
+ !strncmp(tmp, "1", sizeof("1")))
+ {
+ state = E_INFO_KEY_STATE_PRESS;
+ }
+ else if (!strncmp(tmp, "release", sizeof("release")) ||
+ !strncmp(tmp, "up", sizeof("up")) ||
+ !strncmp(tmp, "0", sizeof("0")))
+ {
+ state = E_INFO_KEY_STATE_RELEASE;
+ }
+ else
+ {
+ printf("Please input correct key state (press/down/1) or (release/up/0)\n");
+ return;
+ }
+ }
+ else
+ {
+ _e_info_client_inputgen_usage();
+ return;
+ }
+ }
+
+ if (!code && name[0] == '\0')
+ {
+ printf("Please insert either name or code\n");
+ return;
+ }
+ else if (code && name[0] != '\0')
+ {
+ printf("Please insert only one between name and code\n");
+ return;
+ }
+
+ if (!_e_info_client_eldbus_message_with_args("keygen", _e_info_client_cb_keygen, "sii", name, code, state))
+ return;
+}
+
+
+
typedef struct _ProcInfo
{
const char *option;
},
};
+ProcInfo procs_to_input[] =
+{
+ {
+ "init_device", /* Option */
+ NULL,/* Params */
+ "Initialize input device", /* Description */
+ _e_info_client_proc_init_device /* func */
+ },
+ {
+ "deinit_device", /* Option */
+ NULL,/* Params */
+ "Deinitialize input device", /* Description */
+ _e_info_client_proc_deinit_device /* func */
+ },
+ {
+ "keygen", /* Option */
+ NULL,/* Params */
+ "Generate key events", /* Description */
+ _e_info_client_proc_keygen /* func */
+ },
+};
+
static Eina_List *list_tracelogs = NULL;
static Eina_List *list_printinfo = NULL;
static Eina_List *list_exec= NULL;
+static Eina_List *list_input = NULL;
static int
_util_sort_string_cb(const void *data1, const void *data2)
list_tracelogs = eina_list_free(list_tracelogs);
list_printinfo = eina_list_free(list_printinfo);
list_exec = eina_list_free(list_exec);
+ list_input = eina_list_free(list_input);
}
static void
_e_info_client_init_list(void)
{
int n_info = 0, i;
- list_tracelogs = list_printinfo = list_exec = NULL;
+ list_tracelogs = list_printinfo = list_exec = list_input = NULL;
n_info = sizeof(procs_to_tracelogs) / sizeof(procs_to_tracelogs[0]);
for (i = 0; i < n_info; i++)
list_exec = eina_list_append(list_exec, &procs_to_execute[i]);
}
list_exec = eina_list_sort(list_exec, eina_list_count(list_exec), _util_sort_string_cb);
+
+ n_info = sizeof(procs_to_input) / sizeof(procs_to_input[0]);
+ for (i = 0; i < n_info; i++)
+ {
+ list_input = eina_list_append(list_input, &procs_to_input[i]);
+ }
+ list_input = eina_list_sort(list_input, eina_list_count(list_input), _util_sort_string_cb);
}
static void
}
}
+ EINA_LIST_FOREACH(list_input, l, procinfo)
+ {
+ proc_option_length = strlen(procinfo->option);
+ if (argv_len != proc_option_length) continue;
+ if (!strncmp(argv[1]+1, procinfo->option, proc_option_length))
+ {
+ if (procinfo->func)
+ procinfo->func(argc, argv);
+
+ return EINA_TRUE;
+ }
+ }
+
return EINA_FALSE;
}
{
printf(" %s -%s %s\n", exec, procinfo->option, (procinfo->params)?procinfo->params:"");
}
+ printf("\n\n");
+ EINA_LIST_FOREACH(list_input, l, procinfo)
+ {
+ printf(" %s -%s %s\n", exec, procinfo->option, (procinfo->params)?procinfo->params:"");
+ }
}
static void
}
}
+ EINA_LIST_FOREACH(list_input, l, procinfo)
+ {
+ optlen = strlen(procinfo->option);
+ if (arglen != optlen) continue;
+ if (!strncmp(argv[1]+1, procinfo->option, optlen))
+ {
+ printf(" %s\n\n", (procinfo->description)?procinfo->description:"");
+ printf(" %s -%s %s\n", argv[0], procinfo->option, (procinfo->params)?procinfo->params:"");
+ goto end;
+ }
+ }
+
end:
printf("\n");
}
printf(" -%-30s\t", procinfo->option);
printf(": %s\n", (procinfo->description)?procinfo->description:"");
}
+ printf("\n");
+ EINA_LIST_FOREACH(list_input, l, procinfo)
+ {
+ printf(" -%-30s\t", procinfo->option);
+ printf(": %s\n", (procinfo->description)?procinfo->description:"");
+ }
printf("\n");
}
#include "e_info_protocol.h"
#include <dlfcn.h>
#include "e_comp_object.h"
+#include "e_info_server_input.h"
#define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT
#include <Edje_Edit.h>
return reply;
}
+static Eldbus_Message *
+_e_info_server_cb_init_device(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+ Eldbus_Message *reply;
+ char *name = NULL, *result = NULL;
+ unsigned int type = 0x0;
+
+ if (!eldbus_message_arguments_get(msg, "us", &type, &name))
+ {
+ return eldbus_message_error_new(msg, "InputUtilFailed",
+ "input: an attempt to excute input util from method call message failed");
+ }
+
+ result = e_info_server_input_init_device(type, name);
+
+ reply = eldbus_message_method_return_new(msg);
+
+ eldbus_message_arguments_append(reply, "s", result);
+
+ return reply;
+}
+
+static Eldbus_Message *
+_e_info_server_cb_deinit_device(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+ Eldbus_Message *reply;
+
+ e_info_server_input_deinit_device();
+
+ reply = eldbus_message_method_return_new(msg);
+
+ return reply;
+}
+
+static Eldbus_Message *
+_e_info_server_cb_keygen(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+ Eldbus_Message *reply;
+ char *name = NULL, *result = NULL;
+ int code = 0, state = 0;
+
+ if (!eldbus_message_arguments_get(msg, "sii", &name, &code, &state))
+ {
+ return eldbus_message_error_new(msg, "KeygenFailed",
+ "keygen: an attempt to generate key event from method call message failed");
+ }
+
+ result = e_info_server_input_keygen(name, code, state);
+ reply = eldbus_message_method_return_new(msg);
+
+ eldbus_message_arguments_append(reply, "s", result);
+
+ return reply;
+}
+
//{ "method_name", arguments_from_client, return_values_to_client, _method_cb, ELDBUS_METHOD_FLAG },
static const Eldbus_Method methods[] = {
{ "get_window_info", NULL, ELDBUS_ARGS({"iiiiisiiiiia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}), _e_info_server_cb_window_info_get, 0 },
{ "screen_info", ELDBUS_ARGS({"i", "option"}), ELDBUS_ARGS({"as", "screen info"}), _e_info_server_cb_screen_info_get, 0 },
{ "focus_policy_ext_set", ELDBUS_ARGS({"i", "option"}), ELDBUS_ARGS({"i", "result"}), _e_info_server_cb_focus_policy_ext_set, 0 },
{ "focus_history", NULL, ELDBUS_ARGS({"a(ubbbs)", "history array"}), _e_info_server_cb_focus_history, 0 },
+ { "init_device", ELDBUS_ARGS({"us", "device information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_init_device, 0},
+ { "deinit_device", NULL, NULL, _e_info_server_cb_deinit_device, 0},
+ { "keygen", ELDBUS_ARGS({"sii", "key information"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_keygen, 0},
{ NULL, NULL, NULL, NULL, 0 }
};
--- /dev/null
+#include "e.h"
+#include "e_info_server_input.h"
+#include "e_info_shared_types.h"
+
+#include <linux/uinput.h>
+
+typedef struct _E_Info_Server_Input
+{
+ struct
+ {
+ Eina_Bool virtual_dev;
+ int fd;
+ } gen;
+} E_Info_Server_Input;
+
+static E_Info_Server_Input _e_info_input =
+{
+ {
+ EINA_FALSE, /* virtual_dev */
+ -1 /* fd */
+ }
+};
+
+
+static int
+_e_info_input_keygen_create_device(const char *dev_name)
+{
+ int fd_uinput = -1, nwrite = 0, i;
+ struct uinput_user_dev dev_uinput = {0, };
+
+ fd_uinput = open("/dev/uinput", O_WRONLY | O_NDELAY);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(fd_uinput >= 0, -1);
+
+ strncpy(dev_uinput.name, dev_name, UINPUT_MAX_NAME_SIZE - 1);
+ dev_uinput.id.version = 4;
+ dev_uinput.id.bustype = BUS_VIRTUAL;
+
+ ioctl(fd_uinput, UI_SET_EVBIT, EV_KEY);
+ ioctl(fd_uinput, UI_SET_EVBIT, EV_SYN);
+ ioctl(fd_uinput, UI_SET_EVBIT, EV_MSC);
+
+ for (i = KEY_ESC; i <= KEY_MAX; i++)
+ ioctl(fd_uinput, UI_SET_KEYBIT, i);
+
+ ioctl(fd_uinput, UI_SET_MSCBIT, MSC_SCAN);
+
+ /* Create input device into input sub-system */
+ nwrite = write(fd_uinput, &dev_uinput, sizeof(dev_uinput));
+ if (nwrite < 0) WRN("Failed to write for create device using uinput\n");
+
+ if (ioctl(fd_uinput, UI_DEV_CREATE))
+ {
+ WRN("Failed to create device(%s).", dev_name);
+ close (fd_uinput);
+ return -1;
+ }
+
+ return fd_uinput;
+}
+
+static int
+_e_info_input_keygen_open_device(char *identifier)
+{
+ int fd = -1;
+
+ fd = open(identifier, O_WRONLY | O_NDELAY);
+ if (fd < 0)
+ {
+ ERR("Failed to open %s node.\n", identifier);
+ return -1;
+ }
+
+ return fd;
+}
+
+static int
+_write_event_to_device_node(int type, int code, int value)
+{
+ int nwrite;
+ struct input_event ev;
+
+ gettimeofday(&ev.time, NULL);
+
+ ev.type = type;
+ ev.code = code;
+ ev.value = value;
+
+ nwrite = write(_e_info_input.gen.fd, &ev, sizeof(ev));
+ return nwrite;
+}
+
+static void
+_key_gen(int keycode, int value)
+{
+ _write_event_to_device_node(EV_KEY, keycode, value);
+}
+
+static void
+_sync_gen(void)
+{
+ _write_event_to_device_node(EV_SYN, 0, 0);
+}
+
+static void
+_key_gen_down(int key_code)
+{
+ _key_gen(key_code, 1);
+ _sync_gen();
+}
+
+static void
+_key_gen_up(int key_code)
+{
+ _key_gen(key_code, 0);
+ _sync_gen();
+}
+
+static void
+_e_info_input_keygen(int key_code, int key_state)
+{
+ switch (key_state)
+ {
+ case E_INFO_KEY_STATE_PRESS:
+ _key_gen_down(key_code);
+ break;
+ case E_INFO_KEY_STATE_RELEASE:
+ _key_gen_up(key_code);
+ break;
+ case E_INFO_KEY_STATE_ALL:
+ _key_gen_down(key_code);
+ _key_gen_up(key_code);
+ break;
+ default:
+ return;
+ }
+}
+
+static void
+_e_info_input_keygen_close_device(void)
+{
+ int ret;
+
+ if (_e_info_input.gen.virtual_dev)
+ {
+ ret = ioctl(_e_info_input.gen.fd, UI_DEV_DESTROY, NULL);
+ if (ret) WRN("Failed destroy fd: %d (ret: %d)\n", _e_info_input.gen.fd, ret);
+ }
+ close(_e_info_input.gen.fd);
+
+ _e_info_input.gen.fd = -1;
+ _e_info_input.gen.virtual_dev = EINA_FALSE;
+}
+
+char *
+e_info_server_input_init_device(unsigned int type, char *name)
+{
+ int fd = -1;
+ Eina_List *device_list, *l;
+ Ecore_Device *dev;
+
+ if (_e_info_input.gen.fd >=0) return "Already opened device is exist";
+ if (type)
+ {
+ if (type & E_INPUT_SEAT_KEYBOARD)
+ {
+ fd = _e_info_input_keygen_create_device(name);
+ _e_info_input.gen.virtual_dev = EINA_TRUE;
+ _e_info_input.gen.fd = fd;
+ }
+ else
+ {
+ WRN("Currently only keyboard is supported.\n");
+ }
+ }
+ else
+ {
+ device_list = (Eina_List *)ecore_device_list();
+ EINA_SAFETY_ON_NULL_RETURN_VAL(device_list, "No Opened device");
+
+ EINA_LIST_FOREACH(device_list, l, dev)
+ {
+ if (ecore_device_class_get(dev) != ECORE_DEVICE_CLASS_KEYBOARD)
+ continue;
+ if (!e_util_strcmp(name, ecore_device_identifier_get(dev)))
+ {
+ fd = _e_info_input_keygen_open_device(name);
+ _e_info_input.gen.virtual_dev = EINA_FALSE;
+ _e_info_input.gen.fd = fd;
+ }
+ }
+ }
+
+ if (fd < 0)
+ {
+ _e_info_input.gen.virtual_dev = EINA_FALSE;
+ _e_info_input.gen.fd = -1;
+ return "Failed to open event node or uinput node";
+ }
+
+ return E_INFO_INPUT_RESULT_NONE;
+}
+
+void
+e_info_server_input_deinit_device(void)
+{
+ if (_e_info_input.gen.fd < 0) return;
+
+ if (_e_info_input.gen.virtual_dev)
+ _e_info_input_keygen_close_device();
+ else
+ {
+ close(_e_info_input.gen.fd);
+
+ _e_info_input.gen.fd = -1;
+ _e_info_input.gen.virtual_dev = EINA_FALSE;
+ }
+
+ return;
+}
+
+char
+*e_info_server_input_keygen(char *name, int code, int state)
+{
+ if (_e_info_input.gen.fd < 0) return "Initialize device first";
+
+ if (strlen(name) > 0)
+ {
+ code = e_comp_wl_input_keymap_keyname_to_keycode(name) - 8;
+ }
+ else
+ code = code - 8;
+
+ _e_info_input_keygen(code, state);
+
+ return E_INFO_INPUT_RESULT_NONE;
+}