#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/X.h>
#include <stdio.h>
#include "list.h"
#include "wsutils.h"
#include "multiVis.h"
typedef struct {
short x1, x2, y1, y2;
} myBox, myBOX, myBoxRec, *myBoxPtr;
typedef struct my_XRegion {
long size;
long numRects;
myBOX *rects;
myBOX extents;
} myREGION;
typedef struct {
Window win;
Visual *vis;
Colormap cmap;
int x_rootrel, y_rootrel;
int x_vis, y_vis;
int width, height;
int border_width;
Window parent;
} image_win_type;
typedef struct {
Window win;
Visual *vis;
Colormap cmap;
int x_rootrel, y_rootrel;
int x_vis, y_vis;
int width, height;
int border;
Region visible_region;
} image_region_type;
#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)
#ifndef MIN
#define MIN( a, b) ((a) < (b) ? a : b)
#define MAX( a, b) ((a) > (b) ? a : b)
#endif
#define RED_SHIFT 16
#define GREEN_SHIFT 8
#define BLUE_SHIFT 0
static int QueryColorMap(
Display *, Colormap , Visual *,
XColor **, int *, int *, int *
);
static void TransferImage(
Display *, XImage *,int, int , image_region_type*,
XImage *,int ,int
);
static XImage * ReadRegionsInList(
Display *, Visual *, int ,int ,int ,
int , XRectangle, list_ptr
);
static list_ptr make_region_list(
Display*, Window, XRectangle*,
int*, int, XVisualInfo**, int *
);
static void destroy_region_list(
list_ptr
) ;
static void subtr_rect_from_image_region(
image_region_type *, int , int , int , int
);
static void add_rect_to_image_region(
image_region_type *,
int , int , int , int
);
static int src_in_region_list(
image_win_type *, list_ptr
);
static void add_window_to_list(
list_ptr, Window, int, int ,
int , int , int , int, int,
Visual*, Colormap, Window
);
static int src_in_image(
image_win_type *, int , XVisualInfo**
);
static int src_in_overlay(
image_region_type *, int, OverlayInfo *, int*, int*
);
static void make_src_list(
Display *, list_ptr, XRectangle *, Window,
int, int, XWindowAttributes *, XRectangle *
);
static void destroy_image_region(
image_region_type *
);
void initFakeVisual(Vis)
Visual *Vis ;
{
Vis->ext_data=NULL;
Vis->class = DirectColor ;
Vis->red_mask = 0x00FF0000;
Vis->green_mask = 0x0000FF00 ;
Vis->blue_mask = 0x000000FF ;
Vis->map_entries = 256 ;
Vis->bits_per_rgb = 8 ;
}
static int
QueryColorMap(disp,src_cmap,src_vis,src_colors,rShift,gShift,bShift)
Display *disp ;
Visual *src_vis ;
Colormap src_cmap ;
XColor **src_colors ;
int *rShift, *gShift, *bShift;
{
int ncolors,i ;
unsigned long redMask, greenMask, blueMask;
int redShift, greenShift, blueShift;
XColor *colors ;
ncolors = src_vis->map_entries ;
*src_colors = colors = (XColor *)malloc(ncolors * sizeof(XColor) ) ;
if(src_vis->class != TrueColor && src_vis->class != DirectColor)
{
for(i=0 ; i < ncolors ; i++)
{
colors[i].pixel = i ;
colors[i].pad = 0;
colors[i].flags = DoRed|DoGreen|DoBlue;
}
}
else
{
redMask = src_vis->red_mask;
greenMask = src_vis->green_mask;
blueMask = src_vis->blue_mask;
redShift = 0; while (!(redMask&0x1)) {
redShift++;
redMask = redMask>>1;
}
greenShift = 0; while (!(greenMask&0x1)) {
greenShift++;
greenMask = greenMask>>1;
}
blueShift = 0; while (!(blueMask&0x1)) {
blueShift++;
blueMask = blueMask>>1;
}
*rShift = redShift ;
*gShift = greenShift ;
*bShift = blueShift ;
for (i=0; i<ncolors; i++) {
if( i <= redMask)colors[i].pixel = (i<<redShift) ;
if( i <= greenMask)colors[i].pixel |= (i<<greenShift) ;
if( i <= blueMask)colors[i].pixel |= (i<<blueShift) ;
colors[i].pad = 0;
colors[i].flags = DoRed|DoGreen|DoBlue;
}
}
XQueryColors(disp, src_cmap, colors, ncolors);
return ncolors ;
}
int
GetMultiVisualRegions(disp,srcRootWinid, x, y, width, height,
transparentOverlays,numVisuals, pVisuals,numOverlayVisuals, pOverlayVisuals,
numImageVisuals, pImageVisuals,vis_regions,vis_image_regions,allImage)
Display *disp;
Window srcRootWinid;
int x;
int y;
unsigned int width;
unsigned int height;
int *transparentOverlays ;
int *numVisuals;
XVisualInfo **pVisuals;
int *numOverlayVisuals;
OverlayInfo **pOverlayVisuals;
int *numImageVisuals;
XVisualInfo ***pImageVisuals;
list_ptr *vis_regions;
list_ptr *vis_image_regions ;
int *allImage ;
{
int hasNonDefault;
XRectangle bbox;
bbox.x = x;
bbox.y = y;
bbox.width = width;
bbox.height = height;
GetXVisualInfo(disp,DefaultScreen(disp),
transparentOverlays,
numVisuals, pVisuals,
numOverlayVisuals, pOverlayVisuals,
numImageVisuals, pImageVisuals);
*vis_regions = *vis_image_regions = NULL ;
if ((*vis_regions = make_region_list( disp, srcRootWinid, &bbox,
&hasNonDefault, *numImageVisuals,
*pImageVisuals, allImage)) == NULL)
return 0 ;
if (*transparentOverlays)
{
*allImage = 1;
*vis_image_regions =
make_region_list( disp, srcRootWinid, &bbox, &hasNonDefault,
*numImageVisuals, *pImageVisuals, allImage);
}
if ( ( *vis_regions && (*vis_regions)->next && (*vis_regions)->next->next ) ||
( *vis_image_regions && (*vis_image_regions)->next &&
(*vis_image_regions)->next->next ) ) return 1 ;
else return 0 ;
}
static void TransferImage(disp,reg_image,srcw,srch,reg,
target_image,dst_x,dst_y)
Display *disp;
XImage *reg_image,*target_image ;
image_region_type *reg;
int srcw,srch,dst_x , dst_y ;
{
int i,j,old_pixel,new_pixel,red_ind,green_ind,blue_ind ;
XColor *colors;
int rShift,gShift,bShift;
(void) QueryColorMap(disp,reg->cmap,reg->vis,&colors,
&rShift,&gShift,&bShift) ;
switch (reg->vis->class) {
case TrueColor :
for(i=0 ; i < srch ; i++)
{
for(j=0 ; j < srcw ; j++)
{
old_pixel = XGetPixel(reg_image,j,i) ;
if( reg->vis->map_entries == 16) {
red_ind = (old_pixel & reg->vis->red_mask) >> rShift ;
green_ind = (old_pixel & reg->vis->green_mask) >> gShift ;
blue_ind = (old_pixel & reg->vis->blue_mask) >> bShift ;
new_pixel = (
((colors[red_ind].red >> 8) << RED_SHIFT)
|((colors[green_ind].green >> 8) << GREEN_SHIFT)
|((colors[blue_ind].blue >> 8) << BLUE_SHIFT)
);
}
else
new_pixel = old_pixel;
XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel);
}
}
break;
case DirectColor :
for(i=0 ; i < srch ; i++)
{
for(j=0 ; j < srcw ; j++)
{
old_pixel = XGetPixel(reg_image,j,i) ;
red_ind = (old_pixel & reg->vis->red_mask) >> rShift ;
green_ind = (old_pixel & reg->vis->green_mask) >> gShift ;
blue_ind = (old_pixel & reg->vis->blue_mask) >> bShift ;
new_pixel = (
((colors[red_ind].red >> 8) << RED_SHIFT)
|((colors[green_ind].green >> 8) << GREEN_SHIFT)
|((colors[blue_ind].blue >> 8) << BLUE_SHIFT)
);
XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel);
}
}
break;
default :
for(i=0 ; i < srch ; i++)
{
for(j=0 ; j < srcw ; j++)
{
old_pixel = XGetPixel(reg_image,j,i) ;
new_pixel = (
((colors[old_pixel].red >> 8) << RED_SHIFT)
|((colors[old_pixel].green >> 8) << GREEN_SHIFT)
|((colors[old_pixel].blue >> 8) << BLUE_SHIFT)
);
XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel);
}
}
break;
}
}
static XImage *
ReadRegionsInList(disp,fakeVis,depth,format,width,height,bbox,regions)
Display *disp ;
Visual *fakeVis ;
int depth , width , height ;
int format ;
XRectangle bbox;
list_ptr regions;
{
image_region_type *reg;
int dst_x, dst_y;
int diff;
XImage *reg_image,*ximage ;
int srcRect_x,srcRect_y,srcRect_width,srcRect_height ;
int rem ;
int bytes_per_line;
int bitmap_unit;
bitmap_unit = sizeof (long);
if (format == ZPixmap)
bytes_per_line = width*depth/8;
else
bytes_per_line = width/8;
if (format == ZPixmap) {
rem = (bytes_per_line*8)%bitmap_unit;
if (rem)
bytes_per_line += (rem/8 + 1);
}
ximage = XCreateImage(disp,fakeVis,depth,format,0,NULL,width,height,
8,0) ;
bytes_per_line = ximage->bytes_per_line;
if (format == ZPixmap)
ximage->data = malloc(height*bytes_per_line);
else
ximage->data = malloc(height*bytes_per_line*depth);
ximage->bits_per_pixel = depth;
for (reg = (image_region_type *) first_in_list( regions); reg;
reg = (image_region_type *) next_in_list( regions))
{
int rect;
struct my_XRegion *vis_reg;
vis_reg = (struct my_XRegion *)(reg->visible_region);
for (rect = 0;
rect < vis_reg->numRects;
rect++)
{
srcRect_width = MIN( vis_reg->rects[rect].x2, bbox.width + bbox.x) -
MAX( vis_reg->rects[rect].x1, bbox.x);
srcRect_height = MIN( vis_reg->rects[rect].y2, bbox.height + bbox.y) -
MAX( vis_reg->rects[rect].y1, bbox.y);
diff = bbox.x - vis_reg->rects[rect].x1;
srcRect_x = MAX( 0, diff) + (vis_reg->rects[rect].x1 - reg->x_rootrel - reg->border);
dst_x = MAX( 0, -diff) ;
diff = bbox.y - vis_reg->rects[rect].y1;
srcRect_y = MAX( 0, diff) + (vis_reg->rects[rect].y1 - reg->y_rootrel - reg->border);
dst_y = MAX( 0, -diff) ;
reg_image = XGetImage(disp,reg->win,srcRect_x,srcRect_y,
srcRect_width,srcRect_height,AllPlanes,format) ;
TransferImage(disp,reg_image,srcRect_width,
srcRect_height,reg,ximage,dst_x,dst_y) ;
}
}
return ximage ;
}
XImage *ReadAreaToImage(disp, srcRootWinid, x, y, width, height,
numVisuals,pVisuals,numOverlayVisuals,pOverlayVisuals,numImageVisuals,
pImageVisuals,vis_regions,vis_image_regions,format,allImage)
Display *disp;
Window srcRootWinid;
int x;
int y;
unsigned int width;
unsigned int height;
int numVisuals;
XVisualInfo *pVisuals;
int numOverlayVisuals;
OverlayInfo *pOverlayVisuals;
int numImageVisuals;
XVisualInfo **pImageVisuals;
list_ptr vis_regions;
list_ptr vis_image_regions ;
int format;
int allImage ;
{
image_region_type *reg;
XRectangle bbox;
int depth ;
XImage *ximage, *ximage_ipm = NULL;
Visual fakeVis ;
int x1, y1;
XImage *image;
#if 0
unsigned char *pmData , *ipmData ;
#endif
int transparentColor, transparentType;
int srcRect_x,srcRect_y,srcRect_width,srcRect_height ;
int diff ;
int dst_x, dst_y;
int pixel;
bbox.x = x;
bbox.y = y;
bbox.width = width;
bbox.height = height;
initFakeVisual(&fakeVis) ;
depth = 24 ;
ximage = ReadRegionsInList(disp,&fakeVis,depth,format,width,height,
bbox,vis_regions) ;
#if 0
pmData = (unsigned char *)ximage -> data ;
#endif
if (vis_image_regions && (vis_image_regions->next) && !allImage)
{
ximage_ipm = ReadRegionsInList(disp,&fakeVis,depth,format,width,height,
bbox,vis_image_regions) ;
#if 0
ipmData = (unsigned char *)ximage_ipm -> data ;
#endif
}
for (reg = (image_region_type *) first_in_list( vis_regions); reg;
reg = (image_region_type *) next_in_list( vis_regions))
{
if (src_in_overlay( reg, numOverlayVisuals, pOverlayVisuals,
&transparentColor, &transparentType))
{
int test = 0 ;
srcRect_width = MIN( reg->width + reg->x_vis, bbox.width + bbox.x)
- MAX( reg->x_vis, bbox.x);
srcRect_height = MIN( reg->height + reg->y_vis, bbox.height
+ bbox.y) - MAX( reg->y_vis, bbox.y);
diff = bbox.x - reg->x_vis;
srcRect_x = MAX( 0, diff) + (reg->x_vis - reg->x_rootrel - reg->border);
dst_x = MAX( 0, -diff) ;
diff = bbox.y - reg->y_vis;
srcRect_y = MAX( 0, diff) + (reg->y_vis - reg->y_rootrel - reg->border);
dst_y = MAX( 0, -diff) ;
image = XGetImage(disp, reg->win, srcRect_x, srcRect_y,
srcRect_width, srcRect_height, 0xffffffff, ZPixmap);
if ((image->depth == 8) && (transparentType == TransparentPixel))
{
unsigned char *pixel_ptr;
unsigned char *start_of_line = (unsigned char *) image->data;
for (y1 = 0; y1 < srcRect_height; y1++) {
pixel_ptr = start_of_line;
for (x1 = 0; x1 < srcRect_width; x1++)
{
if (*pixel_ptr++ == transparentColor)
{
#if 0
*pmData++ = *ipmData++;
*pmData++ = *ipmData++;
*pmData++ = *ipmData++;
#endif
pixel = XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1) ;
XPutPixel(ximage,dst_x+x1, dst_y+y1,pixel);
if(!test){
test = 1 ;
}
}
#if 0
else {
pmData +=3;
ipmData +=3;
}
#endif
}
start_of_line += image->bytes_per_line;
}
} else {
if (transparentType == TransparentPixel) {
for (y1 = 0; y1 < srcRect_height; y1++) {
for (x1 = 0; x1 < srcRect_width; x1++)
{
int pixel_value = XGetPixel(image, x1, y1);
if (pixel_value == transparentColor)
{
#if 0
*pmData++ = *ipmData++;
*pmData++ = *ipmData++;
*pmData++ = *ipmData++;
#endif
pixel = XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1) ;
XPutPixel(ximage,dst_x+x1, dst_y+y1,pixel);
if(!test){
test = 1 ;
}
}
#if 0
else {
pmData +=3;
ipmData +=3;
}
#endif
}
}
} else {
for (y1 = 0; y1 < srcRect_height; y1++) {
for (x1 = 0; x1 < srcRect_width; x1++)
{
int pixel_value = XGetPixel(image, x1, y1);
if (pixel_value & transparentColor)
{
#if 0
*pmData++ = *ipmData++;
*pmData++ = *ipmData++;
*pmData++ = *ipmData++;
#endif
pixel = XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1) ;
XPutPixel(ximage,dst_x+x1, dst_y+y1,pixel);
if(!test){
test = 1 ;
}
}
#if 0
else {
pmData +=3;
ipmData +=3;
}
#endif
}
}
}
}
XDestroyImage (image);
}
}
destroy_region_list( vis_regions);
if (vis_image_regions) destroy_region_list( vis_image_regions );
FreeXVisualInfo(pVisuals, pOverlayVisuals, pImageVisuals);
XSync(disp, 0);
return ximage;
}
static void make_src_list( disp, image_wins, bbox, curr, x_rootrel, y_rootrel,
curr_attrs, pclip)
Display *disp;
list_ptr image_wins;
XRectangle *bbox;
Window curr;
int x_rootrel;
int y_rootrel;
XWindowAttributes *curr_attrs;
XRectangle *pclip;
{
XWindowAttributes child_attrs;
Window root, parent, *child;
Window *save_child_list;
unsigned int nchild;
XRectangle child_clip;
int curr_clipX, curr_clipY, curr_clipRt, curr_clipBt;
if (curr_attrs->map_state == IsViewable &&
curr_attrs->class == InputOutput &&
!( pclip->x >= (int) (bbox->x + bbox->width) ||
pclip->y >= (int) (bbox->y + bbox->height) ||
(int) (pclip->x + pclip->width) <= bbox->x ||
(int) (pclip->y + pclip->height) <= bbox->y)) {
XQueryTree( disp, curr, &root, &parent, &child, &nchild );
save_child_list = child;
add_window_to_list( image_wins, curr, x_rootrel, y_rootrel,
pclip->x, pclip->y,
pclip->width, pclip->height,
curr_attrs->border_width,curr_attrs->visual,
curr_attrs->colormap, parent);
curr_clipX = MAX( pclip->x, x_rootrel + (int) curr_attrs->border_width);
curr_clipY = MAX( pclip->y, y_rootrel + (int) curr_attrs->border_width);
curr_clipRt = MIN( pclip->x + (int) pclip->width,
x_rootrel + (int) curr_attrs->width +
2 * (int) curr_attrs->border_width);
curr_clipBt = MIN( pclip->y + (int) pclip->height,
y_rootrel + (int) curr_attrs->height +
2 * (int) curr_attrs->border_width);
while (nchild--) {
int new_width, new_height;
int child_xrr, child_yrr;
XGetWindowAttributes( disp, *child, &child_attrs);
child_xrr = x_rootrel + child_attrs.x + curr_attrs->border_width;
child_clip.x = MAX( curr_clipX, child_xrr);
new_width = MIN( curr_clipRt, child_xrr + (int) child_attrs.width
+ 2 * child_attrs.border_width)
- child_clip.x;
if (new_width >= 0) {
child_clip.width = new_width;
child_yrr = y_rootrel + child_attrs.y +
curr_attrs->border_width;
child_clip.y = MAX( curr_clipY, child_yrr);
new_height = MIN( curr_clipBt,
child_yrr + (int) child_attrs.height +
2 * child_attrs.border_width)
- child_clip.y;
if (new_height >= 0) {
child_clip.height = new_height;
make_src_list( disp, image_wins, bbox, *child,
child_xrr, child_yrr,
&child_attrs, &child_clip);
}
}
child++;
}
XFree( save_child_list);
}
}
static list_ptr make_region_list( disp, win, bbox, hasNonDefault,
numImageVisuals, pImageVisuals, allImage)
Display *disp;
Window win;
XRectangle *bbox;
int *hasNonDefault;
int numImageVisuals;
XVisualInfo **pImageVisuals;
int *allImage;
{
XWindowAttributes win_attrs;
list image_wins;
list_ptr image_regions;
list_ptr srcs_left;
image_region_type *new_reg;
image_win_type *base_src, *src;
Region bbox_region = XCreateRegion();
XRectangle clip;
int image_only;
int count=0 ;
*hasNonDefault = False;
XUnionRectWithRegion( bbox, bbox_region, bbox_region);
XGetWindowAttributes( disp, win, &win_attrs);
zero_list( &image_wins);
clip.x = 0;
clip.y = 0;
clip.width = win_attrs.width;
clip.height = win_attrs.height;
make_src_list( disp, &image_wins, bbox, win,
0 , 0 , &win_attrs, &clip);
image_regions = new_list();
image_only = (*allImage) ? True:False;
for (base_src = (image_win_type *) first_in_list( &image_wins); base_src;
base_src = (image_win_type *) next_in_list( &image_wins))
{
if (!image_only || src_in_image(base_src, numImageVisuals, pImageVisuals))
{
if (!src_in_region_list( base_src, image_regions))
{
if (! (new_reg = (image_region_type *)
malloc( sizeof( image_region_type)))) {
return (list_ptr) NULL;
}
count++;
new_reg->visible_region = XCreateRegion();
new_reg->win = base_src->win;
new_reg->vis = base_src->vis;
new_reg->cmap = base_src->cmap;
new_reg->x_rootrel = base_src->x_rootrel;
new_reg->y_rootrel = base_src->y_rootrel;
new_reg->x_vis = base_src->x_vis;
new_reg->y_vis = base_src->y_vis;
new_reg->width = base_src->width;
new_reg->height = base_src->height;
new_reg->border = base_src->border_width;
srcs_left = (list_ptr) dup_list_head( &image_wins, START_AT_CURR);
for (src = (image_win_type *) first_in_list( srcs_left); src;
src = (image_win_type *) next_in_list( srcs_left)) {
if (SAME_REGIONS( base_src, src)) {
add_rect_to_image_region( new_reg, src->x_vis, src->y_vis,
src->width, src->height);
}
else {
if (!image_only || src_in_image(src, numImageVisuals, pImageVisuals))
{
subtr_rect_from_image_region( new_reg, src->x_vis,
src->y_vis, src->width, src->height);
}
}
}
XIntersectRegion( bbox_region, new_reg->visible_region,
new_reg->visible_region);
if (! XEmptyRegion( new_reg->visible_region)) {
add_to_list( image_regions, new_reg);
if (new_reg->vis != DefaultVisualOfScreen( win_attrs.screen) ||
new_reg->cmap != DefaultColormapOfScreen(
win_attrs.screen)) {
*hasNonDefault = True;
}
}
else {
XDestroyRegion( new_reg->visible_region);
free( (void *) new_reg);
}
}
} else *allImage = 0;
}
delete_list( &image_wins, True);
XDestroyRegion( bbox_region);
return image_regions;
}
static void destroy_image_region(image_region)
image_region_type *image_region;
{
XDestroyRegion( image_region->visible_region);
free( (void *) image_region);
}
static void destroy_region_list( rlist)
list_ptr rlist;
{
delete_list_destroying( rlist, (DESTRUCT_FUNC_PTR)destroy_image_region);
}
static void subtr_rect_from_image_region( image_region, x, y, width, height)
image_region_type *image_region;
int x;
int y;
int width;
int height;
{
XRectangle rect;
Region rect_region;
rect_region = XCreateRegion();
rect.x = x;
rect.y = y;
rect.width = width;
rect.height = height;
XUnionRectWithRegion( &rect, rect_region, rect_region);
XSubtractRegion( image_region->visible_region, rect_region,
image_region->visible_region);
XDestroyRegion( rect_region);
}
static void add_rect_to_image_region( image_region, x, y, width, height)
image_region_type *image_region;
int x;
int y;
int width;
int height;
{
XRectangle rect;
rect.x = x;
rect.y = y;
rect.width = width;
rect.height = height;
XUnionRectWithRegion( &rect, image_region->visible_region,
image_region->visible_region);
}
static int src_in_region_list( src, image_regions)
image_win_type *src;
list_ptr image_regions;
{
image_region_type *ir;
for (ir = (image_region_type *) first_in_list( image_regions); ir;
ir = (image_region_type *) next_in_list( image_regions)) {
if (SAME_REGIONS( ir, src)) {
return 1;
}
}
return 0;
}
static void add_window_to_list( image_wins, w, xrr, yrr, x_vis, y_vis,
width, height, border_width,vis, cmap, parent)
list_ptr image_wins;
Window w;
int xrr;
int yrr;
int x_vis;
int y_vis;
int width;
int height;
int border_width;
Visual *vis;
Colormap cmap;
Window parent;
{
image_win_type *new_src;
if ((new_src = (image_win_type *) malloc( sizeof( image_win_type))) == NULL)
return;
new_src->win = w;
new_src->x_rootrel = xrr;
new_src->y_rootrel = yrr;
new_src->x_vis = x_vis;
new_src->y_vis = y_vis;
new_src->width = width;
new_src->height = height;
new_src->border_width = border_width;
new_src->vis = vis;
new_src->cmap = cmap;
new_src->parent = parent;
add_to_list( image_wins, new_src);
}
static int src_in_image( src, numImageVisuals, pImageVisuals)
image_win_type *src;
int numImageVisuals;
XVisualInfo **pImageVisuals;
{
int i;
for (i = 0 ; i < numImageVisuals ; i++)
{
if (pImageVisuals[i]->visual == src->vis)
return 1;
}
return 0;
}
static int src_in_overlay( src, numOverlayVisuals, pOverlayVisuals,
transparentColor, transparentType)
image_region_type *src;
int numOverlayVisuals;
OverlayInfo *pOverlayVisuals;
int *transparentColor;
int *transparentType;
{
int i;
for (i = 0 ; i < numOverlayVisuals ; i++)
{
if (((pOverlayVisuals[i].pOverlayVisualInfo)->visual == src->vis)
&& (pOverlayVisuals[i].transparentType != None))
{
*transparentColor = pOverlayVisuals[i].value;
*transparentType = pOverlayVisuals[i].transparentType;
return 1;
}
else {
}
}
return 0;
}
#define STATIC_GRAY 0x01
#define GRAY_SCALE 0x02
#define PSEUDO_COLOR 0x04
#define TRUE_COLOR 0x10
#define DIRECT_COLOR 0x11
static int weCreateServerOverlayVisualsProperty = False;
int GetXVisualInfo(display, screen, transparentOverlays,
numVisuals, pVisuals,
numOverlayVisuals, pOverlayVisuals,
numImageVisuals, pImageVisuals)
Display *display;
int screen;
int *transparentOverlays;
int *numVisuals;
XVisualInfo **pVisuals;
int *numOverlayVisuals;
OverlayInfo **pOverlayVisuals;
int *numImageVisuals;
XVisualInfo ***pImageVisuals;
{
XVisualInfo getVisInfo;
int mask;
XVisualInfo *pVis, **pIVis;
OverlayInfo *pOVis;
OverlayVisualPropertyRec *pOOldVis;
int nVisuals, nOVisuals;
Atom overlayVisualsAtom;
Atom actualType;
unsigned long numLongs, bytesAfter;
int actualFormat;
int nImageVisualsAlloced;
int imageVisual;
getVisInfo.screen = screen;
mask = VisualScreenMask;
*pVisuals = XGetVisualInfo(display, mask, &getVisInfo, numVisuals);
if ((nVisuals = *numVisuals) <= 0)
{
return(1);
}
pVis = *pVisuals;
overlayVisualsAtom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True);
if (overlayVisualsAtom != None)
{
bytesAfter = 0;
numLongs = sizeof(OverlayVisualPropertyRec) / 4;
do
{
numLongs += bytesAfter * 4;
XGetWindowProperty(display, RootWindow(display, screen),
overlayVisualsAtom, 0, numLongs, False,
overlayVisualsAtom, &actualType, &actualFormat,
&numLongs, &bytesAfter, (unsigned char**) pOverlayVisuals);
} while (bytesAfter > 0);
*numOverlayVisuals = numLongs / (sizeof(OverlayVisualPropertyRec) / 4);
}
else
{
*numOverlayVisuals = 0;
*pOverlayVisuals = NULL;
*transparentOverlays = 0;
}
*numImageVisuals = 0;
nImageVisualsAlloced = 1;
pIVis = *pImageVisuals = (XVisualInfo **) malloc(sizeof(XVisualInfo *));
while (--nVisuals >= 0)
{
nOVisuals = *numOverlayVisuals;
pOVis = *pOverlayVisuals;
imageVisual = True;
while (--nOVisuals >= 0)
{
pOOldVis = (OverlayVisualPropertyRec *) pOVis;
if (pVis->visualid == pOOldVis->visualID)
{
imageVisual = False;
pOVis->pOverlayVisualInfo = pVis;
if (pOVis->transparentType == TransparentPixel)
*transparentOverlays = 1;
}
pOVis++;
}
if (imageVisual)
{
if ((*numImageVisuals += 1) > nImageVisualsAlloced)
{
nImageVisualsAlloced++;
*pImageVisuals = (XVisualInfo **)
realloc(*pImageVisuals, (nImageVisualsAlloced * sizeof(XVisualInfo *)));
pIVis = *pImageVisuals + (*numImageVisuals - 1);
}
*pIVis++ = pVis;
}
pVis++;
}
return(0);
}
void FreeXVisualInfo(pVisuals, pOverlayVisuals, pImageVisuals)
XVisualInfo *pVisuals;
OverlayInfo *pOverlayVisuals;
XVisualInfo **pImageVisuals;
{
XFree(pVisuals);
if (weCreateServerOverlayVisualsProperty)
free(pOverlayVisuals);
else
XFree(pOverlayVisuals);
free(pImageVisuals);
}