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