Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/unix/native/libawt_xawt/awt/multiVis.c
41154 views
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) \
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)
132
#define MAX( a, b) ((a) > (b) ? a : b)
133
#endif
134
135
#define RED_SHIFT 16
136
#define GREEN_SHIFT 8
137
#define BLUE_SHIFT 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;
207
Vis->class = DirectColor ;
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 != TrueColor && src_vis->class != DirectColor)
232
{
233
for(i=0 ; i < ncolors ; i++)
234
{
235
colors[i].pixel = i ;
236
colors[i].pad = 0;
237
colors[i].flags = DoRed|DoGreen|DoBlue;
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|DoGreen|DoBlue;
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),
302
transparentOverlays,
303
numVisuals, pVisuals,
304
numOverlayVisuals, pOverlayVisuals,
305
numImageVisuals, pImageVisuals);
306
307
*vis_regions = *vis_image_regions = NULL ;
308
if ((*vis_regions = make_region_list( disp, srcRootWinid, &bbox,
309
&hasNonDefault, *numImageVisuals,
310
*pImageVisuals, allImage)) == NULL)
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 TrueColor :
344
for(i=0 ; i < srch ; i++)
345
{
346
for(j=0 ; j < srcw ; j++)
347
{
348
old_pixel = XGetPixel(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_SHIFT)
363
|((colors[green_ind].green >> 8) << GREEN_SHIFT)
364
|((colors[blue_ind].blue >> 8) << BLUE_SHIFT)
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);
375
376
}
377
}
378
break;
379
case DirectColor :
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) ;
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_SHIFT)
392
|((colors[green_ind].green >> 8) << GREEN_SHIFT)
393
|((colors[blue_ind].blue >> 8) << BLUE_SHIFT)
394
);
395
XPutPixel(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) ;
406
407
new_pixel = (
408
((colors[old_pixel].red >> 8) << RED_SHIFT)
409
|((colors[old_pixel].green >> 8) << GREEN_SHIFT)
410
|((colors[old_pixel].blue >> 8) << BLUE_SHIFT)
411
);
412
XPutPixel(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,width,height,
440
8,0) ;
441
bytes_per_line = ximage->bytes_per_line;
442
443
if (format == ZPixmap)
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) -
467
MAX( vis_reg->rects[rect].x1, bbox.x);
468
srcRect_height = MIN( vis_reg->rects[rect].y2, bbox.height + bbox.y) -
469
MAX( vis_reg->rects[rect].y1, bbox.y);
470
diff = bbox.x - vis_reg->rects[rect].x1;
471
srcRect_x = MAX( 0, diff) + (vis_reg->rects[rect].x1 - reg->x_rootrel - reg->border);
472
dst_x = MAX( 0, -diff) ;
473
diff = bbox.y - vis_reg->rects[rect].y1;
474
srcRect_y = MAX( 0, diff) + (vis_reg->rects[rect].y1 - reg->y_rootrel - reg->border);
475
dst_y = MAX( 0, -diff) ;
476
reg_image = XGetImage(disp,reg->win,srcRect_x,srcRect_y,
477
srcRect_width,srcRect_height,AllPlanes,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);
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;
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)
564
- MAX( reg->x_vis, bbox.x);
565
srcRect_height = MIN( reg->height + reg->y_vis, bbox.height
566
+ bbox.y) - MAX( reg->y_vis, bbox.y);
567
diff = bbox.x - reg->x_vis;
568
srcRect_x = MAX( 0, diff) + (reg->x_vis - reg->x_rootrel - reg->border);
569
dst_x = MAX( 0, -diff) ;
570
diff = bbox.y - reg->y_vis;
571
srcRect_y = MAX( 0, diff) + (reg->y_vis - reg->y_rootrel - reg->border);
572
dst_y = MAX( 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, ZPixmap);
576
577
/* let's assume byte per pixel for overlay image for now */
578
if ((image->depth == 8) && (transparentType == TransparentPixel))
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) ;
595
XPutPixel(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 == TransparentPixel) {
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);
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) ;
624
XPutPixel(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);
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) ;
650
XPutPixel(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);
666
} /* end of src_in_overlay */
667
} /** end transparency **/
668
/* JDK modification - call XDestroyImage if non-null */
669
if (ximage_ipm != NULL) {
670
XDestroyImage(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 == IsViewable &&
707
curr_attrs->class == InputOutput &&
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);
730
curr_clipY = MAX( pclip->y, y_rootrel + (int) curr_attrs->border_width);
731
curr_clipRt = MIN( pclip->x + (int) pclip->width,
732
x_rootrel + (int) curr_attrs->width +
733
2 * (int) curr_attrs->border_width);
734
curr_clipBt = MIN( pclip->y + (int) pclip->height,
735
y_rootrel + (int) curr_attrs->height +
736
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);
747
new_width = MIN( curr_clipRt, child_xrr + (int) child_attrs.width
748
+ 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);
756
new_height = MIN( curr_clipBt,
757
child_yrr + (int) child_attrs.height +
758
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 = False;
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) ? True:False;
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;
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_CURR);
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)) {
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) ||
860
new_reg->cmap != DefaultColormapOfScreen(
861
win_attrs.screen)) {
862
*hasNonDefault = True;
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, True);
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)) {
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)
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 != None))
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_GRAY 0x01
1044
#define GRAY_SCALE 0x02
1045
#define PSEUDO_COLOR 0x04
1046
#define TRUE_COLOR 0x10
1047
#define DIRECT_COLOR 0x11
1048
1049
1050
static int weCreateServerOverlayVisualsProperty = False;
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 = VisualScreenMask;
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", True);
1128
if (overlayVisualsAtom != None)
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),
1139
overlayVisualsAtom, 0, numLongs, False,
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;
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 = True;
1166
while (--nOVisuals >= 0)
1167
{
1168
pOOldVis = (OverlayVisualPropertyRec *) pOVis;
1169
if (pVis->visualid == pOOldVis->visualID)
1170
{
1171
imageVisual = False;
1172
pOVis->pOverlayVisualInfo = pVis;
1173
if (pOVis->transparentType == TransparentPixel)
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() */
1218
1219