add support for shaped surfaces
authorDana Jansens <danakj@orodu.net>
Wed, 28 May 2003 05:06:32 +0000 (05:06 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 28 May 2003 05:06:32 +0000 (05:06 +0000)
render2/instance.c
render2/instance.h
render2/render.h
render2/surface.c
render2/surface.h

index 97036248946f6ac7987045b6d3860103ca8ba4b3..7d8d3286e17d225c2128957f658e68a2f02c81c6 100644 (file)
@@ -97,6 +97,9 @@ struct RrInstance *RrInstanceNew(Display *display, int screen)
                                      RrVisual(inst), AllocNone);
         inst->glx_context = glXCreateContext(display, &vilist[best],
                                              NULL, True);
+        inst->shape_window = XCreateSimpleWindow(display,
+                                                 RootWindow(display, screen),
+                                                 0, 0, 1, 1, 0, 0, 0);
         inst->surface_map = g_hash_table_new(g_int_hash, g_int_equal);
 
         assert(inst->glx_context);
index c41a96af66d9f8290f719f2dbc4bc5b9df896220..a9b7833e66255438b819a00b38542ae4d8b58cdc 100644 (file)
@@ -14,6 +14,8 @@ struct RrInstance {
     Colormap cmap;
     GLXContext glx_context;
 
+    Window shape_window;
+
     GHashTable *surface_map;
 };
 
@@ -28,6 +30,8 @@ struct RrInstance {
 #define RrColormap(i) ((i)->cmap)
 #define RrContext(i)  ((i)->glx_context)
 
+#define RrShapeWindow(i) ((i)->shape_window)
+
 struct RrSurface;
 
 void RrInstaceAddSurface(struct RrSurface *sur);
index 5e218b8ed1e2f24115458d1aca6a65e076a9d49f..53599d7e1dfa794c64026951ce6c2727cde820cf 100644 (file)
@@ -125,7 +125,19 @@ void RrSurfaceShow(struct RrSurface *sur);
 void RrSurfaceHide(struct RrSurface *sur);
 int RrSurfaceVisible(struct RrSurface *sur);
 
-void RrSurfaceMinSize(struct RrSurface *sur, int *w, int *h);
+void RrSurfaceMinSize(struct RrSurface *sur,
+                      int *w,
+                      int *h);
+
+void RrSurfaceShape(struct RrSurface *sur);
+
+/*! Set the base shape for a surface. To clear the base, pass 0 for all
+  of the arguments (except for the surface of course!)
+*/
+void RrSurfaceShapeSetBase(struct RrSurface *sur,
+                           Window base,
+                           int x,
+                           int y);
 
 /* planar surfaces */
 
index b4e03370b42e2149d3d556129e3c98640e7cc939..4afb35f264feab698d482ee2084067dbcd3bbd22 100644 (file)
@@ -3,6 +3,9 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef    SHAPE
+#include <X11/extensions/shape.h>
+#endif
 
 /* doesn't set win or parent */
 static struct RrSurface *surface_new(enum RrSurfaceType type,
@@ -12,6 +15,9 @@ static struct RrSurface *surface_new(enum RrSurfaceType type,
 
     sur = malloc(sizeof(struct RrSurface));
     sur->type = type;
+    sur->shape_base = None;
+    sur->shape_base_x = 0;
+    sur->shape_base_y = 0;
     sur->ntextures = numtex;
     if (numtex) {
         sur->texture = malloc(sizeof(struct RrTexture) * numtex);
@@ -277,5 +283,54 @@ void RrSurfaceHide(struct RrSurface *sur)
 
 int RrSurfaceVisible(struct RrSurface *sur)
 {
+    assert(sur->inst);
     return sur->visible;
 }
+
+void RrSurfaceShapeSetBase(struct RrSurface *sur, Window base, int x, int y)
+{
+    assert(sur->inst);
+    sur->shape_base = base;
+    sur->shape_base_x = x;
+    sur->shape_base_y = y;
+}
+
+void RrSurfaceShape(struct RrSurface *sur)
+{
+    GSList *it;
+
+    assert(sur->inst);
+
+#ifdef SHAPE
+    XResizeWindow(RrDisplay(sur->inst), RrShapeWindow(sur->inst),
+                  sur->w, sur->h);
+    XShapeCombineShape(RrDisplay(sur->inst), RrShapeWindow(sur->inst),
+                       ShapeBounding,
+                       sur->shape_base_x, sur->shape_base_y,
+                       sur->shape_base, ShapeBounding, ShapeSet);
+    /* include the shape of the children */
+    for (it = sur->children; it; it = g_slist_next(it)) {
+        struct RrSurface *ch = it->data;
+        if (ch->win)
+            XShapeCombineShape(RrDisplay(sur->inst),
+                               RrShapeWindow(sur->inst),
+                               ShapeBounding, ch->x, ch->y, ch->win,
+                               ShapeBounding, ShapeUnion);
+    }
+    switch (sur->type) {
+    case RR_SURFACE_NONE:
+        break;
+    case RR_SURFACE_PLANAR:
+        /* XXX shape me based on something! an alpha mask? */
+        break;
+    case RR_SURFACE_NONPLANAR:
+        /* XXX shape me based on my GL form! */
+        assert(0);
+        break;
+    }
+
+    /* apply the final shape */
+    XShapeCombineShape(RrDisplay(sur->inst), sur->win, ShapeBounding, 0, 0,
+                       RrShapeWindow(sur->inst), ShapeBounding, ShapeSet);
+#endif
+}
index d3bc9a4fc13f81d02eb9c4567786e7b962cbdcd9..39dbffc2d3731f9e3b2c9d22f10329c6cd1bc1eb 100644 (file)
@@ -29,6 +29,10 @@ struct RrSurface {
     */
     Window win; /* XXX this can optionally be None if parent != NULL ... */
 
+    Window shape_base;
+    int shape_base_x;
+    int shape_base_y;
+
     int ntextures;
     struct RrTexture *texture;