]> icculus.org git repositories - dana/openbox.git/blob - render2/surface.c
add ability to set a texture to None
[dana/openbox.git] / render2 / surface.c
1 #include "surface.h"
2 #include "instance.h"
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 /* doesn't set win or parent */
8 static struct RrSurface *surface_new(enum RrSurfaceType type,
9                                      int numtex)
10 {
11     struct RrSurface *sur;
12
13     sur = malloc(sizeof(struct RrSurface));
14     sur->type = type;
15     sur->ntextures = numtex;
16     if (numtex) {
17         sur->texture = malloc(sizeof(struct RrTexture) * numtex);
18         memset(sur->texture, 0, sizeof(struct RrTexture) * numtex);
19     } else
20         sur->texture = NULL;
21     sur->x = 0;
22     sur->y = 0;
23     sur->w = 1;
24     sur->h = 1;
25     sur->visible = 0;
26     return sur;
27 }
28
29 static Window create_window(struct RrInstance *inst, Window parent)
30 {
31     Window win = XCreateWindow(RrDisplay(inst), parent, 0, 0, 1, 1, 0,
32                                RrDepth(inst), InputOutput, RrVisual(inst),
33                                0, NULL);
34     return win;
35 }
36
37 struct RrSurface *RrSurfaceNewProto(enum RrSurfaceType type,
38                                     int numtex)
39 {
40     struct RrSurface *sur;
41
42     sur = surface_new(type, numtex);
43     sur->inst = NULL;
44     sur->win = None;
45     sur->parent = NULL;
46     sur->visible = 0;
47     return sur;
48 }
49
50 struct RrSurface *RrSurfaceNew(struct RrInstance *inst,
51                                enum RrSurfaceType type,
52                                Window win,
53                                int numtex)
54 {
55     struct RrSurface *sur;
56
57     sur = surface_new(type, numtex);
58     sur->inst = inst;
59     sur->win = win;
60     sur->parent = NULL;
61     sur->visible = 0;
62     return sur;
63 }
64
65 struct RrSurface *RrSurfaceNewChild(enum RrSurfaceType type,
66                                     struct RrSurface *parent,
67                                     int numtex)
68 {
69     struct RrSurface *sur;
70
71     /* can't be a child of a prototype! */
72     assert(parent->inst);
73     if (!parent->inst) return NULL;
74
75     sur = surface_new(type, numtex);
76     sur->inst = parent->inst;
77     sur->win = create_window(sur->inst, parent->win);
78     sur->parent = parent;
79     RrSurfaceShow(sur);
80     return sur;
81 }
82
83 /* doesn't set win or parent */
84 static struct RrSurface *surface_copy(struct RrSurface *orig)
85 {
86     struct RrSurface *sur;
87
88     sur = malloc(sizeof(struct RrSurface));
89     sur->type = orig->type;
90     switch (sur->type) {
91     case RR_SURFACE_PLANAR:
92         sur->data = orig->data;
93         break;
94     case RR_SURFACE_NONPLANAR:
95         assert(0);
96         break;
97     case RR_SURFACE_NONE:
98         break;
99     }
100     sur->ntextures = orig->ntextures;
101     sur->texture = malloc(sizeof(struct RrTexture) * sur->ntextures);
102     memcpy(sur->texture, orig->texture,
103            sizeof(struct RrTexture) * sur->ntextures);
104     return sur;
105 }
106
107 struct RrSurface *RrSurfaceCopy(struct RrInstance *inst,
108                                 struct RrSurface *orig,
109                                 Window win)
110 {
111     struct RrSurface *sur;
112
113     sur = surface_copy(orig);
114     sur->inst = inst;
115     sur->win = win;
116     sur->parent = NULL;
117     sur->visible = 0;
118     return sur;
119 }
120
121 struct RrSurface *RrSurfaceCopyChild(struct RrSurface *orig,
122                                      struct RrSurface *parent)
123 {
124     struct RrSurface *sur;
125
126     /* can't be a child of a prototype! */
127     assert(parent->inst);
128     if (!parent->inst) return NULL;
129
130     sur = surface_copy(orig);
131     sur->inst = parent->inst;
132     sur->win = create_window(sur->inst, parent->win);
133     sur->parent = parent;
134     RrSurfaceShow(sur);
135     return sur;
136 }
137
138 void RrSurfaceFree(struct RrSurface *sur)
139 {
140     int i;
141     if (sur) {
142         for (i = 0; i < sur->ntextures; ++i)
143             RrTextureFreeContents(&sur->texture[i]);
144         if (sur->ntextures)
145             free(sur->texture);
146         if (sur->parent && sur->win)
147             XDestroyWindow(RrDisplay(sur->inst), sur->win);
148         free(sur);
149     }
150 }
151
152 void RrSurfaceSetArea(struct RrSurface *sur,
153                       int x,
154                       int y,
155                       int w,
156                       int h)
157 {
158     assert(w > 0 && h > 0);
159     if (!(w > 0 && h > 0)) return;
160
161     sur->x = x;
162     sur->y = y;
163     sur->w = w;
164     sur->h = h;
165     if (sur->win)
166         XMoveResizeWindow(RrDisplay(sur->inst), sur->win, x, y, w, h);
167 }
168
169 Window RrSurfaceWindow(struct RrSurface *sur)
170 {
171     /* can't get a window for a prototype */
172     assert(sur->inst);
173     if (!sur->inst) return None;
174
175     return sur->win;
176 }
177
178 struct RrTexture *RrSurfaceTexture(struct RrSurface *sur, int texnum)
179 {
180     assert(texnum < sur->ntextures);
181     return &(sur->texture[texnum]);
182 }
183
184 void RrSurfaceMinSize(struct RrSurface *sur, int *w, int *h)
185 {
186     int i;
187     int minw, minh;
188
189     switch(sur->type) {
190     case RR_SURFACE_NONE:
191         *w = *h = 0;
192         break;
193     case RR_SURFACE_PLANAR:
194         RrPlanarMinSize(sur, w, h);
195         break;
196     case RR_SURFACE_NONPLANAR:
197         assert(0);
198         break;
199     }
200
201     for (i = 0; i < sur->ntextures; ++i) {
202         switch (sur->texture[i].type) {
203         case RR_TEXTURE_NONE:
204             minw = MAX(minw, 0);
205             minh = MAX(minh, 0);
206             break;
207         case RR_TEXTURE_TEXT:
208             /* XXX MEASUER STRING PLS */
209             minw = MAX(minw, 100 /*MEASURESTRING*/); 
210             minh = MAX(minh, 10  /*HEIGHTOFFONT*/);
211             break;
212         case RR_TEXTURE_RGBA:
213             minw = MAX(minw, (sur->texture[i].data.rgba.x +
214                               sur->texture[i].data.rgba.w));
215             minh = MAX(minw, (sur->texture[i].data.rgba.y +
216                               sur->texture[i].data.rgba.h));
217             break;
218         }
219     }
220
221     *w += minw;
222     *h += minh;
223     /* zeros are bad. */
224     if (*w == 0) *w = 1;
225     if (*h == 0) *h = 1;
226 }
227
228 void RrSurfaceShow(struct RrSurface *sur)
229 {
230     sur->visible = 1;
231     if (sur->win)
232         XMapWindow(RrDisplay(sur->inst), sur->win);
233 }
234
235 void RrSurfaceHide(struct RrSurface *sur)
236 {
237     sur->visible = 0;
238     if (sur->win)
239         XUnmapWindow(RrDisplay(sur->inst), sur->win);
240 }
241
242 int RrSurfaceVisible(struct RrSurface *sur)
243 {
244     return sur->visible;
245 }