devilhorns pushed a commit to branch master.

commit 5624cee73f7b88b7476b518cc8b96dd0079cf416
Author: Chris Michael <[email protected]>
Date:   Wed Apr 10 11:01:52 2013 +0100

    Add surface smart object support to the desktop shell.
    Add code to handle shell surface requests.
    
    Signed-off-by: Chris Michael <[email protected]>
---
 src/modules/wl_desktop_shell/e_mod_main.c | 577 +++++++++++++++++++++++++++++-
 1 file changed, 568 insertions(+), 9 deletions(-)

diff --git a/src/modules/wl_desktop_shell/e_mod_main.c 
b/src/modules/wl_desktop_shell/e_mod_main.c
index 1834f45..6be2d3b 100644
--- a/src/modules/wl_desktop_shell/e_mod_main.c
+++ b/src/modules/wl_desktop_shell/e_mod_main.c
@@ -1,21 +1,44 @@
 #include "e.h"
 #include "e_comp_wl.h"
+#include "e_surface.h"
 #include "e_mod_main.h"
 #include "e_desktop_shell_protocol.h"
 
 /* shell function prototypes */
 static void _e_wl_shell_cb_destroy(struct wl_listener *listener, void *data 
EINA_UNUSED);
 static void _e_wl_shell_cb_bind(struct wl_client *client, void *data, unsigned 
int version EINA_UNUSED, unsigned int id);
+static void _e_wl_shell_cb_ping(E_Wayland_Surface *ews, unsigned int serial);
+static void _e_wl_shell_cb_pointer_focus(struct wl_listener *listener 
EINA_UNUSED, void *data);
 
 /* shell interface prototypes */
 static void _e_wl_shell_cb_shell_surface_get(struct wl_client *client, struct 
wl_resource *resource, unsigned int id, struct wl_resource *surface_resource);
 
 /* desktop shell function prototypes */
-static void _e_wl_shell_cb_bind_desktop(struct wl_client *client, void *data, 
unsigned int version EINA_UNUSED, unsigned int id);
-static void _e_wl_shell_cb_unbind_desktop(struct wl_resource *resource);
+static void _e_wl_desktop_shell_cb_bind(struct wl_client *client, void *data, 
unsigned int version EINA_UNUSED, unsigned int id);
+static void _e_wl_desktop_shell_cb_unbind(struct wl_resource *resource);
 
 /* desktop shell interface prototypes */
 
