#include <relative-pointer-unstable-v1-server-protocol.h>
#include <pointer-constraints-unstable-v1-server-protocol.h>
+#include <tizen-pointergrab-ext-server-protocol.h>
+
+#ifdef HAVE_CYNARA
+# include <cynara-session.h>
+# include <cynara-client.h>
+# include <cynara-creds-socket.h>
+# include <sys/smack.h>
+#endif
+
+#ifdef HAVE_CYNARA
+static cynara *pointergrab_cynara = NULL;
+static Eina_Bool pointergrab_cynara_initialized;
+#endif
typedef struct _E_Comp_Wl_Pointer_Constraint E_Comp_Wl_Pointer_Constraint;
static char *_env_e_default_xkb_variant = NULL;
static char *_env_e_default_xkb_opts = NULL;
+static void
+_e_comp_wl_input_pointergrab_unlock_pointer(struct wl_client *client,
+ struct wl_resource *resource);
+
static void
_e_comp_wl_input_update_seat_caps(struct wl_client *wc)
{
_e_comp_wl_input_relative_motion_handler(double dx[2], double dy[2], uint64_t time_us)
{
Eina_Bool res;
- res = e_comp_wl_mouse_relative_motion_send(e_comp_wl->ptr_constraints.ec,
- (int)dx[0], (int)dy[0], (int)dx[1], (int)dy[1], time_us);
+
+ ERR("_e_comp_wl_input_relative_motion_handler()");
+
+ if (e_comp_wl->ptr_constraints.ec)
+ {
+ res = e_comp_wl_mouse_relative_motion_send(e_comp_wl->ptr_constraints.ec,
+ (int)dx[0], (int)dy[0], (int)dx[1], (int)dy[1], time_us);
+ }
+ else
+ {
+ res = e_comp_wl_mouse_pointergrab_relative_motion_send(e_comp_wl->pointergrab.client,
+ (int)dx[0], (int)dy[0], (int)dx[1], (int)dy[1], time_us);
+ }
if (!res)
{
}
}
+void
+_e_comp_wl_input_pointergrab_motion_handler(double x, double y, uint32_t timestamp)
+{
+ Eina_Bool res;
+ ERR("_e_comp_wl_input_pointergrab_motion_handler()");
+ res = e_comp_wl_mouse_pointergrab_motion_send(e_comp_wl->pointergrab.client,
+ (int)x, (int)y, timestamp);
+
+ if (!res)
+ {
+ ERR("Could not send pointergrab_motion to client(%p)", e_comp_wl->pointergrab.client);
+ }
+}
+
static void
_e_comp_wl_input_convert_eina_tiler_to_pixman_region32(const Eina_Tiler *tiler,
pixman_region32_t *region)
_e_comp_wl_input_cb_unbind_locked_pointer(struct wl_resource *resource)
{
E_Comp_Wl_Pointer_Constraint *constraint;
- constraint = wl_resource_get_user_data(resource);
+ ERR("_e_comp_wl_input_cb_unbind_locked_pointer()");
+
+ if (e_comp_wl->pointergrab.client)
+ {
+ struct wl_client *wc = wl_resource_get_client(resource);
+ if (e_comp_wl->pointergrab.client == wc)
+ _e_comp_wl_input_pointergrab_unlock_pointer(wc, resource);
+ }
+ constraint = wl_resource_get_user_data(resource);
if (!constraint)
return;
struct wl_resource *resource)
{
E_Comp_Wl_Pointer_Constraint *constraint;
+ ERR("_e_comp_wl_input_cb_locked_pointer_destroy()");
constraint = wl_resource_get_user_data(resource);
if (constraint &&
_e_comp_wl_input_cb_locked_pointer_set_region,
};
+static void
+_e_comp_wl_input_pointergrab_lock_pointer(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id,
+ struct wl_resource *pointer,
+ uint32_t lifetime)
+{
+ ERR("_e_comp_wl_input_pointergrab_lock_pointer()");
+
+ struct wl_resource *res;
+ res = wl_resource_create(client, &zwp_locked_pointer_v1_interface, 1, id);
+
+ if (!res)
+ {
+ ERR("Could not create a resource for zwp_locked_pointer_v1: %m");
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ wl_resource_set_implementation(res, &_e_comp_wl_locked_pointer_interface,
+ NULL, _e_comp_wl_input_cb_unbind_locked_pointer);
+
+ if (!e_input_pointergrab_motion_handler_set(NULL))
+ ERR("ERROR! Could not set pointergrab motion handler !");
+ if (!e_input_relative_motion_handler_set(_e_comp_wl_input_relative_motion_handler))
+ ERR("ERROR! Could not set relative motion handler !");
+ zwp_locked_pointer_v1_send_locked(res);
+
+ e_comp_wl->pointergrab.locked = EINA_TRUE;
+}
+
+static void
+_e_comp_wl_input_pointergrab_unlock_pointer(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ ERR("_e_comp_wl_input_pointergrab_unlock_pointer()");
+
+ if (!e_input_pointergrab_motion_handler_set(_e_comp_wl_input_pointergrab_motion_handler))
+ ERR("ERROR! Could not set pointergrab motion handler !");
+ if (!e_input_relative_motion_handler_set(NULL))
+ ERR("ERROR! Could not set relative motion handler !");
+ zwp_locked_pointer_v1_send_unlocked(resource);
+
+ e_comp_wl->pointergrab.locked = EINA_FALSE;
+}
+
static void
_e_comp_wl_input_cb_pointer_constraints_lock_pointer(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *region,
uint32_t lifetime)
{
+ ERR("_e_comp_wl_input_cb_pointer_constraints_lock_pointer()");
+
+ if (e_comp_wl->pointergrab.client)
+ {
+ _e_comp_wl_input_pointergrab_lock_pointer(client, resource, id, pointer, lifetime);
+ }
+
if (!pointer || !surface)
{
ERR("Pointer resource or surface resource is invalid !");
wl_signal_emit(&e_comp_wl->ptr_constraints.surface_commit_signal, ec);
}
+#ifdef HAVE_CYNARA
+#define E_POINTERGRAB_CYNARA_ERROR_CHECK_GOTO(func_name, ret, label) \
+ do \
+ { \
+ if (EINA_UNLIKELY(CYNARA_API_SUCCESS != ret)) \
+ { \
+ _e_pointergrab_util_cynara_log(func_name, ret); \
+ goto label; \
+ } \
+ } \
+ while (0)
+
+static void
+_e_pointergrab_util_cynara_log(const char *func_name, int err)
+{
+#define CYNARA_BUFSIZE 128
+ char buf[CYNARA_BUFSIZE] = "\0";
+ int ret;
+
+ ret = cynara_strerror(err, buf, CYNARA_BUFSIZE);
+ if (ret != CYNARA_API_SUCCESS)
+ {
+ DBG("Failed to cynara_strerror: %d (error log about %s: %d)\n", ret, func_name, err);
+ return;
+ }
+ DBG("%s is failed: %s\n", func_name, buf);
+}
+
+static Eina_Bool
+_e_pointergrab_util_do_privilege_check(struct wl_client *client, int socket_fd, const char *rule)
+{
+ int ret, pid;
+ char *clientSmack=NULL, *uid=NULL, *client_session=NULL;
+ Eina_Bool res = EINA_FALSE;
+
+ /* If initialization of cynara has been failed, let's not to do further permission checks. */
+ if (pointergrab_cynara == NULL && pointergrab_cynara_initialized) return EINA_TRUE;
+ if (socket_fd < 0) return EINA_FALSE;
+
+ ret = cynara_creds_socket_get_client(socket_fd, CLIENT_METHOD_SMACK, &clientSmack);
+ E_POINTERGRAB_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_client", ret, finish);
+
+ ret = cynara_creds_socket_get_user(socket_fd, USER_METHOD_UID, &uid);
+ E_POINTERGRAB_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_user", ret, finish);
+
+ ret = cynara_creds_socket_get_pid(socket_fd, &pid);
+ E_POINTERGRAB_CYNARA_ERROR_CHECK_GOTO("cynara_creds_socket_get_pid", ret, finish);
+
+ client_session = cynara_session_from_pid(pid);
+
+ ret = cynara_check(pointergrab_cynara, clientSmack, client_session, uid, rule);
+
+ if (CYNARA_API_ACCESS_ALLOWED == ret)
+ res = EINA_TRUE;
+
+finish:
+ E_FREE(client_session);
+ E_FREE(clientSmack);
+ E_FREE(uid);
+
+ return res;
+}
+#endif
+
+static void
+_e_comp_wl_input_cb_pointergrab_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static void
+_e_pointergrab_cb_client_destroy(struct wl_listener *listener, void *data)
+{
+ ERR("_e_pointergrab_cb_client_destroy()");
+
+ e_comp_wl->pointergrab.client = NULL;
+ e_input_pointergrab_motion_handler_set(NULL);
+ e_input_relative_motion_handler_set(NULL);
+
+ if (e_comp_wl->pointergrab.client_destroy_listener.notify)
+ wl_list_remove(&e_comp_wl->pointergrab.client_destroy_listener.link);
+ e_comp_wl->pointergrab.client_destroy_listener.notify = NULL;
+}
+static int
+e_pointergrab_enabled_set(struct wl_client *client, struct wl_resource *resource, Eina_Bool enable)
+{
+ if (enable)
+ {
+ ERR("e_pointergrab_enabled_set() enabled:TRUE");
+ if (e_comp_wl->pointergrab.client && e_comp_wl->pointergrab.client != client)
+ return TIZEN_POINTERGRAB_ERROR_GRABBED_ALREADY;
+
+ e_comp_wl->pointergrab.client = client;
+ e_comp_wl->pointergrab.locked = EINA_FALSE;
+ if (!e_input_pointergrab_motion_handler_set(_e_comp_wl_input_pointergrab_motion_handler))
+ {
+ ERR("ERROR! Could not set pointergrab motion handler !");
+ return TIZEN_POINTERGRAB_ERROR_NO_SYSTEM_RESOURCES;
+ }
+ e_input_relative_motion_handler_set(NULL);
+
+ e_comp_wl->pointergrab.client_destroy_listener.notify = _e_pointergrab_cb_client_destroy;
+ wl_client_add_destroy_listener(client, &e_comp_wl->pointergrab.client_destroy_listener);
+ }
+ else
+ {
+ ERR("e_pointergrab_enabled_set() enabled:FALSE");
+ if (e_comp_wl->pointergrab.client && e_comp_wl->pointergrab.client != client)
+ return TIZEN_POINTERGRAB_ERROR_GRABBED_ALREADY;
+
+ e_comp_wl->pointergrab.client = NULL;
+ e_comp_wl->pointergrab.locked = EINA_FALSE;
+ e_input_pointergrab_motion_handler_set(NULL);
+ e_input_relative_motion_handler_set(NULL);
+
+ if (e_comp_wl->pointergrab.client_destroy_listener.notify)
+ wl_list_remove(&e_comp_wl->pointergrab.client_destroy_listener.link);
+ e_comp_wl->pointergrab.client_destroy_listener.notify = NULL;
+ }
+
+ return TIZEN_POINTERGRAB_ERROR_NONE;
+}
+
+static void
+_e_comp_wl_input_cb_pointergrab_enable(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ int ret = TIZEN_POINTERGRAB_ERROR_NONE;
+
+ ERR("pointergrab_enable");
+
+// #ifdef HAVE_CYNARA
+// if (EINA_FALSE == _e_pointergrab_util_do_privilege_check(client, wl_client_get_fd(client),
+// "http://tizen.org/privilege/pointergrab"))
+// {
+// ERR("pointergrab request:priv check failed");
+// tizen_pointergrab_send_notify(resource, TIZEN_POINTERGRAB_ERROR_NO_PERMISSION);
+// return;
+// }
+// #endif
+
+ ret = e_pointergrab_enabled_set(client, resource, EINA_TRUE);
+ tizen_pointergrab_send_notify(resource, ret);
+}
+
+static void
+_e_comp_wl_input_cb_pointergrab_disable(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ int ret = TIZEN_POINTERGRAB_ERROR_NONE;
+
+ ERR("pointergrab_disable");
+
+// #ifdef HAVE_CYNARA
+// if (EINA_FALSE == _e_pointergrab_util_do_privilege_check(client, wl_client_get_fd(client),
+// "http://tizen.org/privilege/pointergrab"))
+// {
+// ERR("pointergrab request:priv check failed");
+// tizen_pointergrab_send_notify(resource, TIZEN_POINTERGRAB_ERROR_NO_PERMISSION);
+// return;
+// }
+// #endif
+
+ ret = e_pointergrab_enabled_set(client, resource, EINA_FALSE);
+ tizen_pointergrab_send_notify(resource, ret);
+}
+
+static const struct tizen_pointergrab_interface _e_pointergrab_interface = {
+ _e_comp_wl_input_cb_pointergrab_destroy,
+ _e_comp_wl_input_cb_pointergrab_enable,
+ _e_comp_wl_input_cb_pointergrab_disable,
+};
+
+static void
+_e_comp_wl_input_cb_unbind_pointergrab(struct wl_resource *resource)
+{
+ ERR("unbind_pointergrab");
+
+ e_comp_wl->pointergrab.resources =
+ eina_list_remove(e_comp_wl->pointergrab.resources, resource);
+}
+
+static void
+_e_comp_wl_input_cb_bind_pointergrab(struct wl_client *client,
+ void *data EINA_UNUSED,
+ uint32_t version, uint32_t id)
+{
+ struct wl_resource *resource;
+
+ ERR("bind_pointergrab");
+
+ resource = wl_resource_create(client, &tizen_pointergrab_interface, version, id);
+
+ if (!resource)
+ {
+ ERR("Could not create pointergrab resource: %m");
+ return;
+ }
+
+ e_comp_wl->pointergrab.resources =
+ eina_list_append(e_comp_wl->pointergrab.resources, resource);
+
+ wl_resource_set_implementation(resource, &_e_pointergrab_interface,
+ NULL, _e_comp_wl_input_cb_unbind_pointergrab);
+}
+
static void
_e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
{
_e_comp_wl_input_cb_surface_commit,
NULL);
+ e_comp_wl->pointergrab.global =
+ wl_global_create(e_comp_wl->wl.disp,
+ &tizen_pointergrab_interface, 1,
+ e_comp->wl_comp_data,
+ _e_comp_wl_input_cb_bind_pointergrab);
+ if (!e_comp_wl->pointergrab.global)
+ {
+ ERR("Could not create global for pointergrab: %m");
+ return EINA_FALSE;
+ }
wl_array_init(&e_comp_wl->kbd.keys);
wl_array_init(&e_comp_wl->kbd.routed_keys);
&_e_relative_pointer_interface);
}
+EINTERN Eina_Bool
+e_comp_wl_input_pointergrab_check(struct wl_resource *res)
+{
+ return wl_resource_instance_of(res, &tizen_pointergrab_interface,
+ &_e_pointergrab_interface);
+}
+
EINTERN Eina_Bool
e_comp_wl_input_keyboard_check(struct wl_resource *res)
{