File: | multiVis.c |
Location: | line 226, column 38 |
Description: | The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage |
1 | /** ------------------------------------------------------------------------ | |||
2 | This file contains functions to create a list of regions which | |||
3 | tile a specified window. Each region contains all visible | |||
4 | portions of the window which are drawn with the same visual. | |||
5 | If the window consists of subwindows of two different visual types, | |||
6 | there will be two regions in the list. The list can be traversed | |||
7 | to correctly pull an image of the window using XGetImage or the | |||
8 | Image Library. | |||
9 | ||||
10 | Copyright 1994 Hewlett-Packard Co. | |||
11 | Copyright 1996, 1998 The Open Group | |||
12 | ||||
13 | Permission to use, copy, modify, distribute, and sell this software and its | |||
14 | documentation for any purpose is hereby granted without fee, provided that | |||
15 | the above copyright notice appear in all copies and that both that | |||
16 | copyright notice and this permission notice appear in supporting | |||
17 | documentation. | |||
18 | ||||
19 | The above copyright notice and this permission notice shall be included | |||
20 | in all copies or substantial portions of the Software. | |||
21 | ||||
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
23 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||
25 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
26 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
27 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
28 | OTHER DEALINGS IN THE SOFTWARE. | |||
29 | ||||
30 | Except as contained in this notice, the name of The Open Group shall | |||
31 | not be used in advertising or otherwise to promote the sale, use or | |||
32 | other dealings in this Software without prior written authorization | |||
33 | from The Open Group. | |||
34 | ||||
35 | ------------------------------------------------------------------------ **/ | |||
36 | ||||
37 | #include <stdlib.h> | |||
38 | #include <X11/Xlib.h> | |||
39 | #include <X11/Xutil.h> | |||
40 | #include <X11/X.h> | |||
41 | #include <stdio.h> | |||
42 | #include "list.h" | |||
43 | #include "wsutils.h" | |||
44 | #include "multiVis.h" | |||
45 | /* These structures are copied from X11/region.h. For some reason | |||
46 | * they're invisible from the outside. | |||
47 | */ | |||
48 | typedef struct { | |||
49 | short x1, x2, y1, y2; | |||
50 | } myBox, myBOX, myBoxRec, *myBoxPtr; | |||
51 | ||||
52 | typedef struct my_XRegion { | |||
53 | long size; | |||
54 | long numRects; | |||
55 | myBOX *rects; | |||
56 | myBOX extents; | |||
57 | } myREGION; | |||
58 | ||||
59 | /* Items in long list of windows that have some part in the grabbed area */ | |||
60 | typedef struct { | |||
61 | Window win; | |||
62 | Visual *vis; | |||
63 | Colormap cmap; | |||
64 | int x_rootrel, y_rootrel; /* root relative location of window */ | |||
65 | int x_vis, y_vis; /* rt rel x,y of vis part, not parent clipped */ | |||
66 | int width, height; /* width and height of visible part */ | |||
67 | int border_width; /* border width of the window */ | |||
68 | Window parent; /* id of parent (for debugging) */ | |||
69 | } image_win_type; | |||
70 | ||||
71 | /* Items in short list of regions that tile the grabbed area. May have | |||
72 | multiple windows in the region. | |||
73 | */ | |||
74 | typedef struct { | |||
75 | Window win; /* lowest window of this visual */ | |||
76 | Visual *vis; | |||
77 | Colormap cmap; | |||
78 | int x_rootrel, y_rootrel; /* root relative location of bottom window */ | |||
79 | int x_vis, y_vis; /* rt rel x,y of vis part, not parent clipped */ | |||
80 | int width, height; /* w & h of visible rect of bottom window */ | |||
81 | int border; /* border width of the window */ | |||
82 | Region visible_region; | |||
83 | } image_region_type; | |||
84 | ||||
85 | /** ------------------------------------------------------------------------ | |||
86 | Returns TRUE if the two structs pointed to have the same "vis" & | |||
87 | "cmap" fields and s2 lies completely within s1. s1 and s2 can | |||
88 | point to structs of image_win_type or image_region_type. | |||
89 | ------------------------------------------------------------------------ **/ | |||
90 | #define SAME_REGIONS( s1, s2)((s1)->vis == (s2)->vis && (s1)->cmap == (s2 )->cmap && (s1)->x_vis <= (s2)->x_vis && (s1)->y_vis <= (s2)->y_vis && (s1)->x_vis + (s1)->width >= (s2)->x_vis + (s2)->width && (s1)->y_vis + (s1)->height >= (s2)->y_vis + (s2) ->height) \ | |||
91 | ((s1)->vis == (s2)->vis && (s1)->cmap == (s2)->cmap && \ | |||
92 | (s1)->x_vis <= (s2)->x_vis && \ | |||
93 | (s1)->y_vis <= (s2)->y_vis && \ | |||
94 | (s1)->x_vis + (s1)->width >= (s2)->x_vis + (s2)->width && \ | |||
95 | (s1)->y_vis + (s1)->height >= (s2)->y_vis + (s2)->height) | |||
96 | ||||
97 | #ifndef MIN | |||
98 | #define MIN( a, b)((a) < (b) ? a : b) ((a) < (b) ? a : b) | |||
99 | #define MAX( a, b)((a) > (b) ? a : b) ((a) > (b) ? a : b) | |||
100 | #endif | |||
101 | ||||
102 | #define RED_SHIFT16 16 | |||
103 | #define GREEN_SHIFT8 8 | |||
104 | #define BLUE_SHIFT0 0 | |||
105 | ||||
106 | /* | |||
107 | extern list_ptr new_list(); | |||
108 | extern list_ptr dup_list_head(); | |||
109 | extern void * first_in_list(); | |||
110 | extern void * next_in_list(); | |||
111 | extern int add_to_list(); | |||
112 | extern void zero_list(); | |||
113 | extern void delete_list(); | |||
114 | extern void delete_list_destroying(); | |||
115 | extern unsigned int list_length(); | |||
116 | */ | |||
117 | ||||
118 | /* Prototype Declarations for Static Functions */ | |||
119 | static void QueryColorMap( | |||
120 | Display *, Colormap , Visual *, | |||
121 | XColor **, int *, int *, int * | |||
122 | ); | |||
123 | static void TransferImage( | |||
124 | Display *, XImage *,int, int , image_region_type*, | |||
125 | XImage *,int ,int | |||
126 | ); | |||
127 | static XImage * ReadRegionsInList( | |||
128 | Display *, Visual *, int, int, unsigned int, | |||
129 | unsigned int, XRectangle, list_ptr | |||
130 | ); | |||
131 | ||||
132 | static list_ptr make_region_list( | |||
133 | Display*, Window, XRectangle*, | |||
134 | int*, int, XVisualInfo**, int * | |||
135 | ); | |||
136 | ||||
137 | static void destroy_region_list( | |||
138 | list_ptr | |||
139 | ) ; | |||
140 | static void subtr_rect_from_image_region( | |||
141 | image_region_type *, int , int , int , int | |||
142 | ); | |||
143 | static void add_rect_to_image_region( | |||
144 | image_region_type *, | |||
145 | int , int , int , int | |||
146 | ); | |||
147 | static int src_in_region_list( | |||
148 | image_win_type *, list_ptr | |||
149 | ); | |||
150 | static void add_window_to_list( | |||
151 | list_ptr, Window, int, int , | |||
152 | int , int , int , int, int, | |||
153 | Visual*, Colormap, Window | |||
154 | ); | |||
155 | static int src_in_image( | |||
156 | image_win_type *, int , XVisualInfo** | |||
157 | ); | |||
158 | static int src_in_overlay( | |||
159 | image_region_type *, int, OverlayInfo *, int*, int* | |||
160 | ); | |||
161 | static void make_src_list( | |||
162 | Display *, list_ptr, XRectangle *, Window, | |||
163 | int, int, XWindowAttributes *, XRectangle * | |||
164 | ); | |||
165 | static void destroy_image_region( | |||
166 | image_region_type * | |||
167 | ); | |||
168 | ||||
169 | /* End of Prototype Declarations */ | |||
170 | ||||
171 | void initFakeVisual(Visual *Vis) | |||
172 | { | |||
173 | Vis->ext_data=NULL((void*)0); | |||
174 | Vis->class = DirectColor5 ; | |||
175 | Vis->red_mask = 0x00FF0000; | |||
176 | Vis->green_mask = 0x0000FF00 ; | |||
177 | Vis->blue_mask = 0x000000FF ; | |||
178 | Vis->map_entries = 256 ; | |||
179 | Vis->bits_per_rgb = 8 ; | |||
180 | } | |||
181 | ||||
182 | static void | |||
183 | QueryColorMap(Display *disp, Colormap src_cmap, Visual *src_vis, | |||
184 | XColor **src_colors, int *rShift, int *gShift, int *bShift) | |||
185 | { | |||
186 | unsigned int ncolors,i ; | |||
187 | unsigned long redMask, greenMask, blueMask; | |||
188 | int redShift, greenShift, blueShift; | |||
189 | XColor *colors ; | |||
190 | ||||
191 | ncolors = (unsigned) src_vis->map_entries ; | |||
192 | *src_colors = colors = (XColor *)malloc(ncolors * sizeof(XColor) ) ; | |||
193 | ||||
194 | if(src_vis->class != TrueColor4 && src_vis->class != DirectColor5) | |||
195 | { | |||
196 | for(i=0 ; i < ncolors ; i++) | |||
197 | { | |||
198 | colors[i].pixel = i ; | |||
199 | colors[i].pad = 0; | |||
200 | colors[i].flags = DoRed(1<<0)|DoGreen(1<<1)|DoBlue(1<<2); | |||
201 | } | |||
202 | } | |||
203 | else /** src is decomposed rgb ***/ | |||
204 | { | |||
205 | /* Get the X colormap */ | |||
206 | redMask = src_vis->red_mask; | |||
207 | greenMask = src_vis->green_mask; | |||
208 | blueMask = src_vis->blue_mask; | |||
209 | redShift = 0; while (!(redMask&0x1)) { | |||
210 | redShift++; | |||
211 | redMask = redMask>>1; | |||
212 | } | |||
213 | greenShift = 0; while (!(greenMask&0x1)) { | |||
214 | greenShift++; | |||
215 | greenMask = greenMask>>1; | |||
216 | } | |||
217 | blueShift = 0; while (!(blueMask&0x1)) { | |||
218 | blueShift++; | |||
219 | blueMask = blueMask>>1; | |||
220 | } | |||
221 | *rShift = redShift ; | |||
222 | *gShift = greenShift ; | |||
223 | *bShift = blueShift ; | |||
224 | for (i=0; i<ncolors; i++) { | |||
225 | if( i <= redMask)colors[i].pixel = (i<<redShift) ; | |||
226 | if( i <= greenMask)colors[i].pixel |= (i<<greenShift) ; | |||
| ||||
227 | if( i <= blueMask)colors[i].pixel |= (i<<blueShift) ; | |||
228 | /***** example :for gecko's 3-3-2 map, blue index should be <= 3. | |||
229 | colors[i].pixel = (i<<redShift)|(i<<greenShift)|(i<<blueShift); | |||
230 | *****/ | |||
231 | colors[i].pad = 0; | |||
232 | colors[i].flags = DoRed(1<<0)|DoGreen(1<<1)|DoBlue(1<<2); | |||
233 | } | |||
234 | } | |||
235 | ||||
236 | XQueryColors(disp, src_cmap, colors, (int) ncolors); | |||
237 | } | |||
238 | ||||
239 | int | |||
240 | GetMultiVisualRegions(Display *disp, | |||
241 | /* root win on which grab was done */ | |||
242 | Window srcRootWinid, | |||
243 | /* root rel UL corner of bounding box of grab */ | |||
244 | int x, int y, | |||
245 | /* size of bounding box of grab */ | |||
246 | unsigned int width, unsigned int height, | |||
247 | int *transparentOverlays, int *numVisuals, | |||
248 | XVisualInfo **pVisuals, int *numOverlayVisuals, | |||
249 | OverlayInfo **pOverlayVisuals, | |||
250 | int *numImageVisuals, XVisualInfo ***pImageVisuals, | |||
251 | /* list of regions to read from */ | |||
252 | list_ptr *vis_regions, | |||
253 | list_ptr *vis_image_regions, int *allImage) | |||
254 | { | |||
255 | int hasNonDefault; | |||
256 | XRectangle bbox; /* bounding box of grabbed area */ | |||
257 | ||||
258 | ||||
259 | bbox.x = x; /* init X rect for bounding box */ | |||
260 | bbox.y = y; | |||
261 | bbox.width = width; | |||
262 | bbox.height = height; | |||
263 | ||||
264 | GetXVisualInfo(disp,DefaultScreen(disp)(((_XPrivDisplay)(disp))->default_screen), | |||
265 | transparentOverlays, | |||
266 | numVisuals, pVisuals, | |||
267 | numOverlayVisuals, pOverlayVisuals, | |||
268 | numImageVisuals, pImageVisuals); | |||
269 | ||||
270 | *vis_regions = *vis_image_regions = NULL((void*)0) ; | |||
271 | if ((*vis_regions = make_region_list( disp, srcRootWinid, &bbox, | |||
272 | &hasNonDefault, *numImageVisuals, | |||
273 | *pImageVisuals, allImage)) == NULL((void*)0)) | |||
274 | return 0 ; | |||
275 | ||||
276 | if (*transparentOverlays) | |||
277 | { | |||
278 | *allImage = 1; /* until proven otherwise, | |||
279 | this flags that it to be an image only list */ | |||
280 | *vis_image_regions = | |||
281 | make_region_list( disp, srcRootWinid, &bbox, &hasNonDefault, | |||
282 | *numImageVisuals, *pImageVisuals, allImage); | |||
283 | } | |||
284 | ||||
285 | /* if there is a second region in any of the two lists return 1 **/ | |||
286 | if ( ( *vis_regions && (*vis_regions)->next && (*vis_regions)->next->next ) || | |||
287 | ( *vis_image_regions && (*vis_image_regions)->next && | |||
288 | (*vis_image_regions)->next->next ) ) return 1 ; | |||
289 | else return 0 ; | |||
290 | ||||
291 | } | |||
292 | ||||
293 | static void TransferImage(Display *disp, XImage *reg_image, | |||
294 | int srcw, int srch, | |||
295 | image_region_type *reg, XImage *target_image, | |||
296 | int dst_x, int dst_y) | |||
297 | { | |||
298 | int i,j,old_pixel,new_pixel,red_ind,green_ind,blue_ind ; | |||
299 | XColor *colors; | |||
300 | int rShift = 0, gShift = 0, bShift = 0; | |||
301 | ||||
302 | QueryColorMap(disp,reg->cmap,reg->vis,&colors, | |||
| ||||
303 | &rShift,&gShift,&bShift) ; | |||
304 | ||||
305 | switch (reg->vis->class) { | |||
306 | case TrueColor4 : | |||
307 | for(i=0 ; i < srch ; i++) | |||
308 | { | |||
309 | for(j=0 ; j < srcw ; j++) | |||
310 | { | |||
311 | old_pixel = XGetPixel(reg_image,j,i)((*((reg_image)->f.get_pixel))((reg_image), (j), (i))) ; | |||
312 | ||||
313 | if( reg->vis->map_entries == 16) { | |||
314 | ||||
315 | red_ind = (old_pixel & reg->vis->red_mask) >> rShift ; | |||
316 | green_ind = (old_pixel & reg->vis->green_mask) >> gShift ; | |||
317 | blue_ind = (old_pixel & reg->vis->blue_mask) >> bShift ; | |||
318 | ||||
319 | new_pixel = ( | |||
320 | ((colors[red_ind].red >> 8) << RED_SHIFT16) | |||
321 | |((colors[green_ind].green >> 8) << GREEN_SHIFT8) | |||
322 | |((colors[blue_ind].blue >> 8) << BLUE_SHIFT0) | |||
323 | ); | |||
324 | } | |||
325 | else | |||
326 | new_pixel = old_pixel; | |||
327 | ||||
328 | XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel)((*((target_image)->f.put_pixel))((target_image), (dst_x+j ), (dst_y+i), (new_pixel))); | |||
329 | ||||
330 | } | |||
331 | } | |||
332 | break; | |||
333 | case DirectColor5 : | |||
334 | for(i=0 ; i < srch ; i++) | |||
335 | { | |||
336 | ||||
337 | for(j=0 ; j < srcw ; j++) | |||
338 | { | |||
339 | old_pixel = XGetPixel(reg_image,j,i)((*((reg_image)->f.get_pixel))((reg_image), (j), (i))) ; | |||
340 | red_ind = (old_pixel & reg->vis->red_mask) >> rShift ; | |||
341 | green_ind = (old_pixel & reg->vis->green_mask) >> gShift ; | |||
342 | blue_ind = (old_pixel & reg->vis->blue_mask) >> bShift ; | |||
343 | ||||
344 | new_pixel = ( | |||
345 | ((colors[red_ind].red >> 8) << RED_SHIFT16) | |||
346 | |((colors[green_ind].green >> 8) << GREEN_SHIFT8) | |||
347 | |((colors[blue_ind].blue >> 8) << BLUE_SHIFT0) | |||
348 | ); | |||
349 | XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel)((*((target_image)->f.put_pixel))((target_image), (dst_x+j ), (dst_y+i), (new_pixel))); | |||
350 | ||||
351 | } | |||
352 | } | |||
353 | break; | |||
354 | default : | |||
355 | for(i=0 ; i < srch ; i++) | |||
356 | { | |||
357 | for(j=0 ; j < srcw ; j++) | |||
358 | { | |||
359 | old_pixel = XGetPixel(reg_image,j,i)((*((reg_image)->f.get_pixel))((reg_image), (j), (i))) ; | |||
360 | ||||
361 | new_pixel = ( | |||
362 | ((colors[old_pixel].red >> 8) << RED_SHIFT16) | |||
363 | |((colors[old_pixel].green >> 8) << GREEN_SHIFT8) | |||
364 | |((colors[old_pixel].blue >> 8) << BLUE_SHIFT0) | |||
365 | ); | |||
366 | XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel)((*((target_image)->f.put_pixel))((target_image), (dst_x+j ), (dst_y+i), (new_pixel))); | |||
367 | ||||
368 | } | |||
369 | } | |||
370 | break; | |||
371 | } | |||
372 | } | |||
373 | ||||
374 | static XImage * | |||
375 | ReadRegionsInList(Display *disp, Visual *fakeVis, int depth, int format, | |||
376 | unsigned int width, unsigned int height, | |||
377 | XRectangle bbox, /* bounding box of grabbed area */ | |||
378 | list_ptr regions) /* list of regions to read from */ | |||
379 | { | |||
380 | image_region_type *reg; | |||
381 | int dst_x, dst_y; /* where in pixmap to write (UL) */ | |||
382 | int diff; | |||
383 | ||||
384 | XImage *reg_image,*ximage ; | |||
385 | int srcRect_x,srcRect_y,srcRect_width,srcRect_height ; | |||
386 | int bytes_per_line; | |||
387 | ||||
388 | ximage = XCreateImage(disp,fakeVis,depth,format,0,NULL((void*)0),width,height, | |||
389 | 8,0) ; | |||
390 | bytes_per_line = ximage->bytes_per_line; | |||
391 | ||||
392 | if (format == ZPixmap2) | |||
393 | ximage->data = malloc(height*bytes_per_line); | |||
394 | else | |||
395 | ximage->data = malloc(height*bytes_per_line*depth); | |||
396 | ||||
397 | ximage->bits_per_pixel = depth; /** Valid only if format is ZPixmap ***/ | |||
398 | ||||
399 | for (reg = (image_region_type *) first_in_list( regions); reg; | |||
400 | reg = (image_region_type *) next_in_list( regions)) | |||
401 | { | |||
402 | int rect; | |||
403 | struct my_XRegion *vis_reg; | |||
404 | vis_reg = (struct my_XRegion *)(reg->visible_region); | |||
405 | for (rect = 0; | |||
406 | rect < vis_reg->numRects; | |||
407 | rect++) | |||
408 | { | |||
409 | /** ------------------------------------------------------------------------ | |||
410 | Intersect bbox with visible part of region giving src rect & output | |||
411 | location. Width is the min right side minus the max left side. | |||
412 | Similar for height. Offset src rect so x,y are relative to | |||
413 | origin of win, not the root-relative visible rect of win. | |||
414 | ------------------------------------------------------------------------ **/ | |||
415 | srcRect_width = MIN( vis_reg->rects[rect].x2, bbox.width + bbox.x)((vis_reg->rects[rect].x2) < (bbox.width + bbox.x) ? vis_reg ->rects[rect].x2 : bbox.width + bbox.x) - | |||
416 | MAX( vis_reg->rects[rect].x1, bbox.x)((vis_reg->rects[rect].x1) > (bbox.x) ? vis_reg->rects [rect].x1 : bbox.x); | |||
417 | srcRect_height = MIN( vis_reg->rects[rect].y2, bbox.height + bbox.y)((vis_reg->rects[rect].y2) < (bbox.height + bbox.y) ? vis_reg ->rects[rect].y2 : bbox.height + bbox.y) - | |||
418 | MAX( vis_reg->rects[rect].y1, bbox.y)((vis_reg->rects[rect].y1) > (bbox.y) ? vis_reg->rects [rect].y1 : bbox.y); | |||
419 | diff = bbox.x - vis_reg->rects[rect].x1; | |||
420 | srcRect_x = MAX( 0, diff)((0) > (diff) ? 0 : diff) + (vis_reg->rects[rect].x1 - reg->x_rootrel - reg->border); | |||
421 | dst_x = MAX( 0, -diff)((0) > (-diff) ? 0 : -diff) ; | |||
422 | diff = bbox.y - vis_reg->rects[rect].y1; | |||
423 | srcRect_y = MAX( 0, diff)((0) > (diff) ? 0 : diff) + (vis_reg->rects[rect].y1 - reg->y_rootrel - reg->border); | |||
424 | dst_y = MAX( 0, -diff)((0) > (-diff) ? 0 : -diff) ; | |||
425 | reg_image = XGetImage(disp,reg->win,srcRect_x,srcRect_y, | |||
426 | srcRect_width,srcRect_height,AllPlanes((unsigned long)~0L),format) ; | |||
427 | TransferImage(disp,reg_image,srcRect_width, | |||
428 | srcRect_height,reg,ximage,dst_x,dst_y) ; | |||
429 | } | |||
430 | } | |||
431 | return ximage ; | |||
432 | } | |||
433 | ||||
434 | ||||
435 | /** ------------------------------------------------------------------------ | |||
436 | ------------------------------------------------------------------------ **/ | |||
437 | ||||
438 | XImage *ReadAreaToImage(Display *disp, | |||
439 | /* root win on which grab was done */ | |||
440 | Window srcRootWinid, | |||
441 | /* root rel UL corner of bounding box of grab */ | |||
442 | int x, int y, | |||
443 | /* size of bounding box of grab */ | |||
444 | unsigned int width, unsigned int height, | |||
445 | int numVisuals, XVisualInfo *pVisuals, | |||
446 | int numOverlayVisuals, OverlayInfo *pOverlayVisuals, | |||
447 | int numImageVisuals, XVisualInfo **pImageVisuals, | |||
448 | /* list of regions to read from */ | |||
449 | list_ptr vis_regions, | |||
450 | /* list of regions to read from */ | |||
451 | list_ptr vis_image_regions, | |||
452 | int format, int allImage) | |||
453 | { | |||
454 | image_region_type *reg; | |||
455 | XRectangle bbox; /* bounding box of grabbed area */ | |||
456 | int depth ; | |||
457 | XImage *ximage, *ximage_ipm = NULL((void*)0); | |||
458 | Visual fakeVis ; | |||
459 | int x1, y1; | |||
460 | XImage *image; | |||
461 | #if 0 | |||
462 | unsigned char *pmData , *ipmData ; | |||
463 | #endif | |||
464 | int transparentColor, transparentType; | |||
465 | int srcRect_x,srcRect_y,srcRect_width,srcRect_height ; | |||
466 | int diff ; | |||
467 | int dst_x, dst_y; /* where in pixmap to write (UL) */ | |||
468 | int pixel; | |||
469 | ||||
470 | bbox.x = x; /* init X rect for bounding box */ | |||
471 | bbox.y = y; | |||
472 | bbox.width = width; | |||
473 | bbox.height = height; | |||
474 | ||||
475 | ||||
476 | initFakeVisual(&fakeVis) ; | |||
477 | ||||
478 | depth = 24 ; | |||
479 | ximage = ReadRegionsInList(disp,&fakeVis,depth,format,width,height, | |||
480 | bbox,vis_regions) ; | |||
481 | #if 0 | |||
482 | pmData = (unsigned char *)ximage -> data ; | |||
483 | #endif | |||
484 | ||||
485 | /* if transparency possible do it again, but this time for image planes only */ | |||
486 | if (vis_image_regions && (vis_image_regions->next) && !allImage) | |||
487 | { | |||
488 | ximage_ipm = ReadRegionsInList(disp,&fakeVis,depth,format,width,height, | |||
489 | bbox,vis_image_regions) ; | |||
490 | #if 0 | |||
491 | ipmData = (unsigned char *)ximage_ipm -> data ; | |||
492 | #endif | |||
493 | } | |||
494 | /* Now tranverse the overlay visual windows and test for transparency index. */ | |||
495 | /* If you find one, subsitute the value from the matching image plane pixmap. */ | |||
496 | ||||
497 | for (reg = (image_region_type *) first_in_list( vis_regions); reg; | |||
498 | reg = (image_region_type *) next_in_list( vis_regions)) | |||
499 | { | |||
500 | ||||
501 | if (src_in_overlay( reg, numOverlayVisuals, pOverlayVisuals, | |||
502 | &transparentColor, &transparentType)) | |||
503 | { | |||
504 | int test = 0 ; | |||
505 | srcRect_width = MIN( reg->width + reg->x_vis, bbox.width + bbox.x)((reg->width + reg->x_vis) < (bbox.width + bbox.x) ? reg->width + reg->x_vis : bbox.width + bbox.x) | |||
506 | - MAX( reg->x_vis, bbox.x)((reg->x_vis) > (bbox.x) ? reg->x_vis : bbox.x); | |||
507 | srcRect_height = MIN( reg->height + reg->y_vis, bbox.height((reg->height + reg->y_vis) < (bbox.height + bbox.y) ? reg->height + reg->y_vis : bbox.height + bbox.y) | |||
508 | + bbox.y)((reg->height + reg->y_vis) < (bbox.height + bbox.y) ? reg->height + reg->y_vis : bbox.height + bbox.y) - MAX( reg->y_vis, bbox.y)((reg->y_vis) > (bbox.y) ? reg->y_vis : bbox.y); | |||
509 | diff = bbox.x - reg->x_vis; | |||
510 | srcRect_x = MAX( 0, diff)((0) > (diff) ? 0 : diff) + (reg->x_vis - reg->x_rootrel - reg->border); | |||
511 | dst_x = MAX( 0, -diff)((0) > (-diff) ? 0 : -diff) ; | |||
512 | diff = bbox.y - reg->y_vis; | |||
513 | srcRect_y = MAX( 0, diff)((0) > (diff) ? 0 : diff) + (reg->y_vis - reg->y_rootrel - reg->border); | |||
514 | dst_y = MAX( 0, -diff)((0) > (-diff) ? 0 : -diff) ; | |||
515 | /* let's test some pixels for transparency */ | |||
516 | image = XGetImage(disp, reg->win, srcRect_x, srcRect_y, | |||
517 | srcRect_width, srcRect_height, 0xffffffff, ZPixmap2); | |||
518 | ||||
519 | /* let's assume byte per pixel for overlay image for now */ | |||
520 | if ((image->depth == 8) && (transparentType == TransparentPixel1)) | |||
521 | { | |||
522 | unsigned char *pixel_ptr; | |||
523 | unsigned char *start_of_line = (unsigned char *) image->data; | |||
524 | ||||
525 | for (y1 = 0; y1 < srcRect_height; y1++) { | |||
526 | pixel_ptr = start_of_line; | |||
527 | for (x1 = 0; x1 < srcRect_width; x1++) | |||
528 | { | |||
529 | if (*pixel_ptr++ == transparentColor) | |||
530 | { | |||
531 | #if 0 | |||
532 | *pmData++ = *ipmData++; | |||
533 | *pmData++ = *ipmData++; | |||
534 | *pmData++ = *ipmData++; | |||
535 | #endif | |||
536 | pixel = XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1)((*((ximage_ipm)->f.get_pixel))((ximage_ipm), (dst_x+x1), ( dst_y+y1))) ; | |||
537 | XPutPixel(ximage,dst_x+x1, dst_y+y1,pixel)((*((ximage)->f.put_pixel))((ximage), (dst_x+x1), (dst_y+y1 ), (pixel))); | |||
538 | ||||
539 | if(!test){ | |||
540 | test = 1 ; | |||
541 | } | |||
542 | } | |||
543 | #if 0 | |||
544 | else { | |||
545 | pmData +=3; | |||
546 | ipmData +=3; | |||
547 | } | |||
548 | #endif | |||
549 | } | |||
550 | start_of_line += image->bytes_per_line; | |||
551 | } | |||
552 | } else { | |||
553 | if (transparentType == TransparentPixel1) { | |||
554 | for (y1 = 0; y1 < srcRect_height; y1++) { | |||
555 | for (x1 = 0; x1 < srcRect_width; x1++) | |||
556 | { | |||
557 | int pixel_value = XGetPixel(image, x1, y1)((*((image)->f.get_pixel))((image), (x1), (y1))); | |||
558 | if (pixel_value == transparentColor) | |||
559 | { | |||
560 | #if 0 | |||
561 | *pmData++ = *ipmData++; | |||
562 | *pmData++ = *ipmData++; | |||
563 | *pmData++ = *ipmData++; | |||
564 | #endif | |||
565 | pixel = XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1)((*((ximage_ipm)->f.get_pixel))((ximage_ipm), (dst_x+x1), ( dst_y+y1))) ; | |||
566 | XPutPixel(ximage,dst_x+x1, dst_y+y1,pixel)((*((ximage)->f.put_pixel))((ximage), (dst_x+x1), (dst_y+y1 ), (pixel))); | |||
567 | if(!test){ | |||
568 | test = 1 ; | |||
569 | } | |||
570 | } | |||
571 | #if 0 | |||
572 | else { | |||
573 | pmData +=3; | |||
574 | ipmData +=3; | |||
575 | } | |||
576 | #endif | |||
577 | } | |||
578 | } | |||
579 | } else { | |||
580 | for (y1 = 0; y1 < srcRect_height; y1++) { | |||
581 | for (x1 = 0; x1 < srcRect_width; x1++) | |||
582 | { | |||
583 | int pixel_value = XGetPixel(image, x1, y1)((*((image)->f.get_pixel))((image), (x1), (y1))); | |||
584 | if (pixel_value & transparentColor) | |||
585 | { | |||
586 | #if 0 | |||
587 | *pmData++ = *ipmData++; | |||
588 | *pmData++ = *ipmData++; | |||
589 | *pmData++ = *ipmData++; | |||
590 | #endif | |||
591 | pixel = XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1)((*((ximage_ipm)->f.get_pixel))((ximage_ipm), (dst_x+x1), ( dst_y+y1))) ; | |||
592 | XPutPixel(ximage,dst_x+x1, dst_y+y1,pixel)((*((ximage)->f.put_pixel))((ximage), (dst_x+x1), (dst_y+y1 ), (pixel))); | |||
593 | if(!test){ | |||
594 | test = 1 ; | |||
595 | } | |||
596 | } | |||
597 | #if 0 | |||
598 | else { | |||
599 | pmData +=3; | |||
600 | ipmData +=3; | |||
601 | } | |||
602 | #endif | |||
603 | } | |||
604 | } | |||
605 | } | |||
606 | } | |||
607 | XDestroyImage (image)((*((image)->f.destroy_image))((image))); | |||
608 | } /* end of src_in_overlay */ | |||
609 | } /** end transparency **/ | |||
610 | destroy_region_list( vis_regions); | |||
611 | if (vis_image_regions) destroy_region_list( vis_image_regions ); | |||
612 | FreeXVisualInfo(pVisuals, pOverlayVisuals, pImageVisuals); | |||
613 | XSync(disp, 0); | |||
614 | ||||
615 | return ximage; | |||
616 | } | |||
617 | ||||
618 | /** ------------------------------------------------------------------------ | |||
619 | Creates a list of the subwindows of a given window which have a | |||
620 | different visual than their parents. The function is recursive. | |||
621 | This list is used in make_region_list(), which coalesces the | |||
622 | windows with the same visual into a region. | |||
623 | image_wins must point to an existing list struct that's already | |||
624 | been zeroed (zero_list()). | |||
625 | ------------------------------------------------------------------------ **/ | |||
626 | static void make_src_list(Display *disp, list_ptr image_wins, | |||
627 | /* bnding box of area we want */ | |||
628 | XRectangle *bbox, | |||
629 | Window curr, | |||
630 | /* pos of curr WRT root */ | |||
631 | int x_rootrel, int y_rootrel, | |||
632 | XWindowAttributes *curr_attrs, | |||
633 | /* visible part of curr, not obscurred by ancestors */ | |||
634 | XRectangle *pclip) | |||
635 | { | |||
636 | XWindowAttributes child_attrs; | |||
637 | Window root, parent, *child; /* variables for XQueryTree() */ | |||
638 | Window *save_child_list; /* variables for XQueryTree() */ | |||
639 | unsigned int nchild; /* variables for XQueryTree() */ | |||
640 | XRectangle child_clip; /* vis part of child */ | |||
641 | int curr_clipX, curr_clipY, curr_clipRt, curr_clipBt; | |||
642 | ||||
643 | /* check that win is mapped & not outside bounding box */ | |||
644 | if (curr_attrs->map_state == IsViewable2 && | |||
645 | curr_attrs->class == InputOutput1 && | |||
646 | !( pclip->x >= (int) (bbox->x + bbox->width) || | |||
647 | pclip->y >= (int) (bbox->y + bbox->height) || | |||
648 | (int) (pclip->x + pclip->width) <= bbox->x || | |||
649 | (int) (pclip->y + pclip->height) <= bbox->y)) { | |||
650 | ||||
651 | XQueryTree( disp, curr, &root, &parent, &child, &nchild ); | |||
652 | save_child_list = child; /* so we can free list when we're done */ | |||
653 | add_window_to_list( image_wins, curr, x_rootrel, y_rootrel, | |||
654 | pclip->x, pclip->y, | |||
655 | pclip->width, pclip->height, | |||
656 | curr_attrs->border_width,curr_attrs->visual, | |||
657 | curr_attrs->colormap, parent); | |||
658 | ||||
659 | ||||
660 | /** ------------------------------------------------------------------------ | |||
661 | set RR coords of right (Rt), left (X), bottom (Bt) and top (Y) | |||
662 | of rect we clip all children by. This is our own clip rect (pclip) | |||
663 | inflicted on us by our parent plus our own borders. Within the | |||
664 | child loop, we figure the clip rect for each child by adding in | |||
665 | it's rectangle (not taking into account the child's borders). | |||
666 | ------------------------------------------------------------------------ **/ | |||
667 | curr_clipX = MAX( pclip->x, x_rootrel + (int) curr_attrs->border_width)((pclip->x) > (x_rootrel + (int) curr_attrs->border_width ) ? pclip->x : x_rootrel + (int) curr_attrs->border_width ); | |||
668 | curr_clipY = MAX( pclip->y, y_rootrel + (int) curr_attrs->border_width)((pclip->y) > (y_rootrel + (int) curr_attrs->border_width ) ? pclip->y : y_rootrel + (int) curr_attrs->border_width ); | |||
669 | curr_clipRt = MIN( pclip->x + (int) pclip->width,((pclip->x + (int) pclip->width) < (x_rootrel + (int ) curr_attrs->width + 2 * (int) curr_attrs->border_width ) ? pclip->x + (int) pclip->width : x_rootrel + (int) curr_attrs ->width + 2 * (int) curr_attrs->border_width) | |||
670 | x_rootrel + (int) curr_attrs->width +((pclip->x + (int) pclip->width) < (x_rootrel + (int ) curr_attrs->width + 2 * (int) curr_attrs->border_width ) ? pclip->x + (int) pclip->width : x_rootrel + (int) curr_attrs ->width + 2 * (int) curr_attrs->border_width) | |||
671 | 2 * (int) curr_attrs->border_width)((pclip->x + (int) pclip->width) < (x_rootrel + (int ) curr_attrs->width + 2 * (int) curr_attrs->border_width ) ? pclip->x + (int) pclip->width : x_rootrel + (int) curr_attrs ->width + 2 * (int) curr_attrs->border_width); | |||
672 | curr_clipBt = MIN( pclip->y + (int) pclip->height,((pclip->y + (int) pclip->height) < (y_rootrel + (int ) curr_attrs->height + 2 * (int) curr_attrs->border_width ) ? pclip->y + (int) pclip->height : y_rootrel + (int) curr_attrs ->height + 2 * (int) curr_attrs->border_width) | |||
673 | y_rootrel + (int) curr_attrs->height +((pclip->y + (int) pclip->height) < (y_rootrel + (int ) curr_attrs->height + 2 * (int) curr_attrs->border_width ) ? pclip->y + (int) pclip->height : y_rootrel + (int) curr_attrs ->height + 2 * (int) curr_attrs->border_width) | |||
674 | 2 * (int) curr_attrs->border_width)((pclip->y + (int) pclip->height) < (y_rootrel + (int ) curr_attrs->height + 2 * (int) curr_attrs->border_width ) ? pclip->y + (int) pclip->height : y_rootrel + (int) curr_attrs ->height + 2 * (int) curr_attrs->border_width); | |||
675 | ||||
676 | while (nchild--) { | |||
677 | int new_width, new_height; | |||
678 | int child_xrr, child_yrr; /* root relative x & y of child */ | |||
679 | ||||
680 | XGetWindowAttributes( disp, *child, &child_attrs); | |||
681 | ||||
682 | /* intersect parent & child clip rects */ | |||
683 | child_xrr = x_rootrel + child_attrs.x + curr_attrs->border_width; | |||
684 | child_clip.x = MAX( curr_clipX, child_xrr)((curr_clipX) > (child_xrr) ? curr_clipX : child_xrr); | |||
685 | new_width = MIN( curr_clipRt, child_xrr + (int) child_attrs.width((curr_clipRt) < (child_xrr + (int) child_attrs.width + 2 * child_attrs.border_width) ? curr_clipRt : child_xrr + (int) child_attrs .width + 2 * child_attrs.border_width) | |||
686 | + 2 * child_attrs.border_width)((curr_clipRt) < (child_xrr + (int) child_attrs.width + 2 * child_attrs.border_width) ? curr_clipRt : child_xrr + (int) child_attrs .width + 2 * child_attrs.border_width) | |||
687 | - child_clip.x; | |||
688 | if (new_width >= 0) { | |||
689 | child_clip.width = new_width; | |||
690 | ||||
691 | child_yrr = y_rootrel + child_attrs.y + | |||
692 | curr_attrs->border_width; | |||
693 | child_clip.y = MAX( curr_clipY, child_yrr)((curr_clipY) > (child_yrr) ? curr_clipY : child_yrr); | |||
694 | new_height = MIN( curr_clipBt,((curr_clipBt) < (child_yrr + (int) child_attrs.height + 2 * child_attrs.border_width) ? curr_clipBt : child_yrr + (int ) child_attrs.height + 2 * child_attrs.border_width) | |||
695 | child_yrr + (int) child_attrs.height +((curr_clipBt) < (child_yrr + (int) child_attrs.height + 2 * child_attrs.border_width) ? curr_clipBt : child_yrr + (int ) child_attrs.height + 2 * child_attrs.border_width) | |||
696 | 2 * child_attrs.border_width)((curr_clipBt) < (child_yrr + (int) child_attrs.height + 2 * child_attrs.border_width) ? curr_clipBt : child_yrr + (int ) child_attrs.height + 2 * child_attrs.border_width) | |||
697 | - child_clip.y; | |||
698 | if (new_height >= 0) { | |||
699 | child_clip.height = new_height; | |||
700 | make_src_list( disp, image_wins, bbox, *child, | |||
701 | child_xrr, child_yrr, | |||
702 | &child_attrs, &child_clip); | |||
703 | } | |||
704 | } | |||
705 | child++; | |||
706 | } | |||
707 | XFree( save_child_list); | |||
708 | } | |||
709 | } | |||
710 | ||||
711 | ||||
712 | /** ------------------------------------------------------------------------ | |||
713 | This function creates a list of regions which tile a specified | |||
714 | window. Each region contains all visible portions of the window | |||
715 | which are drawn with the same visual. For example, if the | |||
716 | window consists of subwindows of two different visual types, | |||
717 | there will be two regions in the list. | |||
718 | Returns a pointer to the list. | |||
719 | ------------------------------------------------------------------------ **/ | |||
720 | static list_ptr make_region_list(Display *disp, Window win, XRectangle *bbox, | |||
721 | int *hasNonDefault, int numImageVisuals, | |||
722 | XVisualInfo **pImageVisuals, int *allImage) | |||
723 | { | |||
724 | XWindowAttributes win_attrs; | |||
725 | list image_wins; | |||
726 | list_ptr image_regions; | |||
727 | list_ptr srcs_left; | |||
728 | image_region_type *new_reg; | |||
729 | image_win_type *base_src, *src; | |||
730 | Region bbox_region = XCreateRegion(); | |||
731 | XRectangle clip; | |||
732 | int image_only; | |||
733 | ||||
734 | int count=0 ; | |||
735 | ||||
736 | *hasNonDefault = False0; | |||
737 | XUnionRectWithRegion( bbox, bbox_region, bbox_region); | |||
738 | XGetWindowAttributes( disp, win, &win_attrs); | |||
739 | ||||
740 | zero_list( &image_wins); | |||
741 | clip.x = 0; | |||
742 | clip.y = 0; | |||
743 | clip.width = win_attrs.width; | |||
744 | clip.height = win_attrs.height; | |||
745 | make_src_list( disp, &image_wins, bbox, win, | |||
746 | 0 /* x_rootrel */, 0 /* y_rootrel */, &win_attrs, &clip); | |||
747 | ||||
748 | image_regions = new_list(); | |||
749 | image_only = (*allImage) ? True1:False0; | |||
750 | ||||
751 | for (base_src = (image_win_type *) first_in_list( &image_wins); base_src; | |||
752 | base_src = (image_win_type *) next_in_list( &image_wins)) | |||
753 | { | |||
754 | /* test for image visual */ | |||
755 | if (!image_only || src_in_image(base_src, numImageVisuals, pImageVisuals)) | |||
756 | { | |||
757 | /* find a window whose visual hasn't been put in list yet */ | |||
758 | if (!src_in_region_list( base_src, image_regions)) | |||
759 | { | |||
760 | if (! (new_reg = (image_region_type *) | |||
761 | malloc( sizeof( image_region_type)))) { | |||
762 | return (list_ptr) NULL((void*)0); | |||
763 | } | |||
764 | count++; | |||
765 | ||||
766 | new_reg->visible_region = XCreateRegion(); | |||
767 | new_reg->win = base_src->win; | |||
768 | new_reg->vis = base_src->vis; | |||
769 | new_reg->cmap = base_src->cmap; | |||
770 | new_reg->x_rootrel = base_src->x_rootrel; | |||
771 | new_reg->y_rootrel = base_src->y_rootrel; | |||
772 | new_reg->x_vis = base_src->x_vis; | |||
773 | new_reg->y_vis = base_src->y_vis; | |||
774 | new_reg->width = base_src->width; | |||
775 | new_reg->height = base_src->height; | |||
776 | new_reg->border = base_src->border_width; | |||
777 | ||||
778 | srcs_left = (list_ptr) dup_list_head( &image_wins, START_AT_CURR1); | |||
779 | for (src = (image_win_type *) first_in_list( srcs_left); src; | |||
780 | src = (image_win_type *) next_in_list( srcs_left)) { | |||
781 | if (SAME_REGIONS( base_src, src)((base_src)->vis == (src)->vis && (base_src)-> cmap == (src)->cmap && (base_src)->x_vis <= ( src)->x_vis && (base_src)->y_vis <= (src)-> y_vis && (base_src)->x_vis + (base_src)->width >= (src)->x_vis + (src)->width && (base_src)-> y_vis + (base_src)->height >= (src)->y_vis + (src)-> height)) { | |||
782 | add_rect_to_image_region( new_reg, src->x_vis, src->y_vis, | |||
783 | src->width, src->height); | |||
784 | } | |||
785 | else { | |||
786 | if (!image_only || src_in_image(src, numImageVisuals, pImageVisuals)) | |||
787 | { | |||
788 | subtr_rect_from_image_region( new_reg, src->x_vis, | |||
789 | src->y_vis, src->width, src->height); | |||
790 | } | |||
791 | } | |||
792 | } | |||
793 | XIntersectRegion( bbox_region, new_reg->visible_region, | |||
794 | new_reg->visible_region); | |||
795 | if (! XEmptyRegion( new_reg->visible_region)) { | |||
796 | add_to_list( image_regions, new_reg); | |||
797 | if (new_reg->vis != DefaultVisualOfScreen( win_attrs.screen)((win_attrs.screen)->root_visual) || | |||
798 | new_reg->cmap != DefaultColormapOfScreen(((win_attrs.screen)->cmap) | |||
799 | win_attrs.screen)((win_attrs.screen)->cmap)) { | |||
800 | *hasNonDefault = True1; | |||
801 | } | |||
802 | } | |||
803 | else { | |||
804 | XDestroyRegion( new_reg->visible_region); | |||
805 | free( (void *) new_reg); | |||
806 | } | |||
807 | } | |||
808 | } else *allImage = 0; | |||
809 | } | |||
810 | delete_list( &image_wins, True1); | |||
811 | XDestroyRegion( bbox_region); | |||
812 | return image_regions; | |||
813 | } | |||
814 | /** ------------------------------------------------------------------------ | |||
815 | Destructor called from destroy_region_list(). | |||
816 | ------------------------------------------------------------------------ **/ | |||
817 | static void destroy_image_region(image_region_type *image_region) | |||
818 | { | |||
819 | XDestroyRegion( image_region->visible_region); | |||
820 | free( (void *) image_region); | |||
821 | } | |||
822 | ||||
823 | /** ------------------------------------------------------------------------ | |||
824 | Destroys the region list, destroying all the regions contained in it. | |||
825 | ------------------------------------------------------------------------ **/ | |||
826 | static void destroy_region_list(list_ptr rlist) | |||
827 | { | |||
828 | delete_list_destroying( rlist, (DESTRUCT_FUNC_PTR)destroy_image_region); | |||
829 | } | |||
830 | ||||
831 | ||||
832 | /** ------------------------------------------------------------------------ | |||
833 | Subtracts the specified rectangle from the region in image_region. | |||
834 | First converts the rectangle to a region of its own, since X | |||
835 | only provides a way to subtract one region from another, not a | |||
836 | rectangle from a region. | |||
837 | ------------------------------------------------------------------------ **/ | |||
838 | static void subtr_rect_from_image_region(image_region_type *image_region, | |||
839 | int x, int y, int width, int height) | |||
840 | { | |||
841 | XRectangle rect; | |||
842 | Region rect_region; | |||
843 | ||||
844 | rect_region = XCreateRegion(); | |||
845 | rect.x = x; | |||
846 | rect.y = y; | |||
847 | rect.width = width; | |||
848 | rect.height = height; | |||
849 | XUnionRectWithRegion( &rect, rect_region, rect_region); | |||
850 | XSubtractRegion( image_region->visible_region, rect_region, | |||
851 | image_region->visible_region); | |||
852 | XDestroyRegion( rect_region); | |||
853 | } | |||
854 | ||||
855 | ||||
856 | /** ------------------------------------------------------------------------ | |||
857 | Adds the specified rectangle to the region in image_region. | |||
858 | ------------------------------------------------------------------------ **/ | |||
859 | static void add_rect_to_image_region(image_region_type *image_region, | |||
860 | int x, int y, int width, int height) | |||
861 | { | |||
862 | XRectangle rect; | |||
863 | ||||
864 | rect.x = x; | |||
865 | rect.y = y; | |||
866 | rect.width = width; | |||
867 | rect.height = height; | |||
868 | XUnionRectWithRegion( &rect, image_region->visible_region, | |||
869 | image_region->visible_region); | |||
870 | } | |||
871 | ||||
872 | ||||
873 | /** ------------------------------------------------------------------------ | |||
874 | Returns TRUE if the given src's visual is already represented in | |||
875 | the image_regions list, FALSE otherwise. | |||
876 | ------------------------------------------------------------------------ **/ | |||
877 | static int src_in_region_list(image_win_type *src, list_ptr image_regions) | |||
878 | { | |||
879 | image_region_type *ir; | |||
880 | ||||
881 | for (ir = (image_region_type *) first_in_list( image_regions); ir; | |||
882 | ir = (image_region_type *) next_in_list( image_regions)) { | |||
883 | if (SAME_REGIONS( ir, src)((ir)->vis == (src)->vis && (ir)->cmap == (src )->cmap && (ir)->x_vis <= (src)->x_vis && (ir)->y_vis <= (src)->y_vis && (ir)->x_vis + (ir)->width >= (src)->x_vis + (src)->width && (ir)->y_vis + (ir)->height >= (src)->y_vis + (src )->height)) { | |||
884 | ||||
885 | return 1; | |||
886 | } | |||
887 | } | |||
888 | ||||
889 | return 0; | |||
890 | } | |||
891 | ||||
892 | ||||
893 | /** ------------------------------------------------------------------------ | |||
894 | Makes a new entry in image_wins with the given fields filled in. | |||
895 | ------------------------------------------------------------------------ **/ | |||
896 | static void add_window_to_list(list_ptr image_wins, Window w, | |||
897 | int xrr, int yrr, int x_vis, int y_vis, | |||
898 | int width, int height, int border_width, | |||
899 | Visual *vis, Colormap cmap, Window parent) | |||
900 | { | |||
901 | image_win_type *new_src; | |||
902 | ||||
903 | if ((new_src = (image_win_type *) malloc( sizeof( image_win_type))) == NULL((void*)0)) | |||
904 | ||||
905 | return; | |||
906 | ||||
907 | new_src->win = w; | |||
908 | new_src->x_rootrel = xrr; | |||
909 | new_src->y_rootrel = yrr; | |||
910 | new_src->x_vis = x_vis; | |||
911 | new_src->y_vis = y_vis; | |||
912 | new_src->width = width; | |||
913 | new_src->height = height; | |||
914 | new_src->border_width = border_width; | |||
915 | new_src->vis = vis; | |||
916 | new_src->cmap = cmap; | |||
917 | new_src->parent = parent; | |||
918 | add_to_list( image_wins, new_src); | |||
919 | } | |||
920 | ||||
921 | /** ------------------------------------------------------------------------ | |||
922 | Returns TRUE if the given src's visual is in the image planes, | |||
923 | FALSE otherwise. | |||
924 | ------------------------------------------------------------------------ **/ | |||
925 | static int src_in_image(image_win_type *src, int numImageVisuals, | |||
926 | XVisualInfo **pImageVisuals) | |||
927 | { | |||
928 | int i; | |||
929 | ||||
930 | for (i = 0 ; i < numImageVisuals ; i++) | |||
931 | { | |||
932 | if (pImageVisuals[i]->visual == src->vis) | |||
933 | return 1; | |||
934 | } | |||
935 | return 0; | |||
936 | } | |||
937 | ||||
938 | ||||
939 | /** ------------------------------------------------------------------------ | |||
940 | Returns TRUE if the given src's visual is in the overlay planes | |||
941 | and transparency is possible, FALSE otherwise. | |||
942 | ------------------------------------------------------------------------ **/ | |||
943 | static int src_in_overlay(image_region_type *src, int numOverlayVisuals, | |||
944 | OverlayInfo *pOverlayVisuals, | |||
945 | int *transparentColor, int *transparentType) | |||
946 | { | |||
947 | int i; | |||
948 | ||||
949 | for (i = 0 ; i < numOverlayVisuals ; i++) | |||
950 | { | |||
951 | if (((pOverlayVisuals[i].pOverlayVisualInfo)->visual == src->vis) | |||
952 | && (pOverlayVisuals[i].transparentType != None0L)) | |||
953 | { | |||
954 | *transparentColor = pOverlayVisuals[i].value; | |||
955 | *transparentType = pOverlayVisuals[i].transparentType; | |||
956 | return 1; | |||
957 | } | |||
958 | ||||
959 | else { | |||
960 | } | |||
961 | ||||
962 | } | |||
963 | return 0; | |||
964 | } | |||
965 | ||||
966 | ||||
967 | /********************** from wsutils.c ******************************/ | |||
968 | ||||
969 | /****************************************************************************** | |||
970 | * | |||
971 | * This file contains a set of example utility procedures; procedures that can | |||
972 | * help a "window-smart" Starbase or PHIGS program determine information about | |||
973 | * a device, and create image and overlay plane windows. To use these | |||
974 | * utilities, #include "wsutils.h" and compile this file and link the results | |||
975 | * with your program. | |||
976 | * | |||
977 | ******************************************************************************/ | |||
978 | ||||
979 | ||||
980 | ||||
981 | #define STATIC_GRAY0x01 0x01 | |||
982 | #define GRAY_SCALE0x02 0x02 | |||
983 | #define PSEUDO_COLOR0x04 0x04 | |||
984 | #define TRUE_COLOR0x10 0x10 | |||
985 | #define DIRECT_COLOR0x11 0x11 | |||
986 | ||||
987 | ||||
988 | static int weCreateServerOverlayVisualsProperty = False0; | |||
989 | ||||
990 | ||||
991 | /****************************************************************************** | |||
992 | * | |||
993 | * GetXVisualInfo() | |||
994 | * | |||
995 | * This routine takes an X11 Display, screen number, and returns whether the | |||
996 | * screen supports transparent overlays and three arrays: | |||
997 | * | |||
998 | * 1) All of the XVisualInfo struct's for the screen. | |||
999 | * 2) All of the OverlayInfo struct's for the screen. | |||
1000 | * 3) An array of pointers to the screen's image plane XVisualInfo | |||
1001 | * structs. | |||
1002 | * | |||
1003 | * The code below obtains the array of all the screen's visuals, and obtains | |||
1004 | * the array of all the screen's overlay visual information. It then processes | |||
1005 | * the array of the screen's visuals, determining whether the visual is an | |||
1006 | * overlay or image visual. | |||
1007 | * | |||
1008 | * If the routine sucessfully obtained the visual information, it returns zero. | |||
1009 | * If the routine didn't obtain the visual information, it returns non-zero. | |||
1010 | * | |||
1011 | ******************************************************************************/ | |||
1012 | ||||
1013 | int GetXVisualInfo(/* Which X server (aka "display"). */ | |||
1014 | Display *display, | |||
1015 | /* Which screen of the "display". */ | |||
1016 | int screen, | |||
1017 | /* Non-zero if there's at least one overlay visual and | |||
1018 | * if at least one of those supports a transparent pixel. */ | |||
1019 | int *transparentOverlays, | |||
1020 | /* Number of XVisualInfo struct's pointed to by pVisuals. */ | |||
1021 | int *numVisuals, | |||
1022 | /* All of the device's visuals. */ | |||
1023 | XVisualInfo **pVisuals, | |||
1024 | /* Number of OverlayInfo's pointed to by pOverlayVisuals. | |||
1025 | * If this number is zero, the device does not have | |||
1026 | * overlay planes. */ | |||
1027 | int *numOverlayVisuals, | |||
1028 | /* The device's overlay plane visual information. */ | |||
1029 | OverlayInfo **pOverlayVisuals, | |||
1030 | /* Number of XVisualInfo's pointed to by pImageVisuals. */ | |||
1031 | int *numImageVisuals, | |||
1032 | /* The device's image visuals. */ | |||
1033 | XVisualInfo ***pImageVisuals) | |||
1034 | { | |||
1035 | XVisualInfo getVisInfo; /* Paramters of XGetVisualInfo */ | |||
1036 | int mask; | |||
1037 | XVisualInfo *pVis, **pIVis; /* Faster, local copies */ | |||
1038 | OverlayInfo *pOVis; | |||
1039 | OverlayVisualPropertyRec *pOOldVis; | |||
1040 | int nVisuals, nOVisuals; | |||
1041 | Atom overlayVisualsAtom; /* Parameters for XGetWindowProperty */ | |||
1042 | Atom actualType; | |||
1043 | unsigned long numLongs, bytesAfter; | |||
1044 | int actualFormat; | |||
1045 | int nImageVisualsAlloced; /* Values to process the XVisualInfo */ | |||
1046 | int imageVisual; /* array */ | |||
1047 | ||||
1048 | ||||
1049 | /* First, get the list of visuals for this screen. */ | |||
1050 | getVisInfo.screen = screen; | |||
1051 | mask = VisualScreenMask0x2; | |||
1052 | ||||
1053 | *pVisuals = XGetVisualInfo(display, mask, &getVisInfo, numVisuals); | |||
1054 | if ((nVisuals = *numVisuals) <= 0) | |||
1055 | { | |||
1056 | /* Return that the information wasn't sucessfully obtained: */ | |||
1057 | return(1); | |||
1058 | } | |||
1059 | pVis = *pVisuals; | |||
1060 | ||||
1061 | ||||
1062 | /* Now, get the overlay visual information for this screen. To obtain | |||
1063 | * this information, get the SERVER_OVERLAY_VISUALS property. | |||
1064 | */ | |||
1065 | overlayVisualsAtom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True1); | |||
1066 | if (overlayVisualsAtom != None0L) | |||
1067 | { | |||
1068 | /* Since the Atom exists, we can request the property's contents. The | |||
1069 | * do-while loop makes sure we get the entire list from the X server. | |||
1070 | */ | |||
1071 | bytesAfter = 0; | |||
1072 | numLongs = sizeof(OverlayVisualPropertyRec) / sizeof(long); | |||
1073 | do | |||
1074 | { | |||
1075 | numLongs += bytesAfter * sizeof(long); | |||
1076 | XGetWindowProperty(display, RootWindow(display, screen)((&((_XPrivDisplay)(display))->screens[screen])->root ), | |||
1077 | overlayVisualsAtom, 0, numLongs, False0, | |||
1078 | overlayVisualsAtom, &actualType, &actualFormat, | |||
1079 | &numLongs, &bytesAfter, (unsigned char**) pOverlayVisuals); | |||
1080 | } while (bytesAfter > 0); | |||
1081 | ||||
1082 | ||||
1083 | /* Calculate the number of overlay visuals in the list. */ | |||
1084 | *numOverlayVisuals = numLongs / (sizeof(OverlayVisualPropertyRec) / sizeof(long)); | |||
1085 | } | |||
1086 | else | |||
1087 | { | |||
1088 | /* This screen doesn't have overlay planes. */ | |||
1089 | *numOverlayVisuals = 0; | |||
1090 | *pOverlayVisuals = NULL((void*)0); | |||
1091 | *transparentOverlays = 0; | |||
1092 | } | |||
1093 | ||||
1094 | ||||
1095 | /* Process the pVisuals array. */ | |||
1096 | *numImageVisuals = 0; | |||
1097 | nImageVisualsAlloced = 1; | |||
1098 | pIVis = *pImageVisuals = (XVisualInfo **) malloc(sizeof(XVisualInfo *)); | |||
1099 | while (--nVisuals >= 0) | |||
1100 | { | |||
1101 | nOVisuals = *numOverlayVisuals; | |||
1102 | pOVis = *pOverlayVisuals; | |||
1103 | imageVisual = True1; | |||
1104 | while (--nOVisuals >= 0) | |||
1105 | { | |||
1106 | pOOldVis = (OverlayVisualPropertyRec *) pOVis; | |||
1107 | if (pVis->visualid == pOOldVis->visualID) | |||
1108 | { | |||
1109 | imageVisual = False0; | |||
1110 | pOVis->pOverlayVisualInfo = pVis; | |||
1111 | if (pOVis->transparentType == TransparentPixel1) | |||
1112 | *transparentOverlays = 1; | |||
1113 | } | |||
1114 | pOVis++; | |||
1115 | } | |||
1116 | if (imageVisual) | |||
1117 | { | |||
1118 | if ((*numImageVisuals += 1) > nImageVisualsAlloced) | |||
1119 | { | |||
1120 | nImageVisualsAlloced++; | |||
1121 | *pImageVisuals = (XVisualInfo **) | |||
1122 | realloc(*pImageVisuals, (nImageVisualsAlloced * sizeof(XVisualInfo *))); | |||
1123 | pIVis = *pImageVisuals + (*numImageVisuals - 1); | |||
1124 | } | |||
1125 | *pIVis++ = pVis; | |||
1126 | } | |||
1127 | pVis++; | |||
1128 | } | |||
1129 | ||||
1130 | ||||
1131 | /* Return that the information was sucessfully obtained: */ | |||
1132 | return(0); | |||
1133 | ||||
1134 | } /* GetXVisualInfo() */ | |||
1135 | ||||
1136 | ||||
1137 | /****************************************************************************** | |||
1138 | * | |||
1139 | * FreeXVisualInfo() | |||
1140 | * | |||
1141 | * This routine frees the data that was allocated by GetXVisualInfo(). | |||
1142 | * | |||
1143 | ******************************************************************************/ | |||
1144 | ||||
1145 | void FreeXVisualInfo(XVisualInfo *pVisuals, OverlayInfo *pOverlayVisuals, | |||
1146 | XVisualInfo **pImageVisuals) | |||
1147 | { | |||
1148 | XFree(pVisuals); | |||
1149 | if (weCreateServerOverlayVisualsProperty) | |||
1150 | free(pOverlayVisuals); | |||
1151 | else | |||
1152 | XFree(pOverlayVisuals); | |||
1153 | free(pImageVisuals); | |||
1154 | ||||
1155 | } /* FreeXVisualInfo() */ |