+/* shell surface function prototypes */
+static E_Wayland_Shell_Surface *_e_wl_shell_shell_surface_create(void *shell 
EINA_UNUSED, E_Wayland_Surface *ews, const void *client EINA_UNUSED);
+static void _e_wl_shell_shell_surface_destroy(struct wl_resource *resource);
+static void _e_wl_shell_shell_surface_configure(E_Wayland_Surface *ews, 
Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+static void _e_wl_shell_shell_surface_map(E_Wayland_Surface *ews, Evas_Coord 
x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+static void _e_wl_shell_shell_surface_unmap(E_Wayland_Surface *ews);
+static void _e_wl_shell_shell_surface_type_set(E_Wayland_Shell_Surface *ewss);
+static void _e_wl_shell_shell_surface_type_reset(E_Wayland_Shell_Surface 
*ewss);
+static void _e_wl_shell_shell_surface_cb_destroy(struct wl_listener *listener, 
void *data EINA_UNUSED);
+static int _e_wl_shell_shell_surface_cb_ping_timeout(void *data);
+static void _e_wl_shell_shell_surface_cb_render_post(void *data, Evas *evas 
EINA_UNUSED, void *event EINA_UNUSED);
+
+/* shell surface interface prototypes */
+static void _e_wl_shell_shell_surface_cb_pong(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, unsigned int serial);
+static void _e_wl_shell_shell_surface_cb_move(struct wl_client *client, struct 
wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial);
+static void _e_wl_shell_shell_surface_cb_toplevel_set(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource);
+static void _e_wl_shell_shell_surface_cb_maximized_set(struct wl_client 
*client EINA_UNUSED, struct wl_resource *resource, struct wl_resource 
*output_resource EINA_UNUSED);
+static void _e_wl_shell_shell_surface_cb_title_set(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, const char *title);
+static void _e_wl_shell_shell_surface_cb_class_set(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, const char *clas);
+
 /* local wayland interfaces */
 static const struct wl_shell_interface _e_shell_interface = 
 {
@@ -31,6 +54,20 @@ static const struct e_desktop_shell_interface 
_e_desktop_shell_interface =
    NULL // _e_wl_shell_cb_shell_grab_surface_set
 };
 
+static const struct wl_shell_surface_interface _e_shell_surface_interface = 
+{
+   _e_wl_shell_shell_surface_cb_pong,
+   _e_wl_shell_shell_surface_cb_move,
+   NULL, // resize
+   _e_wl_shell_shell_surface_cb_toplevel_set,
+   NULL, // transient_set
+   NULL, // fullscreen_set
+   NULL, // popup_set
+   _e_wl_shell_shell_surface_cb_maximized_set,
+   _e_wl_shell_shell_surface_cb_title_set,
+   _e_wl_shell_shell_surface_cb_class_set
+};
+
 /* local variables */
 
 /* external variables */
@@ -42,6 +79,8 @@ e_modapi_init(E_Module *m)
 {
    E_Wayland_Desktop_Shell *shell = NULL;
    struct wl_global *gshell = NULL;
+   E_Wayland_Input *input = NULL;
+   Eina_List *l = NULL;
 
    /* try to allocate space for the shell structure */
    if (!(shell = E_NEW(E_Wayland_Desktop_Shell, 1)))
@@ -54,6 +93,9 @@ e_modapi_init(E_Module *m)
    shell->wl.destroy_listener.notify = _e_wl_shell_cb_destroy;
    wl_signal_add(&_e_wl_comp->signals.destroy, &shell->wl.destroy_listener);
 
+   /* setup compositor ping callback */
+   _e_wl_comp->ping_cb = _e_wl_shell_cb_ping;
+
    /* setup compositor shell interface functions */
    _e_wl_comp->shell_interface.shell = shell;
 
@@ -66,17 +108,33 @@ e_modapi_init(E_Module *m)
    /* try to add the desktop shell interface to the display's global list */
    if (!wl_display_add_global(_e_wl_comp->wl.display, 
                               &e_desktop_shell_interface, shell, 
-                              _e_wl_shell_cb_bind_desktop))
+                              _e_wl_desktop_shell_cb_bind))
+     goto err;
+
+   /* for each input, we need to create a pointer focus listener */
+   EINA_LIST_FOREACH(_e_wl_comp->seats, l, input)
      {
-        /* remove previously added shell global */
-        wl_display_remove_global(_e_wl_comp->wl.display, gshell);
+        struct wl_listener *lst;
 
-        goto err;
+        /* skip this input if it has no pointer */
+        if (!input->has_pointer) continue;
+
+        /* allocate space for the listener */
+        lst = malloc(sizeof(*lst));
+
+        /* set the listener callback function */
+        lst->notify = _e_wl_shell_cb_pointer_focus;
+
+        /* add this listener to the pointer focus signal */
+        wl_signal_add(&input->wl.seat.pointer->focus_signal, lst);
      }
 
    return m;
 
 err:
+   /* remove previously added shell global */
+   if (gshell) wl_display_remove_global(_e_wl_comp->wl.display, gshell);
+
    /* reset compositor shell interface */
    _e_wl_comp->shell_interface.shell = NULL;
 
@@ -121,16 +179,113 @@ _e_wl_shell_cb_bind(struct wl_client *client, void 
*data, unsigned int version E
                         &_e_shell_interface, id, shell);
 }
 
