wayland: add efl-hints protocol for setting aspect on surfaces
authorMike Blumenkrantz <zmike@osg.samsung.com>
Fri, 4 Aug 2017 20:17:53 +0000 (16:17 -0400)
committerMike Blumenkrantz <zmike@osg.samsung.com>
Fri, 4 Aug 2017 20:15:43 +0000 (16:15 -0400)
@feature

src/Makefile_Ecore_Wl2.am
src/Makefile_Wayland_Protocols.am
src/Makefile_efl_wl.am
src/lib/ecore_wl2/Ecore_Wl2.h
src/lib/ecore_wl2/ecore_wl2_display.c
src/lib/ecore_wl2/ecore_wl2_private.h
src/lib/ecore_wl2/ecore_wl2_window.c
src/lib/efl_wl/Efl_Wl.h
src/lib/efl_wl/efl_wl.c
src/wayland_protocol/efl-hints.xml [new file with mode: 0644]

index 7f3eb2f..0047c36 100644 (file)
@@ -33,7 +33,9 @@ lib/ecore_wl2/linux-dmabuf-unstable-v1-client-protocol.h \
 lib/ecore_wl2/xdg-shell-unstable-v6-client-protocol.h \
 lib/ecore_wl2/xdg-shell-unstable-v6-protocol.c \
 lib/ecore_wl2/text-input-unstable-v1-client-protocol.h \
-lib/ecore_wl2/text-input-unstable-v1-protocol.c
+lib/ecore_wl2/text-input-unstable-v1-protocol.c \
+lib/ecore_wl2/efl-hints-client-protocol.h \
+lib/ecore_wl2/efl-hints-protocol.c
 
 lib_ecore_wl2_libecore_wl2_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_WL2_CFLAGS@
 lib_ecore_wl2_libecore_wl2_la_LIBADD = @ECORE_WL2_LIBS@
@@ -56,6 +58,8 @@ lib/ecore_wl2/efl-aux-hints-client-protocol.h \
  lib/ecore_wl2/session-recovery-protocol.c \
  lib/ecore_wl2/session-recovery-client-protocol.h \
  lib/ecore_wl2/text-input-unstable-v1-client-protocol.h \
- lib/ecore_wl2/text-input-unstable-v1-protocol.c
+ lib/ecore_wl2/text-input-unstable-v1-protocol.c \
+lib/ecore_wl2/efl-hints-client-protocol.h \
+lib/ecore_wl2/efl-hints-protocol.c
 
 endif
index b96cce9..1bbfe20 100644 (file)
@@ -1,5 +1,6 @@
 EXTRA_DIST2 += \
 wayland_protocol/efl-aux-hints.xml \
+wayland_protocol/efl-hints.xml \
 wayland_protocol/session-recovery.xml \
 wayland_protocol/teamwork.xml \
 wayland_protocol/www.xml
index aae58ff..ac3c00d 100644 (file)
@@ -15,7 +15,9 @@ nodist_lib_efl_wl_libefl_wl_la_SOURCES = \
 lib/efl_wl/linux-dmabuf-unstable-v1-protocol.c \
 lib/efl_wl/linux-dmabuf-unstable-v1-server-protocol.h \
 lib/efl_wl/xdg-shell-unstable-v6-protocol.c \
-lib/efl_wl/xdg-shell-unstable-v6-server-protocol.h
+lib/efl_wl/xdg-shell-unstable-v6-server-protocol.h \
+lib/efl_wl/efl-hints-protocol.c \
+lib/efl_wl/efl-hints-server-protocol.h
 
 lib_efl_wl_libefl_wl_la_CPPFLAGS = -I$(top_builddir)/lib/efl @EFL_WL_CFLAGS@
 lib_efl_wl_libefl_wl_la_LIBADD = @EFL_WL_LIBS@
