discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=2b38147c43270815ef71726d8700703968429d90

commit 2b38147c43270815ef71726d8700703968429d90
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Thu Jun 25 19:55:37 2015 -0400

    add hooking for WL_SURFACE_ID atom on XWayland windows and composite them
    
    in order to maximize the amount of reused code the following details the 
current
    process for xwayland compositing:
    
    * get map request from window
    * force reparenting
    * show window
    * await WL_SURFACE_ID x11 message
    * move x11 client data + pixmap onto corresponding wayland client
    * business as usual with wayland compositing
    
    this is pretty similar to the method of the reference code in weston,
    except that there's no x11 compositor in weston
---
 src/bin/e_comp_wl.c |  21 ++++++++--
 src/bin/e_comp_wl.h |  34 ++++++++++++++-
 src/bin/e_comp_x.c  | 119 +++++++++++++++++++++++++++++++++++++++++++++-------
 src/bin/e_comp_x.h  |   8 +++-
 4 files changed, 161 insertions(+), 21 deletions(-)

diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 101e62b..6c77a1a 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -40,7 +40,7 @@ _e_comp_wl_focus_check(void)
 
    if (stopping) return;
    ec = e_client_focused_get();
-   if ((!ec) || (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL))
+   if ((!ec) || e_pixmap_is_x(ec->pixmap))
      e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE);
 }
 
@@ -1442,7 +1442,8 @@ static void
 _e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct 
wl_resource *resource, uint32_t id)
 {
    struct wl_resource *res;
-   E_Client *ec = NULL;
+   E_Client *wc, *ec = NULL;
+   Eina_List *l;
    pid_t pid;
 
    DBG("Compositor Cb Surface Create: %d", id);
@@ -1491,7 +1492,15 @@ _e_comp_wl_compositor_cb_surface_create(struct wl_client 
*client, struct wl_reso
 
    /* set reference to pixmap so we can fetch it later */
    wl_resource_set_user_data(res, ec);
-
+#ifndef HAVE_WAYLAND_ONLY
+   EINA_LIST_FOREACH(e_comp->wl_comp_data->xwl_pending, l, wc)
+     {
+        if (!e_pixmap_is_x(wc->pixmap)) continue;
+        if (wl_resource_get_id(res) != 
((E_Comp_X_Client_Data*)ec->comp_data)->surface_id) continue;
+        e_comp_x_xwayland_client_setup(wc, ec);
+        break;
+     }
+#endif
    /* emit surface create signal */
    wl_signal_emit(&e_comp->wl_comp_data->signals.surface.create, res);
 }
@@ -2964,3 +2973,9 @@ e_comp_wl_output_remove(const char *id)
         /* free(output); */
      }
 }
+
+EINTERN void
+e_comp_wl_xwayland_client_queue(E_Client *ec)
+{
+   e_comp->wl_comp_data->xwl_pending = 
eina_list_append(e_comp->wl_comp_data->xwl_pending, ec);
+}
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index c20aa24..f0bc175 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -1,5 +1,7 @@
 #ifdef E_TYPEDEFS
-
+#  ifndef HAVE_WAYLAND_ONLY
+#   include "e_comp_x.h"
+#  endif
 #else
 # ifndef E_COMP_WL_H
 #  define E_COMP_WL_H
@@ -13,6 +15,10 @@
 
 #  include <xkbcommon/xkbcommon.h>
 
+#  ifndef HAVE_WAYLAND_ONLY
+#   include "e_comp_x.h"
+#  endif
+
 /* #  ifdef HAVE_WAYLAND_EGL */
 /* #   include <EGL/egl.h> */
 /* #   define GL_GLEXT_PROTOTYPES */
@@ -211,6 +217,7 @@ struct _E_Comp_Wl_Data
    Ecore_Idler *idler;
 
    struct wl_client *xwl_client;
+   Eina_List *xwl_pending;
 
    /* Eina_List *retry_clients; */
    /* Ecore_Timer *retry_timer; */
@@ -254,6 +261,10 @@ struct _E_Comp_Wl_Client_Data
      {
         int32_t x, y;
      } popup;
+#ifndef HAVE_WAYLAND_ONLY
+   E_Pixmap *xwayland_pixmap;
+   E_Comp_X_Client_Data *xwayland_data;
+#endif
 
    Eina_Bool keep_buffer : 1;
    Eina_Bool mapped : 1;