+static void 
+_e_wl_shell_cb_ping(E_Wayland_Surface *ews, unsigned int serial)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   if (!ews) return;
+
+   /* try to cast to our shell surface */
+   if (!(ewss = ews->shell_surface)) return;
+
+   /* if we do not have a ping timer yet, create one */
+   if (!ewss->ping_timer)
+     {
+        E_Wayland_Ping_Timer *tmr = NULL;
+
+        /* try to allocate space for a new ping timer */
+        if (!(tmr = E_NEW(E_Wayland_Ping_Timer, 1)))
+          return;
+
+        tmr->serial = serial;
+
+        /* add a timer to the event loop */
+        tmr->source = 
+          wl_event_loop_add_timer(_e_wl_comp->wl.loop, 
+                                  _e_wl_shell_shell_surface_cb_ping_timeout,
+                                  ewss);
+
+        /* update timer source interval */
+        wl_event_source_timer_update(tmr->source, 
+                                     e_config->ping_clients_interval);
+
+        ewss->ping_timer = tmr;
+
+        /* send the ping to the shell surface */
+        wl_shell_surface_send_ping(&ewss->wl.resource, serial);
+     }
+}
+
+static void 
+_e_wl_shell_cb_pointer_focus(struct wl_listener *listener EINA_UNUSED, void 
*data)
+{
+   struct wl_pointer *ptr;
+   E_Wayland_Surface *ews = NULL;
+
+   if (!(ptr = data)) return;
+
+   /* try to cast the current pointer focus to a wayland surface */
+   if (!(ews = (E_Wayland_Surface *)ptr->focus)) return;
+
+   /* if this surface has a shell_surface and it is not active, then we 
+    * should set the busy cursor on it */
+   if ((ews->shell_surface) && (!ews->shell_surface->active))
+     {
+        /* TODO: handle busy cursor */
+     }
+   else
+     {
+        unsigned int serial = 0;
+
+        serial = wl_display_next_serial(_e_wl_comp->wl.display);
+
+        /* ping the surface */
+        _e_wl_shell_cb_ping(ews, serial);
+     }
+}
+
 /* shell interface functions */
 static void 
 _e_wl_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource 
*resource, unsigned int id, struct wl_resource *surface_resource)
 {
+   E_Wayland_Surface *ews = NULL;
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   /* try to cast the surface resource to our structure */
+   if (!(ews = surface_resource->data)) return;
+
+   /* check if this surface already has a shell surface */
+   if ((ews->configure) && 
+       (ews->configure == _e_wl_shell_shell_surface_configure))
+     {
+        wl_resource_post_error(surface_resource, 
+                               WL_DISPLAY_ERROR_INVALID_OBJECT, 
+                               "Shell surface already requested for surface");
+        return;
+     }
 
+   /* try to create a shell surface for this surface */
+   if (!(ewss = _e_wl_shell_shell_surface_create(NULL, ews, NULL)))
+     {
+        wl_resource_post_no_memory(resource);
+        return;
+     }
+
+   ewss->wl.resource.destroy = _e_wl_shell_shell_surface_destroy;
+   ewss->wl.resource.object.id = id;
+   ewss->wl.resource.object.interface = &wl_shell_surface_interface;
+   ewss->wl.resource.object.implementation = 
+     (void (**)(void))&_e_shell_surface_interface;
+   ewss->wl.resource.data = ewss;
+
+   /* add this shell surface to the client */
+   wl_client_add_resource(client, &ewss->wl.resource);
 }
 
 /* desktop shell functions */
 static void 
