5 #include "ecore_wl2_private.h"
7 #include "linux-dmabuf-unstable-v1-client-protocol.h"
8 #include "efl-hints-client-protocol.h"
10 #ifdef HAVE_SYS_INOTIFY_H
11 # include <sys/inotify.h>
15 #include <tizen_core.h>
17 #endif // USE_TIZEN_CORE
19 static Eina_Hash *_server_displays = NULL;
20 static Eina_Hash *_client_displays = NULL;
22 static Eina_Bool _cb_connect_idle(void *data);
23 static Eina_Bool _cb_connect_data(void *data, Ecore_Fd_Handler *hdl);
24 static Eina_Bool _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync);
25 // TIZEN_ONLY(20171129): thread-safety for wl
26 static void _ecore_wl_cb_awake(void *data);
27 // End of TIZEN_ONLY(20171129)
28 static void _ecore_wl2_display_sync_add(Ecore_Wl2_Display *ewd);
30 // TIZEN_ONLY(20190430): support client appinfo
31 static pid_t _base_resolution_pid = 0;
32 static uint32_t _base_resolution_w = 0;
33 static uint32_t _base_resolution_h = 0;
40 static bool initialized;
44 if (!initialized) return ready;
46 env = getenv("TCORE_READY");
47 if (env && !strcmp(env, "1")) ready = true;
52 #endif // USE_TIZEN_CORE
55 _display_event_free(void *d, void *event)
57 ecore_wl2_display_disconnect(d);
62 _ecore_wl2_display_event(Ecore_Wl2_Display *ewd, int event)
64 Ecore_Wl2_Event_Connect *ev;
66 ev = calloc(1, sizeof(Ecore_Wl2_Event_Connect));
67 EINA_SAFETY_ON_NULL_RETURN(ev);
70 ecore_event_add(event, ev, _display_event_free, ewd);
74 _ecore_wl2_display_signal_exit(void)
76 Ecore_Event_Signal_Exit *ev;
78 ev = calloc(1, sizeof(Ecore_Event_Signal_Exit));
82 ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, ev, NULL, NULL);
86 _dmabuf_cb_format(void *data EINA_UNUSED, struct zwp_linux_dmabuf_v1 *dmabuf EINA_UNUSED, uint32_t format EINA_UNUSED)
88 /* It would be awfully nice if this actually happened */
91 static const struct zwp_linux_dmabuf_v1_listener _dmabuf_listener =
98 _xdg_shell_cb_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
100 xdg_wm_base_pong(shell, serial);
101 ecore_wl2_display_flush(data);
104 static const struct xdg_wm_base_listener _xdg_shell_listener =
110 _zxdg_shell_cb_ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial)
112 zxdg_shell_v6_pong(shell, serial);
113 ecore_wl2_display_flush(data);
116 static const struct zxdg_shell_v6_listener _zxdg_shell_listener =
122 _session_recovery_create_uuid(void *data EINA_UNUSED, struct zwp_e_session_recovery *session_recovery EINA_UNUSED, struct wl_surface *surface, const char *uuid)
124 Ecore_Wl2_Window *win;
126 /* surface may have been destroyed */
127 if (!surface) return;
128 win = wl_surface_get_user_data(surface);
130 eina_stringshare_replace(&win->uuid, uuid);
133 static const struct zwp_e_session_recovery_listener _session_listener =
135 _session_recovery_create_uuid,
139 _aux_hints_supported_aux_hints(void *data, struct efl_aux_hints *aux_hints EINA_UNUSED, struct wl_surface *surface_resource, struct wl_array *hints, uint32_t num_hints)
141 Ecore_Wl2_Display *ewd = data;
142 struct wl_surface *surface = surface_resource;
143 Ecore_Wl2_Window *win = NULL;
146 const char *hint = NULL;
148 Ecore_Wl2_Event_Aux_Hint_Supported *ev;
150 if (!surface) return;
151 win = _ecore_wl2_display_window_surface_find(ewd, surface_resource);
155 str = calloc(num_hints, sizeof(char *));
158 while ((const char *)p < ((const char *)hints->data + hints->size))
160 str[i] = (char *)eina_stringshare_add(p);
164 for (i = 0; i < num_hints; i++)
166 hint = eina_stringshare_add(str[i]);
167 win->supported_aux_hints =
168 eina_list_append(win->supported_aux_hints, hint);
172 for (i = 0; i < num_hints; i++)
176 eina_stringshare_del(str[i]);
183 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Aux_Hint_Supported)))) return;
187 ecore_event_add(ECORE_WL2_EVENT_AUX_HINT_SUPPORTED, ev,
188 _display_event_free, ewd);
192 _aux_hints_allowed_aux_hint(void *data, struct efl_aux_hints *aux_hints EINA_UNUSED, struct wl_surface *surface_resource, int id)
194 struct wl_surface *surface = surface_resource;
195 Ecore_Wl2_Window *win = NULL;
196 Ecore_Wl2_Display *ewd = data;
197 Ecore_Wl2_Event_Aux_Hint_Allowed *ev;
199 if (!surface) return;
200 win = _ecore_wl2_display_window_surface_find(ewd, surface_resource);
203 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Aux_Hint_Allowed)))) return;
208 ecore_event_add(ECORE_WL2_EVENT_AUX_HINT_ALLOWED, ev,
209 _display_event_free, ewd);
213 _cb_aux_message_free(void *data EINA_UNUSED, void *event)
215 Ecore_Wl2_Event_Aux_Message *ev;
219 ecore_wl2_display_disconnect(ev->display);
220 eina_stringshare_del(ev->key);
221 eina_stringshare_del(ev->val);
222 EINA_LIST_FREE(ev->options, str)
223 eina_stringshare_del(str);
228 _aux_hints_aux_message(void *data, struct efl_aux_hints *aux_hints EINA_UNUSED, struct wl_surface *surface_resource, const char *key, const char *val, struct wl_array *options)
230 Ecore_Wl2_Window *win = NULL;
231 Ecore_Wl2_Event_Aux_Message *ev;
232 char *p = NULL, *str = NULL;
233 Eina_List *opt_list = NULL;
234 Ecore_Wl2_Display *ewd = data;
236 if (!surface_resource) return;
237 win = _ecore_wl2_display_window_surface_find(ewd, surface_resource);
240 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Aux_Message)))) return;
242 if ((options) && (options->size))
245 while ((const char *)p < ((const char *)options->data + options->size))
247 str = (char *)eina_stringshare_add(p);
248 opt_list = eina_list_append(opt_list, str);
254 ev->key = eina_stringshare_add(key);
255 ev->val = eina_stringshare_add(val);
256 ev->options = opt_list;
260 ecore_event_add(ECORE_WL2_EVENT_AUX_MESSAGE, ev, _cb_aux_message_free, NULL);
263 static const struct efl_aux_hints_listener _aux_hints_listener =
265 _aux_hints_supported_aux_hints,
266 _aux_hints_allowed_aux_hint,
267 _aux_hints_aux_message,
270 // TIZEN_ONLY : To use tizen protocols
272 _tizen_policy_conformant_area_send(Ecore_Wl2_Window *win, uint32_t conformant_part, uint32_t state)
274 Ecore_Wl2_Event_Conformant_Change *ev;
276 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Conformant_Change)))) return;
278 ev->part_type = conformant_part;
280 ecore_event_add(ECORE_WL2_EVENT_CONFORMANT_CHANGE, ev, NULL, NULL);
284 _tizen_policy_cb_conformant(void *data, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface_resource, uint32_t is_conformant)
286 Ecore_Wl2_Display *ewd = data;
287 Ecore_Wl2_Window *win = NULL;
289 if (!surface_resource) return;
290 win = ecore_wl2_display_window_find_by_surface(ewd, surface_resource);
292 win->conformant = is_conformant;
296 _tizen_policy_cb_conformant_area(void *data, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface_resource, uint32_t conformant_part, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h)
298 Ecore_Wl2_Display *ewd = data;
299 Ecore_Wl2_Window *win = NULL;
300 int org_x, org_y, org_w, org_h;
301 Eina_Bool changed = EINA_FALSE;
302 Ecore_Wl2_Indicator_State ind_state;
303 Ecore_Wl2_Virtual_Keyboard_State kbd_state;
304 Ecore_Wl2_Clipboard_State clip_state;
306 if (!surface_resource) return;
307 win = ecore_wl2_display_window_find_by_surface(ewd, surface_resource);
310 if (conformant_part == TIZEN_POLICY_CONFORMANT_PART_INDICATOR)
312 ecore_wl2_window_indicator_geometry_get(win, &org_x, &org_y, &org_w, &org_h);
313 if ((org_x != x) || (org_y != y) || (org_w != w) || (org_h != h))
315 ecore_wl2_window_indicator_geometry_set(win, x, y, w, h);
319 /* The given state is based on the visibility value of indicator.
320 * Thus we need to add 1 to it before comparing with indicator state.
322 ind_state = ecore_wl2_window_indicator_state_get(win);
323 if ((state + 1) != ind_state)
325 ecore_wl2_window_indicator_state_set(win, state + 1);
329 else if (conformant_part == TIZEN_POLICY_CONFORMANT_PART_KEYBOARD)
331 ecore_wl2_window_keyboard_geometry_get(win, &org_x, &org_y, &org_w, &org_h);
332 if ((org_x != x) || (org_y != y) || (org_w != w) || (org_h != h))
334 ecore_wl2_window_keyboard_geometry_set(win, x, y, w, h);
338 /* The given state is based on the visibility value of virtual keyboard window.
339 * Thus we need to add 1 to it before comparing with keyboard state.
341 kbd_state = ecore_wl2_window_keyboard_state_get(win);
342 if ((state + 1) != (kbd_state))
344 ecore_wl2_window_keyboard_state_set(win, state + 1);
348 else if (conformant_part == TIZEN_POLICY_CONFORMANT_PART_CLIPBOARD)
350 ecore_wl2_window_clipboard_geometry_get(win, &org_x, &org_y, &org_w, &org_h);
351 if ((org_x != x) || (org_y != y) || (org_w != w) || (org_h != h))
353 ecore_wl2_window_clipboard_geometry_set(win, x, y, w, h);
357 /* The given state is based on the visibility value of clipboard window.
358 * Thus we need to add 1 to it before comparing with clipboard state.
360 clip_state = ecore_wl2_window_clipboard_state_get(win);
361 if ((state + 1) != clip_state)
363 ecore_wl2_window_clipboard_state_set(win, state + 1);
369 _tizen_policy_conformant_area_send(win, conformant_part, state);
373 _tizen_policy_cb_notification_done(void *data EINA_UNUSED, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, int32_t level EINA_UNUSED, uint32_t state EINA_UNUSED)
378 _tizen_policy_cb_transient_for_done(void *data EINA_UNUSED, struct tizen_policy *tizen_policy EINA_UNUSED, uint32_t child_id EINA_UNUSED)
383 _tizen_policy_cb_window_screen_mode_done(void *data EINA_UNUSED, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t mode EINA_UNUSED, uint32_t state EINA_UNUSED)
388 _tizen_policy_cb_iconify_state_changed(void *data, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface_resource, uint32_t iconified, uint32_t force)
390 Ecore_Wl2_Display *ewd = data;
391 Ecore_Wl2_Window *win = NULL;
392 Ecore_Wl2_Event_Window_Iconify_State_Change *ev = NULL;
394 if (!surface_resource) return;
396 win = ecore_wl2_display_window_find_by_surface(ewd, surface_resource);
399 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Iconify_State_Change)))) return;
401 ev->iconified = iconified;
404 ecore_event_add(ECORE_WL2_EVENT_WINDOW_ICONIFY_STATE_CHANGE, ev, NULL, NULL);
407 void _window_aux_hint_free(Ecore_Wl2_Window *win)
409 const char *supported;
411 EINA_LIST_FREE(win->supported_aux_hints, supported)
412 if (supported) eina_stringshare_del(supported);
416 _tizen_policy_cb_supported_aux_hints(void *data, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface_resource, struct wl_array *hints, uint32_t num_hints)
418 /* 20171112 : this can be replaced with efl_aux_hints procotol */
420 Ecore_Wl2_Display *ewd = data;
421 Ecore_Wl2_Window *win = NULL;
424 const char *hint = NULL;
427 if (!surface_resource) return;
429 win = ecore_wl2_display_window_find_by_surface(ewd, surface_resource);
433 str = calloc(num_hints, sizeof(char *));
436 _window_aux_hint_free(win);
438 while ((const char *)p < ((const char *)hints->data + hints->size))
440 str[i] = (char *)eina_stringshare_add(p);
444 for (i = 0; i < num_hints; i++)
446 hint = eina_stringshare_add(str[i]);
447 win->supported_aux_hints =
448 eina_list_append(win->supported_aux_hints, hint);
452 for (i = 0; i < num_hints; i++)
456 eina_stringshare_del(str[i]);
465 _tizen_policy_cb_allowed_aux_hint(void *data, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface_resource, int id)
467 /* 20171112 : this can be replaced with efl_aux_hints procotol */
469 struct wl_surface *surface = surface_resource;
470 Ecore_Wl2_Window *win = NULL;
471 Ecore_Wl2_Display *ewd = data;
472 Ecore_Wl2_Event_Aux_Hint_Allowed *ev;
474 if (!surface) return;
475 win = _ecore_wl2_display_window_surface_find(ewd, surface_resource);
478 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Aux_Hint_Allowed)))) return;
483 ecore_event_add(ECORE_WL2_EVENT_AUX_HINT_ALLOWED, ev, _display_event_free, ewd);
487 _tizen_policy_cb_aux_message(void *data EINA_UNUSED, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface_resource, const char *key, const char *val, struct wl_array *options)
489 /* 20171112 : this can be replaced with efl_aux_hints procotol */
491 Ecore_Wl2_Window *win = NULL;
492 Ecore_Wl2_Event_Aux_Message *ev;
493 char *p = NULL, *str = NULL;
494 Eina_List *opt_list = NULL;
495 Ecore_Wl2_Display *ewd = data;
497 if (!surface_resource) return;
498 win = _ecore_wl2_display_window_surface_find(ewd, surface_resource);
501 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Aux_Message)))) return;
503 if ((options) && (options->size))
506 while ((const char *)p < ((const char *)options->data + options->size))
508 str = (char *)eina_stringshare_add(p);
509 opt_list = eina_list_append(opt_list, str);
515 ev->key = eina_stringshare_add(key);
516 ev->val = eina_stringshare_add(val);
517 ev->options = opt_list;
521 ecore_event_add(ECORE_WL2_EVENT_AUX_MESSAGE, ev, _cb_aux_message_free, NULL);
525 _tizen_policy_cb_conformant_region(void *data EINA_UNUSED, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t conformant_part EINA_UNUSED, uint32_t state EINA_UNUSED, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, int32_t w EINA_UNUSED, int32_t h EINA_UNUSED, uint32_t serial EINA_UNUSED)
529 // TIZEN_ONLY(20220923) - for interactive move resize
531 _cb_interactive_move_resize_done_free(void *data EINA_UNUSED, void *event)
537 _tizen_policy_cb_interactive_move_done(void *data, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface, int32_t x, int32_t y, uint32_t w, uint32_t h, int32_t angle)
539 Ecore_Wl2_Window *win = NULL;
540 Ecore_Wl2_Event_Window_Interactive_Move_Done *ev;
541 Ecore_Wl2_Display *ewd = data;
543 if (!surface) return;
544 win = _ecore_wl2_display_window_surface_find(ewd, surface);
547 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Interactive_Move_Done));
557 ecore_event_add(ECORE_WL2_EVENT_WINDOW_INTERACTIVE_MOVE_DONE, ev, _cb_interactive_move_resize_done_free, NULL);
561 _tizen_policy_cb_interactive_resize_done(void *data, struct tizen_policy *tizen_policy EINA_UNUSED, struct wl_surface *surface, int32_t x, int32_t y, uint32_t w, uint32_t h, int32_t angle)
563 Ecore_Wl2_Window *win = NULL;
564 Ecore_Wl2_Event_Window_Interactive_Resize_Done *ev;
565 Ecore_Wl2_Display *ewd = data;
567 if (!surface) return;
568 win = _ecore_wl2_display_window_surface_find(ewd, surface);
571 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Interactive_Resize_Done));
581 ecore_event_add(ECORE_WL2_EVENT_WINDOW_INTERACTIVE_RESIZE_DONE, ev, _cb_interactive_move_resize_done_free, NULL);
583 ecore_wl2_window_resize_request_unset(win);
587 static const struct tizen_policy_listener _tizen_policy_listener =
589 _tizen_policy_cb_conformant,
590 _tizen_policy_cb_conformant_area,
591 _tizen_policy_cb_notification_done,
592 _tizen_policy_cb_transient_for_done,
593 _tizen_policy_cb_window_screen_mode_done,
594 _tizen_policy_cb_iconify_state_changed,
595 _tizen_policy_cb_supported_aux_hints,
596 _tizen_policy_cb_allowed_aux_hint,
597 _tizen_policy_cb_aux_message,
598 _tizen_policy_cb_conformant_region,
599 _tizen_policy_cb_interactive_move_done,
600 _tizen_policy_cb_interactive_resize_done
603 // TIZEN_ONLY(20190430): support client appinfo
605 _tizen_appinfo_cb_base_output_resolution_done(void *data, struct tizen_launch_appinfo *tz_appinfo EINA_UNUSED, uint32_t pid, uint32_t width, uint32_t height)
607 Ecore_Wl2_Display *ewd = data;
610 if ((unsigned int)_base_resolution_pid != pid)
612 ERR("tzappinfo_cb_size_get_done pid is different. pid: %d / width: %d / height: %d appinfo_pid: %d", pid, width, height, _base_resolution_pid);
616 if (_base_resolution_w != width) _base_resolution_w = width;
617 if (_base_resolution_h != height) _base_resolution_h = height;
620 static const struct tizen_launch_appinfo_listener _tizen_launch_appinfo_listener =
622 _tizen_appinfo_cb_base_output_resolution_done,
627 _tizen_policy_ext_cb_active_angle(void *data, struct tizen_policy_ext *tizen_policy_ext EINA_UNUSED, uint32_t angle)
629 Ecore_Wl2_Display *ewd = data;
630 ewd->active_angle = angle;
633 static const struct tizen_policy_ext_listener _tizen_policy_ext_listener =
635 _tizen_policy_ext_cb_active_angle,
639 _tizen_effect_cb_start(void *data EINA_UNUSED, struct tizen_effect *tizen_effect EINA_UNUSED, struct wl_surface *surface_resource, unsigned int type)
641 struct wl_surface *surface = surface_resource;
642 Ecore_Wl2_Window *win = NULL;
643 Ecore_Wl2_Event_Effect_Start *ev;
645 if (!surface) return;
646 win = ecore_wl2_window_surface_find(surface);
649 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Effect_Start)))) return;
652 ecore_event_add(ECORE_WL2_EVENT_EFFECT_START, ev, NULL, NULL);
656 _tizen_effect_cb_end(void *data EINA_UNUSED, struct tizen_effect *tizen_effect EINA_UNUSED, struct wl_surface *surface_resource, unsigned int type)
658 struct wl_surface *surface = surface_resource;
659 Ecore_Wl2_Window *win = NULL;
660 Ecore_Wl2_Event_Effect_End *ev;
662 if (!surface) return;
663 win = ecore_wl2_window_surface_find(surface);
666 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Effect_End)))) return;
669 ecore_event_add(ECORE_WL2_EVENT_EFFECT_END, ev, NULL, NULL);
672 static const struct tizen_effect_listener _tizen_effect_listener =
674 _tizen_effect_cb_start,
675 _tizen_effect_cb_end,
679 _tizen_indicator_cb_flick(void *data, struct tizen_indicator *tizen_indicator EINA_UNUSED, struct wl_surface *surface_resource, int type)
681 Ecore_Wl2_Window *win = NULL;
682 Ecore_Wl2_Display *ewd = data;
683 Ecore_Wl2_Event_Indicator_Flick *ev;
685 if (!surface_resource) return;
686 win = _ecore_wl2_display_window_surface_find(ewd, surface_resource);
689 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Indicator_Flick)))) return;
693 ecore_event_add(ECORE_WL2_EVENT_INDICATOR_FLICK, ev, NULL, NULL);
696 static const struct tizen_indicator_listener _tizen_indicator_listener =
698 _tizen_indicator_cb_flick,
702 _tizen_clipboard_cb_data_selected(void *data, struct tizen_clipboard *tizen_clipboard EINA_UNUSED, struct wl_surface *surface)
704 Ecore_Wl2_Window *win = NULL;
705 Ecore_Wl2_Display *ewd = data;
706 Ecore_Wl2_Event_Clipboard_Data_Selected *ev;
708 if (!surface) return;
709 win = _ecore_wl2_display_window_surface_find(ewd, surface);
712 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Clipboard_Data_Selected)))) return;
715 ecore_event_add(ECORE_WL2_EVENT_CLIPBOARD_DATA_SELECTED, ev, NULL, NULL);
719 _tizen_clipboard_cb_allowed_data_only(void *data, struct tizen_clipboard *tizen_clipboard EINA_UNUSED, uint32_t allowed)
721 Ecore_Wl2_Display *ewd = NULL;
722 Ecore_Wl2_Input *input = NULL;
725 input = ecore_wl2_input_default_input_get(ewd);
729 input->is_data_only = EINA_TRUE;
731 input->is_data_only = EINA_FALSE;
734 static const struct tizen_clipboard_listener _tizen_clipboard_listener =
736 _tizen_clipboard_cb_data_selected,
737 _tizen_clipboard_cb_allowed_data_only,
741 //TIZEN_ONLY(20171115): support output transform
743 _tizen_screen_rotation_cb_ignore_output_transform(void *data EINA_UNUSED, struct tizen_screen_rotation *tizen_screen_rotation EINA_UNUSED, struct wl_surface *surface, uint32_t ignore)
745 Ecore_Wl2_Window *win = NULL;
746 Ecore_Wl2_Event_Ignore_Output_Transform *ev;
748 if (!surface) return;
749 win = ecore_wl2_window_surface_find(surface);
752 _ecore_wl2_window_ignore_output_transform_set(win, ignore);
754 if (!(ev = calloc(1, sizeof(Ecore_Wl2_Event_Ignore_Output_Transform)))) return;
757 ev->ignore = (ignore) ? EINA_TRUE : EINA_FALSE;
758 ecore_event_add(ECORE_WL2_EVENT_IGNORE_OUTPUT_TRANSFORM, ev, NULL, NULL);
761 static const struct tizen_screen_rotation_listener _tizen_screen_rotation_listener =
763 _tizen_screen_rotation_cb_ignore_output_transform,
767 _tizen_move_resize_cb_geometry_done(void *data EINA_UNUSED, struct tizen_move_resize *tz_moveresize EINA_UNUSED, struct wl_surface *surface EINA_UNUSED, uint32_t serial EINA_UNUSED, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, int32_t w EINA_UNUSED, int32_t h EINA_UNUSED, uint32_t err EINA_UNUSED)
769 /* to be implemented*/
772 static const struct tizen_move_resize_listener _tizen_move_resize_listener =
774 _tizen_move_resize_cb_geometry_done,
778 //TIZEN_ONLY(20230312): support wtz_screen
780 _wtz_screen_cb_size(void *data, struct wtz_screen *screen EINA_UNUSED, uint32_t width, uint32_t height)
782 Ecore_Wl2_Display *ewd = data;
783 Ecore_Wl2_Screen *ews;
787 ews = _ecore_wl2_display_screen_get(ewd);
790 _ecore_wl2_screen_size_set(ews, width, height);
794 _wtz_screen_cb_name(void *data, struct wtz_screen *screen EINA_UNUSED, const char *name)
796 Ecore_Wl2_Display *ewd = data;
797 Ecore_Wl2_Screen *ews;
801 ews = _ecore_wl2_display_screen_get(ewd);
804 _ecore_wl2_screen_name_set(ews, name);
808 _wtz_screen_cb_capabilities(void *data, struct wtz_screen *screen EINA_UNUSED, struct wl_array *capabilities)
810 Ecore_Wl2_Display *ewd = data;
811 Ecore_Wl2_Screen *ews;
817 ews = _ecore_wl2_display_screen_get(ewd);
820 if ((capabilities) && (capabilities->size))
822 p = capabilities->data;
823 while ((const uint32_t *)p < ((const uint32_t *)capabilities->data + capabilities->size))
825 switch ((uint32_t) *p)
827 case WTZ_SCREEN_CAPABILITY_SPLITSCREEN :
828 capability |= ECORE_WL2_SCREEN_CAPABILITY_SPLITSCREEN;
835 _ecore_wl2_screen_capability_set(ews, capability);
838 static const struct wtz_screen_listener _wtz_screen_listener =
840 .size = _wtz_screen_cb_size,
841 .name = _wtz_screen_cb_name,
842 .capabilities = _wtz_screen_cb_capabilities,
847 _cb_global_event_free(void *data EINA_UNUSED, void *event)
849 Ecore_Wl2_Event_Global *ev;
852 eina_stringshare_del(ev->interface);
853 ecore_wl2_display_disconnect(ev->display);
858 _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version)
860 Ecore_Wl2_Display *ewd;
861 Ecore_Wl2_Event_Global *ev;
863 int client_version = 1;
866 //TIZEN_ONLY(2023): ecore_Wl2: improved Wayland issues handling
869 EINA_LOG_ERR("No data provided for global add event");
876 /* test to see if we have already added this global to our hash */
877 if (!eina_hash_find(ewd->globals, &id))
879 Ecore_Wl2_Global *global;
881 /* allocate space for new global */
882 global = calloc(1, sizeof(Ecore_Wl2_Global));
886 global->interface = eina_stringshare_add(interface);
887 global->version = version;
889 /* add this global to our hash */
890 if (!eina_hash_add(ewd->globals, &global->id, global))
892 eina_stringshare_del(global->interface);
899 if (!strcmp(interface, "wl_compositor"))
901 Ecore_Wl2_Window *window;
902 ewd->wl.compositor_version = MIN(version, 4);
904 wl_registry_bind(registry, id, &wl_compositor_interface,
905 ewd->wl.compositor_version);
907 //TIZEN_ONLY(2023): ecore_wl2: improved Wayland issues handling
908 if (ewd->wl.compositor == NULL)
910 EINA_LOG_ERR("Failed to bind wl_compositor");
915 EINA_INLIST_FOREACH(ewd->windows, window)
916 _ecore_wl2_window_surface_create(window);
918 else if (!strcmp(interface, "wl_subcompositor"))
920 ewd->wl.subcompositor =
921 wl_registry_bind(registry, id, &wl_subcompositor_interface, 1);
923 else if (!strcmp(interface, "wl_shm"))
926 wl_registry_bind(registry, id, &wl_shm_interface, 1);
928 else if (!strcmp(interface, "zwp_linux_dmabuf_v1") && (version >= 2))
931 wl_registry_bind(registry, id, &zwp_linux_dmabuf_v1_interface, 2);
932 zwp_linux_dmabuf_v1_add_listener(ewd->wl.dmabuf, &_dmabuf_listener, ewd);
933 _ecore_wl2_buffer_test(ewd);
934 _ecore_wl2_display_sync_add(ewd);
936 else if (!strcmp(interface, "wl_data_device_manager"))
938 ewd->wl.data_device_manager_version = MIN(version, 3);
939 ewd->wl.data_device_manager =
940 wl_registry_bind(registry, id, &wl_data_device_manager_interface, ewd->wl.data_device_manager_version);
942 else if ((eina_streq(interface, "www")) &&
943 (getenv("EFL_WAYLAND_ENABLE_WWW")))
945 Ecore_Wl2_Window *window;
947 ewd->wl.www = wl_registry_bind(registry, id, &www_interface, 1);
948 EINA_INLIST_FOREACH(ewd->windows, window)
949 _ecore_wl2_window_www_surface_init(window);
951 else if ((!strcmp(interface, "zwp_e_session_recovery")) &&
952 (!no_session_recovery))
954 ewd->wl.session_recovery =
955 wl_registry_bind(registry, id,
956 &zwp_e_session_recovery_interface, 1);
957 zwp_e_session_recovery_add_listener(ewd->wl.session_recovery,
958 &_session_listener, ewd);
960 else if (!strcmp(interface, "efl_aux_hints"))
962 Ecore_Wl2_Window *window;
963 ewd->wl.efl_aux_hints =
964 wl_registry_bind(registry, id,
965 &efl_aux_hints_interface, 1);
966 efl_aux_hints_add_listener(ewd->wl.efl_aux_hints, &_aux_hints_listener, ewd);
967 EINA_INLIST_FOREACH(ewd->windows, window)
968 if (window->surface) efl_aux_hints_get_supported_aux_hints(ewd->wl.efl_aux_hints, window->surface);
970 else if (!strcmp(interface, "zwp_teamwork"))
973 wl_registry_bind(registry, id,
974 &zwp_teamwork_interface, EFL_TEAMWORK_VERSION);
976 else if (!strcmp(interface, "wl_output"))
977 _ecore_wl2_output_add(ewd, id);
978 else if (!strcmp(interface, "wl_seat"))
979 _ecore_wl2_input_add(ewd, id, version);
980 else if (!strcmp(interface, "efl_hints"))
982 Ecore_Wl2_Window *window;
984 ewd->wl.efl_hints = wl_registry_bind(registry, id, &efl_hints_interface, MIN(version, 2));
985 EINA_INLIST_FOREACH(ewd->windows, window)
987 if (!window->xdg_surface) continue;
988 if (window->aspect.set)
989 efl_hints_set_aspect(window->display->wl.efl_hints, window->xdg_surface,
990 window->aspect.w, window->aspect.h, window->aspect.aspect);
991 if (window->weight.set)
992 efl_hints_set_weight(window->display->wl.efl_hints,
993 window->xdg_surface, window->weight.w, window->weight.h);
996 // TIZEN_ONLY : To use tizen protocols
997 else if (!strcmp(interface, "tizen_policy"))
1000 client_version = 13;
1002 client_version = version;
1005 wl_registry_bind(registry, id, &tizen_policy_interface, client_version);
1006 if (ewd->wl.tz_policy)
1007 tizen_policy_add_listener(ewd->wl.tz_policy, &_tizen_policy_listener, ewd);
1009 else if (!strcmp(interface, "tizen_policy_ext"))
1014 client_version = version;
1016 ewd->wl.tz_policy_ext =
1017 wl_registry_bind(registry, id, &tizen_policy_ext_interface, client_version);
1018 if (ewd->wl.tz_policy_ext)
1019 tizen_policy_ext_add_listener(ewd->wl.tz_policy_ext, &_tizen_policy_ext_listener, ewd);
1021 else if (!strcmp(interface, "tizen_surface"))
1024 wl_registry_bind(registry, id, &tizen_surface_interface, 1);
1026 else if (!strcmp(interface, "tizen_effect"))
1029 wl_registry_bind(registry, id, &tizen_effect_interface, 1);
1030 if (ewd->wl.tz_effect)
1031 tizen_effect_add_listener(ewd->wl.tz_effect, &_tizen_effect_listener, ewd->wl.display);
1033 else if (!strcmp(interface, "tizen_indicator"))
1035 ewd->wl.tz_indicator =
1036 wl_registry_bind(registry, id, &tizen_indicator_interface, 1);
1037 if (ewd->wl.tz_indicator)
1038 tizen_indicator_add_listener(ewd->wl.tz_indicator, &_tizen_indicator_listener, ewd);
1040 else if (!strcmp(interface, "tizen_clipboard"))
1045 client_version = version;
1047 ewd->wl.tz_clipboard =
1048 wl_registry_bind(registry, id, &tizen_clipboard_interface, client_version);
1050 if (ewd->wl.tz_clipboard)
1051 tizen_clipboard_add_listener(ewd->wl.tz_clipboard, &_tizen_clipboard_listener, ewd);
1053 // TIZEN_ONLY(20171107): support a tizen_keyrouter interface
1054 else if (!strcmp(interface, "tizen_keyrouter"))
1056 _ecore_wl2_keyrouter_setup(ewd, id, version);
1059 // TIZEN_ONLY(20171109): support a tizen_input_device_manager interface
1060 else if (!strcmp(interface, "tizen_input_device_manager"))
1062 _ecore_wl2_input_device_manager_setup(ewd, id, version);
1065 //TIZEN_ONLY(20171115): support output transform
1066 else if (!strcmp(interface, "tizen_screen_rotation"))
1068 ewd->wl.tz_screen_rotation =
1069 wl_registry_bind(registry, id, &tizen_screen_rotation_interface, 1);
1070 if (ewd->wl.tz_screen_rotation)
1071 tizen_screen_rotation_add_listener(ewd->wl.tz_screen_rotation, &_tizen_screen_rotation_listener, ewd->wl.display);
1074 //TIZEN_ONLY(20180810): support client driven move resize
1075 else if (!strcmp(interface, "tizen_move_resize"))
1077 ewd->wl.tz_moveresize =
1078 wl_registry_bind(registry, id, &tizen_move_resize_interface, 1);
1079 if (ewd->wl.tz_moveresize)
1080 tizen_move_resize_add_listener(ewd->wl.tz_moveresize, &_tizen_move_resize_listener, ewd->wl.display);
1083 // TIZEN_ONLY(20190430): support client appinfo
1084 else if (!strcmp(interface, "tizen_launch_appinfo"))
1086 ewd->wl.tz_appinfo =
1087 wl_registry_bind(registry, id, &tizen_launch_appinfo_interface, 1);
1088 if (ewd->wl.tz_appinfo)
1089 tizen_launch_appinfo_add_listener(ewd->wl.tz_appinfo, &_tizen_launch_appinfo_listener, ewd->wl.display);
1092 //TIZEN_ONLY(20200626): support tizen_renderer
1093 else if (!strcmp(interface, "tizen_renderer"))
1095 ewd->wl.tz_renderer =
1096 wl_registry_bind(registry, id, &tizen_renderer_interface, 1);
1099 //TIZEN_ONLY(20230312): support wtz_screen
1100 else if (!strcmp(interface, "wtz_screen"))
1102 if (ewd->wl.wtz_scr)
1104 // TODO : support multi wtz_screen
1108 wl_registry_bind(registry, id, &wtz_screen_interface, 1);
1109 if (ewd->wl.wtz_scr)
1110 wtz_screen_add_listener(ewd->wl.wtz_scr, &_wtz_screen_listener, ewd);
1113 // TIZEN_ONLY(20230801) : support zwp relative pointer protocol
1114 else if (!strcmp(interface, "zwp_relative_pointer_manager_v1"))
1116 ewd->wl.relative_pointer_manager =
1117 wl_registry_bind(registry, id,
1118 &zwp_relative_pointer_manager_v1_interface, version);
1121 // TIZEN_ONLY(20230801) : support zwp pointer constraints protocol
1122 else if (!strcmp(interface, "zwp_pointer_constraints_v1"))
1124 ewd->wl.pointer_constraints =
1125 wl_registry_bind(registry, id,
1126 &zwp_pointer_constraints_v1_interface, version);
1132 /* allocate space for event structure */
1133 ev = calloc(1, sizeof(Ecore_Wl2_Event_Global));
1139 ev->version = version;
1140 ev->interface = eina_stringshare_add(interface);
1142 /* raise an event saying a new global has been added */
1143 ecore_event_add(ECORE_WL2_EVENT_GLOBAL_ADDED, ev,
1144 _cb_global_event_free, NULL);
1147 //TIZEN_ONLY(2023): ecore_wl2: improved Wayland issues handlin
1149 EINA_LOG_ERR("Failed to create global for registry : %p, id: %d, interface: %s, version: %d", registry, id, interface, version);
1154 _cb_global_remove(void *data, struct wl_registry *registry EINA_UNUSED, unsigned int id)
1156 Ecore_Wl2_Display *ewd;
1157 Ecore_Wl2_Global *global;
1158 Ecore_Wl2_Event_Global *ev;
1162 /* try to find this global in our hash */
1163 global = eina_hash_find(ewd->globals, &id);
1164 if (!global) return;
1166 /* allocate space for event structure */
1167 ev = calloc(1, sizeof(Ecore_Wl2_Event_Global));
1173 ev->version = global->version;
1174 ev->interface = eina_stringshare_add(global->interface);
1176 /* raise an event saying a global has been removed */
1177 ecore_event_add(ECORE_WL2_EVENT_GLOBAL_REMOVED, ev,
1178 _cb_global_event_free, NULL);
1180 /* delete this global from our hash */
1181 if (ewd->globals) eina_hash_del_by_key(ewd->globals, &id);
1184 static const struct wl_registry_listener _registry_listener =
1191 _cb_create_data(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
1193 Ecore_Wl2_Display *ewd = data;
1194 struct wl_event_loop *loop;
1196 loop = wl_display_get_event_loop(ewd->wl.display);
1197 wl_event_loop_dispatch(loop, 0);
1199 /* wl_display_flush_clients(ewd->wl.display); */
1201 return ECORE_CALLBACK_RENEW;
1205 _cb_create_prepare(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
1207 Ecore_Wl2_Display *ewd = data;
1209 wl_display_flush_clients(ewd->wl.display);
1213 _recovery_timer(Ecore_Wl2_Display *ewd)
1215 if (!_ecore_wl2_display_connect(ewd, 1))
1218 ewd->recovery_timer = NULL;
1223 _ecore_wl2_display_globals_cleanup(Ecore_Wl2_Display *ewd)
1225 if (ewd->wl.session_recovery)
1226 zwp_e_session_recovery_destroy(ewd->wl.session_recovery);
1227 if (ewd->wl.www) www_destroy(ewd->wl.www);
1228 if (ewd->wl.xdg_wm_base) xdg_wm_base_destroy(ewd->wl.xdg_wm_base);
1229 if (ewd->wl.zxdg_shell) zxdg_shell_v6_destroy(ewd->wl.zxdg_shell);
1230 if (ewd->wl.shm) wl_shm_destroy(ewd->wl.shm);
1231 if (ewd->wl.data_device_manager)
1232 wl_data_device_manager_destroy(ewd->wl.data_device_manager);
1233 if (ewd->wl.compositor) wl_compositor_destroy(ewd->wl.compositor);
1234 if (ewd->wl.subcompositor) wl_subcompositor_destroy(ewd->wl.subcompositor);
1235 if (ewd->wl.dmabuf) zwp_linux_dmabuf_v1_destroy(ewd->wl.dmabuf);
1236 if (ewd->wl.efl_aux_hints) efl_aux_hints_destroy(ewd->wl.efl_aux_hints);
1237 if (ewd->wl.efl_hints) efl_hints_destroy(ewd->wl.efl_hints);
1241 if (ewd->wl.tz_policy) tizen_policy_destroy(ewd->wl.tz_policy);
1242 if (ewd->wl.tz_policy_ext) tizen_policy_ext_destroy(ewd->wl.tz_policy_ext);
1243 if (ewd->wl.tz_surf) tizen_surface_destroy(ewd->wl.tz_surf);
1244 if (ewd->wl.tz_effect) tizen_effect_destroy(ewd->wl.tz_effect);
1245 if (ewd->wl.tz_indicator) tizen_indicator_destroy(ewd->wl.tz_indicator);
1246 if (ewd->wl.tz_clipboard) tizen_clipboard_destroy(ewd->wl.tz_clipboard);
1247 if (ewd->wl.tz_screen_rotation) tizen_screen_rotation_destroy(ewd->wl.tz_screen_rotation);
1248 if (ewd->wl.tz_moveresize) tizen_move_resize_destroy(ewd->wl.tz_moveresize);
1249 if (ewd->wl.tz_video) tizen_video_destroy(ewd->wl.tz_video);
1250 if (ewd->wl.tz_renderer) tizen_renderer_destroy(ewd->wl.tz_renderer);
1251 if (ewd->wl.wtz_scr) wtz_screen_destroy(ewd->wl.wtz_scr);
1252 if (ewd->wl.relative_pointer_manager)
1253 zwp_relative_pointer_manager_v1_destroy(ewd->wl.relative_pointer_manager);
1254 if (ewd->wl.pointer_constraints)
1255 zwp_pointer_constraints_v1_destroy(ewd->wl.pointer_constraints);
1258 if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry);
1262 _recovery_timer_add(Ecore_Wl2_Display *ewd)
1264 Eina_Inlist *tmp, *tmp2;
1265 Ecore_Wl2_Output *output;
1266 Ecore_Wl2_Input *input;
1267 Ecore_Wl2_Window *window;
1269 eina_hash_free_buckets(ewd->globals);
1270 ecore_idle_enterer_del(ewd->idle_enterer);
1271 ewd->idle_enterer = NULL;
1273 // TIZEN_ONLY(20171129): thread-safety for wl
1274 ecore_main_awake_handler_del(_ecore_wl_cb_awake);
1275 // End of TIZEN_ONLY(20171129)
1276 ecore_main_fd_handler_del(ewd->fd_hdl);
1279 #ifdef USE_TIZEN_CORE
1284 tizen_core_source_destroy(ewd->source);
1289 tizen_core_poll_fd_destroy(ewd->poll_fd);
1290 ewd->poll_fd = NULL;
1293 #endif // USE_TIZEN_CORE
1295 ewd->shell_done = EINA_FALSE;
1296 ewd->sync_done = EINA_FALSE;
1297 ewd->recovering = EINA_TRUE;
1299 _ecore_wl2_display_globals_cleanup(ewd);
1301 memset(&ewd->wl, 0, sizeof(ewd->wl));
1302 EINA_INLIST_FOREACH_SAFE(ewd->inputs, tmp, input)
1303 _ecore_wl2_input_del(input);
1305 EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output)
1306 _ecore_wl2_output_del(output);
1308 EINA_INLIST_FOREACH_SAFE(ewd->windows, tmp, window)
1310 Ecore_Wl2_Subsurface *subsurf;
1312 EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp2, subsurf)
1313 _ecore_wl2_subsurf_unmap(subsurf);
1314 _ecore_wl2_window_semi_free(window);
1315 window->set_config.serial = 0;
1316 window->req_config.serial = 0;
1317 window->xdg_configure_ack = NULL;
1318 window->xdg_set_min_size = NULL;
1319 window->xdg_set_max_size = NULL;
1320 window->zxdg_configure_ack = NULL;
1321 window->zxdg_set_min_size = NULL;
1322 window->zxdg_set_max_size = NULL;
1325 ewd->recovery_timer =
1326 ecore_timer_add(0.5, (Ecore_Task_Cb)_recovery_timer, ewd);
1327 _ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_DISCONNECT);
1331 _begin_recovery_maybe(Ecore_Wl2_Display *ewd, int code)
1333 if ((_server_displays || (code != EPROTO)) && ewd->wl.session_recovery)// && (errno == EPIPE))
1334 _recovery_timer_add(ewd);
1335 else if (!_server_displays)
1337 ERR("Wayland Socket Error: %s", eina_error_msg_get(errno));
1338 _ecore_wl2_display_signal_exit();
1342 // TIZEN_ONLY(20171129): thread-safety for wl
1344 _ecore_wl_cb_pre_handle_data(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED)
1346 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
1348 EINA_SAFETY_ON_NULL_RETURN(ewd);
1350 if (ewd->prepare_read) return;
1353 while (wl_display_prepare_read(ewd->wl.display) != 0)
1355 ret = wl_display_dispatch_pending(ewd->wl.display);
1358 ERR("Wayland Display Dispatch Pending Failed");
1363 wl_display_flush(ewd->wl.display);
1365 ewd->prepare_read = EINA_TRUE;
1369 _ecore_wl_cb_awake(void *data)
1371 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
1373 EINA_SAFETY_ON_NULL_RETURN(ewd);
1374 EINA_SAFETY_ON_NULL_RETURN(ewd->fd_hdl);
1376 if (!ewd->prepare_read) return;
1378 ewd->prepare_read = EINA_FALSE;
1380 if (ecore_main_fd_handler_active_get(ewd->fd_hdl, ECORE_FD_ERROR))
1382 ERR("[ecore_wl_cb_awake] Received error on wayland display fd");
1383 wl_display_cancel_read(ewd->wl.display);
1387 if (ecore_main_fd_handler_active_get(ewd->fd_hdl, ECORE_FD_READ))
1388 wl_display_read_events(ewd->wl.display);
1390 wl_display_cancel_read(ewd->wl.display);
1392 // End of TIZEN_ONLY(20171129)
1395 _cb_connect_data(void *data, Ecore_Fd_Handler *hdl)
1397 // TIZEN_ONLY(20171129): thread-safety for wl
1398 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)data;
1401 EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, ECORE_CALLBACK_CANCEL);
1402 EINA_SAFETY_ON_NULL_RETURN_VAL(ewd->fd_hdl, ECORE_CALLBACK_CANCEL);
1404 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
1406 ERR("Received error on wayland display fd");
1410 if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
1411 ret = wl_display_dispatch_pending(ewd->wl.display);
1412 else if (ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
1414 ret = wl_display_flush(ewd->wl.display);
1416 ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
1419 if ((ret < 0) && (errno != EAGAIN) && (errno != EINVAL))
1422 return ECORE_CALLBACK_RENEW;
1426 _begin_recovery_maybe(ewd, errno);
1428 return ECORE_CALLBACK_CANCEL;
1429 // End of TIZEN_ONLY(20171129)
1433 _cb_globals_hash_del(void *data)
1435 Ecore_Wl2_Global *global;
1439 eina_stringshare_del(global->interface);
1445 _cb_connect_idle(void *data)
1447 Ecore_Wl2_Display *ewd = data;
1450 ret = wl_display_get_error(ewd->wl.display);
1452 if (ret < 0) goto err;
1454 ret = wl_display_dispatch_pending(ewd->wl.display);
1456 if (ret < 0) goto err;
1458 return ECORE_CALLBACK_RENEW;
1461 if ((ret < 0) && (code != EAGAIN))
1463 ewd->idle_enterer = NULL;
1464 _begin_recovery_maybe(ewd, code);
1466 return ECORE_CALLBACK_CANCEL;
1469 return ECORE_CALLBACK_RENEW;
1472 static Ecore_Wl2_Global *
1473 _ecore_wl2_global_find(Ecore_Wl2_Display *ewd, const char *interface)
1476 Ecore_Wl2_Global *global = NULL, *g = NULL;
1478 itr = eina_hash_iterator_data_new(ewd->globals);
1479 if (!itr) return NULL;
1481 EINA_ITERATOR_FOREACH(itr, g)
1483 if (!strcmp(g->interface, interface))
1490 eina_iterator_free(itr);
1495 _ecore_wl2_shell_bind(Ecore_Wl2_Display *ewd)
1497 Ecore_Wl2_Global *global = NULL;
1499 const char *shells[] =
1506 if (ewd->shell_done) return;
1508 for (itr = shells; *itr != NULL; itr++)
1510 global = _ecore_wl2_global_find(ewd, *itr);
1511 if (!global) continue;
1515 if (!global) return;
1517 if (!strcmp(global->interface, "xdg_wm_base"))
1519 ewd->wl.xdg_wm_base =
1520 wl_registry_bind(ewd->wl.registry, global->id,
1521 &xdg_wm_base_interface, 1);
1522 xdg_wm_base_add_listener(ewd->wl.xdg_wm_base,
1523 &_xdg_shell_listener, ewd);
1524 ewd->shell_done = EINA_TRUE;
1526 else if (!strcmp(global->interface, "zxdg_shell_v6"))
1528 ewd->wl.zxdg_shell =
1529 wl_registry_bind(ewd->wl.registry, global->id,
1530 &zxdg_shell_v6_interface, 1);
1531 zxdg_shell_v6_add_listener(ewd->wl.zxdg_shell,
1532 &_zxdg_shell_listener, ewd);
1533 ewd->shell_done = EINA_TRUE;
1538 _cb_sync_done(void *data, struct wl_callback *cb, uint32_t serial EINA_UNUSED)
1540 Ecore_Wl2_Event_Sync_Done *ev;
1541 Ecore_Wl2_Display *ewd;
1544 if (--ewd->syncs) return;
1545 if (ewd->sync_done) return;
1547 ewd->sync_done = EINA_TRUE;
1549 _ecore_wl2_shell_bind(ewd);
1551 wl_callback_destroy(cb);
1552 ecore_wl2_display_flush(ewd);
1554 ev = calloc(1, sizeof(Ecore_Wl2_Event_Sync_Done));
1559 ecore_event_add(ECORE_WL2_EVENT_SYNC_DONE, ev, _display_event_free, ewd);
1562 static const struct wl_callback_listener _sync_listener =
1567 // TIZEN_ONLY(20171110): wait until sync done is called in ecore_wl2_display_sync
1569 _cb_tz_sync_done(void *data, struct wl_callback *cb, uint32_t serial EINA_UNUSED)
1571 Ecore_Wl2_Display *ewd;
1575 ewd->sync_ref_count--;
1577 wl_callback_destroy(cb);
1580 static const struct wl_callback_listener _tz_sync_listener =
1586 _ecore_wl2_disconnected(int error)
1588 if (error == EPIPE ||
1589 error == ECONNRESET)
1596 _ecore_wl2_signal_exit(void)
1598 Ecore_Event_Signal_Exit *ev;
1600 if (!(ev = calloc(1, sizeof(Ecore_Event_Signal_Exit))))
1604 ecore_event_add(ECORE_EVENT_SIGNAL_EXIT, ev, NULL, NULL);
1608 _ecore_wl2_display_dispatch_error(Ecore_Wl2_Display *ewd)
1610 uint32_t ecode = 0, id = 0;
1611 const struct wl_interface *intf = NULL;
1615 /* write out message about protocol error */
1616 ecode = wl_display_get_protocol_error(ewd->wl.display, &intf, &id);
1619 ERR("Wayland Client: Got protocol error %u on interface %s"
1620 " (object %u)\n", ecode, intf->name, id);
1622 /* raise exit signal */
1623 last_err = wl_display_get_error(ewd->wl.display);
1624 if (_ecore_wl2_disconnected(errno) || _ecore_wl2_disconnected(last_err))
1627 if (last_err) _err = last_err;
1628 str = eina_error_msg_get(_err);
1629 ERR("Disconnected from a wayland compositor : error:(%d) %s", _err, str);
1630 _ecore_wl2_signal_exit();
1635 str = eina_error_msg_get(errno);
1636 ERR("wayland socket error:(%d) %s", errno, str);
1642 ecore_wl2_display_sync(Ecore_Wl2_Display *display)
1644 //TIZEN_ONLY(20230428) Improved safety of ecore_wl2_display_sync
1645 struct wl_callback *cb = NULL;
1650 EINA_SAFETY_ON_NULL_RETURN(display);
1651 EINA_SAFETY_ON_NULL_RETURN(display->wl.display);
1653 display->sync_ref_count++;
1654 cb = wl_display_sync(display->wl.display);
1655 //TIZEN_ONLY(20230428) Improved safety of ecore_wl2_display_sync
1658 errno = wl_display_get_error(display->wl.display);
1659 ERR("Disconnected from a wayland compositor : %s", eina_error_msg_get(errno));
1660 _ecore_wl2_signal_exit();
1664 wl_callback_add_listener(cb, &_tz_sync_listener, display);
1666 while (display->sync_ref_count > 0)
1668 last_dpy_err = wl_display_get_error(display->wl.display);
1669 if (_ecore_wl2_disconnected(last_dpy_err))
1671 errno = last_dpy_err;
1672 ERR("Disconnected from a wayland compositor : %s", eina_error_msg_get(errno));
1673 _ecore_wl2_signal_exit();
1676 ret = wl_display_dispatch(display->wl.display);
1677 if ((ret < 0) && (errno != EAGAIN))
1679 _ecore_wl2_display_dispatch_error(display);
1686 //TIZEN_ONLY(20171108): add a new API to ecore_wl2_sync
1688 ecore_wl2_sync(void)
1690 Ecore_Wl2_Display *ewd;
1692 ewd = ecore_wl2_connected_display_get(NULL);
1695 ecore_wl2_display_sync(ewd);
1700 _ecore_wl2_display_sync_add(Ecore_Wl2_Display *ewd)
1702 struct wl_callback *cb;
1705 cb = wl_display_sync(ewd->wl.display);
1706 wl_callback_add_listener(cb, &_sync_listener, ewd);
1709 #ifdef USE_TIZEN_CORE
1711 _tcore_source_prepare_cb(tizen_core_source_h source, int *timeout,
1714 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)user_data;
1716 if (!ewd) return false;
1717 if (ewd->prepare_read) return false;
1719 while (wl_display_prepare_read(ewd->wl.display) != 0)
1721 if (wl_display_dispatch_pending(ewd->wl.display) < 0)
1723 ERR("wl_display_dispach_pending() is failed");
1728 wl_display_flush(ewd->wl.display);
1729 ewd->prepare_read = EINA_TRUE;
1735 _tcore_source_check_cb(tizen_core_source_h source, void *user_data)
1737 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)user_data;
1738 uint16_t returned_events = 0;
1740 if (!ewd) return false;
1741 if (!ewd->source) return false;
1742 if (!ewd->prepare_read) return false;
1744 ewd->prepare_read = EINA_FALSE;
1745 tizen_core_poll_fd_get_returned_events(ewd->poll_fd, &returned_events);
1747 if (returned_events & (TIZEN_CORE_POLL_EVENT_HUP | TIZEN_CORE_POLL_EVENT_ERR))
1749 ERR("Error event received");
1750 wl_display_cancel_read(ewd->wl.display);
1754 if (returned_events & TIZEN_CORE_POLL_EVENT_IN)
1756 wl_display_read_events(ewd->wl.display);
1760 wl_display_cancel_read(ewd->wl.display);
1765 _tcore_source_dispatch_cb(tizen_core_source_h source, void *user_data)
1767 Ecore_Wl2_Display *ewd = (Ecore_Wl2_Display *)user_data;
1768 uint16_t returned_events = 0;
1770 if (!ewd) return false;
1771 if (!ewd->source) return false;
1773 tizen_core_poll_fd_get_returned_events(ewd->poll_fd, &returned_events);
1775 if (returned_events & (TIZEN_CORE_POLL_EVENT_HUP | TIZEN_CORE_POLL_EVENT_ERR))
1777 ERR("Error event received");
1778 tizen_core_source_destroy(ewd->source);
1780 _begin_recovery_maybe(ewd, errno);
1784 if (returned_events & TIZEN_CORE_POLL_EVENT_IN)
1786 if (wl_display_dispatch_pending(ewd->wl.display) < 0)
1788 ERR("wl_display_dispatch_pending() is failed");
1792 wl_display_flush(ewd->wl.display);
1796 static void _tcore_source_destroy(Ecore_Wl2_Display *ewd)
1798 tizen_core_h core = NULL;
1802 tizen_core_find("main", &core);
1803 tizen_core_source_remove_poll(ewd->source, ewd->poll_fd);
1804 tizen_core_remove_source(core, ewd->source);
1810 tizen_core_poll_fd_destroy(ewd->poll_fd);
1811 ewd->poll_fd = NULL;
1816 _tcore_source_create(Ecore_Wl2_Display *ewd)
1818 tizen_core_poll_fd_h poll_fd = NULL;
1819 tizen_core_source_h source = NULL;
1820 tizen_core_h core = NULL;
1823 ret = tizen_core_poll_fd_create(&poll_fd);
1824 if (ret != TIZEN_CORE_ERROR_NONE)
1826 ERR("tizen_core_poll_fd_create() is failed. error=%d", ret);
1830 tizen_core_poll_fd_set_fd(poll_fd, wl_display_get_fd(ewd->wl.display));
1831 tizen_core_poll_fd_set_events(poll_fd, (TIZEN_CORE_POLL_EVENT_IN |
1832 TIZEN_CORE_POLL_EVENT_ERR));
1834 ret = tizen_core_source_create(&source);
1835 if (ret != TIZEN_CORE_ERROR_NONE)
1837 ERR("tizen_core_source_create() is failed. error=%d", ret);
1838 tizen_core_poll_fd_destroy(poll_fd);
1842 tizen_core_source_set_prepare_cb(source, _tcore_source_prepare_cb, ewd);
1843 tizen_core_source_set_check_cb(source, _tcore_source_check_cb, ewd);
1844 tizen_core_source_set_dispatch_cb(source, _tcore_source_dispatch_cb, ewd);
1845 tizen_core_source_add_poll(source, poll_fd);
1846 tizen_core_source_set_priority(source, TIZEN_CORE_PRIORITY_DEFAULT - 10);
1848 tizen_core_find("main", &core);
1849 tizen_core_add_source(core, source);
1851 ewd->poll_fd = poll_fd;
1852 ewd->source = source;
1855 #endif // USE_TIZEN_CORE
1857 #define RUN_WM_READY_FILE "/run/.wm_ready"
1860 _ecore_wl2_display_wait(Ecore_Wl2_Display *ewd)
1867 unsigned char buf[128];
1868 struct inotify_event *event;
1870 fd = inotify_init();
1871 if (fd == -1) return EINA_FALSE;
1873 wd = inotify_add_watch(fd, RUN_WM_READY_FILE, IN_MODIFY | IN_CREATE);
1880 if (access(RUN_WM_READY_FILE, F_OK) == 0)
1882 ERR("The server is ready");
1883 inotify_rm_watch(fd, wd);
1888 ERR("Wait for the server to be ready.[fd: %d, wd: %d", fd, wd);
1889 size = read(fd, buf, sizeof(buf));
1890 while ((i + sizeof(struct inotify_event)) <= size)
1892 event = (struct inotify_event *)&buf[i];
1893 event_size = sizeof(struct inotify_event) + event->len;
1894 if ((event_size + i) > size || (event_size + i) <= 0) break;
1896 if (event->mask & IN_CREATE | event->mask & IN_MODIFY) break;
1899 inotify_rm_watch(fd, wd);
1905 _ecore_wl2_display_connect(Ecore_Wl2_Display *ewd, Eina_Bool sync)
1907 /* try to connect to wayland display with this name */
1908 ewd->wl.display = wl_display_connect(ewd->name);
1909 if (!ewd->wl.display) {
1910 #ifdef HAVE_SYS_INOTIFY_H
1911 if (!_ecore_wl2_display_wait(ewd)) return EINA_FALSE;
1913 ewd->wl.display = wl_display_connect(ewd->name);
1914 ERR("Server is ready, wl.display is created %p", ewd->wl.display);
1920 ewd->recovering = EINA_FALSE;
1922 ewd->wl.registry = wl_display_get_registry(ewd->wl.display);
1923 wl_registry_add_listener(ewd->wl.registry, &_registry_listener, ewd);
1925 _ecore_wl2_display_sync_add(ewd);
1929 /* NB: If we are connecting (as a client), then we will need to setup
1930 * a callback for display_sync and wait for it to complete. There is no
1931 * other option here as we need the compositor, shell, etc, to be setup
1932 * before we can allow a user to make use of the API functions */
1933 while (!ewd->sync_done)
1937 ret = wl_display_dispatch(ewd->wl.display);
1938 if ((ret < 0) && (errno != EAGAIN))
1940 ERR("Received Fatal Error on Wayland Display");
1942 wl_registry_destroy(ewd->wl.registry);
1948 #ifdef USE_TIZEN_CORE
1951 if (_tcore_source_create(ewd) != 0)
1955 wl_registry_destroy(ewd->wl.registry);
1956 wl_display_disconnect(ewd->wl.display);
1957 ewd->wl.registry = NULL;
1958 ewd->wl.display = NULL;
1964 #endif // USE_TIZEN_CORE
1967 ecore_main_fd_handler_add(wl_display_get_fd(ewd->wl.display),
1968 ECORE_FD_READ | ECORE_FD_WRITE |
1970 _cb_connect_data, ewd, NULL, NULL);
1972 // TIZEN_ONLY(20180109): check null condition
1975 ERR("Fail to add ecore fd(%d, wl.display) handler",
1976 wl_display_get_fd(ewd->wl.display));
1979 wl_registry_destroy(ewd->wl.registry);
1980 wl_display_disconnect(ewd->wl.display);
1981 ewd->wl.registry = NULL;
1982 ewd->wl.display = NULL;
1986 // End of TIZEN_ONLY(20180109)
1988 ewd->idle_enterer = ecore_idle_enterer_add(_cb_connect_idle, ewd);
1989 // TIZEN_ONLY(20171129): thread-safety for wl
1990 ecore_main_fd_handler_prepare_callback_set(ewd->fd_hdl,
1991 _ecore_wl_cb_pre_handle_data, ewd);
1993 ecore_main_awake_handler_add(_ecore_wl_cb_awake, ewd);
1995 // End of TIZEN_ONLY(20171129)
1996 _ecore_wl2_display_event(ewd, ECORE_WL2_EVENT_CONNECT);
2001 _ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
2003 Ecore_Wl2_Output *output;
2004 Ecore_Wl2_Input *input;
2007 if (ewd->xkb_context) xkb_context_unref(ewd->xkb_context);
2009 /* free each input */
2010 EINA_INLIST_FOREACH_SAFE(ewd->inputs, tmp, input)
2011 _ecore_wl2_input_del(input);
2013 /* free each output */
2014 EINA_INLIST_FOREACH_SAFE(ewd->outputs, tmp, output)
2015 _ecore_wl2_output_del(output);
2017 if (ewd->idle_enterer) ecore_idle_enterer_del(ewd->idle_enterer);
2019 // TIZEN_ONLY(20171129): thread-safety for wl
2020 ecore_main_awake_handler_del(_ecore_wl_cb_awake);
2021 // End of TIZEN_ONLY(20171129)
2023 if (ewd->fd_hdl) ecore_main_fd_handler_del(ewd->fd_hdl);
2025 #ifdef USE_TIZEN_CORE
2026 _tcore_source_destroy(ewd);
2027 #endif // USE_TIZEN_CORE
2029 eina_hash_free(ewd->globals);
2031 //TIZEN_ONLY(20230312): support wtz_screen
2033 _ecore_wl2_screen_del(ewd->screen);
2036 _ecore_wl2_display_globals_cleanup(ewd);
2040 _ecore_wl2_display_window_surface_find(Ecore_Wl2_Display *display, struct wl_surface *wl_surface)
2042 Ecore_Wl2_Window *window;
2044 if ((!display) || (!wl_surface)) return NULL;
2046 EINA_INLIST_FOREACH(display->windows, window)
2048 if ((window->surface) &&
2049 (window->surface == wl_surface))
2056 EAPI Ecore_Wl2_Display *
2057 ecore_wl2_display_create(const char *name)
2059 Ecore_Wl2_Display *ewd;
2060 struct wl_event_loop *loop;
2062 if (!_server_displays)
2063 _server_displays = eina_hash_string_superfast_new(NULL);
2067 /* someone wants to create a server with a specific display */
2069 /* check hash of cached server displays for this name */
2070 ewd = eina_hash_find(_server_displays, name);
2071 if (ewd) goto found;
2074 /* allocate space for display structure */
2075 ewd = calloc(1, sizeof(Ecore_Wl2_Display));
2076 if (!ewd) return NULL;
2079 ewd->pid = getpid();
2081 /* try to create new wayland display */
2082 ewd->wl.display = wl_display_create();
2083 if (!ewd->wl.display)
2085 ERR("Could not create wayland display");
2093 n = wl_display_add_socket_auto(ewd->wl.display);
2096 ERR("Failed to add display socket");
2100 ewd->name = strdup(n);
2104 if (wl_display_add_socket(ewd->wl.display, name))
2106 ERR("Failed to add display socket");
2110 ewd->name = strdup(name);
2113 setenv("WAYLAND_DISPLAY", ewd->name, 1);
2114 DBG("WAYLAND_DISPLAY: %s", ewd->name);
2116 loop = wl_display_get_event_loop(ewd->wl.display);
2119 ecore_main_fd_handler_add(wl_event_loop_get_fd(loop),
2120 ECORE_FD_READ | ECORE_FD_ERROR,
2121 _cb_create_data, ewd, NULL, NULL);
2123 ecore_main_fd_handler_prepare_callback_set(ewd->fd_hdl,
2124 _cb_create_prepare, ewd);
2126 /* add this new server display to hash */
2127 eina_hash_add(_server_displays, ewd->name, ewd);
2132 wl_display_destroy(ewd->wl.display);
2144 _ecore_wl2_display_sync_get(void)
2146 return !_server_displays || !eina_hash_population(_server_displays);
2149 EAPI Ecore_Wl2_Display *
2150 ecore_wl2_display_connect(const char *name)
2152 Ecore_Wl2_Display *ewd;
2154 Eina_Bool hash_create = !_client_displays;
2156 if (!_client_displays)
2157 _client_displays = eina_hash_string_superfast_new(NULL);
2161 /* client wants to connect to default display */
2162 n = getenv("WAYLAND_DISPLAY");
2163 if (!n) n = "wayland-0";
2165 /* we have a default wayland display */
2167 /* check hash of cached client displays for this name */
2168 ewd = eina_hash_find(_client_displays, n);
2169 if (ewd) goto found;
2173 /* client wants to connect to specific display */
2175 /* check hash of cached client displays for this name */
2176 ewd = eina_hash_find(_client_displays, name);
2177 if (ewd) goto found;
2180 /* allocate space for display structure */
2181 ewd = calloc(1, sizeof(Ecore_Wl2_Display));
2182 if (!ewd) return NULL;
2187 ewd->name = strdup(name);
2189 ewd->name = strdup(n);
2191 ewd->globals = eina_hash_int32_new(_cb_globals_hash_del);
2193 ewd->xkb_context = xkb_context_new(0);
2194 if (!ewd->xkb_context) goto context_err;
2196 /* check server display hash and match on pid. If match, skip sync */
2197 if (!_ecore_wl2_display_connect(ewd, _ecore_wl2_display_sync_get()))
2200 /* add this new client display to hash */
2201 eina_hash_add(_client_displays, ewd->name, ewd);
2206 xkb_context_unref(ewd->xkb_context);
2207 ewd->xkb_context = NULL;
2212 eina_hash_free(ewd->globals);
2219 eina_hash_free(_client_displays);
2220 _client_displays = NULL;
2230 ecore_wl2_display_disconnect(Ecore_Wl2_Display *display)
2232 EINA_SAFETY_ON_NULL_RETURN(display);
2237 ret = wl_display_dispatch_pending(display->wl.display);
2241 if (display->refs == 0)
2243 _ecore_wl2_display_cleanup(display);
2245 wl_display_disconnect(display->wl.display);
2247 /* remove this client display from hash */
2248 eina_hash_del_by_key(_client_displays, display->name);
2250 free(display->name);
2256 ecore_wl2_display_destroy(Ecore_Wl2_Display *display)
2258 EINA_SAFETY_ON_NULL_RETURN(display);
2261 if (display->refs == 0)
2263 /* this ensures that things like wl_registry are destroyed
2264 * before we destroy the actual wl_display */
2265 _ecore_wl2_display_cleanup(display);
2267 wl_display_destroy(display->wl.display);
2269 /* remove this client display from hash */
2270 eina_hash_del_by_key(_server_displays, display->name);
2271 ecore_timer_del(display->recovery_timer);
2273 free(display->name);
2279 ecore_wl2_display_terminate(Ecore_Wl2_Display *display)
2281 EINA_SAFETY_ON_NULL_RETURN(display);
2282 wl_display_terminate(display->wl.display);
2285 EAPI struct wl_display *
2286 ecore_wl2_display_get(Ecore_Wl2_Display *display)
2288 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2289 return display->wl.display;
2292 // TIZEN_ONLY(20190807): Retrieve the existing native wayland display
2294 ecore_wl2_display_native_get(Ecore_Wl2_Display *display)
2296 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2297 return (void *)display->wl.display;
2301 EAPI struct wl_shm *
2302 ecore_wl2_display_shm_get(Ecore_Wl2_Display *display)
2304 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2305 return display->wl.shm;
2309 ecore_wl2_display_dmabuf_get(Ecore_Wl2_Display *display)
2311 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2312 return display->wl.dmabuf;
2315 EAPI Eina_Iterator *
2316 ecore_wl2_display_globals_get(Ecore_Wl2_Display *display)
2318 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2319 EINA_SAFETY_ON_NULL_RETURN_VAL(display->globals, NULL);
2321 return eina_hash_iterator_data_new(display->globals);
2325 ecore_wl2_display_screen_size_get(Ecore_Wl2_Display *display, int *w, int *h)
2327 Ecore_Wl2_Output *output;
2329 // TIZEN_ONLY(20190430): support client appinfo
2333 EINA_SAFETY_ON_NULL_RETURN(display);
2338 // TIZEN_ONLY(20220407): Gets the screen size of all screens
2339 EINA_INLIST_FOREACH(display->outputs, output)
2341 switch (output->transform)
2343 case WL_OUTPUT_TRANSFORM_90:
2344 case WL_OUTPUT_TRANSFORM_270:
2345 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2346 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2347 ow = output->geometry.h;
2348 oh = output->geometry.w;
2351 ow = output->geometry.w;
2352 oh = output->geometry.h;
2358 EINA_INLIST_FOREACH(display->outputs, output)
2360 switch (output->transform)
2362 case WL_OUTPUT_TRANSFORM_90:
2363 case WL_OUTPUT_TRANSFORM_270:
2364 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2365 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2366 ow += output->geometry.h;
2367 oh += output->geometry.w;
2370 ow += output->geometry.w;
2371 oh += output->geometry.h;
2378 // TIZEN_ONLY(20190430): support client appinfo
2379 if (display->wl.tz_appinfo)
2382 if (_base_resolution_pid != pid) _base_resolution_pid = pid;
2384 tizen_launch_appinfo_get_base_output_resolution(display->wl.tz_appinfo, pid);
2385 ecore_wl2_display_sync(display);
2387 if (_base_resolution_w <= 0 || _base_resolution_h <= 0)
2388 goto without_tz_appinfo;
2390 if (w) *w = _base_resolution_w;
2391 if (h) *h = _base_resolution_h;
2393 INF("ecore_wl2_display_screen_size_get called, pid: %d / width: %d / height: %d / b_res_w: %d / b_res_h: %d",
2394 pid, (w? *w : -1), (h? *h : -1), _base_resolution_w, _base_resolution_h);
2404 // TIZEN_ONLY(20220407): Gets the screen size of all screens
2406 ecore_wl2_display_all_screens_size_get(Ecore_Wl2_Display *display, int *w, int *h)
2408 Ecore_Wl2_Output *output;
2411 EINA_SAFETY_ON_NULL_RETURN(display);
2416 EINA_INLIST_FOREACH(display->outputs, output)
2418 switch (output->transform)
2420 case WL_OUTPUT_TRANSFORM_90:
2421 case WL_OUTPUT_TRANSFORM_270:
2422 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2423 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2424 ow += output->geometry.h;
2425 oh += output->geometry.w;
2428 ow += output->geometry.w;
2429 oh += output->geometry.h;
2434 // TODO: Need to consider a base resolution of appinfo
2441 EAPI Ecore_Wl2_Window *
2442 ecore_wl2_display_window_find(Ecore_Wl2_Display *display, unsigned int id)
2444 Ecore_Wl2_Window *window;
2446 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2448 EINA_INLIST_FOREACH(display->windows, window)
2449 if (window->id == (int)id) return window;
2454 EAPI struct wl_registry *
2455 ecore_wl2_display_registry_get(Ecore_Wl2_Display *display)
2457 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2459 return display->wl.registry;
2463 ecore_wl2_display_compositor_version_get(Ecore_Wl2_Display *display)
2465 EINA_SAFETY_ON_NULL_RETURN_VAL(display, 0);
2467 return display->wl.compositor_version;
2470 EAPI Eina_Iterator *
2471 ecore_wl2_display_inputs_get(Ecore_Wl2_Display *display)
2473 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2474 EINA_SAFETY_ON_TRUE_RETURN_VAL(display->pid, NULL);
2475 return eina_inlist_iterator_new(display->inputs);
2478 EAPI Ecore_Wl2_Input *
2479 ecore_wl2_display_input_find(const Ecore_Wl2_Display *display, unsigned int id)
2481 Ecore_Wl2_Input *input;
2483 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2484 EINA_SAFETY_ON_TRUE_RETURN_VAL(display->pid, NULL);
2485 EINA_INLIST_FOREACH(display->inputs, input)
2486 if (input->id == id) return input;
2490 EAPI Ecore_Wl2_Input *
2491 ecore_wl2_display_input_find_by_name(const Ecore_Wl2_Display *display, const char *name)
2493 Ecore_Wl2_Input *input;
2495 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2496 EINA_SAFETY_ON_TRUE_RETURN_VAL(display->pid, NULL);
2497 EINA_INLIST_FOREACH(display->inputs, input)
2498 if (eina_streq(input->name, name)) return input;
2503 ecore_wl2_display_sync_is_done(const Ecore_Wl2_Display *display)
2505 EINA_SAFETY_ON_NULL_RETURN_VAL(display, EINA_FALSE);
2506 return display->sync_done;
2510 ecore_wl2_display_name_get(const Ecore_Wl2_Display *display)
2512 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2513 return display->name;
2517 ecore_wl2_display_flush(Ecore_Wl2_Display *display)
2521 EINA_SAFETY_ON_NULL_RETURN(display);
2523 ret = wl_display_flush(display->wl.display);
2524 if (ret >= 0) return;
2527 #ifdef USE_TIZEN_CORE
2530 _begin_recovery_maybe(display, code);
2533 #endif // USE_TIZEN_CORE
2536 ecore_main_fd_handler_active_set(display->fd_hdl,
2537 (ECORE_FD_READ | ECORE_FD_WRITE));
2541 _begin_recovery_maybe(display, code);
2544 EAPI Ecore_Wl2_Window *
2545 ecore_wl2_display_window_find_by_surface(Ecore_Wl2_Display *display, struct wl_surface *surface)
2547 return _ecore_wl2_display_window_surface_find(display, surface);
2550 EAPI Ecore_Wl2_Display *
2551 ecore_wl2_connected_display_get(const char *name)
2553 Ecore_Wl2_Display *ewd;
2555 EINA_SAFETY_ON_NULL_RETURN_VAL(_client_displays, NULL);
2561 /* client wants to connected to default display */
2562 n = getenv("WAYLAND_DISPLAY");
2563 if (!n) n = "wayland-0";
2565 /* we have a default wayland display */
2567 /* check hash of cached client displays for this name */
2568 ewd = eina_hash_find(_client_displays, n);
2572 /* client wants to connect to specific display */
2574 /* check hash of cached client displays for this name */
2575 ewd = eina_hash_find(_client_displays, name);
2581 EAPI struct wl_compositor *
2582 ecore_wl2_display_compositor_get(Ecore_Wl2_Display *display)
2584 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
2585 return display->wl.compositor;