summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiago Vignatti <tiago.vignatti@intel.com>2012-12-19 15:29:14 -0200
committerTiago Vignatti <tiago.vignatti@intel.com>2012-12-28 14:26:32 -0200
commit9c5153e02f379238a203e27acf8a74735906e16f (patch)
tree7a0dab23728dcfa72b7d1b0aa0635ecda7145797
parent34a86fc44fb78ecce0e291a79ad964475a5b000f (diff)
xwayland: Fix opaque and input region settings
This patch brings back a feature we removed previously (#1 opaque region box) and fix the input region settings, which was broken. Tested-by: Scott Moreau <oreaus@gmail.com> Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
-rw-r--r--clients/xwm.c56
-rw-r--r--protocol/xserver.xml24
-rw-r--r--src/xwayland/window-manager.c49
3 files changed, 98 insertions, 31 deletions
diff --git a/clients/xwm.c b/clients/xwm.c
index 58e16f7..0805991 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 e92b0e6..dc9c0a3 100644
--- a/protocol/xserver.xml
+++ b/protocol/xserver.xml
@@ -130,6 +130,30 @@
<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 19f1309..eb27228 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;