redo e_pointer to support xwayland cursors
authorMike Blumenkrantz <zmike@osg.samsung.com>
Thu, 9 Jul 2015 18:42:55 +0000 (14:42 -0400)
committerMike Blumenkrantz <zmike@osg.samsung.com>
Thu, 9 Jul 2015 18:45:04 +0000 (14:45 -0400)
this requires that both canvas cursors and window cursors be present for the same
E_Pointer object, even though only the canvas cursor is actually visible

 #kansas

src/bin/e_comp_x.c
src/bin/e_pointer.c
src/bin/e_pointer.h

index fe4c273..e528287 100644 (file)
@@ -5183,6 +5183,8 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
         e_pointer_type_push(e_comp->pointer, e_comp->pointer, "default");
         ecore_x_icccm_state_set(ecore_evas_window_get(e_comp->ee), ECORE_X_WINDOW_STATE_HINT_NORMAL);
      }
+   else
+     e_comp->pointer->win = e_comp->root;
    _e_comp_x_manage_windows();
 
    {
index 696658a..f7c4e04 100644 (file)
@@ -55,12 +55,12 @@ _e_pointer_cb_idle_poller(void *data)
         return ECORE_CALLBACK_CANCEL;
      }
 
+   if (ptr->canvas)
+     ecore_evas_pointer_xy_get(ptr->ee, &x, &y);
 #ifndef HAVE_WAYLAND_ONLY
-   if (!ptr->canvas)
-     ecore_x_pointer_xy_get(ptr->win, &x, &y);
    else
+     ecore_x_pointer_xy_get(ptr->win, &x, &y);
 #endif
-     ecore_evas_pointer_xy_get(ptr->ee, &x, &y);
 
    if ((ptr->x != x) || (ptr->y != y))
      {
@@ -103,12 +103,12 @@ _e_pointer_cb_idle_pre(void *data)
 
    if (!(ptr = data)) return ECORE_CALLBACK_RENEW;
 
+   if (ptr->canvas)
+     ecore_evas_pointer_xy_get(ptr->ee, &ptr->x, &ptr->y);
 #ifndef HAVE_WAYLAND_ONLY
-   if (!ptr->canvas)
-     ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
    else
+     ecore_x_pointer_xy_get(ptr->win, &ptr->x, &ptr->y);
 #endif
-     ecore_evas_pointer_xy_get(ptr->ee, &ptr->x, &ptr->y);
 
    ptr->idle_tmr = ecore_timer_loop_add(4.0, _e_pointer_cb_idle_wait, ptr);
 
@@ -209,10 +209,9 @@ _e_pointer_cb_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *ev
 static void 
 _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
 {
-   E_Pointer *ptr;
+   E_Pointer *ptr = data;
    int x = 0, y = 0;
 
-   if (!(ptr = data)) return;
    if (!ptr->e_cursor) return;
    if (!evas_object_visible_get(ptr->o_ptr)) return;
    edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot", 
@@ -223,22 +222,40 @@ _e_pointer_cb_hot_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA
 static void 
 _e_pointer_cb_hot_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
 {
-   E_Pointer *ptr;
+   E_Pointer *ptr = data;
    int x = 0, y = 0;
 
-   if (!(ptr = data)) return;
+   if (!ptr->e_cursor) return;
    edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot", 
                                  &x, &y, NULL, NULL);
    _e_pointer_hot_update(ptr, x, y);
 }
 
+static void
+_e_pointer_pointer_canvas_init(E_Pointer *ptr, Evas *e, Evas_Object **o_ptr, Evas_Object **o_hot)
+{
+   /* create pointer object */
+   *o_ptr = edje_object_add(e);
+
+   /* create hotspot object */
+   *o_hot = evas_object_rectangle_add(e);
+   evas_object_color_set(*o_hot, 0, 0, 0, 0);
+
+   evas_object_event_callback_add(*o_hot, EVAS_CALLBACK_MOVE,
+                                  _e_pointer_cb_hot_move, ptr);
+   evas_object_event_callback_add(*o_hot, EVAS_CALLBACK_SHOW,
+                                  _e_pointer_cb_hot_show, ptr);
+
+   evas_object_move(*o_ptr, 0, 0);
+   evas_object_resize(*o_ptr, ptr->w, ptr->h);
+}
+
 static void 
 _e_pointer_canvas_del(E_Pointer *ptr)
 {
-   E_FREE_FUNC(ptr->o_hot, evas_object_del);
-   E_FREE_FUNC(ptr->o_ptr, evas_object_del);
-   if (ptr->evas) evas_free(ptr->evas);
-   ptr->evas = NULL;
+   E_FREE_FUNC(ptr->buffer_o_hot, evas_object_del);
+   E_FREE_FUNC(ptr->buffer_o_ptr, evas_object_del);
+   E_FREE_FUNC(ptr->buffer_evas, evas_free);
    E_FREE(ptr->pixels);
 }
 
@@ -249,19 +266,19 @@ _e_pointer_canvas_add(E_Pointer *ptr)
    int method = 0;
 
    /* try to create new canvas */
-   if (!(ptr->evas = evas_new())) goto err;
+   if (!(ptr->buffer_evas = evas_new())) goto err;
 
    method = evas_render_method_lookup("buffer");
-   evas_output_method_set(ptr->evas, method);
-   evas_output_size_set(ptr->evas, ptr->w, ptr->h);
-   evas_output_viewport_set(ptr->evas, 0, 0, ptr->w, ptr->h);
+   evas_output_method_set(ptr->buffer_evas, method);
+   evas_output_size_set(ptr->buffer_evas, ptr->w, ptr->h);
+   evas_output_viewport_set(ptr->buffer_evas, 0, 0, ptr->w, ptr->h);
 
    /* try to allocate space for pixels */
    if (!(ptr->pixels = malloc(ptr->w * ptr->h * sizeof(int))))
      goto err;
 
    /* try to get the buffer engine info */
-   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
+   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->buffer_evas);
    if (!einfo) goto err;
 
    /* fill in buffer engine info */
