devilhorns pushed a commit to branch master.

commit deec13f2cea029b9012736dbe5c3e02fd9772aae
Author: Chris Michael <[email protected]>
Date:   Tue Apr 9 11:03:14 2013 +0100

    Add code to support initialize, setup and destruction of wayland
    inputs (pointer, keyboard, touch).
    
    Signed-off-by: Chris Michael <[email protected]>
---
 src/bin/e_comp_wl.c | 633 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 626 insertions(+), 7 deletions(-)

diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index c2430d9..305975a 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -7,14 +7,33 @@ static void _e_comp_wl_cb_bind(struct wl_client *client, void 
*data EINA_UNUSED,
 static Eina_Bool _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler 
*hdl EINA_UNUSED);
 static Eina_Bool _e_comp_wl_cb_idle(void *data EINA_UNUSED);
 
-/* input function prototypes */
-static Eina_Bool _e_comp_wl_input_init(void);
-static void _e_comp_wl_input_shutdown(void);
-
 /* compositor interface prototypes */
 static void _e_comp_wl_cb_surface_create(struct wl_client *client, struct 
wl_resource *resource, unsigned int id);
 static void _e_comp_wl_cb_region_create(struct wl_client *client, struct 
wl_resource *resource, unsigned int id);
 
+/* input function prototypes */
+static Eina_Bool _e_comp_wl_input_init(void);
+static void _e_comp_wl_input_shutdown(void);
+static void _e_comp_wl_input_cb_bind(struct wl_client *client, void *data, 
unsigned int version EINA_UNUSED, unsigned int id);
+static void _e_comp_wl_input_cb_unbind(struct wl_resource *resource);
+static struct xkb_keymap *_e_comp_wl_input_keymap_get(void);
+static int _e_comp_wl_input_keymap_fd_get(off_t size);
+static E_Wayland_Keyboard_Info *_e_comp_wl_input_keyboard_info_get(struct 
xkb_keymap *keymap);
+static void _e_comp_wl_input_modifiers_update(unsigned int serial);
+
+/* input interface prototypes */
+static void _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct 
wl_resource *resource, unsigned int id);
+static void _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct 
wl_resource *resource, unsigned int id);
+static void _e_comp_wl_input_cb_touch_get(struct wl_client *client, struct 
wl_resource *resource, unsigned int id);
+
+/* pointer function prototypes */
+static void _e_comp_wl_pointer_cb_destroy(struct wl_listener *listener, void 
*data EINA_UNUSED);
+static void _e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, 
Evas_Coord y, Evas_Coord w, Evas_Coord h);
+static void _e_comp_wl_pointer_unmap(E_Wayland_Surface *ews);
+
+/* pointer interface prototypes */
+static void _e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct 
wl_resource *resource, unsigned int serial, struct wl_resource 
*surface_resource, int x, int y);
+
 /* local wayland interfaces */
 static const struct wl_compositor_interface _e_compositor_interface = 
 {
@@ -22,6 +41,18 @@ static const struct wl_compositor_interface 
_e_compositor_interface =
    _e_comp_wl_cb_region_create
 };
 
+static const struct wl_seat_interface _e_input_interface = 
+{
+   _e_comp_wl_input_cb_pointer_get,
+   _e_comp_wl_input_cb_keyboard_get,
+   _e_comp_wl_input_cb_touch_get,
+};
+
+static const struct wl_pointer_interface _e_pointer_interface = 
+{
+   _e_comp_wl_pointer_cb_cursor_set
+};
+
 /* local variables */
 
 /* external variables */
@@ -218,29 +249,617 @@ _e_comp_wl_cb_idle(void *data EINA_UNUSED)
    return ECORE_CALLBACK_RENEW;
 }
 
