src/bin/server/e_comp_wl.c \
src/bin/server/e_comp_wl_data.c \
src/bin/server/e_comp_wl_input.c \
+src/bin/server/e_comp_wl_input_thread.c \
src/bin/server/e_comp_wl_subsurface.c \
src/bin/server/e_comp_wl_tbm.c \
src/bin/server/e_comp_wl_renderer.c \
E_CLIENT_REVERSE_FOREACH(cec)
{
- if (_e_client_under_pointer_helper_ignore_client(desk, cec)) continue;
+ Eina_Bool ignore_client = _e_client_under_pointer_helper_ignore_client(desk, cec);
+ if (ignore_client) continue;
Eina_List *list = NULL;
Eina_Rectangle *rect;
if (!ec) return EINA_FALSE;
return ec->vkbd.vkbd;
}
+
/////////////////////////////////////////////////////////
EINTERN E_Comp_Wl_Subsurf_Data *
e_client_subsurface_data_try_get(E_Client *ec)
printf("%s", USAGE_VIDEO_SHELL);
}
+static void
+_e_info_client_proc_pointer_thread_mode(int argc, char **argv)
+{
+ int set = 0;
+ Eina_Bool res;
+
+ EINA_SAFETY_ON_FALSE_GOTO(argc == 3, usage);
+
+ set = atoi(argv[2]);
+ if ((set != 0) && (set != 1))
+ goto usage;
+
+ res = _e_info_client_eldbus_message_with_args("pointer_thread_mode", NULL, "i", set);
+ EINA_SAFETY_ON_FALSE_RETURN(res);
+
+ goto finish;
+
+usage :
+ printf("Usage: %s -pointer_thread_mode [0:unset(default), 1:set(input thread)]\n", argv[0]);
+
+finish:
+ return;
+}
+
typedef struct _ProcInfo
{
const char *option;
"Print key events elapsed time (default path:/tmp/elapsed_time.txt)", /* Description */
_e_info_client_proc_key_elapsed_time /* func */
},
+ {
+ "pointer_thread_mode",
+ "[0:unset(default), 1:set(input thread)]",
+ "Set/Unset pointer_thread_mode",
+ _e_info_client_proc_pointer_thread_mode
+ },
};
static Eina_List *list_tracelogs = NULL;
return reply;
}
+static Eldbus_Message *
+_e_info_server_cb_pointer_thread_mode(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Message *msg)
+{
+ Eldbus_Message *reply = eldbus_message_method_return_new(msg);
+ int set = 0;
+
+ if (!eldbus_message_arguments_get(msg, "i", &set))
+ {
+ ERR("Failed to get argument");
+ return reply;
+ }
+
+ if (set)
+ {
+ e_input_pointer_thread_mode_set(EINA_TRUE);
+ }
+ else
+ {
+ e_input_pointer_thread_mode_set(EINA_FALSE);
+ }
+
+ 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({"iiisiiia("VALUE_TYPE_FOR_TOPVWINS")", "array of ec"}), _e_info_server_cb_window_info_get, 0 },
{ VIDEO_SHELL_BORDER_METHOD_NAME, ELDBUS_ARGS({"b", "The command for border of video viewport"}), NULL, _e_info_server_cb_video_shell_border, 0},
{ VIDEO_SHELL_INFO_METHOD_NAME, ELDBUS_ARGS({"s", "Print video shell information"}), NULL, _e_info_server_cb_video_shell_info, 0},
{ "key_elapsed_time", ELDBUS_ARGS({"i", "key elapsed time"}), ELDBUS_ARGS({"s", "result message"}), _e_info_server_cb_key_elapsed_time, 0},
+ { "pointer_thread_mode", ELDBUS_ARGS({"i", "set pointer_thread_mode"}), NULL, _e_info_server_cb_pointer_thread_mode, 0 },
{ NULL, NULL, NULL, NULL, 0 }
};
static GList *_key_event_list = NULL;
static GList *_elapsed_time_list = NULL;
static int _print_count = 0;
+static Eina_Bool g_pointer_thread_mode = EINA_FALSE;
GSourceFuncs input_event_funcs = {
.prepare = input_thread_prepare,
{
e_input_backend_thread_safe_call(_e_input_thread_cb_print_count_set, &count, sizeof(int));
}
+
+EINTERN Eina_Bool
+e_input_pointer_thread_mode_get()
+{
+ return g_pointer_thread_mode;
+}
+
+EINTERN void
+e_input_pointer_thread_mode_set(Eina_Bool set)
+{
+ g_pointer_thread_mode = set;
+}
+
{
Ecore_Event_Mouse_Move *ev = event;
- if (ev->dev) ecore_device_unref(ev->dev);
+ if (ev->dev)
+ {
+ if (e_input_thread_mode_get() && e_input_pointer_thread_mode_get())
+ g_object_unref(ev->dev);
+ else
+ ecore_device_unref(ev->dev);
+ }
free(ev);
}
if (tmp) free(tmp);
}
-static void
-_device_pointer_motion(E_Input_Evdev *evdev, struct libinput_event_pointer *event)
+static Ecore_Device *
+_device_pointer_send_motion(E_Input_Evdev *evdev)
{
E_Input_Backend *input;
- Ecore_Event_Mouse_Move *ev;
Ecore_Device *ecore_dev = NULL, *data, *detent_data = NULL;
Eina_List *l;
const char *device_name = NULL;
- uint32_t timestamp = 0;
-
- if (!(input = evdev->seat->input)) return;
-
- ecore_thread_main_loop_begin();
+ if (!(input = evdev->seat->input)) return NULL;
device_name = evdev->name;
- if (event)
- timestamp = libinput_event_pointer_get_time(event);
if (evdev->ecore_dev) ecore_dev = evdev->ecore_dev;
else if (evdev->ecore_dev_list && eina_list_count(evdev->ecore_dev_list) > 0)
if (!ecore_dev)
{
ERR("Failed to get source ecore device from event !\n");
- goto end;
+ return NULL;
}
else if ((detent_data == ecore_dev) || e_devicemgr_detent_is_detent(ecore_device_name_get(ecore_dev)))
{
/* Do not process detent device's move events. */
- goto end;
+ return NULL;
}
+ return ecore_dev;
+}
+
+static E_Device *
+_device_pointer_send_motion_thread_mode(E_Input_Evdev *evdev)
+{
+ E_Input_Backend *input;
+ E_Device *e_dev = NULL, *e_dev_data, *detent_data = NULL;
+ GList *glist = NULL;
+ const char *device_name = NULL;
+
+ if (!(input = evdev->seat->input)) return NULL;
+ device_name = evdev->name;
+
+ if (evdev->e_dev) e_dev = evdev->e_dev;
+ else if (evdev->e_dev_list && g_list_length(evdev->e_dev_list) > 0)
+ {
+ glist = evdev->e_dev_list;
+ while (glist)
+ {
+ e_dev_data = glist->data;
+ if (e_device_class_get(e_dev_data) == ECORE_DEVICE_CLASS_MOUSE)
+ {
+ e_dev = e_dev_data;
+ break;
+ }
+ else if (e_device_class_get(e_dev_data) == ECORE_DEVICE_CLASS_NONE)
+ {
+ detent_data = e_dev_data;
+ break;
+ }
+ }
+ if (!e_dev && e_devicemgr_detent_is_detent(device_name))
+ {
+ e_dev = detent_data;
+ }
+ }
+ else
+ {
+ evdev->e_dev = e_input_evdev_e_device_get(evdev->path, ECORE_DEVICE_CLASS_MOUSE);
+ e_dev = evdev->e_dev;
+ }
+
+ if (!e_dev)
+ {
+ ERR("Failed to get source ecore device from event !\n");
+ return NULL;
+ }
+ else if ((detent_data == e_dev) || e_devicemgr_detent_is_detent(e_device_name_get(e_dev)))
+ {
+ /* Do not process detent device's move events. */
+ return NULL;
+ }
+
+ return e_dev;
+}
+
+static void
+_device_pointer_motion(E_Input_Evdev *evdev, struct libinput_event_pointer *event)
+{
+ Ecore_Device *ecore_dev = NULL;
+ E_Device *e_dev = NULL;
+ Ecore_Event_Mouse_Move *ev;
+ E_Input_Backend *input;
+ uint32_t timestamp = 0;
+ const char *device_name = evdev->name;
+
+ if (!(input = evdev->seat->input)) return;
+ if (event)
+ timestamp = libinput_event_pointer_get_time(event);
+
if (!(ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)))) return;
evdev->mouse.dx = evdev->seat->ptr.dx;
{
ev->timestamp = e_util_timestamp_get();
ELOGF("Mouse", "Move (x: %d, y: %d, timestamp: %u (current time), device: %s)", NULL,
- ev->x, ev->y, ev->timestamp, ecore_device_name_get(ecore_dev));
+ ev->x, ev->y, ev->timestamp, device_name);
}
ev->multi.device = evdev->mt_slot;
ev->multi.root.x = ev->x;
ev->multi.root.y = ev->y;
- ev->dev = ecore_device_ref(ecore_dev);
+ if (e_input_thread_mode_get() && e_input_pointer_thread_mode_get())
+ {
+ e_dev = _device_pointer_send_motion_thread_mode(evdev);
+ ev->dev = (Eo *)g_object_ref(e_dev);
+ e_input_event_add(input->event_source, ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+ }
+ else
+ {
+ ecore_thread_main_loop_begin();
- ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
+ ecore_dev = _device_pointer_send_motion(evdev);
+ ev->dev = ecore_device_ref(ecore_dev);
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, _e_input_event_mouse_move_cb_free, NULL);
-end:
- ecore_thread_main_loop_end();
+ ecore_thread_main_loop_end();
+ }
}
void
EINTERN void e_input_hook_call(E_Input_Hook_Point hookpoint, const char *device_name);
+EINTERN Eina_Bool e_input_pointer_thread_mode_get();
+EINTERN void e_input_pointer_thread_mode_set(Eina_Bool set);
+
#endif
EINTERN Eina_Bool e_input_thread_check_client_cloning_needed()
{
- // Disable cloning of e_client data temporarily.
- return EINA_FALSE;
+ return EINA_TRUE;
}
E_API E_Input_Thread_Client *e_input_thread_client_above_get(E_Input_Thread_Client *iec)
#include "e_comp_wl_viewport_intern.h"
#include "e_comp_intern.h"
#include "e_input_backend_intern.h"
+#include "e_input_event_intern.h"
#include "e_keyrouter_wl_intern.h"
#include "e_error_intern.h"
#include "e_pointer_intern.h"
#include "e_comp_input_intern.h"
#include "e_blur_intern.h"
#include "e_input_thread_client_intern.h"
+#include "e_input_thread_client.h"
#include "e_display_intern.h"
#include "e_devicemgr_wl_intern.h"
#include "e_view_client_intern.h"
+#include "e_comp_wl_input_thread_intern.h"
#include <tizen-extension-server-protocol.h>
#include <relative-pointer-unstable-v1-server-protocol.h>
static Eina_List *hooks = NULL;
static Eina_Bool serial_trace_debug = 0;
+static E_Input_Hook *input_hook = NULL;
+
/* local functions */
static void
_e_comp_wl_hooks_clean(void)
e_comp_wl_touch_frame_send_ec_set(NULL);
}
-static void
-_e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp)
+EINTERN void
+e_comp_wl_surface_send_mouse_move(struct wl_resource *surface, int x, int y, int client_x, int client_y, unsigned int timestamp)
{
struct wl_resource *res;
struct wl_client *wc;
Eina_List *l;
- if (!ec) return;
- if (ec->cur_mouse_action) return;
- if (e_object_is_del(E_OBJECT(ec))) return;
- struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
if (!surface) return;
wc = wl_resource_get_client(surface);
if (!e_comp_wl_input_pointer_check(res)) continue;
if (wl_resource_get_client(res) != wc) continue;
wl_pointer_send_motion(res, timestamp,
- wl_fixed_from_int(x - ec->client.x),
- wl_fixed_from_int(y - ec->client.y));
+ wl_fixed_from_int(x - client_x),
+ wl_fixed_from_int(y - client_y));
}
}
static void
+_e_comp_wl_send_mouse_move(E_Client *ec, int x, int y, unsigned int timestamp)
+{
+ if (!ec) return;
+ if (ec->cur_mouse_action) return;
+ if (e_object_is_del(E_OBJECT(ec))) return;
+ struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
+ e_comp_wl_surface_send_mouse_move(surface, x, y, ec->client.x, ec->client.y, timestamp);
+}
+
+static void
_e_comp_wl_cursor_move_timer_control(E_Client *ec)
{
if (e_comp_wl->ptr.hide_tmr)
Evas_Device *dev = NULL;
const char *dev_name;
E_Comp_Config *comp_conf;
+ Evas_Device_Class dev_class;
ev = event;
dev = ev->dev;
dev_name = evas_device_description_get(dev);
+ dev_class = evas_device_class_get(dev);
comp_conf = e_comp_config_get();
if (comp_conf && comp_conf->input_log_enable)
ec, obj, ev->timestamp, ev->cur.canvas.x, ev->cur.canvas.y, ev->cur.output.x, ev->cur.output.y,
e_client_util_name_get(ec), dev_name);
- if (dev && (evas_device_class_get(dev) == EVAS_DEVICE_CLASS_TOUCH))
+ if (dev && (dev_class == EVAS_DEVICE_CLASS_TOUCH))
{
if (!e_comp_wl->drag_client)
{
{
_e_comp_wl_device_send_event_device(ec, dev, ev->timestamp);
if (dev_name)
- _e_comp_wl_device_handle_axes(dev_name, evas_device_class_get(dev),
+ _e_comp_wl_device_handle_axes(dev_name, dev_class,
ec, 0, ev->radius_x, ev->radius_y, ev->pressure, ev->angle);
_e_comp_wl_send_touch_move(ec, 0, ev->cur.canvas.x, ev->cur.canvas.y, ev->timestamp);
}
E_FREE(e_comp_wl->evas_gl);
}
+static void
+_e_comp_wl_cb_input_thread_start(void *data, const char *device_name)
+{
+ INF("Input thread hook cb ");
+ e_comp_wl_input_thread_add_e_input_handlers();
+}
+
/* public functions */
/**
E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREEN_CHANGE, _e_comp_wl_cb_randr_change, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD, _e_comp_wl_cb_comp_object_add, NULL);
E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_MOVE, _e_comp_wl_cb_mouse_move, NULL);
+ if (e_input_thread_mode_get())
+ {
+ if (e_input_thread_id_get())
+ {
+ ERR("Input thread is ready. add handlers");
+ e_comp_wl_input_thread_add_e_input_handlers();
+ }
+ else
+ {
+ ERR("Input thread is not ready YET. add hook");
+ input_hook = e_input_hook_add(E_INPUT_HOOK_INPUT_THREAD_START,
+ (E_Input_Hook_Cb)_e_comp_wl_cb_input_thread_start, NULL);
+ }
+ }
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_RELATIVE_MOVE, _e_comp_wl_cb_mouse_relative_move, NULL);
E_LIST_HANDLER_PREPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_CANCEL, _e_comp_wl_cb_mouse_button_cancel, NULL);
E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DISPLAY_STATE_CHANGE, _e_comp_wl_cb_zone_display_state_change, NULL);
/* free handlers */
E_FREE_LIST(handlers, ecore_event_handler_del);
E_FREE_LIST(hooks, e_client_hook_del);
+
+ if (e_input_thread_mode_get())
+ e_input_hook_del(input_hook);
+
+ e_comp_wl_input_thread_remove_e_input_handlers();
_e_comp_wl_gl_shutdown();
e_comp_wl_capture_shutdown();
--- /dev/null
+#include "e_comp_wl_intern.h"
+#include "e_input.h"
+#include "e_input_intern.h"
+#include "e_comp_wl_input_intern.h"
+#include "e_input_event_intern.h"
+#include "e_input_thread_client_intern.h"
+#include "e_input_thread_client.h"
+
+static E_Input_Event_Handler *_mouse_move_handler = NULL;
+static Eina_Bool e_input_handlers_added = EINA_FALSE;
+
+static Eina_Bool
+_e_input_thread_client_under_pointer_helper_ignore_client(E_Input_Thread_Client *iec)
+{
+ /* If a border was specified which should be excluded from the list
+ * (because it will be closed shortly for example), skip */
+ E_Visibility vis = e_input_thread_client_visibility_get(iec);
+ if (vis != E_VISIBILITY_UNOBSCURED &&
+ vis != E_VISIBILITY_PARTIALLY_OBSCURED)
+ return EINA_TRUE;
+
+ if (e_input_thread_client_cursor_mode_get(iec)) return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
+static E_Input_Thread_Client *
+_e_comp_wl_input_thread_client_under_pointer(int x, int y)
+{
+ E_Input_Thread_Client *iec, *target_iec = NULL;
+ Eina_Bool inside = EINA_FALSE;
+ int cx, cy, cw, ch;
+ Eina_Bool ignore_client = EINA_FALSE;
+ GList *input_region_list = NULL;
+ Eina_Rectangle *rect;
+ int ir_x, ir_y, ir_w, ir_h;
+
+ for (iec = e_input_thread_client_top_get(); iec; iec = e_input_thread_client_below_get(iec))
+ {
+ ignore_client = _e_input_thread_client_under_pointer_helper_ignore_client(iec);
+
+ if (ignore_client) continue;
+
+ e_input_thread_client_geometry_get(iec, &cx, &cy, &cw, &ch);
+ e_input_thread_client_input_region_get(iec, &input_region_list);
+ if (input_region_list)
+ {
+ for (GList *list = g_list_first(input_region_list); list; list = list->next)
+ {
+ rect = (Eina_Rectangle *)list->data;
+
+ ir_x = rect->x;
+ ir_y = rect->y;
+ ir_w = rect->w;
+ ir_h = rect->h;
+
+ if (E_INSIDE(x, y, ir_x, ir_y, ir_w, ir_h))
+ {
+ inside = EINA_TRUE;
+ }
+ }
+ }
+ else if (E_INSIDE(x, y, cx, cy, cw, ch))
+ {
+ inside = EINA_TRUE;
+ }
+
+ if (!inside) continue;
+ else
+ {
+ target_iec = iec;
+ break;
+ }
+ }
+
+ return target_iec;
+}
+
+static Eina_Bool
+_e_comp_wl_cb_mouse_move_thread_mode(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
+{
+ Ecore_Event_Mouse_Move *ev = event;
+ E_Input_Thread_Client *iec;
+ E_Comp_Config *comp_conf;
+ E_Device *dev = NULL;
+ const char *dev_name;
+ Ecore_Device_Class dev_class;
+ int client_x = 0, client_y = 0;
+
+ e_comp_wl->ptr.x = wl_fixed_from_int(ev->x);
+ e_comp_wl->ptr.y = wl_fixed_from_int(ev->y);
+
+ ELOGF("Mouse", "E Event Mouse Move (time: %d, x:%d y:%d)", NULL, ev->timestamp, ev->x, ev->y);
+
+ if (!e_input_pointer_thread_mode_get()) return ECORE_CALLBACK_RENEW;
+
+ iec = _e_comp_wl_input_thread_client_under_pointer(ev->x, ev->y);
+ if (!iec)
+ return ECORE_CALLBACK_RENEW;
+
+ struct wl_resource *surface = e_input_thread_client_wl_resource_get(iec);
+ if (!surface)
+ {
+ ELOGF("Mouse", "Move. surface NULL", NULL);
+ goto err;
+ }
+
+ dev = (E_Device *)ev->dev;
+ dev_name = e_device_name_get(dev);
+ dev_class = e_device_class_get(dev);
+
+ comp_conf = e_comp_config_get();
+ if (comp_conf && comp_conf->input_log_enable)
+ ELOGF("Mouse", "Move (time: %d, output(%d, %d), name:%20s) (dev:%s, device class:%d)",
+ NULL, ev->timestamp, ev->x, ev->y,
+ e_input_thread_client_util_name_get(iec), dev_name, dev_class);
+
+ e_input_thread_client_geometry_get(iec, &client_x, &client_y, NULL, NULL);
+
+ e_comp_wl_surface_send_mouse_move(surface, ev->x, ev->y, client_x, client_y, ev->timestamp);
+
+ e_pointer_mouse_move(e_comp->pointer, ev->x, ev->y);
+
+err:
+ return ECORE_CALLBACK_RENEW;
+}
+
+EINTERN void
+e_comp_wl_input_thread_add_e_input_handlers()
+{
+ E_Input_Event_Source *input_event_source = NULL;
+
+ if (e_input_handlers_added == EINA_TRUE)
+ return;
+
+ if (e_input_thread_mode_get())
+ {
+ input_event_source = e_input_event_source_get();
+ if (input_event_source)
+ {
+ INF("Succeeded to get input_event_source");
+ if (!_mouse_move_handler)
+ _mouse_move_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_MOUSE_MOVE, _e_comp_wl_cb_mouse_move_thread_mode, NULL);
+
+ e_input_handlers_added = EINA_TRUE;
+ }
+ }
+ else
+ ERR("Input source is NULL. handlers not added yet");
+}
+
+EINTERN void
+e_comp_wl_input_thread_remove_e_input_handlers()
+{
+ E_Input_Event_Source *input_event_source = NULL;
+
+ if (e_input_handlers_added == EINA_TRUE)
+ return;
+
+ if (e_input_thread_mode_get())
+ {
+ input_event_source = e_input_event_source_get();
+ if (input_event_source)
+ {
+ INF("Succeeded to get input_event_source");
+ e_input_event_handler_del(input_event_source, _mouse_move_handler);
+
+ _mouse_move_handler = NULL;
+ }
+ }
+ else
+ ERR("Input source is NULL. handlers not added yet");
+}
--- /dev/null
+#ifndef E_COMP_WL_INPUT_THREAD_INTERN_H
+#define E_COMP_WL_INPUT_THREAD_INTERN_H
+
+#include "e_intern.h"
+
+EINTERN void e_comp_wl_input_thread_add_e_input_handlers();
+EINTERN void e_comp_wl_input_thread_remove_e_input_handlers();
+
+#endif
EINTERN void e_comp_wl_trace_serial_debug(Eina_Bool on);
+EINTERN void e_comp_wl_surface_send_mouse_move(struct wl_resource *surface, int x, int y, int client_x, int client_y, unsigned int timestamp);
+
#endif
_e_pointer_hook_call(E_POINTER_HOOK_TOUCH_MOVE, ptr);
}
+static void
+_pointer_position_update(void *data)
+{
+ E_Pointer *ptr = data;
+ _e_pointer_position_update(ptr);
+}
+
E_API void
e_pointer_mouse_move(E_Pointer *ptr, int x, int y)
{
if (ptr->device != E_POINTER_MOUSE) ptr->device = E_POINTER_MOUSE;
- _e_pointer_position_update(ptr);
+ ecore_main_loop_thread_safe_call_async(_pointer_position_update, ptr);
_e_pointer_hook_call(E_POINTER_HOOK_MOUSE_MOVE, ptr);
}
E_API Eina_Bool e_client_vkbd_floating_state_get(E_Client *ec);
E_API void e_client_vkbd_vkbd_set(E_Client *ec, Eina_Bool set);
E_API Eina_Bool e_client_vkbd_vkbd_get(E_Client *ec);
+
/////////////////////////////////////////////////////////
#endif