@@ -274,23 +291,15 @@ _e_pointer_canvas_add(E_Pointer *ptr)
    einfo->info.func.free_update_region = NULL;
 
    /* set buffer engine info */
-   evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
-
-   /* create pointer object */
-   ptr->o_ptr = edje_object_add(ptr->evas);
-
-   /* create hotspot object */
-   ptr->o_hot = evas_object_rectangle_add(ptr->evas);
-   evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
-
-   evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE, 
-                                  _e_pointer_cb_hot_move, ptr);
-   evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW, 
-                                  _e_pointer_cb_hot_show, ptr);
-
-   evas_object_move(ptr->o_ptr, 0, 0);
-   evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
+   evas_engine_info_set(ptr->buffer_evas, (Evas_Engine_Info *)einfo);
 
+   _e_pointer_pointer_canvas_init(ptr, ptr->buffer_evas, &ptr->buffer_o_ptr, &ptr->buffer_o_hot);
+   if (!ptr->evas)
+     {
+        ptr->evas = ptr->buffer_evas;
+        ptr->o_ptr = ptr->buffer_o_ptr;
+        ptr->o_hot = ptr->buffer_o_hot;
+     }
    return;
 
 err:
@@ -305,20 +314,20 @@ _e_pointer_canvas_resize(E_Pointer *ptr, int w, int h)
    if ((ptr->w == w) && (ptr->h == h)) return;
    ptr->w = w;
    ptr->h = h;
-   evas_output_size_set(ptr->evas, w, h);
-   evas_output_viewport_set(ptr->evas, 0, 0, w, h);
+   evas_output_size_set(ptr->buffer_evas, w, h);
+   evas_output_viewport_set(ptr->buffer_evas, 0, 0, w, h);
 
    ptr->pixels = realloc(ptr->pixels, (ptr->w * ptr->h * sizeof(int)));
 
-   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->evas);
+   einfo = (Evas_Engine_Info_Buffer *)evas_engine_info_get(ptr->buffer_evas);
    EINA_SAFETY_ON_NULL_RETURN(einfo);
 
    einfo->info.dest_buffer = ptr->pixels;
    einfo->info.dest_buffer_row_bytes = (ptr->w * sizeof(int));
-   evas_engine_info_set(ptr->evas, (Evas_Engine_Info *)einfo);
+   evas_engine_info_set(ptr->buffer_evas, (Evas_Engine_Info *)einfo);
 
-   evas_object_move(ptr->o_ptr, 0, 0);
-   evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
+   evas_object_move(ptr->buffer_o_ptr, 0, 0);
+   evas_object_resize(ptr->buffer_o_ptr, ptr->w, ptr->h);
 }
 
 static void 
@@ -340,7 +349,7 @@ _e_pointer_cb_free(E_Pointer *ptr)
    E_FREE_FUNC(ptr->idle_tmr, ecore_timer_del);
    E_FREE_FUNC(ptr->idle_poll, ecore_poller_del);
 
-   if (!ptr->canvas) _e_pointer_canvas_del(ptr);
+   if (ptr->buffer_evas) _e_pointer_canvas_del(ptr);
 
    free(ptr);
 }
@@ -366,7 +375,7 @@ _e_pointer_type_set(E_Pointer *ptr, const char *type)
         int x = 0, y = 0;
 
         /* create a pointer canvas if we need to */
