This patch brings back a feature we removed previously (#1 opaque region box)
and fix the input region settings, which was broken.

Signed-off-by: Tiago Vignatti <[email protected]>
---
 clients/xwm.c                 |   56 ++++++++++++++++++-----------------------
 protocol/xserver.xml          |   24 ++++++++++++++++++
 src/xwayland/window-manager.c |   49 ++++++++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 31 deletions(-)

diff --git a/clients/xwm.c b/clients/xwm.c
index a4ab816..49e992b 100644
--- a/clients/xwm.c
+++ b/clients/xwm.c
@@ -39,6 +39,7 @@
 struct xwm {
        struct wl_registry *registry;
        struct wl_display *wl_display;
+       struct wl_compositor *compositor;
        struct wm *wm;
        struct wm_xwin *wm_xwin;
        struct display *display;
@@ -793,20 +794,18 @@ xwm_window_draw_decoration(struct xwm_window *window)
 {
        struct xwm_wm *wm = window->wm;
        struct theme *t = wm->theme;
+       struct wl_region *region;
        cairo_t *cr;
        int x, y, width, height;
        const char *title;
        uint32_t flags = 0;
 
        if (window->frame_id == XCB_WINDOW_NONE) {
-#if 0
-               if (window->surface != NULL) {
-                       window->surface->opaque_rect[0] = 0.0;
-                       window->surface->opaque_rect[1] = 1.0;
-                       window->surface->opaque_rect[2] = 0.0;
-                       window->surface->opaque_rect[3] = 1.0;
-               }
-#endif
+               xwm_window_get_frame_size(window, &width, &height);
+               region = wl_compositor_create_region(wm->xwm->compositor);
+               wl_region_add(region, 0, 0, width, height);
+               wm_xwin_set_opaque_override(window->xwin, region);
+               wl_region_destroy(region);
                return;
        }
 
@@ -840,28 +839,20 @@ xwm_window_draw_decoration(struct xwm_window *window)
        xcb_flush(window->wm->conn);
 
        cairo_destroy(cr);
-#if 0
-       if (window->surface) {
-               pixman_region32_fini(&window->surface->pending.opaque);
-               pixman_region32_init_rect(&window->surface->pending.opaque, 0, 
0,
-                                         width, height);
-
-               /* We leave an extra pixel around the X window area to
-                * make sure we don't sample from the undefined alpha
-                * channel when filtering. */
-               pixman_region32_intersect_rect(&window->surface->pending.opaque,
-                                              &window->surface->pending.opaque,
-                                              x - 1, y - 1,
-                                              window->width + 2,
-                                              window->height + 2);
-               window->surface->geometry.dirty = 1;
-
-               pixman_region32_init_rect(&window->surface->input,
-                                         t->margin, t->margin,
-                                         width - 2 * t->margin,
-                                         height - 2 * t->margin);
-       }
-#endif
+
+       region = wl_compositor_create_region(wm->xwm->compositor);
+       /* We leave an extra pixel around the X window area to make sure we
+        * don't sample from the undefined alpha channel when filtering. */
+       wl_region_add(region, x - 1, y - 1,
+                     window->width + 2, window->height + 2);
+       wm_xwin_set_opaque_override(window->xwin_frame, region);
+       wl_region_destroy(region);
+
+       region = wl_compositor_create_region(wm->xwm->compositor);
+       wl_region_add(region, t->margin, t->margin,
+                     width - 2 * t->margin, height - 2 * t->margin);
+       wm_xwin_set_input_region(window->xwin_frame, region);
+       wl_region_destroy(region);
 }
 
 static void
@@ -1594,7 +1585,10 @@ registry_handle_global(void *data, struct wl_registry 
*registry, uint32_t id,
 {
        struct xwm *xwm = data;
 
-       if (!strcmp(interface, "wm")) {
+       if (strcmp(interface, "wl_compositor") == 0) {
+               xwm->compositor = wl_registry_bind(registry, id,
+                                       &wl_compositor_interface, 1);
+       } else if (!strcmp(interface, "wm")) {
                xwm->wm = wl_registry_bind(registry, id,
                                        &wm_interface, 1);
                wm_add_listener(xwm->wm, &wm_listener, xwm);
diff --git a/protocol/xserver.xml b/protocol/xserver.xml
index a5dbebd..05f771f 100644
--- a/protocol/xserver.xml
+++ b/protocol/xserver.xml
@@ -129,6 +129,30 @@
       <arg name="height" type="int"/>
       <arg name="flags" type="uint"/>
     </request>
+
+    <request name="set_opaque_override">
+      <description summary="set opaque override region">
+       Textures coming from X windows usually have their X window as RGBx,
+       i.e. 32 bit with an undefined alpha channel for the content part while
+       the decorations are rendered with a well-defined alpha channel. On
+       this case set_opaque_override is needed for marking a rectangle in a
+       texture and force the alpha = 1.0.
+
+       This is different from the wl_surface.set_opaque_region, where that
+       one is meant only as a hint for optimization while this is a necessity
+       for painting XWayland windows right. Therefore X must never use
+       wl_surface.set_opaque_region either.
+      </description>
+
+      <arg name="region" type="object" interface="wl_region"/>
+    </request>
+
+    <request name="set_input_region">
+      <description summary="set window input region">
+      </description>
+
+      <arg name="region" type="object" interface="wl_region" 
allow-null="true"/>
+    </request>
  
     <request name="move">
     </request>
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 7fb7379..00d6175 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -156,6 +156,52 @@ wm_xwin_handle_set_window(struct wl_client *client,
 }
 
 static void
+wm_xwin_handle_opaque_override(struct wl_client *client,
+                              struct wl_resource *resource,
+                              struct wl_resource *region_resource)
+{
+       struct xserver_window *window = resource->data;
+       struct weston_surface *surface =
+               (struct weston_surface *) window->surface;
+       struct weston_region *region;
+
+       if (!region_resource) {
+               weston_log("Region resource not provided\n");
+               return;
+       }
+       region = region_resource->data;
+
+       if (!surface)
+               return;
+
+       pixman_region32_copy(&surface->pending.opaque, &region->region);
+       surface->geometry.dirty = 1;
+}
+
+static void
+wm_xwin_handle_input_region(struct wl_client *client,
+                           struct wl_resource *resource,
+                           struct wl_resource *region_resource)
+{
+       struct xserver_window *window = resource->data;
+       struct weston_surface *surface =
+               (struct weston_surface *) window->surface;
+       struct weston_region *region;
+
+       if (!region_resource) {
+               weston_log("Region resource not provided\n");
+               return;
+       }
+       region = region_resource->data;
+
+       if (!surface)
+               return;
+
+       pixman_region32_copy(&surface->pending.input, &region->region);
+       surface->geometry.dirty = 1;
+}
+
+static void
 wm_xwin_handle_move(struct wl_client *client, struct wl_resource *resource)
 {
        struct xserver_window *window = resource->data;
@@ -207,6 +253,8 @@ wm_xwin_handle_destroy(struct wl_client *client, struct 
wl_resource *resource)
 const struct wm_xwin_interface wm_xwin_implementation = {
        wm_xwin_handle_map,
        wm_xwin_handle_set_window,
+       wm_xwin_handle_opaque_override,
+       wm_xwin_handle_input_region,
        wm_xwin_handle_move,
        wm_xwin_handle_resize,
        wm_xwin_handle_destroy
@@ -287,6 +335,7 @@ wm_handle_create_xwindow(struct wl_client *client,
                 return;
        }
 
+       window->surface = NULL;
        window->shsurf = NULL;
        window->wxs = wxs;
        window->xid = xid;
-- 
1.7.9.5

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to