ecore_wl2: Support new wtz-screen protocol 97/289997/9
authorJunseok Kim <juns.kim@samsung.com>
Thu, 23 Mar 2023 08:46:07 +0000 (17:46 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 29 Mar 2023 09:51:35 +0000 (09:51 +0000)
@tizen_only

Change-Id: I40d839e0b789b4159f1fcb3f7c494e11d9652659

packaging/efl.spec
po/POTFILES.in
src/lib/ecore_wl2/ecore_wl2_display.c
src/lib/ecore_wl2/ecore_wl2_private.h
src/lib/ecore_wl2/ecore_wl2_screen.c [new file with mode: 0644]
src/lib/ecore_wl2/meson.build

index 2933078..30916bd 100644 (file)
@@ -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
index aefb381..a862cd6 100644 (file)
@@ -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
index a6863a4..e3f2e50 100644 (file)
@@ -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);
 }
 
index a86103d..a954cec 100644 (file)
 #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;
 
@@ -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 (file)
index 0000000..685d5b4
--- /dev/null
@@ -0,0 +1,327 @@
+#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);
+}
index 48db951..4a7bec2 100644 (file)
@@ -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',