-        if ((!ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_add(ptr);
+        if ((!ptr->buffer_evas) && ptr->win) _e_pointer_canvas_add(ptr);
 
         if (ptr->color)
           snprintf(cursor, sizeof(cursor), 
@@ -378,8 +387,11 @@ _e_pointer_type_set(E_Pointer *ptr, const char *type)
         /* try to set the edje object theme */
         if (!e_theme_edje_object_set(ptr->o_ptr, "base/theme/pointer", cursor))
           goto fallback;
-
-        edje_object_part_swallow(ptr->o_ptr, "e.swallow.hotspot", ptr->o_hot);
+        if (ptr->buffer_o_ptr && (ptr->buffer_o_ptr != ptr->o_ptr))
+          {
+             e_theme_edje_object_set(ptr->buffer_o_ptr, "base/theme/pointer", cursor);
+             edje_object_part_swallow(ptr->buffer_o_ptr, "e.swallow.hotspot", ptr->buffer_o_hot);
+          }
 
         edje_object_part_geometry_get(ptr->o_ptr, "e.swallow.hotspot", 
                                       &x, &y, NULL, NULL);
@@ -394,8 +406,9 @@ _e_pointer_type_set(E_Pointer *ptr, const char *type)
      }
 
 fallback:
-   if ((ptr->evas) && (!ptr->canvas)) _e_pointer_canvas_del(ptr);
+   if (ptr->buffer_evas) _e_pointer_canvas_del(ptr);
 #ifndef HAVE_WAYLAND_ONLY
+   if (!e_comp_util_has_x()) return;
    Ecore_X_Cursor cursor = 0;
 
    if (!strcmp(type, "move"))
@@ -439,7 +452,6 @@ fallback:
    ecore_x_window_cursor_set(ptr->win, cursor);
    if (cursor) ecore_x_cursor_free(cursor);
 #endif
-   return;
 }
 
 EINTERN int 
@@ -510,18 +522,7 @@ e_pointer_canvas_new(Ecore_Evas *ee, Eina_Bool filled)
 
    ptr->ee = ee;
    ptr->evas = ecore_evas_get(ee);
-
-   ptr->o_ptr = edje_object_add(ptr->evas);
-
-   ptr->o_hot = evas_object_rectangle_add(ptr->evas);
-   evas_object_color_set(ptr->o_hot, 0, 0, 0, 0);
-   evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_MOVE, 
-                                  _e_pointer_cb_hot_move, ptr);
-   evas_object_event_callback_add(ptr->o_hot, EVAS_CALLBACK_SHOW, 
-                                  _e_pointer_cb_hot_show, ptr);
-
-   evas_object_move(ptr->o_ptr, 0, 0);
-   evas_object_resize(ptr->o_ptr, ptr->w, ptr->h);
+   _e_pointer_pointer_canvas_init(ptr, ptr->evas, &ptr->o_ptr, &ptr->o_hot);
 
    /* set pointer default type */
    if (filled) e_pointer_type_push(ptr, ptr, "default");
@@ -545,30 +546,31 @@ e_pointers_size_set(int size)
    EINA_LIST_FOREACH(_ptrs, l, ptr)
      {
         if ((ptr->w == size) && (ptr->h == size)) continue;
-        if ((ptr->evas) && (!ptr->canvas))
+        if (ptr->buffer_evas)
           _e_pointer_canvas_resize(ptr, size, size);
-        else if (ptr->canvas)
+        if (ptr->canvas)
           {
              ptr->w = size;
              ptr->h = size;
              evas_object_resize(ptr->o_ptr, size, size);
           }
-
+     }
 #ifndef HAVE_WAYLAND_ONLY
-        ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
+   if (e_comp_util_has_x())
+     ecore_x_cursor_size_set(e_config->cursor_size * 3 / 4);
 #endif
-     }
 }
 
 E_API void 
 e_pointer_hide(E_Pointer *ptr)
 {
-   if ((ptr->evas) && (!ptr->canvas)) 
+   if (ptr->buffer_evas)
      _e_pointer_canvas_del(ptr);
-   else if (ptr->canvas)
+   if (ptr->canvas)
      evas_object_hide(ptr->o_ptr);
 #ifndef HAVE_WAYLAND_ONLY
-   ecore_x_window_cursor_set(ptr->win, 0);
+   if (ptr->win)
+     ecore_x_window_cursor_set(ptr->win, 0);
 #endif
 }
 
@@ -720,16 +722,16 @@ e_pointer_idler_before(void)
 
    EINA_LIST_FOREACH(_ptrs, l, ptr)
      {
-        if ((!ptr->e_cursor) || (!ptr->evas)) continue;
+        if ((!ptr->e_cursor) || (!ptr->buffer_evas)) continue;
 
         if (ptr->hot.update)
           _e_pointer_type_set(ptr, ptr->type);
  
-        if (!ptr->canvas)
+        if (ptr->buffer_evas)
           {
              Eina_List *updates;
 
-             if ((updates = evas_render_updates(ptr->evas)))
+             if ((updates = evas_render_updates(ptr->buffer_evas)))
                {
 #ifndef HAVE_WAYLAND_ONLY
                   Ecore_X_Cursor cur;
index ba38398..8aeed7f 100644 (file)
@@ -29,10 +29,12 @@ struct _E_Pointer
 
    Evas *evas;
    Ecore_Evas *ee;
+   Evas *buffer_evas;
    Evas_Object *o_ptr;
    Evas_Object *o_hot;
+   Evas_Object *buffer_o_ptr;
+   Evas_Object *buffer_o_hot;
 
-//   E_Pixmap *pixmap;
    Ecore_Window win;
 
    int *pixels;