};
//
+//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)
{
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:
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);
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);
}
#include "wayland-egl-tizen.h"
//
+// TIZEN_ONLY(20230312) : support wtz screen protocol
+#include <wayland-extension/wtz-screen-client-protocol.h>
+//
+
extern int _ecore_wl2_log_dom;
extern Eina_Bool no_session_recovery;
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;
//
int compositor_version;
+
+ //
+ //TIZEN_ONLY(20230312): support wtz_screen
+ struct wtz_screen *wtz_scr;
+ //
} wl;
uint32_t serial;
// 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
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
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#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);
+}