index 81084e1..eab1bfe 100644 (file)
@@ -737,6 +737,13 @@ EAPI struct wl_surface *ecore_wl2_window_surface_get(Ecore_Wl2_Window *window);
 EAPI int ecore_wl2_window_surface_id_get(Ecore_Wl2_Window *window);
 
 /**
+ * @see evas_object_size_hint_aspect_set
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since 1.21
+ */
+EAPI void ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int aspect);
+
+/**
  * Show a given Ecore_Wl2_Window
  *
  * @param window The Ecore_Wl2_Window to show
index 48c62e5..63c79f9 100644 (file)
@@ -5,6 +5,7 @@
 #include "ecore_wl2_private.h"
 
 #include "linux-dmabuf-unstable-v1-client-protocol.h"
+#include "efl-hints-client-protocol.h"
 
 static Eina_Hash *_server_displays = NULL;
 static Eina_Hash *_client_displays = NULL;
@@ -336,6 +337,16 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const
      _ecore_wl2_output_add(ewd, id);
    else if (!strcmp(interface, "wl_seat"))
      _ecore_wl2_input_add(ewd, id, version);
+   else if (!strcmp(interface, "efl_hints"))
+     {
+        Ecore_Wl2_Window *window;
+
+        ewd->wl.efl_hints = wl_registry_bind(registry, id, &efl_hints_interface, 1);
+        EINA_INLIST_FOREACH(ewd->windows, window)
+          if (window->zxdg_toplevel && window->aspect.set)
+            efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel,
+              window->aspect.w, window->aspect.h, window->aspect.aspect);
+     }
 
 event:
    /* allocate space for event structure */
@@ -437,6 +448,7 @@ _ecore_wl2_display_globals_cleanup(Ecore_Wl2_Display *ewd)
    if (ewd->wl.subcompositor) wl_subcompositor_destroy(ewd->wl.subcompositor);
    if (ewd->wl.dmabuf) zwp_linux_dmabuf_v1_destroy(ewd->wl.dmabuf);
    if (ewd->wl.efl_aux_hints) efl_aux_hints_destroy(ewd->wl.efl_aux_hints);
+   if (ewd->wl.efl_hints) efl_hints_destroy(ewd->wl.efl_hints);
 
    if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry);
 }
index 3569db9..e857bbd 100644 (file)
@@ -96,6 +96,7 @@ struct _Ecore_Wl2_Display
         struct zwp_e_session_recovery *session_recovery;
         struct efl_aux_hints *efl_aux_hints;
         struct zwp_teamwork *teamwork;
+        struct efl_hints *efl_hints;
         int compositor_version;
      } wl;
 
@@ -180,6 +181,13 @@ struct _Ecore_Wl2_Window
 
    Ecore_Wl2_Window_Type type;
 
+   struct
+   {
+      int w, h;
+      unsigned int aspect;
+      Eina_Bool set : 1;
+   } aspect;
+
    Eina_Inlist *subsurfs;
    Eina_List *supported_aux_hints;
 
index 78f6129..bb5196f 100644 (file)
@@ -3,6 +3,7 @@
 #endif
 
 #include "ecore_wl2_private.h"
+#include "efl-hints-client-protocol.h"
 
 void
 _ecore_wl2_window_semi_free(Ecore_Wl2_Window *window)
@@ -472,6 +473,9 @@ _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window)
 
         if (window->fullscreen)
           zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
+        if (window->aspect.set && window->display->wl.efl_hints)
+          efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel,
+            window->aspect.w, window->aspect.h, window->aspect.aspect);
 
         wl_surface_commit(window->surface);
      }
@@ -1535,3 +1539,20 @@ ecore_wl2_window_floating_mode_get(Ecore_Wl2_Window *window)
    EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
    return window->floating;
 }
+
+EAPI void
+ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int aspect)
+{
+   EINA_SAFETY_ON_NULL_RETURN(window);
+   EINA_SAFETY_ON_TRUE_RETURN(w < 1);
+   EINA_SAFETY_ON_TRUE_RETURN(h < 1);
+   if ((window->aspect.aspect == aspect) &&
+     (window->aspect.w == w) &&
+     (window->aspect.h == h)) return;
+   window->aspect.w = w;
+   window->aspect.h = h;
+   window->aspect.aspect = aspect;
+   window->aspect.set = 1;
+   if (window->display->wl.efl_hints && window->zxdg_toplevel)
+     efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel, w, h, aspect);
+}
index 2de79e2..51bcc43 100644 (file)
@@ -106,6 +106,14 @@ EAPI void efl_wl_rotate(Evas_Object *obj, Efl_Wl_Rotation rot, Eina_Bool rtl);
  * @param scale The scale factor to set
  */
 EAPI void efl_wl_scale_set(Evas_Object *obj, double scale);
+
+/**
+ * Transfer aspect hints from top-most surface onto the efl_wl object
+ *
+ * @param obj The compositor widget
+ * @param set Whether to enable aspect setting
+ */
+EAPI void efl_wl_aspect_set(Evas_Object *obj, Eina_Bool set);
 #endif
 
 #endif
index 03e1128..2a78282 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <wayland-server.h>
 #include "xdg-shell-unstable-v6-server-protocol.h"
+#include "efl-hints-server-protocol.h"
 #include "dmabuf.h"
 
 #include "Ecore_Evas.h"
