7 #include <X11/extensions/shape.h>
10 /* doesn't set win or parent */
11 static struct RrSurface *surface_new(enum RrSurfaceType type,
14 struct RrSurface *sur;
16 sur = malloc(sizeof(struct RrSurface));
18 sur->shape_base = None;
19 sur->shape_base_x = 0;
20 sur->shape_base_y = 0;
21 sur->ntextures = numtex;
23 sur->texture = malloc(sizeof(struct RrTexture) * numtex);
24 memset(sur->texture, 0, sizeof(struct RrTexture) * numtex);
36 static Window create_window(struct RrInstance *inst, Window parent)
38 XSetWindowAttributes attrib;
41 attrib.event_mask = ExposureMask;
42 win = XCreateWindow(RrDisplay(inst), parent, 0, 0, 1, 1, 0,
43 RrDepth(inst), InputOutput, RrVisual(inst),
44 CWEventMask, &attrib);
48 struct RrSurface *RrSurfaceNewProto(enum RrSurfaceType type,
51 struct RrSurface *sur;
53 sur = surface_new(type, numtex);
61 struct RrSurface *RrSurfaceNew(struct RrInstance *inst,
62 enum RrSurfaceType type,
66 struct RrSurface *sur;
68 sur = surface_new(type, numtex);
74 RrInstaceAddSurface(sur);
78 struct RrSurface *RrSurfaceNewChild(enum RrSurfaceType type,
79 struct RrSurface *parent,
82 struct RrSurface *sur;
84 /* can't be a child of a prototype! */
86 if (!parent->inst) return NULL;
88 sur = surface_new(type, numtex);
89 sur->inst = parent->inst;
90 sur->win = create_window(sur->inst, parent->win);
94 parent->children = g_slist_append(parent->children, sur);
96 RrInstaceAddSurface(sur);
100 void RrSurfaceCopy(struct RrSurface *dest, struct RrSurface *src)
102 dest->type = src->type;
103 switch (dest->type) {
104 case RR_SURFACE_PLANAR:
105 dest->data = src->data;
107 case RR_SURFACE_NONPLANAR:
110 case RR_SURFACE_NONE:
114 dest->ntextures = src->ntextures;
115 dest->texture = malloc(sizeof(struct RrTexture) * dest->ntextures);
116 memcpy(dest->texture, src->texture,
117 sizeof(struct RrTexture) * dest->ntextures);
120 void RrSurfaceFree(struct RrSurface *sur)
125 sur->parent->children = g_slist_remove(sur->parent->children, sur);
127 RrInstaceRemoveSurface(sur);
128 for (i = 0; i < sur->ntextures; ++i)
129 RrTextureFreeContents(&sur->texture[i]);
132 if (sur->parent && sur->win)
133 XDestroyWindow(RrDisplay(sur->inst), sur->win);
138 void RrSurfaceSetPos(struct RrSurface *sur,
142 RrSurfaceSetArea(sur, x, y, sur->w, sur->h);
145 void RrSurfaceSetSize(struct RrSurface *sur,
149 RrSurfaceSetArea(sur, sur->x, sur->y, w, h);
152 void RrSurfaceSetArea(struct RrSurface *sur,
160 assert(w > 0 && h > 0);
161 if (!(w > 0 && h > 0)) return;
163 m = sur->x != x || sur->y != y;
164 r = sur->w != w || sur->h != h;
172 XMoveResizeWindow(RrDisplay(sur->inst), sur->win, x, y, w, h);
174 XMoveWindow(RrDisplay(sur->inst), sur->win, x, y);
176 XResizeWindow(RrDisplay(sur->inst), sur->win, w, h);
180 Window RrSurfaceWindow(struct RrSurface *sur)
182 /* can't get a window for a prototype */
184 if (!sur->inst) return None;
189 struct RrTexture *RrSurfaceTexture(struct RrSurface *sur, int texnum)
191 assert(texnum < sur->ntextures);
192 return &(sur->texture[texnum]);
195 void RrSurfaceMinSize(struct RrSurface *sur, int *w, int *h)
201 case RR_SURFACE_NONE:
204 case RR_SURFACE_PLANAR:
205 RrPlanarMinSize(sur, w, h);
207 case RR_SURFACE_NONPLANAR:
213 for (i = 0; i < sur->ntextures; ++i) {
214 switch (sur->texture[i].type) {
215 case RR_TEXTURE_NONE:
219 case RR_TEXTURE_TEXT:
222 RrFontMeasureString(sur->texture[i].data.text.font,
223 sur->texture[i].data.text.string));
224 minh = MAX(minh, RrFontHeight(sur->texture[i].data.text.font));
226 case RR_TEXTURE_RGBA:
227 minw = MAX(minw, (sur->texture[i].data.rgba.x +
228 sur->texture[i].data.rgba.w));
229 minh = MAX(minw, (sur->texture[i].data.rgba.y +
230 sur->texture[i].data.rgba.h));
242 void RrSurfaceShow(struct RrSurface *sur)
246 XMapWindow(RrDisplay(sur->inst), sur->win);
249 void RrSurfaceHide(struct RrSurface *sur)
253 XUnmapWindow(RrDisplay(sur->inst), sur->win);
256 int RrSurfaceVisible(struct RrSurface *sur)
262 void RrSurfaceShapeSetBase(struct RrSurface *sur, Window base, int x, int y)
265 sur->shape_base = base;
266 sur->shape_base_x = x;
267 sur->shape_base_y = y;
270 void RrSurfaceShape(struct RrSurface *sur)
277 XResizeWindow(RrDisplay(sur->inst), RrShapeWindow(sur->inst),
279 XShapeCombineShape(RrDisplay(sur->inst), RrShapeWindow(sur->inst),
281 sur->shape_base_x, sur->shape_base_y,
282 sur->shape_base, ShapeBounding, ShapeSet);
283 /* include the shape of the children */
284 for (it = sur->children; it; it = g_slist_next(it)) {
285 struct RrSurface *ch = it->data;
287 XShapeCombineShape(RrDisplay(sur->inst),
288 RrShapeWindow(sur->inst),
289 ShapeBounding, ch->x, ch->y, ch->win,
290 ShapeBounding, ShapeUnion);
293 case RR_SURFACE_NONE:
295 case RR_SURFACE_PLANAR:
296 /* XXX shape me based on something! an alpha mask? */
298 case RR_SURFACE_NONPLANAR:
299 /* XXX shape me based on my GL form! */
304 /* apply the final shape */
305 XShapeCombineShape(RrDisplay(sur->inst), sur->win, ShapeBounding, 0, 0,
306 RrShapeWindow(sur->inst), ShapeBounding, ShapeSet);