+/* compositor interface functions */
+static void 
+_e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource 
*resource, unsigned int id)
+{
+
+}
+
+static void 
+_e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource 
*resource, unsigned int id)
+{
+
+}
+
 /* input functions */
 static Eina_Bool 
 _e_comp_wl_input_init(void)
 {
+   struct xkb_keymap *keymap;
+
+   /* try to allocate space for a new compositor */
+   if (!(_e_wl_comp->input = E_NEW(E_Wayland_Input, 1)))
+     return EINA_FALSE;
+
+   /* initialize the seat */
+   wl_seat_init(&_e_wl_comp->input->wl.seat);
+
+   /* try to add this input to the diplay's list of globals */
+   if (!wl_display_add_global(_e_wl_comp->wl.display, &wl_seat_interface, 
+                              _e_wl_comp->input, _e_comp_wl_input_cb_bind))
+     {
+        ERR("Could not add Input to Wayland Display Globals: %m");
+        goto err;
+     }
+
+   _e_wl_comp->input->pointer.surface = NULL;
+   _e_wl_comp->input->pointer.surface_destroy.notify = 
+     _e_comp_wl_pointer_cb_destroy;
+   _e_wl_comp->input->pointer.hot.x = 16;
+   _e_wl_comp->input->pointer.hot.y = 16;
+
+   /* initialize wayland pointer */
+   wl_pointer_init(&_e_wl_comp->input->wl.pointer);
+
+   /* tell the seat about this pointer */
+   wl_seat_set_pointer(&_e_wl_comp->input->wl.seat, 
+                       &_e_wl_comp->input->wl.pointer);
+
+   /* set flag to indicate we have a pointer */
+   _e_wl_comp->input->has_pointer = EINA_TRUE;
+
+   /* create the xkb context */
+   _e_wl_comp->xkb.context = xkb_context_new(0);
+
+   /* try to fetch the keymap */
+   if ((keymap = _e_comp_wl_input_keymap_get()))
+     {
+        /* try to create new keyboard info */
+        _e_wl_comp->input->xkb.info = 
+          _e_comp_wl_input_keyboard_info_get(keymap);
+
+        /* create new xkb state */
+        _e_wl_comp->input->xkb.state = xkb_state_new(keymap);
+
+        /* unreference the keymap */
+        xkb_map_unref(keymap);
+     }
+
+   /* initialize the keyboard */
+   wl_keyboard_init(&_e_wl_comp->input->wl.keyboard);
+
+   /* tell the seat about this keyboard */
+   wl_seat_set_keyboard(&_e_wl_comp->input->wl.seat, 
+                        &_e_wl_comp->input->wl.keyboard);
+
+   /* set flag to indicate we have a keyboard */
+   _e_wl_comp->input->has_keyboard = EINA_TRUE;
+
+   wl_list_init(&_e_wl_comp->input->wl.link);
+
+   /* append this input to the list */
+   _e_wl_comp->seats = eina_list_append(_e_wl_comp->seats, _e_wl_comp->input);
+
+   /* emit a signal saying that input has been initialized */
+   wl_signal_emit(&_e_wl_comp->signals.seat, _e_wl_comp->input);
+
+   /* return success */
    return EINA_TRUE;
+
+err:
+   /* release the wl_seat */
+   wl_seat_release(&_e_wl_comp->input->wl.seat);
+
+   /* free the allocated input structure */
+   E_FREE(_e_wl_comp->input);
+
+   /* return failure */
+   return EINA_FALSE;
 }
 
 static void 
 _e_comp_wl_input_shutdown(void)
 {
+   /* safety check */
+   if (!_e_wl_comp->input) return;
+
+   /* destroy keyboard */
+   if (_e_wl_comp->input->xkb.info)
+     {
+        /* if we have a keymap, unreference it */
+        if (_e_wl_comp->input->xkb.info->keymap)
+          xkb_map_unref(_e_wl_comp->input->xkb.info->keymap);
+
+        /* if we have a keymap mmap'd area, unmap it */
+        if (_e_wl_comp->input->xkb.info->area)
+          munmap(_e_wl_comp->input->xkb.info->area, 
+                 _e_wl_comp->input->xkb.info->size);
+
+        /* if we created an fd for keyboard input, close it */
+        if (_e_wl_comp->input->xkb.info->fd) 
+          close(_e_wl_comp->input->xkb.info->fd);
+
+        /* free the allocated keyboard info structure */
+        E_FREE(_e_wl_comp->input->xkb.info);
+     }
+
+   /* unreference the xkb state we created */
+   if (_e_wl_comp->input->xkb.state) 
+     xkb_state_unref(_e_wl_comp->input->xkb.state);
+
+   /* unreference the xkb context we created */
+   if (_e_wl_comp->xkb.context)
+     xkb_context_unref(_e_wl_comp->xkb.context);
+
+   /* TODO: destroy pointer surface
+    * 
+    * NB: Currently, we do not create one */
 
+   wl_list_remove(&_e_wl_comp->input->wl.link);
+
+   /* release the seat */
+   wl_seat_release(&_e_wl_comp->input->wl.seat);
+
+   /* free the allocated input structure */
+   E_FREE(_e_wl_comp->input);
 }
 
