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