@@ -142,6 +143,7 @@ typedef struct Comp
    Eina_Bool data_device_proxy : 1;
    Eina_Bool x11_selection : 1;
    Eina_Bool rtl : 1;
+   Eina_Bool aspect : 1;
 } Comp;
 
 typedef struct Comp_Data_Device_Source Comp_Data_Device_Source;
@@ -1166,6 +1168,18 @@ shell_surface_activate_recurse(Comp_Surface *cs)
 }
 
 static void
+shell_surface_aspect_update(Comp_Surface *cs)
+{
+   Evas_Aspect_Control aspect;
+   int w, h;
+
+   if (!cs) return;
+   if (!cs->c->aspect) return;
+   evas_object_size_hint_aspect_get(cs->obj, &aspect, &w, &h);
+   evas_object_size_hint_aspect_set(cs->c->obj, aspect, w, h);
+}
+
+static void
 shell_surface_send_configure(Comp_Surface *cs)
 {
    uint32_t serial, *s;
@@ -1210,6 +1224,7 @@ shell_surface_send_configure(Comp_Surface *cs)
         EINA_INLIST_FOREACH(cs->children, ccs)
           if (ccs->shell.surface && ccs->role && ccs->shell.popup)
             ccs->shell.activated = cs->shell.activated;
+        shell_surface_aspect_update(cs);
      }
    else
      shell_surface_deactivate_recurse(cs);
@@ -4895,6 +4910,32 @@ EFL_CALLBACKS_ARRAY_DEFINE(comp_device_cbs,
   { EFL_CANVAS_EVENT_DEVICE_REMOVED, comp_device_del });
 
 static void
+hints_set_aspect(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t width, uint32_t height, uint32_t aspect)
+{
+   Comp_Surface *cs = wl_resource_get_user_data(surface);
+   evas_object_size_hint_aspect_set(cs->obj, aspect, width, height);
+   if (cs == cs->c->active_surface)
+     shell_surface_aspect_update(cs);
+}
+
+static const struct efl_hints_interface hints_interface =
+{
+   hints_set_aspect,
+};
+
+static void
+efl_hints_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+   struct wl_resource *res;
+
+   if (!client_allowed_check(data, client)) return;
+   res = wl_resource_create(client, &efl_hints_interface, version, id);
+   wl_resource_set_implementation(res, &hints_interface, data, NULL);
+}
+
+
+
+static void
 comp_smart_add(Evas_Object *obj)
 {
    Comp *c;
@@ -4930,6 +4971,7 @@ comp_smart_add(Evas_Object *obj)
    wl_global_create(c->display, &wl_output_interface, 2, c, output_bind);
    wl_global_create(c->display, &zxdg_shell_v6_interface, 1, c, shell_bind);
    wl_global_create(c->display, &wl_data_device_manager_interface, 3, c, data_device_manager_bind);
+   wl_global_create(c->display, &efl_hints_interface, 1, c, efl_hints_bind);
    wl_display_init_shm(c->display);
 
    if (env)
@@ -5317,3 +5359,17 @@ efl_wl_scale_set(Evas_Object *obj, double scale)
      if (wl_resource_get_version(res) >= WL_OUTPUT_SCALE_SINCE_VERSION)
        wl_output_send_scale(res, lround(c->scale));
 }
+
+void
+efl_wl_aspect_set(Evas_Object *obj, Eina_Bool set)
+{
+   Comp *c;
+
+   if (!eina_streq(evas_object_type_get(obj), "comp")) abort();
+   c = evas_object_smart_data_get(obj);
+   c->aspect = !!set;
+   if (c->aspect)
+     shell_surface_aspect_update(c->active_surface);
+   else
+     evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_NONE, 0, 0);
+}
diff --git a/src/wayland_protocol/efl-hints.xml b/src/wayland_protocol/efl-hints.xml
new file mode 100644 (file)
index 0000000..51689d7
--- /dev/null
@@ -0,0 +1,19 @@
+<protocol name="efl_hints">
+
+  <interface name="efl_hints" version="1">
+    <enum name="aspect">
+      <entry name="none" value="0"/>
+      <entry name="neither" value="1"/>
+      <entry name="horizontal" value="2"/>
+      <entry name="vertical" value="3"/>
+      <entry name="both" value="4"/>
+    </enum>
+    <request name="set_aspect">
+      <arg name="surface" type="object" interface="zxdg_toplevel_v6"/>
+      <arg name="width" type="uint"/>
+      <arg name="height" type="uint"/>
+      <arg name="aspect" type="uint" enum="aspect"/>
+    </request>
+  </interface>
+
+</protocol>