-_e_wl_shell_cb_bind_desktop(struct wl_client *client, void *data, unsigned int 
version EINA_UNUSED, unsigned int id)
+_e_wl_desktop_shell_cb_bind(struct wl_client *client, void *data, unsigned int 
version EINA_UNUSED, unsigned int id)
 {
    E_Wayland_Desktop_Shell *shell = NULL;
    struct wl_resource *res = NULL;
@@ -151,11 +306,415 @@ _e_wl_shell_cb_bind_desktop(struct wl_client *client, 
void *data, unsigned int v
    shell->wl.resource = res;
 
    /* set desktop shell destroy callback */
-   res->destroy = _e_wl_shell_cb_unbind_desktop;
+   res->destroy = _e_wl_desktop_shell_cb_unbind;
 }
 
 static void 
-_e_wl_shell_cb_unbind_desktop(struct wl_resource *resource)
+_e_wl_desktop_shell_cb_unbind(struct wl_resource *resource)
 {
    free(resource);
 }
+
+/* desktop shell interface functions */
+
+/* shell surface functions */
+static E_Wayland_Shell_Surface *
+_e_wl_shell_shell_surface_create(void *shell EINA_UNUSED, E_Wayland_Surface 
*ews, const void *client EINA_UNUSED)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   /* try to allocate space for our shell surface structure */
+   if (!(ewss = E_NEW(E_Wayland_Shell_Surface, 1)))
+     return NULL;
+
+   /* set some function pointers on the surface */
+   ews->configure = _e_wl_shell_shell_surface_configure;
+   ews->map = _e_wl_shell_shell_surface_map;
+   ews->unmap = _e_wl_shell_shell_surface_unmap;
+
+   /* set some properties on the shell surface */
+   ewss->surface = ews;
+   ews->shell_surface = ewss;
+
+   /* setup shell surface destroy */
+   wl_signal_init(&ewss->wl.resource.destroy_signal);
+   ewss->wl.surface_destroy.notify = _e_wl_shell_shell_surface_cb_destroy;
+   wl_signal_add(&ews->wl.surface.resource.destroy_signal, 
+                 &ewss->wl.surface_destroy);
+
+   wl_list_init(&ewss->wl.link);
+
+   /* set some defaults on this shell surface */
+   ewss->active = EINA_TRUE;
+   ewss->type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE;
+   ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE;
+
+   return ewss;
+}
+
+static void 
+_e_wl_shell_shell_surface_destroy(struct wl_resource *resource)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   /* try to cast the resource to our shell surface */
+   if (!(ewss = resource->data)) return;
+
+   wl_list_remove(&ewss->wl.surface_destroy.link);
+   ewss->surface->configure = NULL;
+
+   wl_list_remove(&ewss->wl.link);
+
+   /* try to free our allocated structure */
+   E_FREE(ewss);
+}
+
+static void 
+_e_wl_shell_shell_surface_configure(E_Wayland_Surface *ews, Evas_Coord x, 
Evas_Coord y, Evas_Coord w, Evas_Coord h)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+   Eina_Bool changed_type = EINA_FALSE;
+
+   if ((ews->configure == _e_wl_shell_shell_surface_configure))
+     {
+        if (!(ewss = ews->shell_surface)) return;
+     }
+   else 
+     return;
+
+   printf("Configure Surface: %d %d %d %d\n", x, y, w, h);
+
+   /* handle shell_surface type change */
+   if ((ewss->next_type != E_WAYLAND_SHELL_SURFACE_TYPE_NONE) && 
+       (ewss->type != ewss->next_type))
+     {
+        /* set the shell surface type */
+        _e_wl_shell_shell_surface_type_set(ewss);
+
+        changed_type = EINA_TRUE;
+     }
+
+   /* if this surface is not mapped yet, then we need to map it */
+   if (!ews->mapped)
+     {
+        /* if the surface has a map function, call that. Else we use a 
+         * default one for this shell */
+        if (ews->map) ews->map(ews, x, y, w, h);
+        else _e_wl_shell_shell_surface_map(ews, x, y, w, h);
+     }
+   else if ((changed_type) || 
+            (ews->geometry.x != x) || (ews->geometry.y != y) || 
+            (ews->geometry.w != w) || (ews->geometry.h != h))
+     {
+        /* TODO */
+        if ((ews->geometry.x != x) || (ews->geometry.y != y))
+          {
+             ews->geometry.x = x;
+             ews->geometry.y = y;
+             ews->geometry.changed = EINA_FALSE;
+
+             if ((ews->bd) && 
+                 (ewss->type != E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED))
+               e_border_move(ews->bd, x, y);
+          }
+
+        if ((ews->geometry.w != w) || (ews->geometry.h != h))
+          {
+             ews->geometry.w = w;
+             ews->geometry.h = h;
+             ews->geometry.changed = EINA_FALSE;
+
+             if ((ews->bd) && 
+                 (ewss->type != E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED))
+               e_border_resize(ews->bd, w, h);
+          }
+     }
+}
+
+static void 
+_e_wl_shell_shell_surface_map(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord 
y, Evas_Coord w, Evas_Coord h)
+{
+   E_Container *con = NULL;
+   Evas *evas;
+
+   /* safety check */
+   if (!ews) return;
+
+   /* update surface geometry */
+   ews->geometry.x = x;
+   ews->geometry.y = y;
+   ews->geometry.w = w;
+   ews->geometry.h = h;
+
+   /* get the current container */
+   con = e_container_current_get(e_manager_current_get());
+
+   /* create an ecore evas to represent this 'window' */
+   ews->ee = ecore_evas_new(NULL, x, y, w, h, NULL);
+   ecore_evas_alpha_set(ews->ee, EINA_TRUE);
+   ecore_evas_borderless_set(ews->ee, EINA_FALSE);
+
+   /* get a reference to the canvas */
+   evas = ecore_evas_get(ews->ee);
+
+   /* setup a post_render callback */
+   evas_event_callback_add(evas, EVAS_CALLBACK_RENDER_POST, 
+                           _e_wl_shell_shell_surface_cb_render_post, ews);
+
+   /* create a surface smart object */
+   ews->obj = e_surface_add(evas);
+   evas_object_move(ews->obj, 0, 0);
+   evas_object_resize(ews->obj, w, h);
+   evas_object_show(ews->obj);
+
+   /* create the e border for this surface */
+   ews->bd = e_border_new(con, ecore_evas_window_get(ews->ee), 1, 1);
+   e_border_move_resize(ews->bd, x, y, w, h);
+   e_border_show(ews->bd);
+
+   ews->mapped = EINA_TRUE;
+}
+
+static void 
+_e_wl_shell_shell_surface_unmap(E_Wayland_Surface *ews)
+{
+   Eina_List *l = NULL;
+   E_Wayland_Input *input;
+
+   if (!ews) return;
+
+   EINA_LIST_FOREACH(_e_wl_comp->seats, l, input)
+     {
+        if ((input->wl.seat.keyboard) && 
+            (input->wl.seat.keyboard->focus == &ews->wl.surface))
+          wl_keyboard_set_focus(input->wl.seat.keyboard, NULL);
+        if ((input->wl.seat.pointer) && 
+            (input->wl.seat.pointer->focus == &ews->wl.surface))
+          wl_pointer_set_focus(input->wl.seat.pointer, NULL, 0, 0);
+     }
+
+   if (ews->obj) evas_object_del(ews->obj);
+   if (ews->ee) ecore_evas_free(ews->ee);
+   if (ews->bd) e_object_del(E_OBJECT(ews->bd));
+
+   ews->mapped = EINA_FALSE;
+}
+
+static void 
+_e_wl_shell_shell_surface_type_set(E_Wayland_Shell_Surface *ewss)
+{
+   /* safety check */
+   if (!ewss) return;
+
+   /* reset the shell surface type */
+   _e_wl_shell_shell_surface_type_reset(ewss);
+
+   ewss->type = ewss->next_type;
+   ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE;
+
+   switch (ewss->type)
+     {
+        /* record the current geometry so we can restore it on unmaximize */
+      case E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED:
+        ewss->saved.x = ewss->surface->geometry.x;
+        ewss->saved.y = ewss->surface->geometry.y;
+        ewss->saved.w = ewss->surface->geometry.w;
+        ewss->saved.h = ewss->surface->geometry.h;
+        ewss->saved.valid = EINA_TRUE;
+        break;
+      default:
+        break;
+     }
+}
+
+static void 
+_e_wl_shell_shell_surface_type_reset(E_Wayland_Shell_Surface *ewss)
+{
+   /* safety check */
+   if (!ewss) return;
+
+   switch (ewss->type)
+     {
+      case E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED:
+        /* unmaximize the border */
+        if (ewss->surface->bd)
+          e_border_unmaximize(ewss->surface->bd, 
+                              (e_config->maximize_policy & E_MAXIMIZE_TYPE) | 
+                              E_MAXIMIZE_BOTH);
+
+        /* restore the saved geometry */
+        ewss->surface->geometry.x = ewss->saved.x;
+        ewss->surface->geometry.y = ewss->saved.y;
+        ewss->surface->geometry.w = ewss->saved.w;
+        ewss->surface->geometry.h = ewss->saved.h;
+        ewss->surface->geometry.changed = EINA_TRUE;
+        break;
+      default:
+        break;
+     }
+
+   /* reset the current type to none */
+   ewss->type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE;
+}
+
+static void 
+_e_wl_shell_shell_surface_cb_destroy(struct wl_listener *listener, void *data 
EINA_UNUSED)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   /* try to get the shell surface from the listener */
+   ewss = container_of(listener, E_Wayland_Shell_Surface, wl.surface_destroy);
+   if (!ewss) return;
+
+   if (ewss->wl.resource.client)
+     wl_resource_destroy(&ewss->wl.resource);
+   else
+     wl_signal_emit(&ewss->wl.resource.destroy_signal, &ewss->wl.resource);
+}
+
+static int 
+_e_wl_shell_shell_surface_cb_ping_timeout(void *data)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   /* try to cast to our shell surface structure */
+   if (!(ewss = data)) return 1;
+
+   ewss->active = EINA_FALSE;
+
+   /* TODO: handle busy grab */
+
+   return 1;
+}
+
+static void 
+_e_wl_shell_shell_surface_cb_render_post(void *data, Evas *evas EINA_UNUSED, 
void *event EINA_UNUSED)
+{
+   E_Wayland_Surface *ews = NULL;
+   unsigned int secs = 0;
+   E_Wayland_Surface_Frame_Callback *cb = NULL, *ncb = NULL;
+
+   /* try to cast data to our surface structure */
+   if (!(ews = data)) return;
+
+   /* grab the current server time */
+   secs = e_comp_wl_time_get();
+
+   /* for each frame callback in the surface, signal it is done */
+   wl_list_for_each_safe(cb, ncb, &ews->wl.frames, wl.link)
+     {
+        wl_callback_send_done(&cb->wl.resource, secs);
+        wl_resource_destroy(&cb->wl.resource);
+     }
+}
+
+/* shell surface interface functions */
+static void 
+_e_wl_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct 
wl_resource *resource, unsigned int serial)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+   E_Wayland_Ping_Timer *tmr = NULL;
+   Eina_Bool responsive = EINA_FALSE;
+
+   /* try to cast the resource to our shell surface */
+   if (!(ewss = resource->data)) return;
+
+   /* try to cast the ping timer */
+   if (!(tmr = (E_Wayland_Ping_Timer *)ewss->ping_timer))
+     return;
+
+   if (tmr->serial != serial) return;
+
+   responsive = ewss->active;
+   ewss->active = EINA_TRUE;
+
+   if (!responsive)
+     {
+        /* TODO: Handle busy grab */
+     }
+
+   if (tmr->source) wl_event_source_remove(tmr->source);
+
+   /* free the allocated space for ping timer */
+   E_FREE(tmr);
+   ewss->ping_timer = NULL;
+}
+
+static void 
+_e_wl_shell_shell_surface_cb_move(struct wl_client *client, struct wl_resource 
*resource, struct wl_resource *seat_resource, unsigned int serial)
+{
+   /* TODO */
+}
+
+static void 
+_e_wl_shell_shell_surface_cb_toplevel_set(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   /* try to cast the resource to our shell surface */
+   if (!(ewss = resource->data)) return;
+
+   /* set next surface type */
+   ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_TOPLEVEL;
+}
+
+static void 
+_e_wl_shell_shell_surface_cb_maximized_set(struct wl_client *client 
EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource 
EINA_UNUSED)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+
+   /* try to cast the resource to our shell surface */
+   if (!(ewss = resource->data)) return;
+
+   /* TODO */
+
+   /* set next surface type */
+   ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED;
+}
+
+static void 
+_e_wl_shell_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, const char *title)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+   E_Wayland_Surface *ews = NULL;
+
+   /* try to cast the resource to our shell surface */
+   if (!(ewss = resource->data)) return;
+
+   /* free any previous title */
+   free(ewss->title);
+
+   /* set new title */
+   ewss->title = strdup(title);
+
+   /* update ecore_evas with new title */
+   if ((ews = ewss->surface))
+     {
+        if (ews->ee)
+          ecore_evas_title_set(ews->ee, ewss->title);
+     }
+}
+
+static void 
+_e_wl_shell_shell_surface_cb_class_set(struct wl_client *client EINA_UNUSED, 
struct wl_resource *resource, const char *clas)
+{
+   E_Wayland_Shell_Surface *ewss = NULL;
+   E_Wayland_Surface *ews = NULL;
+
+   /* try to cast the resource to our shell surface */
+   if (!(ewss = resource->data)) return;
+
+   /* free any previous class */
+   free(ewss->clas);
+
+   /* set new class */
+   ewss->clas = strdup(clas);
+
+   /* update ecore_evas with new class */
+   if ((ews = ewss->surface))
+     {
+        if (ews->ee)
+          ecore_evas_name_class_set(ews->ee, ewss->title, ewss->clas);
+     }
+}
+

-- 

------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter

Reply via email to