       1 /*
       2  * Copyright (c) 1999, 2013, 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 /* $XConsortium: multiVis.c /main/4 1996/10/14 15:04:08 swick $ */
      26 /** ------------------------------------------------------------------------
      27         This file contains functions to create a list of regions which
      28         tile a specified window.  Each region contains all visible
      29         portions of the window which are drawn with the same visual.
      30         If the window consists of subwindows of two different visual types,
      31         there will be two regions in the list.  The list can be traversed
      32         to correctly pull an image of the window using XGetImage or the
      33         Image Library.
      34
      35  This file is available under and governed by the GNU General Public
      36  License version 2 only, as published by the Free Software Foundation.
      37  However, the following notice accompanied the original version of this
      38  file:
      39
      40 Copyright (c) 1994 Hewlett-Packard Co.
      41 Copyright (c) 1996  X Consortium
      42
      43 Permission is hereby granted, free of charge, to any person obtaining
      44 a copy of this software and associated documentation files (the
      45 "Software"), to deal in the Software without restriction, including
      46 without limitation the rights to use, copy, modify, merge, publish,
      47 distribute, sublicense, and sell copies of the Software, and to
      48 permit persons to whom the Software is furnished to do so, subject to
      49 the following conditions:
      50
      51 The above copyright notice and this permission notice shall be included
      52 in all copies or substantial portions of the Software.
      53
      54 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      55 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      56 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      57 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
      58 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      59 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      60 OTHER DEALINGS IN THE SOFTWARE.
      61
      62 Except as contained in this notice, the name of the X Consortium shall
      63 not be used in advertising or otherwise to promote the sale, use or
      64 other dealings in this Software without prior written authorization
      65 from the X Consortium.
      66
      67     ------------------------------------------------------------------------ **/
      68 #include <stdlib.h>
      69 #include <X11/Xlib.h>
      70 #include <X11/Xutil.h>
      71 #include <X11/X.h>
      72 #include <stdio.h>
      73 #include "list.h"
      74 #include "wsutils.h"
      75 #include "multiVis.h"
      76 #include "robot_common.h"
      77
      78 static char *vis_class_str[] = { "StaticGray" , "GrayScale" , "StaticColor",
      79                                  "PseudoColor","TrueColor","DirectColor" } ;
      80 /* These structures are copied from X11/region.h.  For some reason
      81  * they're invisible from the outside.*/
      82
      83 typedef struct {
      84     short x1, x2, y1, y2;
      85 } myBox, myBOX, myBoxRec, *myBoxPtr;
      86
      87 typedef struct my_XRegion {    /* 64-bit: Region is supposed to be opaque    */
      88     long size;                 /* but it is defined here anyway.  I'm going  */
      89     long numRects;             /* to leave those longs alone.                */
      90     myBOX *rects;
      91     myBOX extents;
      92 } myREGION;
      93
      94 /* Items in long list of windows that have some part in the grabbed area */
      95 typedef struct {
      96     Window win;
      97     Visual *vis;
      98     Colormap cmap;
      99     int32_t x_rootrel, y_rootrel;       /* root relative location of window */
     100     int32_t x_vis, y_vis;               /* rt rel x,y of vis part, not parent clipped */
     101     int32_t width, height;              /* width and height of visible part */
     102     int32_t border_width;               /* border width of the window */
     103     Window parent;              /* id of parent (for debugging) */
     104 } image_win_type;
     105
     106 /*  Items in short list of regions that tile the grabbed area.  May have
     107     multiple windows in the region.
     108 */
     109 typedef struct {
     110     Window win;                 /* lowest window of this visual */
     111     Visual *vis;
     112     Colormap cmap;
     113     int32_t x_rootrel, y_rootrel;       /* root relative location of bottom window */
     114     int32_t x_vis, y_vis;               /* rt rel x,y of vis part, not parent clipped */
     115     int32_t width, height;              /* w & h of visible rect of bottom window */
     116     int32_t border;                     /* border width of the window */
     117     Region visible_region;
     118 } image_region_type;
     119
     120 /** ------------------------------------------------------------------------
     121         Returns TRUE if the two structs pointed to have the same "vis" &
     122         "cmap" fields and s2 lies completely within s1.  s1 and s2 can
     123         point to structs of image_win_type or image_region_type.
     124     ------------------------------------------------------------------------ **/
     125 #define SAME_REGIONS( s1, s2)   \
     126         ((s1)->vis == (s2)->vis && (s1)->cmap == (s2)->cmap &&          \
     127          (s1)->x_vis <= (s2)->x_vis &&                              \
     128          (s1)->y_vis <= (s2)->y_vis &&                              \
     129          (s1)->x_vis + (s1)->width  >= (s2)->x_vis + (s2)->width && \
     130          (s1)->y_vis + (s1)->height >= (s2)->y_vis + (s2)->height)
     131
     132 #ifndef MIN
     133 #define MIN( a, b)      ((a) < (b) ? a : b)
     134 #define MAX( a, b)      ((a) > (b) ? a : b)
     135 #endif
     136
     137 #define RED_SHIFT        16
     138 #define GREEN_SHIFT       8
     139 #define BLUE_SHIFT        0
     140
     141 /*
     142 extern list_ptr new_list();
     143 extern list_ptr dup_list_head();
     144 extern void *   first_in_list();
     145 extern void *   next_in_list();
     146 extern int32_t  add_to_list();
     147 extern void     zero_list();
     148 extern void     delete_list();
     149 extern void     delete_list_destroying();
     150 extern uint32_t list_length();
     151 */
     152
     153 /* Prototype Declarations for Static Functions */
     154 static void TransferImage(
     155 #if NeedFunctionPrototypes
     156            Display *, XImage *,int32_t, int32_t , image_region_type*,
     157            XImage *,int32_t ,int32_t
     158 #endif
     159            );
     160 static XImage * ReadRegionsInList(
     161 #if NeedFunctionPrototypes
     162            Display *, Visual *, int32_t ,int32_t ,int32_t ,
     163            int32_t , XRectangle, list_ptr
     164 #endif
     165            );
     166
     167 static list_ptr make_region_list(
     168 #if NeedFunctionPrototypes
     169                   Display*, Window, XRectangle*,
     170                   int32_t*, int32_t, XVisualInfo**, int32_t     *
     171 #endif
     172          );
     173
     174 static void destroy_region_list(
     175 #if NeedFunctionPrototypes
     176             list_ptr
     177 #endif
     178             ) ;
     179 static void subtr_rect_from_image_region(
     180 #if NeedFunctionPrototypes
     181            image_region_type *, int32_t , int32_t , int32_t , int32_t
     182 #endif
     183      );
     184 static void add_rect_to_image_region(
     185 #if NeedFunctionPrototypes
     186            image_region_type *,
     187            int32_t , int32_t , int32_t , int32_t
     188 #endif
     189      );
     190 static int32_t src_in_region_list(
     191 #if NeedFunctionPrototypes
     192     image_win_type *, list_ptr
     193 #endif
     194     );
     195 static void add_window_to_list(
     196 #if NeedFunctionPrototypes
     197     list_ptr, Window, int32_t, int32_t ,
     198     int32_t     , int32_t , int32_t , int32_t, int32_t,
     199     Visual*, Colormap, Window
     200 #endif
     201     );
     202 static int32_t src_in_image(
     203 #if NeedFunctionPrototypes
     204     image_win_type      *, int32_t      , XVisualInfo**
     205 #endif
     206     );
     207 static int32_t src_in_overlay(
     208 #if NeedFunctionPrototypes
     209     image_region_type *, int32_t, OverlayInfo *, int32_t*, int32_t*
     210 #endif
     211     );
     212
     213 /* End of Prototype Declarations */
     214
     215 void initFakeVisual(Vis)
     216 Visual *Vis ;
     217 {
     218     Vis->ext_data=NULL;
     219     Vis->class = DirectColor ;
     220     Vis->red_mask =   0x00FF0000;
     221     Vis->green_mask = 0x0000FF00 ;
     222     Vis->blue_mask  = 0x000000FF ;
     223     Vis->map_entries = 256 ;
     224     Vis->bits_per_rgb = 8 ;
     225 }
     226
     227 /* QueryColorMap has been moved into robot_common.c so it can be used by
     228  * awt_DataTransferer.c as well.
     229  */
     230
     231 int32_t
     232 GetMultiVisualRegions(disp,srcRootWinid, x, y, width, height,
     233     transparentOverlays,numVisuals, pVisuals,numOverlayVisuals, pOverlayVisuals,
     234     numImageVisuals, pImageVisuals,vis_regions,vis_image_regions,allImage)
     235     Display             *disp;
     236     Window              srcRootWinid;   /* root win on which grab was done */
     237     int32_t             x;      /* root rel UL corner of bounding box of grab */
     238     int32_t             y;
     239     uint32_t            width;  /* size of bounding box of grab */
     240     uint32_t            height;
     241     int32_t             *transparentOverlays ;
     242     int32_t             *numVisuals;
     243     XVisualInfo         **pVisuals;
     244     int32_t             *numOverlayVisuals;
     245     OverlayInfo         **pOverlayVisuals;
     246     int32_t             *numImageVisuals;
     247     XVisualInfo         ***pImageVisuals;
     248     list_ptr            *vis_regions;    /* list of regions to read from */
     249     list_ptr            *vis_image_regions ;
     250     int32_t             *allImage ;
     251 {
     252     int32_t             hasNonDefault;
     253     XRectangle          bbox;           /* bounding box of grabbed area */
     254
     255
     256     /* Java uses 32-bit ints for coordinates, but XRectangles use 16-bit shorts.
     257      * Hope nobody passes in too big a coordinate */
     258
     259     bbox.x = (short) x;                 /* init X rect for bounding box */
     260     bbox.y = (short) y;
     261     bbox.width = (unsigned short) width;
     262     bbox.height = (unsigned short) height;
     263
     264     GetXVisualInfo(disp,DefaultScreen(disp),
     265                     transparentOverlays,
     266                     numVisuals, pVisuals,
     267                     numOverlayVisuals, pOverlayVisuals,
     268                     numImageVisuals, pImageVisuals);
     269
     270     *vis_regions = *vis_image_regions = NULL ;
     271     if ((*vis_regions = make_region_list( disp, srcRootWinid, &bbox,
     272                                          &hasNonDefault, *numImageVisuals,
     273                                          *pImageVisuals, allImage)) == NULL)
     274         return 0 ;
     275
     276     if (*transparentOverlays)
     277     {
     278         *allImage = 1; /* until proven otherwise,
     279                          this flags that it to be an image only list */
     280         *vis_image_regions =
     281                 make_region_list( disp, srcRootWinid, &bbox, &hasNonDefault,
     282                                         *numImageVisuals, *pImageVisuals, allImage);
     283     }
     284
     285     /* if there is a second region in any of the two lists return 1 **/
     286     if ( ( *vis_regions && (*vis_regions)->next && (*vis_regions)->next->next ) ||
     287          ( *vis_image_regions && (*vis_image_regions)->next &&
     288            (*vis_image_regions)->next->next ) ) return 1 ;
     289     else return 0 ;
     290
     291 }
     292
     293 static void TransferImage(disp,reg_image,srcw,srch,reg,
     294                           target_image,dst_x,dst_y)
     295 Display *disp;
     296 XImage *reg_image,*target_image ;
     297 image_region_type       *reg;
     298 int32_t srcw,srch,dst_x , dst_y ;
     299 {
     300     int32_t ncolors;
     301     int32_t i,j,old_pixel,new_pixel,red_ind,green_ind,blue_ind ;
     302     XColor *colors;
     303     int32_t rShift,gShift,bShift;
     304     int32_t targetBytesPerLine ;
     305
     306     ncolors = QueryColorMap(disp,reg->cmap,reg->vis,&colors,
     307          &rShift,&gShift,&bShift) ;
     308
     309     targetBytesPerLine = target_image->bytes_per_line;
     310
     311     switch (reg->vis->class) {
     312     case TrueColor :
     313        for(i=0 ; i < srch ; i++)
     314        {
     315          for(j=0 ; j < srcw ;  j++)
     316          {
     317            old_pixel = (int32_t) XGetPixel(reg_image,j,i) ;
     318
     319 /* commented out since not using server RGB masks in all true color modes
     320  * causes the R and B values to be swapped around on some X servers
     321  *    - robi.khan@eng 9/7/1999
     322  *           if( reg->vis->map_entries == 16) {
     323  */
     324              red_ind   = (old_pixel & reg->vis->red_mask) >> rShift ;
     325                  green_ind = (old_pixel & reg->vis->green_mask) >> gShift ;
     326                  blue_ind  = (old_pixel & reg->vis->blue_mask) >> bShift ;
     327
     328                  new_pixel = (
     329                               ((colors[red_ind].red >> 8) << RED_SHIFT)
     330                               |((colors[green_ind].green >> 8) << GREEN_SHIFT)
     331                               |((colors[blue_ind].blue >> 8) << BLUE_SHIFT)
     332                              );
     333 /*         }
     334  *  else
     335  *    new_pixel = old_pixel;
     336  */
     337
     338            XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel);
     339
     340          }
     341        }
     342        break;
     343     case DirectColor :
     344        for(i=0 ; i < srch ; i++)
     345        {
     346          for(j=0 ; j < srcw ;  j++)
     347          {
     348            old_pixel = (int32_t) XGetPixel(reg_image,j,i) ;
     349            red_ind   = (old_pixel & reg->vis->red_mask) >> rShift ;
     350                green_ind = (old_pixel & reg->vis->green_mask) >> gShift ;
     351                blue_ind  = (old_pixel & reg->vis->blue_mask) >> bShift ;
     352
     353                new_pixel = (
     354                          ((colors[red_ind].red >> 8) << RED_SHIFT)
     355                         |((colors[green_ind].green >> 8) << GREEN_SHIFT)
     356                         |((colors[blue_ind].blue >> 8) << BLUE_SHIFT)
     357                        );
     358            XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel);
     359
     360          }
     361        }
     362        break;
     363     default :
     364        for(i=0 ; i < srch ; i++)
     365        {
     366          for(j=0 ; j < srcw ;  j++)
     367          {
     368                old_pixel = (int32_t) XGetPixel(reg_image,j,i) ;
     369
     370                new_pixel = (
     371                          ((colors[old_pixel].red >> 8) << RED_SHIFT)
     372                         |((colors[old_pixel].green >> 8) << GREEN_SHIFT)
     373                         |((colors[old_pixel].blue >> 8) << BLUE_SHIFT)
     374                        );
     375            XPutPixel(target_image,dst_x+j, dst_y+i,new_pixel);
     376
     377          }
     378        }
     379        break;
     380     }
     381
     382     /* Fix memory leak by freeing colors
     383      *  - robi.khan@eng 9/22/1999
     384      */
     385     free(colors);
     386 }
     387
     388 static XImage *
     389 ReadRegionsInList(disp,fakeVis,depth,format,width,height,bbox,regions)
     390 Display *disp ;
     391 Visual *fakeVis ;
     392 int32_t depth , width , height ;
     393 int32_t format ;
     394 XRectangle      bbox;           /* bounding box of grabbed area */
     395 list_ptr regions;/* list of regions to read from */
     396 {
     397     image_region_type   *reg;
     398     int32_t                     dst_x, dst_y;   /* where in pixmap to write (UL) */
     399     int32_t                     diff;
     400
     401     XImage              *reg_image,*ximage ;
     402     int32_t             srcRect_x,srcRect_y,srcRect_width,srcRect_height ;
     403     int32_t     rem ;
     404     int32_t     bytes_per_line;
     405     int32_t     bitmap_unit;
     406
     407     bitmap_unit = sizeof (long);
     408     if (format == ZPixmap)
     409        bytes_per_line = width*depth/8;
     410     else
     411        bytes_per_line = width/8;
     412
     413
     414     /* Find out how many more bytes are required for padding so that
     415     ** bytes per scan line will be multiples of bitmap_unit bits */
     416     if (format == ZPixmap) {
     417        rem = (bytes_per_line*8)%bitmap_unit;
     418     if (rem)
     419        bytes_per_line += (rem/8 + 1);
     420     }
     421
     422     ximage = XCreateImage(disp,fakeVis,(uint32_t) depth,format,0,NULL,
     423                           (uint32_t)width,(uint32_t)height,8,0);
     424
     425     bytes_per_line = ximage->bytes_per_line;
     426
     427     if (format == ZPixmap)
     428           ximage->data = malloc(height*bytes_per_line);
     429     else
     430         ximage->data = malloc(height*bytes_per_line*depth);
     431
     432     ximage->bits_per_pixel = depth; /** Valid only if format is ZPixmap ***/
     433
     434     for (reg = (image_region_type *) first_in_list( regions); reg;
     435          reg = (image_region_type *) next_in_list( regions))
     436     {
     437                 int32_t rect;
     438                 struct my_XRegion *vis_reg;
     439                 vis_reg = (struct my_XRegion *)(reg->visible_region);
     440                 for (rect = 0;
     441                      rect < vis_reg->numRects;
     442                      rect++)
     443                 {
     444                 /** ------------------------------------------------------------------------
     445                         Intersect bbox with visible part of region giving src rect & output
     446                         location.  Width is the min right side minus the max left side.
     447                         Similar for height.  Offset src rect so x,y are relative to
     448                         origin of win, not the root-relative visible rect of win.
     449                     ------------------------------------------------------------------------ **/
     450                     srcRect_width  = MIN( vis_reg->rects[rect].x2, bbox.width + bbox.x)
     451              - MAX( vis_reg->rects[rect].x1, bbox.x);
     452
     453                     srcRect_height = MIN( vis_reg->rects[rect].y2, bbox.height + bbox.y)
     454              - MAX( vis_reg->rects[rect].y1, bbox.y);
     455
     456                     diff = bbox.x - vis_reg->rects[rect].x1;
     457                     srcRect_x = MAX( 0, diff)  + (vis_reg->rects[rect].x1 - reg->x_rootrel - reg->border);
     458                     dst_x     = MAX( 0, -diff) ;
     459                     diff = bbox.y - vis_reg->rects[rect].y1;
     460                     srcRect_y = MAX( 0, diff)  + (vis_reg->rects[rect].y1 - reg->y_rootrel - reg->border);
     461                     dst_y     = MAX( 0, -diff) ;
     462             reg_image = XGetImage(disp,reg->win,srcRect_x,srcRect_y,
     463              (uint32_t) srcRect_width, (uint32_t) srcRect_height,AllPlanes,format) ;

     464                     TransferImage(disp,reg_image,srcRect_width,
     465                                  srcRect_height,reg,ximage,dst_x,dst_y) ;
     466             XDestroyImage(reg_image);

     467             }
     468     }
     469     return ximage ;
     470 }
     471
     472
     473 /** ------------------------------------------------------------------------
     474     ------------------------------------------------------------------------ **/
     475
     476 XImage *ReadAreaToImage(disp, srcRootWinid, x, y, width, height,
     477     numVisuals,pVisuals,numOverlayVisuals,pOverlayVisuals,numImageVisuals,
     478     pImageVisuals,vis_regions,vis_image_regions,format,allImage)
     479     Display             *disp;
     480     Window              srcRootWinid;   /* root win on which grab was done */
     481     int32_t                     x;   /* root rel UL corner of bounding box of grab */
     482     int32_t                     y;
     483     uint32_t            width;  /* size of bounding box of grab */
     484     uint32_t            height;
     485     /** int32_t                 transparentOverlays; ***/
     486     int32_t                     numVisuals;
     487     XVisualInfo         *pVisuals;
     488     int32_t                     numOverlayVisuals;
     489     OverlayInfo         *pOverlayVisuals;
     490     int32_t                     numImageVisuals;
     491     XVisualInfo         **pImageVisuals;
     492     list_ptr            vis_regions;    /* list of regions to read from */
     493     list_ptr            vis_image_regions ;/* list of regions to read from */
     494     int32_t                     format;
     495     int32_t             allImage ;
     496 {
     497     image_region_type   *reg;
     498     XRectangle          bbox;           /* bounding box of grabbed area */
     499     int32_t             depth ;
     500     XImage              *ximage, *ximage_ipm ;
     501     Visual              fakeVis ;
     502     int32_t     x1, y1;
     503     XImage      *image;
     504     unsigned char       *pmData ,  *ipmData ;
     505     int32_t                 transparentColor, transparentType;
     506     int32_t                     srcRect_x,srcRect_y,srcRect_width,srcRect_height ;
     507     int32_t                     diff ;
     508     int32_t                     dst_x, dst_y;   /* where in pixmap to write (UL) */
     509     int32_t                     pixel;
     510
     511     bbox.x = (short) x;                 /* init X rect for bounding box */
     512     bbox.y = (short) y;
     513     bbox.width = (unsigned short) width;
     514     bbox.height = (unsigned short) height;
     515     ximage_ipm = NULL;
     516
     517
     518     initFakeVisual(&fakeVis) ;
     519
     520     depth = 24 ;
     521     ximage = ReadRegionsInList(disp,&fakeVis,depth,format,
     522              (int32_t) width, (int32_t) height, bbox,vis_regions) ;
     523
     524     pmData = (unsigned char *)ximage -> data ;
     525
     526 /* if transparency possible do it again, but this time for image planes only */
     527     if (vis_image_regions && (vis_image_regions->next) && !allImage)
     528     {
     529             ximage_ipm = ReadRegionsInList(disp,&fakeVis,depth,format,
     530                          (int32_t) width, (int32_t) height,bbox,vis_image_regions) ;
     531         ipmData = (unsigned char *)ximage_ipm -> data ;
     532     }
     533 /* Now tranverse the overlay visual windows and test for transparency index.  */
     534 /* If you find one, subsitute the value from the matching image plane pixmap. */
     535
     536     for (reg = (image_region_type *) first_in_list( vis_regions); reg;
     537          reg = (image_region_type *) next_in_list( vis_regions))
     538     {
     539
     540         if (src_in_overlay( reg, numOverlayVisuals, pOverlayVisuals,
     541                                  &transparentColor, &transparentType))
     542         {
     543          int32_t test = 0 ;
     544              srcRect_width  = MIN( reg->width + reg->x_vis, bbox.width + bbox.x)
     545                                  - MAX( reg->x_vis, bbox.x);
     546              srcRect_height = MIN( reg->height + reg->y_vis, bbox.height
     547                                  + bbox.y) - MAX( reg->y_vis, bbox.y);
     548          diff = bbox.x - reg->x_vis;
     549          srcRect_x = MAX( 0, diff) + (reg->x_vis - reg->x_rootrel - reg->border);
     550          dst_x     = MAX( 0, -diff) ;
     551              diff = bbox.y - reg->y_vis;
     552              srcRect_y = MAX( 0, diff)  + (reg->y_vis - reg->y_rootrel - reg->border);
     553              dst_y     = MAX( 0, -diff) ;
     554         /* let's test some pixels for transparency */
     555          image = XGetImage(disp, reg->win, srcRect_x, srcRect_y,
     556                            (uint32_t) srcRect_width, (uint32_t) srcRect_height,
     557                            0xffffffff, ZPixmap);
     558
     559         /* let's assume byte per pixel for overlay image for now */
     560              if ((image->depth == 8) && (transparentType == TransparentPixel))
     561              {
     562                  unsigned char *pixel_ptr;
     563                  unsigned char *start_of_line = (unsigned char *) image->data;
     564
     565                  for (y1 = 0; y1 < srcRect_height; y1++) {
     566                     pixel_ptr = start_of_line;
     567                     for (x1 = 0; x1 < srcRect_width; x1++)
     568                     {
     569                         if (*pixel_ptr++ == transparentColor)
     570                         {
     571                         /*
     572                             *pmData++ = *ipmData++;
     573                             *pmData++ = *ipmData++;
     574                             *pmData++ = *ipmData++;
     575                         */
     576                         pixel = (int32_t) XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1) ;
     577                     XPutPixel(ximage,dst_x+x1, dst_y+y1,(unsigned long)pixel);
     578
     579                         if(!test){
     580                            test = 1 ;
     581                         }
     582                         }
     583                         /*
     584                         else {
     585                             pmData +=3;
     586                             ipmData +=3;
     587                         }
     588                         */
     589                     }
     590                     start_of_line += image->bytes_per_line;
     591                 }
     592         } else {
     593                 if (transparentType == TransparentPixel) {
     594                 for (y1 = 0; y1 < srcRect_height; y1++) {
     595                       for (x1 = 0; x1 < srcRect_width; x1++)
     596                       {
     597                             int32_t pixel_value = (int32_t) XGetPixel(image, x1, y1);
     598                             if (pixel_value == transparentColor)
     599                             {
     600                             /*
     601                                 *pmData++ = *ipmData++;
     602                                 *pmData++ = *ipmData++;
     603                                 *pmData++ = *ipmData++;
     604                             */
     605                         pixel = (int32_t) XGetPixel(ximage_ipm,dst_x+x1,dst_y+y1) ;
     606                     XPutPixel(ximage,dst_x+x1, dst_y+y1,(unsigned long)pixel);
     607                         if(!test){
     608                            test = 1 ;
     609                         }
     610                             }
     611                             /*
     612                             else {
     613                                 pmData +=3;
     614                                 ipmData +=3;
     615                             }
     616                             */
     617                         }
     618                     }
     619                 } else {
     620                     for (y1 = 0; y1 < srcRect_height; y1++) {
     621                         for (x1 = 0; x1 < srcRect_width; x1++)
     622                         {
     623                             int32_t pixel_value = (int32_t) XGetPixel(image, x1, y1);
     624                             if (pixel_value & transparentColor)
     625                             {
     626                             /*
     627                                 *pmData++ = *ipmData++;
     628                                 *pmData++ = *ipmData++;
     629                                 *pmData++ = *ipmData++;
     630                             */
     631                      pixel = (int32_t) XGetPixel(ximage_ipm,dst_x+x1,
     632                                     dst_y+y1) ;
     633                      XPutPixel(ximage,dst_x+x1, dst_y+y1,(unsigned long)pixel);
     634                         if(!test){
     635                            test = 1 ;
     636                         }
     637                             }
     638                             /*
     639                             else {
     640                                 pmData +=3;
     641                                 ipmData +=3;
     642                             }
     643                             */
     644                         }
     645                     }
     646                 }
     647         }
     648         XDestroyImage (image);
     649       } /* end of src_in_overlay */
     650     } /** end transparency **/
     651     if (ximage_ipm != NULL) {
     652         XDestroyImage(ximage_ipm);
     653     }
     654     destroy_region_list( vis_regions);
     655     if (vis_image_regions) destroy_region_list( vis_image_regions );
     656     FreeXVisualInfo(pVisuals, pOverlayVisuals, pImageVisuals);
     657     XSync(disp, 0);
     658
     659     return ximage;
     660 }
     661
     662 /** ------------------------------------------------------------------------
     663         Creates a list of the subwindows of a given window which have a
     664         different visual than their parents.  The function is recursive.
     665         This list is used in make_region_list(), which coalesces the
     666         windows with the same visual into a region.
     667         image_wins must point to an existing list struct that's already
     668         been zeroed (zero_list()).
     669     ------------------------------------------------------------------------ **/
     670 static void make_src_list( disp, image_wins, bbox, curr, x_rootrel, y_rootrel,
     671                     curr_attrs, pclip)
     672     Display             *disp;
     673     list_ptr            image_wins;
     674     XRectangle          *bbox;                  /* bnding box of area we want */
     675     Window              curr;
     676     int32_t                     x_rootrel;              /* pos of curr WRT root */
     677     int32_t                     y_rootrel;
     678     XWindowAttributes   *curr_attrs;
     679     XRectangle          *pclip;                 /* visible part of curr, not */
     680                                                 /* obscurred by ancestors */
     681 {
     682     XWindowAttributes child_attrs;
     683     Window root, parent, *child;        /* variables for XQueryTree() */
     684     Window *save_child_list;            /* variables for XQueryTree() */
     685     uint32_t nchild;            /* variables for XQueryTree() */
     686     XRectangle child_clip;              /* vis part of child */
     687     int32_t curr_clipX, curr_clipY, curr_clipRt, curr_clipBt;
     688
     689     /* check that win is mapped & not outside bounding box */
     690     if (curr_attrs->map_state == IsViewable &&
     691         curr_attrs->class == InputOutput &&
     692         !( pclip->x >= (bbox->x + bbox->width)  ||
     693            pclip->y >= (bbox->y + bbox->height) ||
     694            (pclip->x + pclip->width)  <= bbox->x        ||
     695            (pclip->y + pclip->height) <= bbox->y)) {
     696
     697         XQueryTree( disp, curr, &root, &parent, &child, &nchild );
     698         save_child_list = child;      /* so we can free list when we're done */
     699         add_window_to_list( image_wins, curr, x_rootrel, y_rootrel,
     700                             (int32_t) pclip->x, (int32_t) pclip->y,
     701                             (int32_t) pclip->width, (int32_t) pclip->height,
     702                             curr_attrs->border_width,curr_attrs->visual,
     703                             curr_attrs->colormap, parent);
     704
     705
     706 /** ------------------------------------------------------------------------
     707         set RR coords of right (Rt), left (X), bottom (Bt) and top (Y)
     708         of rect we clip all children by.  This is our own clip rect (pclip)
     709         inflicted on us by our parent plus our own borders.  Within the
     710         child loop, we figure the clip rect for each child by adding in
     711         it's rectangle (not taking into account the child's borders).
     712     ------------------------------------------------------------------------ **/
     713         curr_clipX = MAX( pclip->x, x_rootrel + curr_attrs->border_width);
     714         curr_clipY = MAX( pclip->y, y_rootrel + curr_attrs->border_width);
     715         curr_clipRt = MIN(pclip->x + pclip->width,
     716                                   x_rootrel + curr_attrs->width + 2 * curr_attrs->border_width);
     717
     718         curr_clipBt = MIN(pclip->y + pclip->height,
     719                                   y_rootrel + curr_attrs->height + 2 * curr_attrs->border_width);
     720
     721
     722         while (nchild--) {
     723             int32_t new_width, new_height;
     724             int32_t child_xrr, child_yrr;       /* root relative x & y of child */
     725
     726             XGetWindowAttributes( disp, *child, &child_attrs);
     727
     728             /* intersect parent & child clip rects */
     729             child_xrr = x_rootrel + child_attrs.x + curr_attrs->border_width;
     730             child_clip.x = (short) MAX( curr_clipX, child_xrr);
     731             new_width = MIN(curr_clipRt,
     732                         child_xrr + child_attrs.width +
     733                          2 * child_attrs.border_width) - child_clip.x;
     734
     735             if (new_width >= 0) {
     736                 child_clip.width = (unsigned short) new_width;
     737
     738                 child_yrr = y_rootrel + child_attrs.y +
     739                             curr_attrs->border_width;
     740                 child_clip.y = (short) MAX( curr_clipY, child_yrr);
     741                 new_height = MIN(curr_clipBt,
     742                                          child_yrr + (int32_t) child_attrs.height +
     743                                          2 * child_attrs.border_width) - child_clip.y;
     744
     745                 if (new_height >= 0) {
     746                     child_clip.height = (unsigned short) new_height;
     747                     make_src_list( disp, image_wins, bbox, *child,
     748                                    child_xrr, child_yrr,
     749                                    &child_attrs, &child_clip);
     750                 }
     751             }
     752             child++;
     753         }
     754         XFree( save_child_list);
     755     }
     756 }
     757
     758
     759 /** ------------------------------------------------------------------------
     760         This function creates a list of regions which tile a specified
     761         window.  Each region contains all visible portions of the window
     762         which are drawn with the same visual.  For example, if the
     763         window consists of subwindows of two different visual types,
     764         there will be two regions in the list.
     765         Returns a pointer to the list.
     766     ------------------------------------------------------------------------ **/
     767 static list_ptr make_region_list( disp, win, bbox, hasNonDefault,
     768                              numImageVisuals, pImageVisuals, allImage)
     769     Display             *disp;
     770     Window              win;
     771     XRectangle          *bbox;
     772     int32_t             *hasNonDefault;
     773     int32_t                     numImageVisuals;
     774     XVisualInfo         **pImageVisuals;
     775     int32_t                     *allImage;
     776 {
     777     XWindowAttributes   win_attrs;
     778     list                image_wins;
     779     list_ptr            image_regions;
     780     list_ptr            srcs_left;
     781     image_region_type   *new_reg;
     782     image_win_type      *base_src, *src;
     783     Region              bbox_region = XCreateRegion();
     784     XRectangle          clip;
     785     int32_t                     image_only;
     786
     787     int32_t                 count=0 ;
     788
     789     *hasNonDefault = False;
     790     XUnionRectWithRegion( bbox, bbox_region, bbox_region);
     791     XGetWindowAttributes( disp, win, &win_attrs);
     792
     793     zero_list( &image_wins);
     794     clip.x = 0;
     795     clip.y = 0;
     796     clip.width  = (unsigned short) win_attrs.width;
     797     clip.height = (unsigned short) win_attrs.height;
     798     make_src_list( disp, &image_wins, bbox, win,
     799                    0 /* x_rootrel */, 0 /* y_rootrel */, &win_attrs, &clip);
     800
     801     image_regions = new_list();
     802     image_only = (*allImage) ? True:False;
     803
     804     for (base_src = (image_win_type *) first_in_list( &image_wins); base_src;
     805          base_src = (image_win_type *) next_in_list( &image_wins))
     806     {
     807         /* test for image visual */
     808         if (!image_only || src_in_image(base_src, numImageVisuals, pImageVisuals))
     809         {
     810             /* find a window whose visual hasn't been put in list yet */
     811             if (!src_in_region_list( base_src, image_regions))
     812             {
     813                 if (! (new_reg = (image_region_type *)
     814                                         malloc( sizeof( image_region_type)))) {
     815                     return (list_ptr) NULL;
     816                 }
     817                 count++;
     818
     819                 new_reg->visible_region = XCreateRegion();
     820                 new_reg->win            = base_src->win;
     821                 new_reg->vis            = base_src->vis;
     822                 new_reg->cmap           = base_src->cmap;
     823                 new_reg->x_rootrel      = base_src->x_rootrel;
     824                 new_reg->y_rootrel      = base_src->y_rootrel;
     825                 new_reg->x_vis          = base_src->x_vis;
     826                 new_reg->y_vis          = base_src->y_vis;
     827                 new_reg->width          = base_src->width;
     828                 new_reg->height         = base_src->height;
     829                 new_reg->border         = base_src->border_width;
     830
     831                 srcs_left = (list_ptr) dup_list_head( &image_wins, START_AT_CURR);
     832                 for (src = (image_win_type *) first_in_list( srcs_left); src;
     833                      src = (image_win_type *) next_in_list( srcs_left)) {
     834                     if (SAME_REGIONS( base_src, src)) {
     835                         add_rect_to_image_region( new_reg, src->x_vis, src->y_vis,
     836                                                   src->width, src->height);
     837                     }
     838                     else {
     839                         if (!image_only || src_in_image(src, numImageVisuals, pImageVisuals))
     840                         {
     841                             subtr_rect_from_image_region( new_reg, src->x_vis,
     842                                           src->y_vis, src->width, src->height);
     843                         }
     844                     }
     845                 }
     846                 XIntersectRegion( bbox_region, new_reg->visible_region,
     847                                   new_reg->visible_region);
     848                 if (! XEmptyRegion( new_reg->visible_region)) {
     849                     add_to_list( image_regions, new_reg);
     850                     if (new_reg->vis != DefaultVisualOfScreen( win_attrs.screen) ||
     851                         new_reg->cmap != DefaultColormapOfScreen(
     852                                                             win_attrs.screen)) {
     853                         *hasNonDefault = True;
     854                     }
     855                 }
     856                 else {
     857                     XDestroyRegion( new_reg->visible_region);
     858                     free( (void *) new_reg);
     859                 }
     860             }
     861         } else *allImage = 0;
     862     }
     863     delete_list( &image_wins, True);
     864     XDestroyRegion( bbox_region);
     865     return image_regions;
     866 }
     867 /** ------------------------------------------------------------------------
     868         Destructor called from destroy_region_list().
     869     ------------------------------------------------------------------------ **/
     870 void destroy_image_region( image_region)
     871     image_region_type *image_region;
     872 {
     873     XDestroyRegion( image_region->visible_region);
     874     free( (void *) image_region);
     875 }
     876
     877 /** ------------------------------------------------------------------------
     878         Destroys the region list, destroying all the regions contained in it.
     879     ------------------------------------------------------------------------ **/
     880 static void destroy_region_list( rlist)
     881     list_ptr rlist;
     882 {
     883     delete_list_destroying( rlist, (DESTRUCT_FUNC_PTR)destroy_image_region);
     884 }
     885
     886
     887 /** ------------------------------------------------------------------------
     888         Subtracts the specified rectangle from the region in image_region.
     889         First converts the rectangle to a region of its own, since X
     890         only provides a way to subtract one region from another, not a
     891         rectangle from a region.
     892     ------------------------------------------------------------------------ **/
     893 static void subtr_rect_from_image_region( image_region, x, y, width, height)
     894     image_region_type *image_region;
     895     int32_t x;
     896     int32_t y;
     897     int32_t width;
     898     int32_t height;
     899 {
     900     XRectangle rect;
     901     Region rect_region;
     902
     903     rect_region = XCreateRegion();
     904     rect.x = (short)x;
     905     rect.y = (short)y;
     906     rect.width = (unsigned short)width;
     907     rect.height = (unsigned short)height;
     908     XUnionRectWithRegion( &rect, rect_region, rect_region);
     909     XSubtractRegion( image_region->visible_region, rect_region,
     910                      image_region->visible_region);
     911     XDestroyRegion( rect_region);
     912 }
     913
     914
     915 /** ------------------------------------------------------------------------
     916         Adds the specified rectangle to the region in image_region.
     917     ------------------------------------------------------------------------ **/
     918 static void add_rect_to_image_region( image_region, x, y, width, height)
     919     image_region_type *image_region;
     920     int32_t x;
     921     int32_t y;
     922     int32_t width;
     923     int32_t height;
     924 {
     925     XRectangle rect;
     926
     927     rect.x = (short) x;
     928     rect.y = (short) y;
     929     rect.width = (unsigned short) width;
     930     rect.height = (unsigned short) height;
     931     XUnionRectWithRegion( &rect, image_region->visible_region,
     932                           image_region->visible_region);
     933 }
     934
     935
     936 /** ------------------------------------------------------------------------
     937         Returns TRUE if the given src's visual is already represented in
     938         the image_regions list, FALSE otherwise.
     939     ------------------------------------------------------------------------ **/
     940 static int32_t src_in_region_list( src, image_regions)
     941     image_win_type *src;
     942     list_ptr image_regions;
     943 {
     944     image_region_type   *ir;
     945
     946     for (ir = (image_region_type *) first_in_list( image_regions); ir;
     947          ir = (image_region_type *) next_in_list( image_regions)) {
     948         if (SAME_REGIONS( ir, src)) {
     949
     950             return 1;
     951         }
     952     }
     953
     954     return 0;
     955 }
     956
     957
     958 /** ------------------------------------------------------------------------
     959         Makes a new entry in image_wins with the given fields filled in.
     960     ------------------------------------------------------------------------ **/
     961 static void add_window_to_list( image_wins, w, xrr, yrr, x_vis, y_vis,
     962                                 width, height, border_width,vis, cmap, parent)
     963     list_ptr    image_wins;
     964     Window      w;
     965     int32_t             xrr;
     966     int32_t     yrr;
     967     int32_t             x_vis;
     968     int32_t     y_vis;
     969     int32_t     width;
     970     int32_t     height;
     971     int32_t     border_width;
     972     Visual      *vis;
     973     Colormap    cmap;
     974     Window      parent;
     975 {
     976     image_win_type      *new_src;
     977
     978     if ((new_src = (image_win_type *) malloc( sizeof( image_win_type))) == NULL)
     979
     980         return;
     981
     982     new_src->win = w;
     983     new_src->x_rootrel = xrr;
     984     new_src->y_rootrel = yrr;
     985     new_src->x_vis = x_vis;
     986     new_src->y_vis = y_vis;
     987     new_src->width = width;
     988     new_src->height = height;
     989     new_src->border_width = border_width;
     990     new_src->vis = vis;
     991     new_src->cmap = cmap;
     992     new_src->parent = parent;
     993     add_to_list( image_wins, new_src);
     994 }
     995
     996 /** ------------------------------------------------------------------------
     997         Returns TRUE if the given src's visual is in the image planes,
     998         FALSE otherwise.
     999     ------------------------------------------------------------------------ **/
    1000 static int32_t src_in_image( src, numImageVisuals, pImageVisuals)
    1001     image_win_type      *src;
    1002     int32_t                     numImageVisuals;
    1003     XVisualInfo         **pImageVisuals;
    1004 {
    1005     int32_t             i;
    1006
    1007     for (i = 0 ; i < numImageVisuals ; i++)
    1008     {
    1009         if (pImageVisuals[i]->visual == src->vis)
    1010             return 1;
    1011     }
    1012     return 0;
    1013 }
    1014
    1015
    1016 /** ------------------------------------------------------------------------
    1017         Returns TRUE if the given src's visual is in the overlay planes
    1018         and transparency is possible, FALSE otherwise.
    1019     ------------------------------------------------------------------------ **/
    1020 static int32_t src_in_overlay( src, numOverlayVisuals, pOverlayVisuals,
    1021                         transparentColor, transparentType)
    1022     image_region_type   *src;
    1023     int32_t                     numOverlayVisuals;
    1024     OverlayInfo         *pOverlayVisuals;
    1025     int32_t                     *transparentColor;
    1026     int32_t                     *transparentType;
    1027 {
    1028     int32_t             i;
    1029
    1030     for (i = 0 ; i < numOverlayVisuals ; i++)
    1031     {
    1032         if (((pOverlayVisuals[i].pOverlayVisualInfo)->visual == src->vis)
    1033                 && (pOverlayVisuals[i].transparentType != None))
    1034         {
    1035             *transparentColor = pOverlayVisuals[i].value;
    1036             *transparentType = pOverlayVisuals[i].transparentType;
    1037             return 1;
    1038         }
    1039
    1040         else {
    1041         }
    1042
    1043     }
    1044     return 0;
    1045 }
    1046
    1047
    1048 /********************** from wsutils.c ******************************/
    1049
    1050 /******************************************************************************
    1051  *
    1052  * This file contains a set of example utility procedures; procedures that can
    1053  * help a "window-smart" Starbase or PHIGS program determine information about
    1054  * a device, and create image and overlay plane windows.  To use these
    1055  * utilities, #include "wsutils.h" and compile this file and link the results
    1056  * with your program.
    1057  *
    1058  ******************************************************************************/
    1059
    1060
    1061
    1062 #define STATIC_GRAY     0x01
    1063 #define GRAY_SCALE      0x02
    1064 #define PSEUDO_COLOR    0x04
    1065 #define TRUE_COLOR      0x10
    1066 #define DIRECT_COLOR    0x11
    1067
    1068
    1069 static int32_t  weCreateServerOverlayVisualsProperty = False;
    1070
    1071
    1072 /******************************************************************************
    1073  *
    1074  * GetXVisualInfo()
    1075  *
    1076  * This routine takes an X11 Display, screen number, and returns whether the
    1077  * screen supports transparent overlays and three arrays:
    1078  *
    1079  *      1) All of the XVisualInfo struct's for the screen.
    1080  *      2) All of the OverlayInfo struct's for the screen.
    1081  *      3) An array of pointers to the screen's image plane XVisualInfo
    1082  *         structs.
    1083  *
    1084  * The code below obtains the array of all the screen's visuals, and obtains
    1085  * the array of all the screen's overlay visual information.  It then processes
    1086  * the array of the screen's visuals, determining whether the visual is an
    1087  * overlay or image visual.
    1088  *
    1089  * If the routine sucessfully obtained the visual information, it returns zero.
    1090  * If the routine didn't obtain the visual information, it returns non-zero.
    1091  *
    1092  ******************************************************************************/
    1093
    1094 int32_t GetXVisualInfo(display, screen, transparentOverlays,
    1095                    numVisuals, pVisuals,
    1096                    numOverlayVisuals, pOverlayVisuals,
    1097                    numImageVisuals, pImageVisuals)
    1098
    1099     Display     *display;                   /* Which X server (aka "display"). */
    1100     int32_t             screen;                 /* Which screen of the "display". */
    1101     int32_t             *transparentOverlays;   /* Non-zero if there's at least one
    1102                                          * overlay visual and if at least one
    1103                                          * of those supports a transparent
    1104                                          * pixel. */
    1105     int32_t             *numVisuals;            /* Number of XVisualInfo struct's
    1106                                          * pointed to by pVisuals. */
    1107     XVisualInfo **pVisuals;             /* All of the device's visuals. */
    1108     int32_t             *numOverlayVisuals;     /* Number of OverlayInfo's pointed
    1109                                          * to by pOverlayVisuals.  If this
    1110                                          * number is zero, the device does
    1111                                          * not have overlay planes. */
    1112     OverlayInfo **pOverlayVisuals;      /* The device's overlay plane visual
    1113                                          * information. */
    1114     int32_t             *numImageVisuals;       /* Number of XVisualInfo's pointed
    1115                                          * to by pImageVisuals. */
    1116     XVisualInfo ***pImageVisuals;       /* The device's image visuals. */
    1117 {
    1118     XVisualInfo getVisInfo;             /* Parameters of XGetVisualInfo */
    1119     int32_t             mask;
    1120     XVisualInfo *pVis, **pIVis;         /* Faster, local copies */
    1121     OverlayInfo *pOVis;
    1122     OverlayVisualPropertyRec    *pOOldVis;
    1123     int32_t             nVisuals, nOVisuals;
    1124     Atom        overlayVisualsAtom;     /* Parameters for XGetWindowProperty */
    1125     Atom        actualType;
    1126     unsigned long numLongs, bytesAfter;
    1127     int32_t             actualFormat;
    1128     int32_t             nImageVisualsAlloced;   /* Values to process the XVisualInfo */
    1129     int32_t             imageVisual;            /* array */
    1130
    1131
    1132     /* First, get the list of visuals for this screen. */
    1133     getVisInfo.screen = screen;
    1134     mask = VisualScreenMask;
    1135
    1136     *pVisuals = XGetVisualInfo(display, mask, &getVisInfo, numVisuals);
    1137     if ((nVisuals = *numVisuals) <= 0)
    1138     {
    1139         /* Return that the information wasn't sucessfully obtained: */
    1140         return(1);
    1141     }
    1142     pVis = *pVisuals;
    1143
    1144
    1145     /* Now, get the overlay visual information for this screen.  To obtain
    1146      * this information, get the SERVER_OVERLAY_VISUALS property.
    1147      */
    1148     overlayVisualsAtom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True);
    1149     if (overlayVisualsAtom != None)
    1150     {
    1151         /* Since the Atom exists, we can request the property's contents.  The
    1152          * do-while loop makes sure we get the entire list from the X server.
    1153          */
    1154         bytesAfter = 0;
    1155         numLongs = sizeof(OverlayVisualPropertyRec) / 4;
    1156         do
    1157         {
    1158             numLongs += bytesAfter * 4;
    1159             XGetWindowProperty(display, RootWindow(display, screen),
    1160                                overlayVisualsAtom, 0, numLongs, False,
    1161                                overlayVisualsAtom, &actualType, &actualFormat,
    1162                                &numLongs, &bytesAfter, (unsigned char**) pOverlayVisuals);
    1163         } while (bytesAfter > 0);
    1164
    1165
    1166         /* Calculate the number of overlay visuals in the list. */
    1167         /* *numOverlayVisuals = numLongs / (sizeof(OverlayVisualPropertyRec) / 4); */
    1168         *numOverlayVisuals = numLongs / (sizeof(OverlayVisualPropertyRec) / sizeof(long));
    1169     }
    1170     else
    1171     {
    1172         /* This screen doesn't have overlay planes. */
    1173         *numOverlayVisuals = 0;
    1174         *pOverlayVisuals = NULL;
    1175         *transparentOverlays = 0;
    1176     }
    1177
    1178
    1179     /* Process the pVisuals array. */
    1180     *numImageVisuals = 0;
    1181     nImageVisualsAlloced = 1;
    1182     pIVis = *pImageVisuals = (XVisualInfo **) malloc(sizeof(XVisualInfo *));
    1183     while (--nVisuals >= 0)
    1184     {
    1185         nOVisuals = *numOverlayVisuals;
    1186         pOVis = *pOverlayVisuals;
    1187         imageVisual = True;
    1188         while (--nOVisuals >= 0)
    1189         {
    1190             pOOldVis = (OverlayVisualPropertyRec *) pOVis;
    1191             if (pVis->visualid == pOOldVis->visualID)
    1192             {
    1193                 imageVisual = False;
    1194                 pOVis->pOverlayVisualInfo = pVis;
    1195                 if (pOVis->transparentType == TransparentPixel)
    1196                     *transparentOverlays = 1;
    1197             }
    1198             pOVis++;
    1199         }
    1200         if (imageVisual)
    1201         {
    1202             if ((*numImageVisuals += 1) > nImageVisualsAlloced)
    1203             {
    1204                 nImageVisualsAlloced++;
    1205                 *pImageVisuals = (XVisualInfo **)
    1206                     realloc(*pImageVisuals, (nImageVisualsAlloced * sizeof(XVisualInfo *)));
    1207                 pIVis = *pImageVisuals + (*numImageVisuals - 1);
    1208             }
    1209             *pIVis++ = pVis;
    1210         }
    1211         pVis++;
    1212     }
    1213
    1214
    1215     /* Return that the information was sucessfully obtained: */
    1216     return(0);
    1217
    1218 } /* GetXVisualInfo() */
    1219
    1220
    1221 /******************************************************************************
    1222  *
    1223  * FreeXVisualInfo()
    1224  *
    1225  * This routine frees the data that was allocated by GetXVisualInfo().
    1226  *
    1227  ******************************************************************************/
    1228
    1229 void FreeXVisualInfo(pVisuals, pOverlayVisuals, pImageVisuals)
    1230
    1231     XVisualInfo *pVisuals;
    1232     OverlayInfo *pOverlayVisuals;
    1233     XVisualInfo **pImageVisuals;
    1234 {
    1235     XFree(pVisuals);
    1236     if (weCreateServerOverlayVisualsProperty)
    1237         free(pOverlayVisuals);
    1238     else
    1239         XFree(pOverlayVisuals);
    1240     free(pImageVisuals);
    1241
    1242 } /* FreeXVisualInfo() */
    --- EOF ---