From aacba912cef6e5ed0a358bf9c461c502d8939544 Mon Sep 17 00:00:00 2001 From: Junseok Kim Date: Thu, 23 Mar 2023 17:46:07 +0900 Subject: [PATCH] ecore_wl2: Support new wtz-screen protocol @tizen_only Change-Id: I40d839e0b789b4159f1fcb3f7c494e11d9652659 --- packaging/efl.spec | 2 + po/POTFILES.in | 1 + src/lib/ecore_wl2/ecore_wl2_display.c | 93 ++++++++++ src/lib/ecore_wl2/ecore_wl2_private.h | 39 ++++ src/lib/ecore_wl2/ecore_wl2_screen.c | 327 ++++++++++++++++++++++++++++++++++ src/lib/ecore_wl2/meson.build | 5 +- 6 files changed, 466 insertions(+), 1 deletion(-) create mode 100644 src/lib/ecore_wl2/ecore_wl2_screen.c diff --git a/packaging/efl.spec b/packaging/efl.spec index 2933078..30916bd 100644 --- a/packaging/efl.spec +++ b/packaging/efl.spec @@ -47,6 +47,8 @@ BuildRequires: pkgconfig(tizen-launch-client) BuildRequires: pkgconfig(tizen-remote-surface-client) BuildRequires: pkgconfig(tizen-policy-ext-client) BuildRequires: pkgconfig(wtz-foreign-client) +BuildRequires: pkgconfig(wtz-screen-client) +BuildRequires: pkgconfig(wtz-shell-client) BuildRequires: wayland-protocols Requires: libwayland-extension-client Requires: libwayland-egl-tizen diff --git a/po/POTFILES.in b/po/POTFILES.in index aefb381..a862cd6 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1650,6 +1650,7 @@ src/lib/ecore_wl2/ecore_wl2_display.c src/lib/ecore_wl2/ecore_wl2_buffer.c src/lib/ecore_wl2/ecore_wl2_input.c src/lib/ecore_wl2/ecore_wl2_subsurf.c +src/lib/ecore_wl2/ecore_wl2_screen.c src/lib/ecore_wayland/xdg-shell-protocol.c src/lib/ecore_wayland/ecore_wl_input.c src/lib/ecore_wayland/ecore_wl_window.c diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c index a6863a4..e3f2e50 100644 --- a/src/lib/ecore_wl2/ecore_wl2_display.c +++ b/src/lib/ecore_wl2/ecore_wl2_display.c @@ -752,6 +752,74 @@ static const struct tizen_move_resize_listener _tizen_move_resize_listener = }; // +//TIZEN_ONLY(20230312): support wtz_screen +static void +_wtz_screen_cb_size(void *data, struct wtz_screen *screen EINA_UNUSED, uint32_t width, uint32_t height) +{ + Ecore_Wl2_Display *ewd = data; + Ecore_Wl2_Screen *ews; + + if (!ewd) return; + + ews = _ecore_wl2_display_screen_get(ewd); + if (!ews) return; + + _ecore_wl2_screen_size_set(ews, width, height); +} + +static void +_wtz_screen_cb_name(void *data, struct wtz_screen *screen EINA_UNUSED, const char *name) +{ + Ecore_Wl2_Display *ewd = data; + Ecore_Wl2_Screen *ews; + + if (!ewd) return; + + ews = _ecore_wl2_display_screen_get(ewd); + if (!ews) return; + + _ecore_wl2_screen_name_set(ews, name); +} + +static void +_wtz_screen_cb_capabilities(void *data, struct wtz_screen *screen EINA_UNUSED, struct wl_array *capabilities) +{ + Ecore_Wl2_Display *ewd = data; + Ecore_Wl2_Screen *ews; + uint32_t *p; + int capability = 0; + + if (!ewd) return; + + ews = _ecore_wl2_display_screen_get(ewd); + if (!ews) return; + + if ((capabilities) && (capabilities->size)) + { + p = capabilities->data; + while ((const uint32_t *)p < ((const uint32_t *)capabilities->data + capabilities->size)) + { + switch ((uint32_t) *p) + { + case WTZ_SCREEN_CAPABILITY_SPLITSCREEN : + capability |= ECORE_WL2_SCREEN_CAPABILITY_SPLITSCREEN; + break; + } + p += sizeof(uint32_t); + } + } + + _ecore_wl2_screen_capability_set(ews, capability); +} + +static const struct wtz_screen_listener _wtz_screen_listener = +{ + .size = _wtz_screen_cb_size, + .name = _wtz_screen_cb_name, + .capabilities = _wtz_screen_cb_capabilities, +}; +// + static void _cb_global_event_free(void *data EINA_UNUSED, void *event) { @@ -988,6 +1056,25 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const wl_registry_bind(registry, id, &tizen_renderer_interface, 1); } // +//TIZEN_ONLY(20230312): support wtz_screen + else if (!strcmp(interface, "wtz_screen")) + { + if (ewd->wl.wtz_scr) + { + ERR("wtz_screen: ecore_wl2_window can support one wtz_screen. ignore it."); + return; + } + ewd->wl.wtz_scr = + wl_registry_bind(registry, id, &wtz_screen_interface, 1); + if (ewd->wl.wtz_scr) + { + wtz_screen_add_listener(ewd->wl.wtz_scr, &_wtz_screen_listener, ewd); + Ecore_Wl2_Screen *ews = _ecore_wl2_display_screen_get(ewd); + if (!ews) + ERR("wtz_screen: couldn't create default screen"); + } + } +// // event: @@ -1103,6 +1190,7 @@ _ecore_wl2_display_globals_cleanup(Ecore_Wl2_Display *ewd) if (ewd->wl.tz_moveresize) tizen_move_resize_destroy(ewd->wl.tz_moveresize); if (ewd->wl.tz_video) tizen_video_destroy(ewd->wl.tz_video); if (ewd->wl.tz_renderer) tizen_renderer_destroy(ewd->wl.tz_renderer); + if (ewd->wl.wtz_scr) wtz_screen_destroy(ewd->wl.wtz_scr); // if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry); @@ -1657,6 +1745,11 @@ _ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd) eina_hash_free(ewd->globals); +//TIZEN_ONLY(20230312): support wtz_screen + /* free screen */ + _ecore_wl2_screen_del(ewd->screen); +// + _ecore_wl2_display_globals_cleanup(ewd); } diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index a86103d..a954cec 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -37,6 +37,10 @@ #include "wayland-egl-tizen.h" // +// TIZEN_ONLY(20230312) : support wtz screen protocol +#include +// + extern int _ecore_wl2_log_dom; extern Eina_Bool no_session_recovery; @@ -93,6 +97,12 @@ typedef struct _Ecore_Wl2_Input_Devices int window_id; } Ecore_Wl2_Input_Devices; +//TIZEN_ONLY(20230312): support wtz_screen +typedef struct _Ecore_Wl2_Screen Ecore_Wl2_Screen; +typedef struct _Ecore_Wl2_Splitscreen Ecore_Wl2_Splitscreen; +typedef struct _Ecore_Wl2_Splitscreen_Region Ecore_Wl2_Splitscreen_Region; +// + struct _Ecore_Wl2_Display { int refs; @@ -146,6 +156,11 @@ struct _Ecore_Wl2_Display // int compositor_version; + + // + //TIZEN_ONLY(20230312): support wtz_screen + struct wtz_screen *wtz_scr; + // } wl; uint32_t serial; @@ -178,6 +193,10 @@ struct _Ecore_Wl2_Display // TIZEN_ONLY(20171129): thread-safety for wl Eina_Bool prepare_read; // End of TIZEN_ONLY(20171129) + + //TIZEN_ONLY(20230312): support wtz_screen + Ecore_Wl2_Screen *screen; + // }; struct _Ecore_Wl2_Subsurface @@ -957,6 +976,26 @@ void _ecore_wl2_cursor_config_shutdown(void); void _ecore_wl2_cursor_config_reload(void); const char * _ecore_wl2_cursor_config_name_get(void); Eina_Bool _ecore_wl2_cursor_config_save(void); + +//TIZEN_ONLY(20230312): support wtz_screen +typedef enum _Ecore_Wl2_Screen_Capabilities +{ + ECORE_WL2_SCREEN_CAPABILITY_SPLITSCREEN = 1 << 0, +} Ecore_Wl2_Screen_Capabilities; + +Ecore_Wl2_Screen *_ecore_wl2_display_screen_get(Ecore_Wl2_Display *ewd); +void _ecore_wl2_screen_del(Ecore_Wl2_Screen *ews); +Eina_Bool _ecore_wl2_screen_geometry_get(Ecore_Wl2_Screen *ews, int *x, int *y, int *w, int *h); +void _ecore_wl2_screen_size_set(Ecore_Wl2_Screen *ews, int w, int h); +void _ecore_wl2_screen_name_set(Ecore_Wl2_Screen *ews, const char *name); +void _ecore_wl2_screen_capability_set(Ecore_Wl2_Screen *ews, int capabilities); +Ecore_Wl2_Splitscreen *_ecore_wl2_screen_splitscreen_get(Ecore_Wl2_Screen *ews); +void _ecore_wl2_splitscreen_activate(Ecore_Wl2_Splitscreen *ewsp); +void _ecore_wl2_splitscreen_deactivate(Ecore_Wl2_Splitscreen *ewsp); +Eina_Bool _ecore_wl2_splitscreen_activated_get(Ecore_Wl2_Splitscreen *ewsp); +Ecore_Wl2_Splitscreen_Region *_ecore_wl2_splitscreen_region_get(Ecore_Wl2_Splitscreen *ewsp, const char *name); +void _ecore_wl2_splitscreen_region_assign_appid(Ecore_Wl2_Splitscreen_Region *ewsr, const char *appid); +Eina_Bool _ecore_wl2_splitscreen_region_get_geometry(Ecore_Wl2_Splitscreen_Region *ewsr, int *x, int *y, int *w, int *h); // #endif diff --git a/src/lib/ecore_wl2/ecore_wl2_screen.c b/src/lib/ecore_wl2/ecore_wl2_screen.c new file mode 100644 index 0000000..685d5b4 --- /dev/null +++ b/src/lib/ecore_wl2/ecore_wl2_screen.c @@ -0,0 +1,327 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include "ecore_wl2_private.h" + +struct _Ecore_Wl2_Screen +{ + Ecore_Wl2_Display *display; + Ecore_Wl2_Splitscreen *splitscreen; + + int x, y, w, h; + Eina_Stringshare *name; + int capabilities; +}; + +struct _Ecore_Wl2_Splitscreen +{ + Ecore_Wl2_Screen *screen; + Eina_Bool activated; + Eina_List *regions; + + struct + { + struct wtz_splitscreen *splitscreen; + } wl; +}; + +struct _Ecore_Wl2_Splitscreen_Region +{ + Ecore_Wl2_Screen *screen; + Ecore_Wl2_Splitscreen *sps; + + int x, y, w, h; + Eina_Stringshare *name; + + struct + { + struct wtz_splitscreen_region *region; + } wl; +}; + +static void _ecore_wl2_splitscreen_del(Ecore_Wl2_Splitscreen *ewsp); +static void _ecore_wl2_splitscreen_region_del(Ecore_Wl2_Splitscreen_Region *ewsr); + +static void +_wtz_splitscreen_region_cb_geometry(void *data, struct wtz_splitscreen_region *region EINA_UNUSED, uint32_t x, uint32_t y, uint32_t w, uint32_t h) +{ + Ecore_Wl2_Splitscreen_Region *ewsr; + + ewsr = (Ecore_Wl2_Splitscreen_Region *)data; + ewsr->x = x; + ewsr->y = y; + ewsr->w = w; + ewsr->h = h; + + // TODO: need emit event? +} + +static void +_wtz_splitscreen_region_cb_name(void *data, struct wtz_splitscreen_region *region EINA_UNUSED, const char *name) +{ + Ecore_Wl2_Splitscreen_Region *ewsr; + + ewsr = (Ecore_Wl2_Splitscreen_Region *)data; + + if (ewsr->name) eina_stringshare_del(ewsr->name); + ewsr->name = eina_stringshare_add(name); +} + +static const struct wtz_splitscreen_region_listener _splitscreen_region_listener = +{ + .name = _wtz_splitscreen_region_cb_name, + .geometry = _wtz_splitscreen_region_cb_geometry, +}; + +static void +_wtz_splitscreen_cb_region(void *data, struct wtz_splitscreen *splitscreen EINA_UNUSED, struct wtz_splitscreen_region *splitscreen_region) +{ + Ecore_Wl2_Splitscreen *ewsp; + Ecore_Wl2_Splitscreen_Region *ewsr; + + ewsr = (Ecore_Wl2_Splitscreen_Region *)calloc(1, sizeof(Ecore_Wl2_Splitscreen_Region)); + EINA_SAFETY_ON_NULL_RETURN(ewsr); + + ewsp = data; + ewsp->regions = eina_list_append(ewsp->regions, ewsr); + + ewsr->sps = ewsp; + ewsr->wl.region = splitscreen_region; + wtz_splitscreen_region_add_listener(splitscreen_region, &_splitscreen_region_listener, ewsr); +} + +static const struct wtz_splitscreen_listener _splitscreen_listener = +{ + .region = _wtz_splitscreen_cb_region, +}; + +static Ecore_Wl2_Screen * +_ecore_wl2_screen_new(Ecore_Wl2_Display *ewd) +{ + Ecore_Wl2_Screen *ews; + Ecore_Wl2_Splitscreen *ewsp; + + EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL); + + ews = (Ecore_Wl2_Screen *)calloc(1, sizeof(Ecore_Wl2_Screen)); + EINA_SAFETY_ON_NULL_RETURN_VAL(ews, NULL); + + ews->display = ewd; + + return ews; +} + +Ecore_Wl2_Screen * +_ecore_wl2_display_screen_get(Ecore_Wl2_Display *ewd) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL); + + if (ewd->screen) return ewd->screen; + + ewd->screen = _ecore_wl2_screen_new(ewd); + return ewd->screen; +} + +void +_ecore_wl2_screen_del(Ecore_Wl2_Screen *ews) +{ + EINA_SAFETY_ON_NULL_RETURN(ews); + + _ecore_wl2_splitscreen_del(ews->splitscreen); + + if (ews->name) + { + eina_stringshare_del(ews->name); + ews->name = NULL; + } + + free(ews); +} + +Eina_Bool +_ecore_wl2_screen_geometry_get(Ecore_Wl2_Screen *ews, int *x, int *y, int *w, int *h) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ews, EINA_FALSE); + + if (x) *x = ews->x; + if (y) *y = ews->y; + if (w) *w = ews->w; + if (h) *h = ews->h; + + return EINA_TRUE; +} + +void +_ecore_wl2_screen_size_set(Ecore_Wl2_Screen *ews, int w, int h) +{ + EINA_SAFETY_ON_NULL_RETURN(ews); + + ews->w = w; + ews->h = h; +} + +void +_ecore_wl2_screen_name_set(Ecore_Wl2_Screen *ews, const char *name) +{ + EINA_SAFETY_ON_NULL_RETURN(ews); + + ews->name = eina_stringshare_add(name); +} + +void +_ecore_wl2_screen_capability_set(Ecore_Wl2_Screen *ews, int capabilities) +{ + EINA_SAFETY_ON_NULL_RETURN(ews); + + ews->capabilities = capabilities; + + if (ews->capabilities & ECORE_WL2_SCREEN_CAPABILITY_SPLITSCREEN) + { + if (!ews->splitscreen) + ews->splitscreen = _ecore_wl2_screen_splitscreen_get(ews); + } +} + +static Ecore_Wl2_Splitscreen * +_ecore_wl2_screen_splitscreen_new(Ecore_Wl2_Screen *ews) +{ + Ecore_Wl2_Splitscreen *ewsp; + struct wtz_splitscreen *wss = NULL; + + if (!ews->display) return NULL; + + wss = wtz_screen_get_splitscreen(ews->display->wl.wtz_scr); + if (!wss) return NULL; + + ewsp = (Ecore_Wl2_Splitscreen *)calloc(1, sizeof(Ecore_Wl2_Splitscreen)); + EINA_SAFETY_ON_NULL_RETURN_VAL(ewsp, NULL); + + ewsp->screen = ews; + ewsp->wl.splitscreen = wss; + ews->splitscreen = ewsp; + wtz_splitscreen_add_listener(wss, &_splitscreen_listener, ewsp); + + return ewsp; +} + +Ecore_Wl2_Splitscreen * +_ecore_wl2_screen_splitscreen_get(Ecore_Wl2_Screen *ews) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ews, NULL); + + if (ews->splitscreen) return ews->splitscreen; + return _ecore_wl2_screen_splitscreen_new(ews); +} + +void +_ecore_wl2_splitscreen_activate(Ecore_Wl2_Splitscreen *ewsp) +{ + EINA_SAFETY_ON_NULL_RETURN(ewsp); + EINA_SAFETY_ON_NULL_RETURN(ewsp->wl.splitscreen); + + ewsp->activated = EINA_TRUE; + wtz_splitscreen_activate(ewsp->wl.splitscreen); +} + +void +_ecore_wl2_splitscreen_deactivate(Ecore_Wl2_Splitscreen *ewsp) +{ + EINA_SAFETY_ON_NULL_RETURN(ewsp); + EINA_SAFETY_ON_NULL_RETURN(ewsp->wl.splitscreen); + + ewsp->activated = EINA_FALSE; + wtz_splitscreen_deactivate(ewsp->wl.splitscreen); +} + +Eina_Bool +_ecore_wl2_splitscreen_activated_get(Ecore_Wl2_Splitscreen *ewsp) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ewsp, EINA_FALSE); + + return ewsp->activated; +} + +static void +_ecore_wl2_splitscreen_del(Ecore_Wl2_Splitscreen *ewsp) +{ + Ecore_Wl2_Splitscreen_Region *ewsr; + + EINA_SAFETY_ON_NULL_RETURN(ewsp); + + if (ewsp->wl.splitscreen) + { + wtz_splitscreen_destroy(ewsp->wl.splitscreen); + ewsp->wl.splitscreen = NULL; + } + + EINA_LIST_FREE(ewsp->regions, ewsr) + { + _ecore_wl2_splitscreen_region_del(ewsr);; + } + + free(ewsp); +} + +Ecore_Wl2_Splitscreen_Region * +_ecore_wl2_splitscreen_region_get(Ecore_Wl2_Splitscreen *ewsp, const char *name) +{ + Ecore_Wl2_Splitscreen_Region *ewsr; + Eina_List *l; + + EINA_SAFETY_ON_NULL_RETURN_VAL(ewsp, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); + + EINA_LIST_FOREACH(ewsp->regions, l, ewsr) + { + if (ewsr->name && !strcmp(ewsr->name, name)) + return ewsr; + } + + return NULL; +} + +void +_ecore_wl2_splitscreen_region_assign_appid(Ecore_Wl2_Splitscreen_Region *ewsr, const char *appid) +{ + EINA_SAFETY_ON_NULL_RETURN(ewsr); + EINA_SAFETY_ON_NULL_RETURN(ewsr->wl.region); + EINA_SAFETY_ON_NULL_RETURN(appid); + + wtz_splitscreen_region_assign_appid(ewsr->wl.region, appid); +} + +Eina_Bool +_ecore_wl2_splitscreen_region_get_geometry(Ecore_Wl2_Splitscreen_Region *ewsr, int *x, int *y, int *w, int *h) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ewsr, EINA_FALSE); + + if (x) *x = ewsr->x; + if (y) *y = ewsr->y; + if (w) *w = ewsr->w; + if (h) *h = ewsr->h; + + return EINA_TRUE; +} + +static void +_ecore_wl2_splitscreen_region_del(Ecore_Wl2_Splitscreen_Region *ewsr) +{ + EINA_SAFETY_ON_NULL_RETURN(ewsr); + + if (ewsr->wl.region) + { + wtz_splitscreen_region_destroy(ewsr->wl.region); + ewsr->wl.region = NULL; + } + + if (ewsr->name) + { + eina_stringshare_del(ewsr->name); + ewsr->name = NULL; + } + free(ewsr); +} diff --git a/src/lib/ecore_wl2/meson.build b/src/lib/ecore_wl2/meson.build index 48db951..4a7bec2 100644 --- a/src/lib/ecore_wl2/meson.build +++ b/src/lib/ecore_wl2/meson.build @@ -20,7 +20,8 @@ ecore_wl2_src = files([ 'ecore_wl2_private.h', 'ecore_wl2_buffer.c', 'ecore_wl2_surface.c', - 'ecore_wl2_cursor.c' + 'ecore_wl2_cursor.c', + 'ecore_wl2_screen.c', ]) # <----- TIZEN_ONLY(20190109: introduce mesonbuild on tizen env @@ -33,6 +34,8 @@ ecore_wl2_ext_deps += [ dependency('wayland-egl-tizen'), dependency('tizen-policy-ext-client'), dependency('wtz-foreign-client'), + dependency('wtz-screen-client'), + dependency('wtz-shell-client'), ] ecore_wl2_src += files([ 'ecore_wl2_tbmsurface.c', -- 2.7.4