@@ -294,6 +305,27 @@ E_API struct wl_signal 
e_comp_wl_surface_create_signal_get(void);
 E_API double e_comp_wl_idle_time_get(void);
 E_API Eina_Bool e_comp_wl_output_init(const char *id, const char *make, const 
char *model, int x, int y, int w, int h, int pw, int ph, unsigned int refresh, 
unsigned int subpixel, unsigned int transform);
 E_API void e_comp_wl_output_remove(const char *id);
+# ifndef HAVE_WAYLAND_ONLY
+EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec);
+static inline E_Comp_X_Client_Data *
+e_comp_wl_client_xwayland_data(const E_Client *ec)
+{
+   return ec->comp_data ? 
((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_data : NULL;
+}
+
+static inline E_Pixmap *
+e_comp_wl_client_xwayland_pixmap(const E_Client *ec)
+{
+   return ((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_pixmap;
+}
 
+static inline void
+e_comp_wl_client_xwayland_setup(E_Client *ec, E_Comp_X_Client_Data *cd, 
E_Pixmap *ep)
+{
+   ((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_data = cd;
+   ((E_Comp_Wl_Client_Data*)ec->comp_data)->xwayland_pixmap = ep;
+   e_comp->wl_comp_data->xwl_pending = 
eina_list_remove(e_comp->wl_comp_data->xwl_pending, ec);
+}
+#  endif
 # endif
 #endif
diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index 077b2a8..4e918f2 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -57,6 +57,8 @@ static Eina_Bool screensaver_dimmed = EINA_FALSE;
 static Ecore_X_Atom backlight_atom = 0;
 extern double e_bl_val;
 
+static void _e_comp_x_hook_client_pre_frame_assign(void *d EINA_UNUSED, 
E_Client *ec);
+
 static Eina_Bool
 _e_comp_x_flusher(void *data EINA_UNUSED)
 {
@@ -1142,6 +1144,15 @@ _e_comp_x_show_request(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Eve
         ecore_x_window_show(ev->win);
         return ECORE_CALLBACK_RENEW;
      }
+   if ((e_comp->comp_type != E_PIXMAP_TYPE_X) && ec->ignored)
+     {
+        ec->visible = 1;
+        if (ec->comp_data->need_reparent)
+          _e_comp_x_hook_client_pre_frame_assign(NULL, ec);
+        else
+          ecore_x_window_show(ev->win);
+        return ECORE_CALLBACK_RENEW;
+     }
 
    if ((!ec->comp_data->reparented) && (!e_client_util_ignored_get(ec)))
      {
@@ -1395,7 +1406,7 @@ _e_comp_x_configure(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_
    EINA_RECTANGLE_SET(&ec->client, ev->x, ev->y, ev->w, ev->h);
    if (move)
      evas_object_move(ec->frame, ev->x, ev->y);
-   if (resize)
+   if (resize && e_pixmap_is_x(ec->pixmap))
      {
         e_pixmap_dirty(ec->pixmap);
         evas_object_resize(ec->frame, ev->w, ev->h);
@@ -1993,6 +2004,25 @@ _e_comp_x_message(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_Cl
              break;
           }
      }
+#ifdef HAVE_WAYLAND
+   else if (ev->message_type == WL_SURFACE_ID)
+     {
+        void *res;
+        E_Client *wc = NULL;
+
+        if (e_comp->comp_type != E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_RENEW;
+        res = wl_client_get_object(e_comp->wl_comp_data->xwl_client, 
ev->data.l[0]);
+        if (res)
+          wc = wl_resource_get_user_data(res);
+        if (wc)
+          e_comp_x_xwayland_client_setup(ec, wc);
+        else
+          {
+             ec->comp_data->surface_id = ev->data.l[0];
+             e_comp_wl_xwayland_client_queue(ec);
+          }
+     }
+#endif
    return ECORE_CALLBACK_PASS_ON;
 }
 
@@ -2737,7 +2767,10 @@ _e_comp_x_hook_client_pre_frame_assign(void *d 
EINA_UNUSED, E_Client *ec)
                             ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
                             0, 0, 0, 0, 0,
                             win, ECORE_X_WINDOW_STACK_ABOVE);
-   ecore_x_event_mask_set(pwin, ECORE_X_EVENT_MASK_MOUSE_IN | 
ECORE_X_EVENT_MASK_MOUSE_OUT);
+   ecore_x_event_mask_set(pwin, ECORE_X_EVENT_MASK_KEY_DOWN | 
ECORE_X_EVENT_MASK_KEY_UP |
+                                ECORE_X_EVENT_MASK_MOUSE_MOVE | 
ECORE_X_EVENT_MASK_MOUSE_DOWN |
+                                ECORE_X_EVENT_MASK_MOUSE_UP | 
ECORE_X_EVENT_MASK_MOUSE_WHEEL |
+                                ECORE_X_EVENT_MASK_MOUSE_IN | 
ECORE_X_EVENT_MASK_MOUSE_OUT);
    ecore_x_window_border_width_set(win, 0);
    ec->border_size = 0;
 
@@ -4090,6 +4123,7 @@ _e_comp_x_hook_client_new(void *d EINA_UNUSED, E_Client 
*ec)
    ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NONE;
 
    if (!_e_comp_x_client_new_helper(ec)) return;
+   ec->ignored |= e_comp->comp_type == E_PIXMAP_TYPE_WL;
 
    ec->comp_data->first_damage = ec->internal;
 
@@ -4561,16 +4595,19 @@ _e_comp_x_randr_change(void *data EINA_UNUSED, int 
ev_type EINA_UNUSED, void *ev
    if ((e_comp->w != e_randr2->w) ||
        (e_comp->h != e_randr2->h))
      {
-        e_comp_canvas_resize(e_randr2->w, e_randr2->h);
+        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
+          e_comp_canvas_resize(e_randr2->w, e_randr2->h);
      }
    else
      {
         E_Client *ec;
 
         ecore_x_netwm_desk_size_set(e_comp->root, e_comp->w, e_comp->h);
-        e_randr2_screens_setup(e_comp->w, e_comp->h);
+        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
+          e_randr2_screens_setup(e_comp->w, e_comp->h);
 
-        e_comp_canvas_update();
+        if (e_comp->comp_type == E_PIXMAP_TYPE_X)
+          e_comp_canvas_update();
         E_CLIENT_FOREACH(ec)
           {
              if (!e_client_util_ignored_get(ec))
@@ -4891,6 +4928,7 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
    e_hints_init(root, e_comp->cm_selection);
    ecore_x_window_background_color_set(root, 0, 0, 0);
    ecore_x_screen_is_composited_set(0, e_comp->cm_selection);
+   ecore_x_selection_owner_set(e_comp->cm_selection, 
ecore_x_atom_get("WM_S0"), ecore_x_current_time_get());
 
    e_comp->win = ecore_x_composite_render_window_enable(root);
    if (!e_comp->win)
@@ -4937,7 +4975,10 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
    e_comp->bindings_grab_cb = _e_comp_x_bindings_grab_cb;
    e_comp->bindings_ungrab_cb = _e_comp_x_bindings_ungrab_cb;
 
-   if (!e_comp_canvas_init(w, h)) return EINA_FALSE;
+   if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
+     {
+        if (!e_comp_canvas_init(w, h)) return EINA_FALSE;
+     }
 
    e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE);
 
@@ -4959,6 +5000,7 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
         ec->lock_client_stacking = 1;
         ec->internal = 1;
         ec->visible = 1;
+        evas_object_del(e_comp->layers[i].obj);
         e_comp->layers[i].obj = ec->frame;
         evas_object_layer_set(ec->frame, e_comp_canvas_layer_map_to(i));
         evas_object_pass_events_set(ec->frame, 1);
@@ -4968,11 +5010,14 @@ _e_comp_x_setup(Ecore_X_Window root, int w, int h)
      ecore_x_window_lower(e_comp->layers[i].win);
 
    ecore_evas_lower(e_comp->ee);
-   e_comp->pointer = e_pointer_window_new(e_comp->root, 0);
-   e_comp->pointer->color = ecore_x_cursor_color_supported_get();
-   e_pointer_type_push(e_comp->pointer, e_comp->pointer, "default");
+   if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
+     {
+        e_comp->pointer = e_pointer_window_new(e_comp->root, 0);
+        e_comp->pointer->color = ecore_x_cursor_color_supported_get();
+        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);
+     }
    _e_comp_x_manage_windows();
-   ecore_x_icccm_state_set(ecore_evas_window_get(e_comp->ee), 
ECORE_X_WINDOW_STATE_HINT_NORMAL);
 
    {
       E_Client *ec;
@@ -4994,8 +5039,11 @@ _e_comp_x_screens_setup(void)
    Ecore_X_Window root;
    int rw, rh;
 
-   e_comp_x_randr_screen_iface_set();
-   if (!e_randr2_init()) return 0;
+   if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
+     {
+        e_comp_x_randr_screen_iface_set();
+        if (!e_randr2_init()) return 0;
+     }
    root = ecore_x_window_root_first_get();
    if (!root)
      {
@@ -5003,11 +5051,12 @@ _e_comp_x_screens_setup(void)
         return 0;
      }
    ecore_x_window_size_get(root, &rw, &rh);
-   e_randr2_screens_setup(rw, rh);
+   if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
+     e_randr2_screens_setup(rw, rh);
    return _e_comp_x_setup(root, rw, rh);
 }
 
-EINTERN Eina_Bool
+E_API Eina_Bool
 e_comp_x_init(void)
 {
    if (!ecore_x_init(NULL))
@@ -5143,7 +5192,7 @@ e_comp_x_init(void)
    return EINA_TRUE;
 }
 
-EINTERN void
+E_API void
 e_comp_x_shutdown(void)
 {
    E_FREE_LIST(handlers, ecore_event_handler_del);
@@ -5170,3 +5219,43 @@ e_comp_x_nocomp_end(void)
    ecore_x_composite_redirect_subwindows(e_comp->root, 
ECORE_X_COMPOSITE_UPDATE_MANUAL);
    _e_comp_x_focus_check();
 }
+
+#ifdef HAVE_WAYLAND
+EINTERN void
+e_comp_x_xwayland_client_setup(E_Client *ec, E_Client *wc)
+{
+   Ecore_X_Window win;
+   E_Comp_X_Client_Data *cd;
+
+   win = e_client_util_win_get(ec);
+   cd = ec->comp_data;
+   e_comp_wl_client_xwayland_setup(wc, cd, e_pixmap_ref(ec->pixmap));
+   eina_hash_del(damages_hash, &cd->damage, ec);
+   ecore_x_damage_free(cd->damage);
+   E_FREE_FUNC(cd->first_draw_delay, ecore_timer_del);
+   cd->damage = 0;
+   ec->comp_data = NULL;
+   cd->evas_init = 0;
+   _e_comp_x_client_evas_init(wc);
+   wc->borderless = ec->borderless;
+   wc->border.changed = 1;
+   EC_CHANGED(wc);
+   wc->depth = ec->depth;
+   wc->override = ec->override;
+   wc->placed = ec->placed;
+   wc->input_only = ec->input_only;
+   wc->border_size = ec->border_size;
+   memcpy(&wc->icccm, &ec->icccm, sizeof(ec->icccm));
+   memcpy(&wc->netwm, &ec->netwm, sizeof(ec->netwm));
+   memcpy(&wc->e, &ec->e, sizeof(ec->e));
+   ec->new_client = 1;
+   e_comp->new_clients++;
+
+   eina_hash_set(clients_win_hash, &win, wc);
+   wc->visible = 1;
+   evas_object_show(wc->frame);
+   e_object_del(E_OBJECT(ec));
+   e_hints_window_visible_set(wc);
+   _e_comp_x_client_stack(wc);
+}
+#endif
diff --git a/src/bin/e_comp_x.h b/src/bin/e_comp_x.h
index b392d65..1be3d46 100644
--- a/src/bin/e_comp_x.h
+++ b/src/bin/e_comp_x.h
@@ -87,6 +87,9 @@ struct _E_Comp_X_Client_Data
          Ecore_X_Illume_Window_State state;
       } win_state;
    } illume;
+#ifdef HAVE_WAYLAND
+   uint32_t surface_id;
+#endif
 
    Eina_Bool moving : 1;
    Eina_Bool first_map : 1;
@@ -102,10 +105,11 @@ struct _E_Comp_X_Client_Data
    Eina_Bool unredirected_single : 1;
 };
 
-EINTERN Eina_Bool e_comp_x_init(void);
-EINTERN void e_comp_x_shutdown(void);
+E_API Eina_Bool e_comp_x_init(void);
+E_API void e_comp_x_shutdown(void);
 
 E_API void e_alert_composite_win(Ecore_X_Window root, Ecore_X_Window win);
 EINTERN void e_comp_x_nocomp_end(void);
+EINTERN void e_comp_x_xwayland_client_setup(E_Client *ec, E_Client *wc);
 # endif
 #endif

-- 


Reply via email to