1 #define EXECUTIVE_MODE_ENABLED
5 E_API int E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = -1;
6 static Eina_Bool dont_set_e_input_keymap = EINA_FALSE;
7 static Eina_Bool dont_use_xkb_cache = EINA_FALSE;
8 static Eina_Bool use_cache_keymap = EINA_FALSE;
10 /* default XKB values from enviroment variables */
11 static char *_env_e_default_xkb_rules = NULL;
12 static char *_env_e_default_xkb_model = NULL;
13 static char *_env_e_default_xkb_layout = NULL;
14 static char *_env_e_default_xkb_variant = NULL;
15 static char *_env_e_default_xkb_opts = NULL;
18 _e_comp_wl_input_update_seat_caps(struct wl_client *wc)
21 struct wl_resource *res;
22 enum wl_seat_capability caps = 0;
24 if (e_comp_wl->ptr.enabled)
25 caps |= WL_SEAT_CAPABILITY_POINTER;
26 if (e_comp_wl->kbd.enabled)
27 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
28 if (e_comp_wl->touch.enabled)
29 caps |= WL_SEAT_CAPABILITY_TOUCH;
31 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, res)
33 /* if a wc is null, send seat capability to all wl_seat resources */
34 if (wc && (wl_resource_get_client(res) != wc)) continue;
35 wl_seat_send_capabilities(res, caps);
40 _e_comp_wl_input_pointer_map(struct wl_resource *resource)
46 if (!(ec = wl_resource_get_user_data(resource))) return;
47 if (e_object_is_del(E_OBJECT(ec))) return;
49 //if cursor ec have external content
50 e_comp_object_content_unset(ec->frame);
52 if (!e_comp_wl->ptr.ec || !e_comp_wl->ptr.ec->comp_data || !e_comp_wl->ptr.ec->comp_data->surface) return;
53 wc = wl_resource_get_client(resource);
54 if (wc != wl_resource_get_client(e_comp_wl->ptr.ec->comp_data->surface)) return;
55 if (!e_comp_wl->ptr.ec->pointer_enter_sent) return;
57 if ((ptr = e_comp->pointer))
58 e_pointer_object_set(ptr, ec->frame, ptr->hot.x, ptr->hot.y);
62 _e_comp_wl_input_pointer_configure(struct wl_resource *resource,
63 Evas_Coord x, Evas_Coord y,
64 Evas_Coord w, Evas_Coord h)
68 if (!(ec = wl_resource_get_user_data(resource))) return;
69 if (e_object_is_del(E_OBJECT(ec))) return;
71 e_client_util_resize_without_frame(ec, w, h);
75 _e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
77 wl_resource_destroy(resource);
81 _e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *surface_resource, int32_t x, int32_t y)
84 Eina_Bool got_mouse = EINA_FALSE;
88 if (e_object_is_del(E_OBJECT(ec))) continue;
89 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) continue;
90 if (!ec->comp_data->surface) continue;
91 if (client != wl_resource_get_client(ec->comp_data->surface)) continue;
92 if (ec->mouse.in && ec->pointer_enter_sent)
94 got_mouse = EINA_TRUE;
98 if (!got_mouse) return;
99 if (!surface_resource)
101 e_pointer_object_set(e_comp->pointer, NULL, x, y);
104 ec = wl_resource_get_user_data(surface_resource);
110 ec->lock_focus_out = ec->layer_block = ec->visible = 1;
111 if (!e_config->show_cursor) ec->override = 1;
112 ec->icccm.title = eina_stringshare_add("Cursor");
113 e_client_window_role_set(ec, "wl_pointer-cursor");
114 evas_object_pass_events_set(ec->frame, 1);
115 e_client_focus_stack_set(eina_list_remove(e_client_focus_stack_get(), ec));
116 /* wl_pointer-cursor surface is always alpha window */
117 ec->argb = EINA_TRUE;
118 ELOGF("COMP", "Set argb:%d", ec, ec->argb);
119 e_comp_object_alpha_set(ec->frame, EINA_TRUE);
122 /* Set fuctions to prevent unwanted handling by shell */
123 ec->comp_data->shell.surface = surface_resource;
124 ec->comp_data->shell.configure = _e_comp_wl_input_pointer_configure;
125 ec->comp_data->shell.map = _e_comp_wl_input_pointer_map;
127 e_client_layer_set(ec, E_LAYER_CLIENT_CURSOR);
128 ec->is_cursor = EINA_TRUE;
131 /* Set a pointer_object after wl_surface commit
132 * if cursor image is changed,
133 * changed information is sent using attach / damage
134 * So in commit, we can know real current cursor image.
137 /* ignore cursor changes during resize/move I guess */
138 if (e_client_action_get()) return;
139 e_pointer_object_set(e_comp->pointer, ec->frame, x, y);
143 e_comp->pointer->hot.x = x;
144 e_comp->pointer->hot.y = y;
145 ec->visible = EINA_TRUE;
149 static const struct wl_pointer_interface _e_pointer_interface =
151 _e_comp_wl_input_pointer_cb_cursor_set,
152 _e_comp_wl_input_cb_resource_destroy
155 static const struct wl_keyboard_interface _e_keyboard_interface =
157 _e_comp_wl_input_cb_resource_destroy
160 static const struct wl_touch_interface _e_touch_interface =
162 _e_comp_wl_input_cb_resource_destroy
166 _e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
168 e_comp_wl->ptr.resources =
169 eina_list_remove(e_comp_wl->ptr.resources, resource);
173 _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
175 struct wl_resource *res;
176 struct wl_client *ptr_client = NULL;
177 E_Comp_Wl_Client_Data *cdata = NULL;
179 /* try to create pointer resource */
180 res = wl_resource_create(client, &wl_pointer_interface,
181 wl_resource_get_version(resource), id);
184 ERR("Could not create pointer on seat %s: %m",
185 e_comp_wl->seat.name);
186 wl_client_post_no_memory(client);
190 e_comp_wl->ptr.resources =
191 eina_list_append(e_comp_wl->ptr.resources, res);
192 wl_resource_set_implementation(res, &_e_pointer_interface,
193 e_comp->wl_comp_data,
194 _e_comp_wl_input_cb_pointer_unbind);
196 if ((e_comp_wl->ptr.num_devices == 1) && e_comp_wl->ptr.ec && !e_comp_wl->ptr.ec->pointer_enter_sent && !e_config->use_cursor_timer)
198 cdata = (E_Comp_Wl_Client_Data*)e_comp_wl->ptr.ec->comp_data;
199 if (cdata && cdata->wl_surface)
200 ptr_client = wl_resource_get_client(cdata->wl_surface);
202 if (ptr_client == client)
204 Evas_Device *last_ptr = NULL, *dev;
206 const char *name, *desc;
208 list = (Eina_List *)evas_device_list(evas_object_evas_get(e_comp_wl->ptr.ec->frame), NULL);
209 EINA_LIST_FOREACH(list, l, dev)
211 name = evas_device_name_get(dev);
212 desc = evas_device_description_get(dev);
213 if (!name || !desc) continue;
215 if ((!strncmp(name, e_devicemgr->last_device_ptr->name, strlen(e_devicemgr->last_device_ptr->name))) &&
216 (!strncmp(desc, e_devicemgr->last_device_ptr->identifier, strlen(e_devicemgr->last_device_ptr->identifier))) &&
217 (evas_device_class_get(dev) == (Evas_Device_Class)e_devicemgr->last_device_ptr->clas))
224 e_comp_wl_mouse_in_renew(e_comp_wl->ptr.ec, 0, wl_fixed_to_int(e_comp_wl->ptr.x), wl_fixed_to_int(e_comp_wl->ptr.y), NULL, NULL, NULL, ecore_time_get(), EVAS_EVENT_FLAG_NONE, last_ptr, NULL);
230 _e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
233 struct wl_resource *res;
235 e_comp_wl->kbd.resources =
236 eina_list_remove(e_comp_wl->kbd.resources, resource);
237 EINA_LIST_FOREACH_SAFE(e_comp_wl->kbd.focused, l, ll, res)
239 e_comp_wl->kbd.focused =
240 eina_list_remove_list(e_comp_wl->kbd.focused, l);
244 e_comp_wl_input_keyboard_enter_send(E_Client *ec)
246 struct wl_resource *res;
250 if (!ec->comp_data->surface) return;
252 if (!e_comp_wl->kbd.focused) return;
254 e_comp_wl_input_keyboard_modifiers_serialize();
256 serial = wl_display_next_serial(e_comp_wl->wl.disp);
258 EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
260 wl_keyboard_send_enter(res, serial, ec->comp_data->surface,
261 &e_comp_wl->kbd.keys);
262 wl_keyboard_send_modifiers(res, serial,
263 e_comp_wl->kbd.mod_depressed,
264 e_comp_wl->kbd.mod_latched,
265 e_comp_wl->kbd.mod_locked,
266 e_comp_wl->kbd.mod_group);
271 _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
274 struct wl_resource *res;
276 /* try to create keyboard resource */
277 res = wl_resource_create(client, &wl_keyboard_interface,
278 wl_resource_get_version(resource), id);
281 ERR("Could not create keyboard on seat %s: %m",
282 e_comp_wl->seat.name);
283 wl_client_post_no_memory(client);
287 e_comp_wl->kbd.resources =
288 eina_list_append(e_comp_wl->kbd.resources, res);
289 wl_resource_set_implementation(res, &_e_keyboard_interface,
290 e_comp->wl_comp_data,
291 _e_comp_wl_input_cb_keyboard_unbind);
293 /* send current repeat_info */
294 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
295 wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate, e_comp_wl->kbd.repeat_delay);
297 /* send current keymap */
298 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap);
299 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
301 e_comp_wl->xkb.size);
304 /* if the client owns the focused surface, we need to send an enter */
305 focused = e_client_focused_get();
306 if ((!focused) || (e_object_is_del(E_OBJECT(focused))) ||
307 (!focused->comp_data) || (!focused->comp_data->surface)) return;
309 if (client != wl_resource_get_client(focused->comp_data->surface)) return;
310 e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
312 e_comp_wl_input_keyboard_enter_send(focused);
316 _e_comp_wl_input_cb_touch_unbind(struct wl_resource *resource)
318 e_comp_wl->touch.resources =
319 eina_list_remove(e_comp_wl->touch.resources, resource);
323 _e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
325 struct wl_resource *res;
327 /* try to create pointer resource */
328 res = wl_resource_create(client, &wl_touch_interface,
329 wl_resource_get_version(resource), id);
332 ERR("Could not create touch on seat %s: %m",
333 e_comp_wl->seat.name);
334 wl_client_post_no_memory(client);
338 e_comp_wl->touch.resources =
339 eina_list_append(e_comp_wl->touch.resources, res);
340 wl_resource_set_implementation(res, &_e_touch_interface,
341 e_comp->wl_comp_data,
342 _e_comp_wl_input_cb_touch_unbind);
345 static const struct wl_seat_interface _e_seat_interface =
347 _e_comp_wl_input_cb_pointer_get,
348 _e_comp_wl_input_cb_keyboard_get,
349 _e_comp_wl_input_cb_touch_get,
353 _e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
355 E_Comp_Wl_Seat *seat = wl_resource_get_user_data(resource);
357 DBG("Unbind seat: %u (client: %p)", wl_resource_get_id(resource), wl_resource_get_client(resource));
359 e_comp_wl->seat.resources =
360 eina_list_remove(e_comp_wl->seat.resources, resource);
365 _e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
367 struct wl_resource *res;
369 struct wl_resource *tmp_res;
370 E_Comp_Wl_Seat *seat;
372 seat = E_NEW(E_Comp_Wl_Seat, 1);
375 ERR("Failed to allocate memory for seat data\n");
376 wl_client_post_no_memory(client);
379 seat->is_first_resource = 1;
381 EINA_LIST_FOREACH(e_comp_wl->seat.resources, l, tmp_res)
383 if (wl_resource_get_client(tmp_res) != client) continue;
384 DBG("wl_seat (res: %d) is already bound to client (%p)",
385 wl_resource_get_id(tmp_res), client);
386 seat->is_first_resource = 0;
389 res = wl_resource_create(client, &wl_seat_interface, version, id);
392 ERR("Could not create seat resource: %m");
396 DBG("Bind seat: %u (client: %p)", wl_resource_get_id(res), client);
398 /* store version of seat interface for reuse in updating capabilities */
399 e_comp_wl->seat.version = version;
400 e_comp_wl->seat.resources =
401 eina_list_append(e_comp_wl->seat.resources, res);
403 wl_resource_set_implementation(res, &_e_seat_interface,
405 _e_comp_wl_input_cb_unbind_seat);
407 _e_comp_wl_input_update_seat_caps(client);
408 if (e_comp_wl->seat.version >= WL_SEAT_NAME_SINCE_VERSION)
409 wl_seat_send_name(res, e_comp_wl->seat.name);
413 _e_comp_wl_input_keymap_cache_create(const char *keymap_path, char *keymap_data)
416 TRACE_INPUT_BEGIN(_e_comp_wl_input_keymap_cache_create);
418 if ((EINA_FALSE == e_config->xkb.use_cache) && !dont_use_xkb_cache)
426 if (!e_util_file_realpath_check(keymap_path, EINA_TRUE))
428 WRN("%s is maybe link, so delete it\n", keymap_path);
431 file = fopen(keymap_path, "w");
432 EINA_SAFETY_ON_NULL_RETURN(file);
434 if (fputs(keymap_data, file) < 0)
436 WRN("Failed to write keymap file: %s\n", keymap_path);
442 INF("Success to make keymap file: %s\n", keymap_path);
450 _e_comp_wl_input_keymap_fd_get(off_t size)
452 int fd = 0, blen = 0, len = 0;
454 char tmp[PATH_MAX] = {0, };
458 blen = sizeof(tmp) - 20;
460 path = e_util_env_get("XDG_RUNTIME_DIR");
461 if (!path) return -1;
463 len = strlen(path) + 19;
466 strncpy(tmp, path, PATH_MAX - 20);
467 strncat(tmp, "/e-wl-keymap-XXXXXX", 19);
476 old_umask = umask(S_IRWXG|S_IRWXO);
480 EINA_SAFETY_ON_FALSE_RETURN_VAL(fd >= 0, -1);
482 flags = fcntl(fd, F_GETFD);
489 if (fcntl(fd, F_SETFD, (flags | FD_CLOEXEC)) == -1)
495 if (ftruncate(fd, size) < 0)
506 _e_comp_wl_input_keymap_update(struct xkb_keymap *keymap, const char *keymap_path)
509 xkb_mod_mask_t latched = 0, locked = 0, group = 0;
510 struct wl_resource *res;
513 /* unreference any existing keymap */
514 if (e_comp_wl->xkb.keymap)
515 xkb_map_unref(e_comp_wl->xkb.keymap);
517 /* unmap any existing keyboard area */
518 if (e_comp_wl->xkb.area)
519 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
520 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
522 /* unreference any existing keyboard state */
523 if (e_comp_wl->xkb.state)
526 xkb_state_serialize_mods(e_comp_wl->xkb.state,
527 XKB_STATE_MODS_LATCHED);
529 xkb_state_serialize_mods(e_comp_wl->xkb.state,
530 XKB_STATE_MODS_LOCKED);
532 xkb_state_serialize_layout(e_comp_wl->xkb.state,
533 XKB_STATE_LAYOUT_EFFECTIVE);
534 xkb_state_unref(e_comp_wl->xkb.state);
537 /* create a new xkb state */
538 e_comp_wl->xkb.state = xkb_state_new(keymap);
540 if (!e_comp_wl->xkb.state) return;
542 if ((latched) || (locked) || (group))
543 xkb_state_update_mask(e_comp_wl->xkb.state, 0,
544 latched, locked, 0, 0, group);
546 /* increment keymap reference */
547 e_comp_wl->xkb.keymap = keymap;
549 /* fetch updated modifiers */
550 e_comp_wl->kbd.mod_shift =
551 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
552 e_comp_wl->kbd.mod_caps =
553 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
554 e_comp_wl->kbd.mod_ctrl =
555 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
556 e_comp_wl->kbd.mod_alt =
557 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
558 e_comp_wl->kbd.mod_super =
559 xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
561 if (!(tmp = xkb_map_get_as_string(keymap)))
563 ERR("Could not get keymap string");
567 e_comp_wl->xkb.size = strlen(tmp) + 1;
569 _e_comp_wl_input_keymap_fd_get(e_comp_wl->xkb.size);
570 if (e_comp_wl->xkb.fd < 0)
572 ERR("Could not create keymap file");
577 _e_comp_wl_input_keymap_cache_create(keymap_path, tmp);
579 e_comp_wl->xkb.area =
580 mmap(NULL, e_comp_wl->xkb.size, (PROT_READ | PROT_WRITE),
581 MAP_SHARED, e_comp_wl->xkb.fd, 0);
582 if (e_comp_wl->xkb.area == MAP_FAILED)
584 ERR("Failed to mmap keymap area: %m");
589 strncpy(e_comp_wl->xkb.area, tmp, e_comp_wl->xkb.size);
592 /* send updated keymap */
593 TRACE_INPUT_BEGIN(wl_keyboard_send_keymap_update);
594 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
595 wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
597 e_comp_wl->xkb.size);
600 /* update modifiers */
601 e_comp_wl_input_keyboard_modifiers_update();
605 e_comp_wl_input_init(void)
607 /* set default seat name */
608 if (!e_comp_wl->seat.name)
609 e_comp_wl->seat.name = "default";
611 e_comp_wl->xkb.fd = -1;
612 dont_set_e_input_keymap = getenv("NO_E_INPUT_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
613 dont_use_xkb_cache = getenv("NO_KEYMAP_CACHE") ? EINA_TRUE : EINA_FALSE;
615 /* get default keyboard repeat rate/delay from configuration */
616 e_comp_wl->kbd.repeat_delay = e_config->keyboard.repeat_delay;
617 e_comp_wl->kbd.repeat_rate = e_config->keyboard.repeat_rate;
619 /* check for valid repeat_delay and repeat_rate value */
620 /* if invalid, set the default value of repeat delay and rate value */
621 if (e_comp_wl->kbd.repeat_delay < 0) e_comp_wl->kbd.repeat_delay = 400;
622 if (e_comp_wl->kbd.repeat_rate < 0) e_comp_wl->kbd.repeat_rate = 25;
624 /* create the global resource for input seat */
625 e_comp_wl->seat.global =
626 wl_global_create(e_comp_wl->wl.disp, &wl_seat_interface, 4,
627 e_comp->wl_comp_data, _e_comp_wl_input_cb_bind_seat);
628 if (!e_comp_wl->seat.global)
630 ERR("Could not create global for seat: %m");
634 wl_array_init(&e_comp_wl->kbd.keys);
635 wl_array_init(&e_comp_wl->kbd.routed_keys);
637 E_EVENT_TEXT_INPUT_PANEL_VISIBILITY_CHANGE = ecore_event_type_new();
639 /* get string values from environment variables */
640 _env_e_default_xkb_rules = e_util_env_get("E_DEFAULT_XKB_RULES" );
641 _env_e_default_xkb_model = e_util_env_get("E_DEFAULT_XKB_MODEL" );
642 _env_e_default_xkb_layout = e_util_env_get("E_DEFAULT_XKB_LAYOUT" );
643 _env_e_default_xkb_variant = e_util_env_get("E_DEFAULT_XKB_VARIANT");
644 _env_e_default_xkb_opts = e_util_env_get("E_DEFAULT_XKB_OPTIONS");
650 e_comp_wl_input_shutdown(void)
652 struct wl_resource *res;
654 /* free environment variable string */
655 E_FREE(_env_e_default_xkb_rules );
656 E_FREE(_env_e_default_xkb_model );
657 E_FREE(_env_e_default_xkb_layout );
658 E_FREE(_env_e_default_xkb_variant);
659 E_FREE(_env_e_default_xkb_opts );
661 /* destroy pointer resources */
662 EINA_LIST_FREE(e_comp_wl->ptr.resources, res)
663 wl_resource_destroy(res);
665 /* destroy keyboard resources */
666 EINA_LIST_FREE(e_comp_wl->kbd.resources, res)
667 wl_resource_destroy(res);
668 e_comp_wl->kbd.resources = eina_list_free(e_comp_wl->kbd.resources);
670 /* destroy touch resources */
671 EINA_LIST_FREE(e_comp_wl->touch.resources, res)
672 wl_resource_destroy(res);
674 /* destroy e_comp_wl->kbd.keys array */
675 wl_array_release(&e_comp_wl->kbd.keys);
676 wl_array_release(&e_comp_wl->kbd.routed_keys);
678 /* unmap any existing keyboard area */
679 if (e_comp_wl->xkb.area)
680 munmap(e_comp_wl->xkb.area, e_comp_wl->xkb.size);
681 if (e_comp_wl->xkb.fd >= 0) close(e_comp_wl->xkb.fd);
683 /* unreference any existing keyboard state */
684 if (e_comp_wl->xkb.state)
685 xkb_state_unref(e_comp_wl->xkb.state);
687 /* unreference any existing keymap */
688 if (e_comp_wl->xkb.keymap)
689 xkb_map_unref(e_comp_wl->xkb.keymap);
691 /* unreference any existing context */
692 if (e_comp_wl->xkb.context)
693 xkb_context_unref(e_comp_wl->xkb.context);
695 /* destroy the global seat resource */
696 if (e_comp_wl->seat.global)
697 wl_global_destroy(e_comp_wl->seat.global);
698 e_comp_wl->seat.global = NULL;
700 dont_set_e_input_keymap = EINA_FALSE;
701 dont_use_xkb_cache = EINA_FALSE;
705 e_comp_wl_input_pointer_check(struct wl_resource *res)
707 return wl_resource_instance_of(res, &wl_pointer_interface,
708 &_e_pointer_interface);
712 e_comp_wl_input_keyboard_check(struct wl_resource *res)
714 return wl_resource_instance_of(res, &wl_keyboard_interface,
715 &_e_keyboard_interface);
719 e_comp_wl_input_keyboard_modifiers_serialize(void)
721 Eina_Bool changed = EINA_FALSE;
723 xkb_layout_index_t grp;
725 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
726 XKB_STATE_DEPRESSED);
727 changed |= mod != e_comp_wl->kbd.mod_depressed;
728 e_comp_wl->kbd.mod_depressed = mod;
730 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
731 XKB_STATE_MODS_LATCHED);
732 changed |= mod != e_comp_wl->kbd.mod_latched;
733 e_comp_wl->kbd.mod_latched = mod;
735 mod = xkb_state_serialize_mods(e_comp_wl->xkb.state,
736 XKB_STATE_MODS_LOCKED);
737 changed |= mod != e_comp_wl->kbd.mod_locked;
738 e_comp_wl->kbd.mod_locked = mod;
740 grp = xkb_state_serialize_layout(e_comp_wl->xkb.state,
741 XKB_STATE_LAYOUT_EFFECTIVE);
742 changed |= grp != e_comp_wl->kbd.mod_group;
743 e_comp_wl->kbd.mod_group = grp;
748 e_comp_wl_input_keyboard_modifiers_update(void)
751 struct wl_resource *res;
754 if (!e_comp_wl_input_keyboard_modifiers_serialize()) return;
756 if (!e_comp_wl->kbd.focused) return;
758 serial = wl_display_next_serial(e_comp_wl->wl.disp);
759 EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
760 wl_keyboard_send_modifiers(res, serial,
761 e_comp_wl->kbd.mod_depressed,
762 e_comp_wl->kbd.mod_latched,
763 e_comp_wl->kbd.mod_locked,
764 e_comp_wl->kbd.mod_group);
768 e_comp_wl_input_keyboard_state_update(uint32_t keycode, Eina_Bool pressed)
770 enum xkb_key_direction dir;
772 if (!e_comp_wl->xkb.state) return;
774 if (pressed) dir = XKB_KEY_DOWN;
775 else dir = XKB_KEY_UP;
777 e_comp_wl->kbd.mod_changed =
778 xkb_state_update_key(e_comp_wl->xkb.state, keycode + 8, dir);
780 e_comp_wl_input_keyboard_modifiers_update();
784 e_comp_wl_input_pointer_enabled_set(Eina_Bool enabled)
786 /* check for valid compositor data */
787 if (!e_comp->wl_comp_data)
789 ERR("No compositor data");
793 e_comp_wl->ptr.enabled = !!enabled;
794 _e_comp_wl_input_update_seat_caps(NULL);
798 e_comp_wl_input_keyboard_enabled_set(Eina_Bool enabled)
800 /* check for valid compositor data */
801 if (!e_comp->wl_comp_data)
803 ERR("No compositor data");
807 e_comp_wl->kbd.enabled = !!enabled;
808 _e_comp_wl_input_update_seat_caps(NULL);
812 e_comp_wl_input_keymap_cache_file_use_get(void)
814 return use_cache_keymap;
817 E_API Eina_Stringshare *
818 e_comp_wl_input_keymap_path_get(struct xkb_rule_names names)
820 return eina_stringshare_printf("/var/lib/xkb/%s-%s-%s-%s-%s.xkb",
821 names.rules ? names.rules : "evdev",
822 names.model ? names.model : "pc105",
823 names.layout ? names.layout : "us",
824 names.variant ? names.variant : "",
825 names.options ? names.options : "");
828 E_API struct xkb_keymap *
829 e_comp_wl_input_keymap_compile(struct xkb_context *ctx, struct xkb_rule_names names, char **keymap_path)
831 struct xkb_keymap *keymap;
832 char *cache_path = NULL;
835 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
837 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_compile);
839 if (e_config->xkb.use_cache && !dont_use_xkb_cache)
841 cache_path = (char *)e_comp_wl_input_keymap_path_get(names);
842 file = fopen(cache_path, "r");
847 INF("There is a no keymap file (%s). Generate keymap using rmlvo\n", cache_path);
849 /* fetch new keymap based on names */
850 keymap = xkb_map_new_from_names(ctx, &names, 0);
851 use_cache_keymap = EINA_FALSE;
855 INF("Keymap file (%s) has been found. xkb_keymap is going to be generated with it.\n", cache_path);
856 keymap = xkb_map_new_from_file(ctx, file, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
859 WRN("Keymap file is exist (%s) but it is invaild file. Generate keymap using rmlvo\n", cache_path);
861 if (remove(cache_path) != 0)
862 WRN("Failed to remove keymap file: %s (errno: %d)", cache_path, errno);
863 keymap = xkb_map_new_from_names(ctx, &names, 0);
864 use_cache_keymap = EINA_FALSE;
868 eina_stringshare_del(cache_path);
871 use_cache_keymap = EINA_TRUE;
875 *keymap_path = cache_path;
876 EINA_SAFETY_ON_NULL_RETURN_VAL(keymap, NULL);
884 e_comp_wl_input_keymap_set(const char *rules, const char *model, const char *layout,
885 const char *variant, const char *options,
886 struct xkb_context *dflt_ctx, struct xkb_keymap *dflt_map)
888 struct xkb_keymap *keymap;
889 struct xkb_rule_names names;
890 char *keymap_path = NULL;
891 Eina_Bool use_dflt_xkb = EINA_FALSE;
892 const char *default_rules, *default_model, *default_layout, *default_variant, *default_options;
894 /* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
895 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set);
897 if (dflt_ctx && dflt_map) use_dflt_xkb = EINA_TRUE;
899 /* unreference any existing context */
900 if (e_comp_wl->xkb.context)
901 xkb_context_unref(e_comp_wl->xkb.context);
903 /* create a new xkb context */
904 if (use_dflt_xkb) e_comp_wl->xkb.context = dflt_ctx;
905 else e_comp_wl->xkb.context = xkb_context_new(0);
907 if (!e_comp_wl->xkb.context)
913 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
914 e_input_device_keyboard_cached_context_set(e_comp_wl->xkb.context);
916 /* assemble xkb_rule_names so we can fetch keymap */
917 memset(&names, 0, sizeof(names));
918 if (rules) names.rules = strdup(rules);
921 default_rules = e_comp_wl_input_keymap_default_rules_get();
922 names.rules = strdup(default_rules);
924 if (model) names.model = strdup(model);
927 default_model = e_comp_wl_input_keymap_default_model_get();
928 names.model = strdup(default_model);
930 if (layout) names.layout = strdup(layout);
933 default_layout = e_comp_wl_input_keymap_default_layout_get();
934 names.layout = strdup(default_layout);
936 if (variant) names.variant = strdup(variant);
939 default_variant = e_comp_wl_input_keymap_default_variant_get();
940 if (default_variant) names.variant = strdup(default_variant);
942 if (options) names.options = strdup(options);
945 default_options = e_comp_wl_input_keymap_default_options_get();
946 if (default_options) names.options = strdup(default_options);
949 TRACE_INPUT_BEGIN(e_comp_wl_input_keymap_set_keymap_compile);
953 keymap_path = (char *)e_comp_wl_input_keymap_path_get(names);
954 if (access(keymap_path, R_OK) == 0)
956 eina_stringshare_del(keymap_path);
961 keymap = e_comp_wl_input_keymap_compile(e_comp_wl->xkb.context, names, &keymap_path);
964 /* update compositor keymap */
965 _e_comp_wl_input_keymap_update(keymap, keymap_path);
967 if (e_config->xkb.use_cache && !dont_set_e_input_keymap)
968 e_input_device_keyboard_cached_keymap_set(keymap);
971 if (keymap_path) eina_stringshare_del(keymap_path);
972 free((char *)names.rules);
973 free((char *)names.model);
974 free((char *)names.layout);
975 if (names.variant) free((char *)names.variant);
976 if (names.options) free((char *)names.options);
981 e_comp_wl_input_keymap_default_rules_get(void)
983 if (e_config->xkb.default_rmlvo.rules)
984 return e_config->xkb.default_rmlvo.rules;
986 if (_env_e_default_xkb_rules)
987 return _env_e_default_xkb_rules;
993 e_comp_wl_input_keymap_default_model_get(void)
995 if (e_config->xkb.default_rmlvo.model)
996 return e_config->xkb.default_rmlvo.model;
998 if (_env_e_default_xkb_model)
999 return _env_e_default_xkb_model;
1005 e_comp_wl_input_keymap_default_layout_get(void)
1007 if (e_config->xkb.default_rmlvo.layout)
1008 return e_config->xkb.default_rmlvo.layout;
1010 if (_env_e_default_xkb_layout)
1011 return _env_e_default_xkb_layout;
1017 e_comp_wl_input_keymap_default_variant_get(void)
1019 if (e_config->xkb.default_rmlvo.variant)
1020 return e_config->xkb.default_rmlvo.variant;
1022 if (_env_e_default_xkb_variant)
1023 return _env_e_default_xkb_variant;
1029 e_comp_wl_input_keymap_default_options_get(void)
1031 if (e_config->xkb.default_rmlvo.options)
1032 return e_config->xkb.default_rmlvo.options;
1034 if (_env_e_default_xkb_opts)
1035 return _env_e_default_xkb_opts;
1041 e_comp_wl_input_touch_enabled_set(Eina_Bool enabled)
1043 /* check for valid compositor data */
1044 if (!e_comp->wl_comp_data)
1046 ERR("No compositor data");
1050 e_comp_wl->touch.enabled = !!enabled;
1051 _e_comp_wl_input_update_seat_caps(NULL);
1055 e_comp_wl_input_seat_caps_set(unsigned int caps)
1057 Eina_Bool need_update = EINA_FALSE;
1059 /* check for valid compositor data */
1060 if (!e_comp->wl_comp_data)
1062 ERR("No compositor data");
1066 if (caps & E_INPUT_SEAT_POINTER)
1067 e_comp_wl->ptr.enabled = need_update = EINA_TRUE;
1068 if (caps & E_INPUT_SEAT_KEYBOARD)
1069 e_comp_wl->kbd.enabled = need_update = EINA_TRUE;
1070 if (caps & E_INPUT_SEAT_TOUCH)
1071 e_comp_wl->touch.enabled = need_update = EINA_TRUE;
1074 _e_comp_wl_input_update_seat_caps(NULL);
1078 e_comp_wl_input_touch_check(struct wl_resource *res)
1080 return wl_resource_instance_of(res, &wl_touch_interface,
1081 &_e_touch_interface);
1085 e_comp_wl_input_keyboard_repeat_set(int delay, int rate)
1087 struct wl_resource *res;
1090 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
1092 e_comp_wl->kbd.repeat_delay = delay;
1093 e_comp_wl->kbd.repeat_rate = rate;
1095 EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
1097 if (wl_resource_get_version(res) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
1098 wl_keyboard_send_repeat_info(res, e_comp_wl->kbd.repeat_rate,
1099 e_comp_wl->kbd.repeat_delay);
1103 typedef struct _keycode_map{
1104 xkb_keysym_t keysym;
1105 xkb_keycode_t keycode;
1109 find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
1111 keycode_map *found_keycodes = (keycode_map *)data;
1112 xkb_keysym_t keysym = found_keycodes->keysym;
1114 const xkb_keysym_t *syms_out = NULL;
1116 nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
1117 if (nsyms && syms_out)
1119 if (*syms_out == keysym)
1121 found_keycodes->keycode = key;
1127 _e_comp_wl_input_keymap_keysym_to_keycode(struct xkb_keymap *keymap, xkb_keysym_t keysym)
1129 keycode_map found_keycodes = {0,};
1130 found_keycodes.keysym = keysym;
1131 xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes);
1133 return found_keycodes.keycode;
1137 e_comp_wl_input_keymap_keyname_to_keycode(const char * name)
1139 struct xkb_keymap *keymap = NULL;
1140 xkb_keysym_t keysym = 0x0;
1144 EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0);
1145 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, 0);
1147 keymap = e_comp_wl->xkb.keymap;
1148 EINA_SAFETY_ON_NULL_GOTO(keymap, finish);
1150 keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
1151 if (keysym == XKB_KEY_NoSymbol)
1153 if (strlen(name) <= sizeof("Keycode-")) goto finish;
1155 if (!strncmp(name, "Keycode-", sizeof("Keycode-") - 1))
1157 name_tmp = (char *)name + sizeof("Keycode-") - 1;
1158 keycode = atoi(name_tmp);
1159 if (keycode <= 8) goto finish;
1167 keycode = _e_comp_wl_input_keymap_keysym_to_keycode(keymap, keysym);
1176 e_comp_wl_input_keymap_keycode_to_keyname(int keycode)
1178 struct xkb_state *state;
1179 xkb_keysym_t sym = XKB_KEY_NoSymbol;
1180 char name[256] = {0, };
1182 EINA_SAFETY_ON_FALSE_RETURN_VAL(8 <= keycode, NULL);
1183 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, NULL);
1184 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->xkb.state, NULL);
1186 state = e_comp_wl->xkb.state;
1187 sym = xkb_state_key_get_one_sym(state, keycode);
1188 if (sym == XKB_KEY_NoSymbol)
1190 snprintf(name, sizeof(name), "Keycode-%u", keycode);
1193 xkb_keysym_get_name(sym, name, sizeof(name));
1195 return strdup(name);