-/* compositor interface functions */
 static void 
-_e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource 
*resource, unsigned int id)
+_e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int 
version EINA_UNUSED, unsigned int id)
 {
+   struct wl_seat *seat = NULL;
+   struct wl_resource *resource = NULL;
+   enum wl_seat_capability caps = 0;
+
+   /* try to cast data to our seat */
+   if (!(seat = data)) return;
+
+   /* add the seat object to the client */
+   resource = 
+     wl_client_add_object(client, &wl_seat_interface, 
+                          &_e_input_interface, id, data);
+   wl_list_insert(&seat->base_resource_list, &resource->link);
+
+   /* set resource destroy callback */
+   resource->destroy = _e_comp_wl_input_cb_unbind;
 
+   /* set capabilities based on seat */
+   if (seat->pointer) caps |= WL_SEAT_CAPABILITY_POINTER;
+   if (seat->keyboard) caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+   if (seat->touch) caps |= WL_SEAT_CAPABILITY_TOUCH;
+
+   /* inform the resource about the seat capabilities */
+   wl_seat_send_capabilities(resource, caps);
 }
 
 static void 
-_e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource 
*resource, unsigned int id)
+_e_comp_wl_input_cb_unbind(struct wl_resource *resource)
+{
+   /* remove the link */
+   wl_list_remove(&resource->link);
+
+   /* free the resource */
+   free(resource);
+}
+
+static struct xkb_keymap *
+_e_comp_wl_input_keymap_get(void)
+{
+   struct xkb_rule_names names;
+
+   memset(&names, 0, sizeof(names));
+
+   /* if we are running under X11, try to get the xkb rule names atom */
+   if (getenv("DISPLAY"))
+     {
+        Ecore_X_Atom rules = 0;
+        Ecore_X_Window root = 0;
+        int len = 0;
+        unsigned char *data;
+
+        /* TODO: FIXME: NB:
+         * 
+         * The below commented out code is for using the "already" configured 
+         * E xkb settings in the wayland clients. The only Major problem with 
+         * that is: That the E_Config_XKB_Layout does not define a 
+         * 'RULES' which we need ....
+         * 
+         */
+
+        /* E_Config_XKB_Layout *kbd_layout; */
+        /* kbd_layout = e_xkb_layout_get(); */
+        /* names.model = strdup(kbd_layout->model); */
+        /* names.layout = strdup(kbd_layout->name); */
+
+        root = ecore_x_window_root_first_get();
+        rules = ecore_x_atom_get("_XKB_RULES_NAMES");
+        ecore_x_window_prop_property_get(root, rules, ECORE_X_ATOM_STRING, 
+                                         1024, &data, &len);
+
+        if ((data) && (len > 0))
+          {
+             names.rules = strdup((const char *)data);
+             data += strlen((const char *)data) + 1;
+             names.model = strdup((const char *)data);
+             data += strlen((const char *)data) + 1;
+             names.layout = strdup((const char *)data);
+//             free(data);
+          }
+     }
+
+   /* printf("Names\n"); */
+   /* printf("\tRules: %s\n", names.rules); */
+   /* printf("\tModel: %s\n", names.model); */
+   /* printf("\tLayout: %s\n", names.layout); */
+
+   return xkb_map_new_from_names(_e_wl_comp->xkb.context, &names, 0);
+}
+
+static int 
+_e_comp_wl_input_keymap_fd_get(off_t size)
+{
+   char tmp[PATH_MAX];
+   const char *path;
+   int fd = 0;
+   long flags;
+
+   if (!(path = getenv("XDG_RUNTIME_DIR")))
+     return -1;
+
+   strcpy(tmp, path);
+   strcat(tmp, "/e-wl-keymap-XXXXXX");
+
+   if ((fd = mkstemp(tmp)) < 0)
+     return -1;
+
+   /* TODO: really should error check the returns here */
+
+   flags = fcntl(fd, F_GETFD);
+   fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+
+   if (ftruncate(fd, size) < 0)
+     {
+        close(fd);
+        return -1;
+     }
+
+   unlink(tmp);
+   return fd;
+}
+
+static E_Wayland_Keyboard_Info *
+_e_comp_wl_input_keyboard_info_get(struct xkb_keymap *keymap)
+{
+   E_Wayland_Keyboard_Info *info = NULL;
+   char *tmp;
+
+   /* try to allocate space for the keyboard info structure */
+   if (!(info = E_NEW(E_Wayland_Keyboard_Info, 1)))
+     return NULL;
+
+   info->keymap = xkb_map_ref(keymap);
+
+   /* init modifiers */
+   info->mod_shift = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
+   info->mod_caps = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
+   info->mod_ctrl = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
+   info->mod_alt = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
+   info->mod_super = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
+
+   /* try to get a string of this keymap */
+   if (!(tmp = xkb_map_get_as_string(keymap)))
+     {
+        printf("Could not map get as string\n");
+     }
+
+   info->size = strlen(tmp) + 1;
+
+   /* try to create an fd we can listen on for input */
+   info->fd = _e_comp_wl_input_keymap_fd_get(info->size);
+   if (info->fd < 0)
+     {
+        printf("Could not create keymap fd\n");
+     }
+
+   info->area = 
+     mmap(NULL, info->size, PROT_READ | PROT_WRITE, MAP_SHARED, info->fd, 0);
+
+   /* TODO: error check mmap */
+
+   strcpy(info->area, tmp);
+   free(tmp);
+
+   return info;
+}
+
+static void 
+_e_comp_wl_input_modifiers_update(unsigned int serial)
 {
+   struct wl_keyboard *kbd;
+   struct wl_keyboard_grab *grab;
+   unsigned int pressed = 0, latched = 0, locked = 0, group = 0;
+   Eina_Bool changed = EINA_FALSE;
+
+   /* check for valid keyboard */
+   if (!(kbd = _e_wl_comp->input->wl.seat.keyboard)) 
+     return;
+
+   /* try to get the current keyboard's grab interface. 
+    * Fallback to the default grab */
+   if (!(grab = kbd->grab)) grab = &kbd->default_grab;
+
+   pressed = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, 
+                                      XKB_STATE_DEPRESSED);
+   latched = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, 
+                                      XKB_STATE_LATCHED);
+   locked = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, 
+                                     XKB_STATE_LOCKED);
+   group = xkb_state_serialize_group(_e_wl_comp->input->xkb.state, 
+                                     XKB_STATE_EFFECTIVE);
+
+   if ((pressed != kbd->modifiers.mods_depressed) || 
+       (latched != kbd->modifiers.mods_latched) || 
+       (locked != kbd->modifiers.mods_locked) || 
+       (group != kbd->modifiers.group))
+     changed = EINA_TRUE;
+
+   kbd->modifiers.mods_depressed = pressed;
+   kbd->modifiers.mods_latched = latched;
+   kbd->modifiers.mods_locked = locked;
+   kbd->modifiers.group = group;
+
+   /* TODO: update leds ? */
+
+   if (changed)
+     grab->interface->modifiers(grab, serial, 
+                                kbd->modifiers.mods_depressed, 
+                                kbd->modifiers.mods_latched, 
+                                kbd->modifiers.mods_locked,
+                                kbd->modifiers.group);
+}
+
+/* input interface functions */
+static void 
+_e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource 
*resource, unsigned int id)
+{
+   E_Wayland_Input *input = NULL;
+   struct wl_resource *ptr = NULL;
+
+   /* try to cast the resource data to our input structure */
+   if (!(input = resource->data)) return;
+
+   /* check that input has a pointer */
+   if (!input->has_pointer) return;
 
+   /* add a pointer object to the client */
+   ptr = wl_client_add_object(client, &wl_pointer_interface, 
+                              &_e_pointer_interface, id, input);
+   wl_list_insert(&input->wl.seat.pointer->resource_list, &ptr->link);
+
+   /* set pointer destroy callback */
+   ptr->destroy = _e_comp_wl_input_cb_unbind;
+
+   /* if the pointer has a focused surface, set it */
+   if ((input->wl.seat.pointer->focus) && 
+       (input->wl.seat.pointer->focus->resource.client == client))
+     {
+        /* FIXME: what to pass to wl_pointer_set_focus (x/y) */
+        wl_pointer_set_focus(input->wl.seat.pointer, 
+                             input->wl.seat.pointer->focus, 
+                             input->wl.seat.pointer->x, 
+                             input->wl.seat.pointer->y);
+     }
+}
+
+static void 
+_e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource 
*resource, unsigned int id)
+{
+   E_Wayland_Input *input = NULL;
+   struct wl_resource *kbd = NULL;
+
+   /* try to cast the resource data to our input structure */
+   if (!(input = resource->data)) return;
+
+   /* check that input has a keyboard */
+   if (!input->has_keyboard) return;
+
+   /* add a keyboard object to the client */
+   kbd = wl_client_add_object(client, &wl_keyboard_interface, NULL, id, input);
+   wl_list_insert(&input->wl.seat.keyboard->resource_list, &kbd->link);
+
+   /* set keyboard destroy callback */
+   kbd->destroy = _e_comp_wl_input_cb_unbind;
+
+   /* send the current keymap to the keyboard object */
+   wl_keyboard_send_keymap(kbd, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, 
+                           input->xkb.info->fd, input->xkb.info->size);
+
+   /* test if keyboard has a focused client */
+   if ((input->wl.seat.keyboard->focus) && 
+       (input->wl.seat.keyboard->focus->resource.client == client))
+     {
+        /* set keyboard focus */
+        wl_keyboard_set_focus(input->wl.seat.keyboard, 
+                              input->wl.seat.keyboard->focus);
+
+        /* update the keyboard focus in the data device */
+        wl_data_device_set_keyboard_focus(&input->wl.seat);
+     }
+}
+
+static void 
+_e_comp_wl_input_cb_touch_get(struct wl_client *client, struct wl_resource 
*resource, unsigned int id)
+{
+   E_Wayland_Input *input = NULL;
+   struct wl_resource *tch = NULL;
+
+   /* try to cast the resource data to our input structure */
+   if (!(input = resource->data)) return;
+
+   /* check that input has a touch */
+   if (!input->has_touch) return;
+
+   /* add a touch object to the client */
+   tch = wl_client_add_object(client, &wl_touch_interface, NULL, id, input);
+   wl_list_insert(&input->wl.seat.touch->resource_list, &tch->link);
+
+   /* set touch destroy callback */
+   tch->destroy = _e_comp_wl_input_cb_unbind;
+}
+
+/* pointer functions */
+static void 
+_e_comp_wl_pointer_cb_destroy(struct wl_listener *listener, void *data 
EINA_UNUSED)
+{
+   E_Wayland_Input *input = NULL;
+
+   /* try to get the input from this listener */
+   if (!(input = container_of(listener, E_Wayland_Input, 
pointer.surface_destroy)))
+     return;
+
+   input->pointer.surface = NULL;
+}
+
+static void 
+_e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord 
y, Evas_Coord w, Evas_Coord h)
+{
+   E_Wayland_Input *input = NULL;
+   E_Wayland_Surface *focus = NULL;
+
+   /* safety check */
+   if (!ews) return;
+
+   /* see if this surface has 'input' */
+   if (!(input = ews->input)) return;
+
+   input->pointer.hot.x -= x;
+   input->pointer.hot.y -= y;
+
+   /* configure the surface geometry */
+   ews->geometry.x = x;
+   ews->geometry.h = h;
+   ews->geometry.w = w;
+   ews->geometry.h = h;
+   ews->geometry.changed = EINA_TRUE;
+
+   /* tell pixman we are finished with this region */
+   pixman_region32_fini(&ews->pending.input);
+
+   /* reinitalize the pending input region */
+   pixman_region32_init(&ews->pending.input);
+
+   /* do we have a focused surface ? */
+   if ((focus = (E_Wayland_Surface *)input->wl.seat.pointer->focus))
+     {
+        /* NB: Ideally, I wanted to use the e_pointer methods here so that 
+         * the cursor would match the E theme, however Wayland currently 
+         * provides NO Method to get the cursor name :( so we are stuck 
+         * using the pixels from their cursor surface */
+
+        /* is it mapped ? */
+        if ((focus->mapped) && (focus->ee))
+          {
+             Ecore_Window win;
+
+             /* try to get the ecore_window */
+             if ((win = ecore_evas_window_get(focus->ee)))
+               {
+                  void *pixels;
+                  Ecore_X_Cursor cur;
+
+                  /* grab the pixels from the cursor surface */
+                  pixels = wl_shm_buffer_get_data(ews->reference.buffer);
+
+                  /* create the new X cursor with this image */
+                  cur = ecore_x_cursor_new(win, pixels, w, h,
+                                           input->pointer.hot.x, 
+                                           input->pointer.hot.y);
+
+                  /* set the cursor on this window */
+                  ecore_x_window_cursor_set(win, cur);
+
+                  /* free the cursor */
+                  ecore_x_cursor_free(cur);
+               }
+          }
+     }
+}
+
+static void 
+_e_comp_wl_pointer_unmap(E_Wayland_Surface *ews)
+{
+   E_Wayland_Input *input = NULL;
+
+   /* safety check */
+   if (!ews) return;
+
+   if (!(input = ews->input)) return;
+
+   wl_list_remove(&input->pointer.surface_destroy.link);
+
+   if (input->pointer.surface)
+     input->pointer.surface->configure = NULL;
+
+   input->pointer.surface = NULL;
+}
+
+/* pointer interface functions */
+static void 
+_e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource 
*resource, unsigned int serial, struct wl_resource *surface_resource, int x, 
int y)
+{
+   E_Wayland_Input *input = NULL;
+   E_Wayland_Surface *ews = NULL;
+
+   /* try to cast the resource data to our input structure */
+   if (!(input = resource->data)) return;
+
+   /* if we were passed in a surface, try to cast it to our structure */
+   if (surface_resource) ews = (E_Wayland_Surface *)surface_resource->data;
+
+   /* if the input has no current focus, get out */
+   if (!input->wl.seat.pointer->focus) return;
+
+   if (input->wl.seat.pointer->focus->resource.client != client) return;
+   if ((input->wl.seat.pointer->focus_serial - serial) > (UINT32_MAX / 2))
+     return;
+
+   /* is the passed in surface the same as our pointer surface ? */
+   if ((ews) && (ews != input->pointer.surface))
+     {
+        if (ews->configure)
+          {
+             wl_resource_post_error(&ews->wl.surface.resource, 
+                                    WL_DISPLAY_ERROR_INVALID_OBJECT, 
+                                    "Surface already configured");
+             return;
+          }
+     }
+
+   /* if we have an existing pointer surface, unmap it */
+   if (input->pointer.surface) 
+     {
+        /* call the unmap function */
+        if (input->pointer.surface->unmap)
+          input->pointer.surface->unmap(input->pointer.surface);
+     }
+
+   if (!ews) return;
+
+   /* set the destroy listener */
+   wl_signal_add(&ews->wl.surface.resource.destroy_signal, 
+                 &input->pointer.surface_destroy);
+
+   /* set some properties on this surface */
+   ews->unmap = _e_comp_wl_pointer_unmap;
+   ews->configure = _e_comp_wl_pointer_configure;
+   ews->input = input;
+
+   /* update input structure with new values */
+   input->pointer.surface = ews;
+   input->pointer.hot.x = x;
+   input->pointer.hot.y = y;
+
+   if (ews->reference.buffer)
+     {
+        Evas_Coord bw = 0, bh = 0;
+
+        /* grab the size of the buffer */
+        bw = ews->reference.buffer->width;
+        bh = ews->reference.buffer->height;
+
+        /* configure the pointer surface */
+        _e_comp_wl_pointer_configure(ews, 0, 0, bw, bh);
+     }
 }
 

-- 

------------------------------------------------------------------------------
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