/* grX11su2.c -
 *
 *     ********************************************************************* 
 *     * Copyright (C) 1985, 1990 Regents of the University of California. * 
 *     * Permission to use, copy, modify, and distribute this              * 
 *     * software and its documentation for any purpose and without        * 
 *     * fee is hereby granted, provided that the above copyright          * 
 *     * notice appear in all copies.  The University of California        * 
 *     * makes no representations about the suitability of this            * 
 *     * software for any purpose.  It is provided "as is" without         * 
 *     * express or implied warranty.  Export of this software outside     * 
 *     * of the United States of America may require an export license.    * 
 *     *********************************************************************
 *
 * This file contains additional functions to manipulate an X
 * color display.  Included here are rectangle drawing and color map
 * loading.
 */

#define HIRES          /* There is NO reason to turn this off. With HIRES
			  defined the code tests if  8bit pseudocolor is 
			  available and uses it if it is. Therefore, if
			  the old code (assume 8bit pseudocolor) would
			  work at all the new code will work the same way. */
/* debugging only */
/* #define HIRESDB */

#include <stdio.h>
#ifdef OS2
#include <stdlib.h>   /* Current Linux has conflict with wchar_t, but
			 OS2 needs stdlib.h   */
#else
char *getenv();
#endif  /* OS2 */
#include <X11/Xlib.h>

#ifdef HIRES
#include <X11/Xutil.h>
#endif  /* HIRES */

#include "misc/magic.h"
#include "textio/textio.h"
#include "utils/geometry.h"
#ifdef HIRES
#include "graphics/glyphs.h"
#endif
#include "graphics/graphics.h"
#include "windows/windows.h"
#include "graphics/graphicsInt.h"
#include "grX11Int.h"

#ifdef HIRES
extern char *DBWStyleType;
unsigned long grPixels[256];
unsigned long grPlanes[256];
XColor   colors[256*3];	/* Unique colors used by Magic */
#else
unsigned long grPixels[128];
unsigned long grPlanes[128];
XColor   colors[256];	/* Unique colors used by Magic */
#endif  /* HIRES */
Visual   *grVisual;
int      grClass;
unsigned long grCompleteMask;
Colormap grXcmap;

/* disgusting machine-dependent constants - see below */
#ifdef macII
#define X_COLORMAP_BASE		128
#define X_COLORMAP_RESERVED	4
#else
#if defined(OS2) || defined(CYGWIN)
#define X_COLORMAP_BASE		128
#define X_COLORMAP_RESERVED	0
#else
#define X_COLORMAP_BASE		0
#define X_COLORMAP_RESERVED	2
#endif  /* OS2 */
#endif

extern void MainExit(int);
extern void GrX11Close(void);


/*---------------------------------------------------------
 * GrXSetCMap:  I've seen about 6 versions of this procedure now,
 	all of them flawed in some way or another.  I expect this
	one to be no different...

	Anyway, the idea here is to first try allocating the required
	planes out of the default colormap.  This is the kindest,
	gentlest thing to do because it doesn't cause all the other
	windows to go technicolor when the cursor is in a magic window.
	If this fails, we go ahead and allocate a colormap specifically
	for magic.  The problem now is using this colormap in such
	a way that the other windows' colors get mangled the least.
	Unfortunately, doing this is X-server dependent.  This is where
	the constants above come in.  X_COLORMAP_BASE indicates
	which part of the colormap (assuming the number of planes
	required is less than the number of planes in the display)
	to fill in the colors magic requires.  X_COLORMAP_RESERVED
	tells how many high-end colors the server won't let us touch;
	if we even try to query these colors, we get an X error.
	If, starting at X_COLORMAP_BASE, the number of colors required
	would push us into the top X_COLORMAP_RESERVED colors, then
	we won't be able to set all the colors the user wanted us
	to set.  The top colors will remain identical to those
	in the default colormap.
	
	There are clearly some shortcomings in this approach.  For
	example, a server might reserve colors at the bottom of
	the colormap.  Since I haven't seen such a server yet
	and I'm really sick of X11, this eventuality is not supported.
	
	The best way to use Magic under X is to pick a 	number of 
	planes small enough to fix in the default colormap, and not
	to waste random colors on things like xterms, xclocks and xbiffs.
	Do you really need a yellow and black xterm and a red xclock?
	Think about it.
 *	
 *
 * Results:	None.
 *
 * Side Effects:
 *	The values in the color map are set from the array indicated
 *	by pmap. X color cells are allocated if this display has
 *	more than 1 plane.
 *
 * Errors:		None.
 *
 *---------------------------------------------------------
 */

/* Void */
void
GrX11SetCMap (pmap)
    char *pmap;			/* A pointer to 256*3 bytes containing the
				 * new values for the color map.  The first
				 * three values are red, green, and blue
				 * intensities for color 0, and so on.
				 */
{
    char *p;	
    int i,j;
#ifdef HIRES
    static unsigned long planes[32];
    XVisualInfo grvisual_info, *grvisual_get, grtemplate;
    VisualID defpsvid;
    int defpsindex = -1;
    int gritems, gritems_list, grcolorCount;
    int red_size, green_size, blue_size, red_shift, green_shift, blue_shift;
    int red_mask, green_mask, blue_mask;

    char *visual_type[7];
#define visual_table_len  7
    int visual_table[visual_table_len];
    char *log_color, *env_str;
    int color_base, color_reserved;
#else
    static unsigned long planes[8];
#endif  /* HIRES */
    int status;
    unsigned long basepixel;
    static int firstCall = 1;
    static int planeCount;	/* how many planes we want to allocate */
    static int colorCount;	/* how many colors we want to allocate */
    static int realColors;	/* how many colors we actually do allocate */

    if (firstCall)
    {
         firstCall = 0;
#ifdef HIRES
         visual_type[0] = "StaticGrey";
         visual_type[1] = "GreyScale";
         visual_type[2] = "StaticColor";
         visual_type[3] = "PseudoColor";
         visual_type[4] = "TrueColor";
         visual_type[5] = "DirectColor";
	 visual_type[6] = "UNKNOWN";
#else
/* Cannot hold the total set of colors in an array for grCurrent.depth > 8 */
	 colorCount = 1 << grCurrent.depth;
	 realColors = colorCount;
#endif  /* HIRES */
	 grXcmap = XDefaultColormap(grXdpy,grXscrn);
#ifdef HIRES
/* Discover properties of Server.  */
         grVisual = XDefaultVisual(grXdpy, grXscrn);
         defpsvid = XVisualIDFromVisual(grVisual);
         grtemplate.screen = grXscrn;
         grtemplate.depth = 0; 
         grvisual_get = XGetVisualInfo(grXdpy, VisualScreenMask, &grtemplate, &gritems);
         if(grvisual_get == NULL) {
           TxPrintf("Could not obtain Visual Info from Server %s. Will attempt default.\n",
              getenv("DISPLAY"));}
         else {
#ifdef HIRESDB
          TxPrintf("Server Vendor: %s\n", ServerVendor(grXdpy));
          TxPrintf("Vendor Release: %d\n", VendorRelease(grXdpy));
          TxPrintf("Protocol Version: %d\n", ProtocolVersion(grXdpy));
          TxPrintf("Protocol Revision: %d\n", ProtocolRevision(grXdpy));
#ifdef OS2
          TxPrintf("HOSTTYPE: i386-OS/2\n");
#else
          TxPrintf("HOSTTYPE: %s\n", getenv("HOSTTYPE"));
#endif  /* OS2 */
          TxPrintf("XGetVisualInfo returned visuals list of length %d:\n", gritems);
          TxPrintf("Default VisualID 0x%x\n", defpsvid);
#endif  /* HIRESDB */
          gritems_list = gritems;
          for(gritems = 0; gritems < gritems_list; gritems++) {
	   j = grvisual_get[gritems].class;
	   if( j < 0 || j > 5) {
	     TxPrintf("Unknown visual class index: %d\n", j);
	     j = 6; }
#ifdef HIRESDB
           TxPrintf("Found Visual Class %s, ID 0x%x with:\n     depth %d, colormap_size %d, bits_per_rgb %d.\n",
             visual_type[j],
             grvisual_get[gritems].visualid,
             grvisual_get[gritems].depth,
             grvisual_get[gritems].colormap_size,
             grvisual_get[gritems].bits_per_rgb);
           if(grvisual_get[gritems].class == 4) {
             TxPrintf("     TrueColor masks: red %06x, green %06x, blue %06x\n",
               grvisual_get[gritems].red_mask, grvisual_get[gritems].green_mask,
               grvisual_get[gritems].blue_mask);
           }
#endif  /* HIRESDB */
           if ((grvisual_get[gritems].class == 3) &&
             (grvisual_get[gritems].visualid == defpsvid)) { defpsindex = gritems;}
         }
/* Unfortunately, the list returned by Xservers has classes in random order.
   Therefore, a search is needed to find a good choice. The only currently
   supported classes are PseudoColor at depth 8 and TrueColor at depth 15,
   16, and 24.
   It is likely that TrueColor depths 8 through 32 will work, but these have
   not been tested.
   In addition, it has been discovered that some SUN systems "offer" more
   than one Pseudocolor at depth 8, but with differing colormap sizes.
   There is nothing about how to handle this in the X11 documentation, so
   the search below chooses the "first" class. The class with 256 colors
   seems preferable and works at present. The second Pseudocolor in the
   list gives a BatMatch reject from the server, so it is useless. Basing
   the selection on 256 colors might be effective, but might conflict in
   other cases... As usual X11 is just guesswork.

   At present the preferred order is: PseudoColor at 8, then TrueColor at 24,
   then TrueColor at 16, ...
   Unless this is overridden by the MAGIC_COLOR environment variable, which
   can be: bw, 8, 16, 24
*/
         for(j = 0; j < visual_table_len; j++) { visual_table[j] = -1; }
         for(j = 0; j < gritems_list; j++) {
           if((grvisual_get[j].class == 0) && (grvisual_get[j].depth == 8)
             && (visual_table[1] == -1)) visual_table[1] = j; /* StaticGrey */
           if((grvisual_get[j].class == 1) && (grvisual_get[j].depth == 8)
             && (visual_table[2] == -1)) visual_table[2] = j; /* GreyScale */
           if((grvisual_get[j].class == 3) && (grvisual_get[j].depth == 8)
             && (visual_table[3] == -1)) visual_table[3] = j; /* Psuedocolor */
           if((grvisual_get[j].class == 4) && (grvisual_get[j].depth == 15)
             && (visual_table[4] == -1)) visual_table[4] = j; /* TrueColor */
           if((grvisual_get[j].class == 4) && (grvisual_get[j].depth == 16)
             && (visual_table[5] == -1)) visual_table[5] = j; /* TrueColor */
           if((grvisual_get[j].class == 4) && (grvisual_get[j].depth == 24)
             && (visual_table[6] == -1)) visual_table[6] = j; /* TrueColor */
         }
         if(defpsindex != -1) { visual_table[3] = defpsindex; }
         log_color = getenv("MAGIC_COLOR");

	 /* Allow environment variables to override the colormap base and */
	 /* number of reserved colors, as these depend on the terminal X  */
	 /* server, NOT on the machine running magic.			  */
	 /* Note:  ought to use something that checks for errors in place */
	 /* of atoi().							  */

	 env_str = getenv("X_COLORMAP_BASE");
	 if (env_str != NULL)
	    color_base = (int)atoi(env_str);
	 else
	    color_base = X_COLORMAP_BASE;
	 env_str = getenv("X_COLORMAP_RESERVED");
	 if (env_str != NULL)
	    color_reserved = (int)atoi(env_str);
	 else
	    color_reserved = X_COLORMAP_RESERVED;
	 
         gritems = -1;
         if(log_color != NULL) {
            if(strncmp(log_color, "8bit", 4) == 0)  gritems = visual_table[3];
            if(strncmp(log_color, "15bit", 5) == 0) gritems = visual_table[4];
            if(strncmp(log_color, "16bit", 5) == 0) gritems = visual_table[5];
            if(strncmp(log_color, "24bit", 5) == 0) gritems = visual_table[6];
            if(gritems == -1) {
               printf("The visual mode %s is not available. Sorry.\n", log_color);
               XFree(grvisual_get);
               MainExit(1); }
         }
         else {
            if(visual_table[3] != -1)      gritems = visual_table[3];
            else if(visual_table[6] != -1) gritems = visual_table[6];
            else if(visual_table[5] != -1) gritems = visual_table[5];
            else if(visual_table[4] != -1) gritems = visual_table[4];
         }
         if(gritems == -1) {
           TxPrintf("Neither TrueColor 15, 16 nor 24, nor PseudoColor 8 found. ");
           TxPrintf("Cannot initialize DISPLAY %s\n", getenv("DISPLAY"));
           XFree(grvisual_get);
           MainExit(1);
         }
         else {
           TxPrintf("Using %s, VisualID 0x%x depth %d\n",
             visual_type[grvisual_get[gritems].class],
             grvisual_get[gritems].visualid,
             grvisual_get[gritems].depth); }
         grClass         = grvisual_get[gritems].class;
         grVisual        = grvisual_get[gritems].visual;
         grcolorCount    = grvisual_get[gritems].colormap_size;
         grCurrent.depth = grvisual_get[gritems].depth;
         red_mask        = grvisual_get[gritems].red_mask;
         green_mask      = grvisual_get[gritems].green_mask;
         blue_mask       = grvisual_get[gritems].blue_mask;
       }
       XFree(grvisual_get);
       planeCount = grCurrent.depth;
       colorCount = grcolorCount;
       realColors = colorCount;
       if(planeCount > 8) {    /* must load appropriate Dstyle file. */
          grDStyleType = "24bit";
          if(GrLoadStyles(DBWStyleType, ".", SysLibPath))
		/* MainExit(); */
		MainExit(1);
       }
       if(planeCount == 8) {
          grCurrent.depth = 7;
          planeCount = 7;      /* This resets to old 7-plane mode */
          colorCount = 1 << (planeCount);
	  realColors = colorCount;
       }
#endif  /* HIRES */ 
       if(grCurrent.depth) {
#ifdef HIRES
          status = 0;
          if(grClass != 4)
#endif  /* HIRES */
	     status= XAllocColorCells(grXdpy,grXcmap,True,planes,planeCount,
	     							&basepixel,1); 
	  if (status == 0) 
	  /* ok, we tried to be nice; now lets whack the default colormap
	     and put in one of our own.
	     */
	  {
#ifdef HIRES
             int actualColors = grcolorCount;
#else
             int actualColors = 1 << XDefaultDepth(grXdpy,grXscrn);
#endif  /* HIRES */
             int usableColors = actualColors - color_reserved;

#ifdef HIRES
             if(usableColors > 256) usableColors = 256;
             if(grClass != 4)
#endif  /* HIRES */
	       TxPrintf("Unable to allocate %d planes in default colormap; making a new one.\n",planeCount);
             if(planeCount <= 8) {
#ifdef HIRES
	        grXcmap = XCreateColormap(grXdpy,grCurrent.window, 
                  grVisual, AllocAll);
#else
	        grXcmap = XCreateColormap(grXdpy,grCurrent.window,
		  				XDefaultVisual(grXdpy,
							grXscrn),
							AllocAll);
#endif  /* HIRES */
#ifdef HIRESDB
                TxPrintf("actualColors %d, usableColors %d, planeCount %d\n",
                  actualColors, usableColors, planeCount);
#endif  /* HIRESDB */
                basepixel = color_base;
              }
              else {
#ifdef HIRES
	        grXcmap = XCreateColormap(grXdpy,grCurrent.window,
                  grVisual, AllocNone);
#else
	        grXcmap = XCreateColormap(grXdpy,grCurrent.window,
                  XDefaultVisual(grXdpy, grXscrn), AllocNone);
#endif  /* HIRES */
                 basepixel = 0;
              }
              for (j=0; j < planeCount; j++) planes[j] = 1<<j;
	      status = 1;
 	      for (i=0; i < usableColors; i++) colors[i].pixel = i;
	      XQueryColors(grXdpy, XDefaultColormap(grXdpy, 
                grXscrn), colors, usableColors);
#ifdef HIRES
              if(planeCount <= 8)
#endif  /* HIRES */
		 XStoreColors(grXdpy, grXcmap, colors, usableColors);
	      realColors = (basepixel+colorCount > usableColors)?
		  			    usableColors-basepixel:
					    colorCount;
#ifdef HIRES
	      if ((realColors != colorCount) && (planeCount <= 8))
#else
	      if (realColors != colorCount)
#endif  /* HIRES */
	      {
	         TxPrintf("Only %d contiguous colors were available.\n",realColors);
                   colorCount=realColors;
	      }
	    }
	     			
	    if (grXcmap == 0 || status ==0) 
	    {
	       TxError( "X11 setup: Unable to allocate %d planes\n",planeCount);
	       MainExit(1);
	    }

	     /* grCompleteMask is a mask of all the planes not used by this 
	        technology.  It is OR'd in with the mask that magic supplies
	        to ensure that unused bits of the pixel are cleared.
	   
	        grNumBitPlanes is set when the dstyles file is read in; for
	        the following to work, the dstyles file must be read before
	        the colormap.  I changed main.c so that this was the case.
	        If you aren't getting mutually exclusive colors, this may
	        be why.
	   					-dcs
	     */
#ifdef HIRES
#ifdef HIRESDB
            TxPrintf("planeCount %d, realColors %d\n", planeCount, realColors);
#endif  /* HIRESDB */
            if(planeCount > 8) {
               p = pmap;
               if(planeCount == 16) {
                 red_size = 5; green_size = 6; blue_size = 5; }
               else if(planeCount == 15) {
                 red_size = 5; green_size = 5; blue_size = 5; }
               else {
                 red_size = 8; green_size = 8; blue_size = 8; }
               red_shift = green_size + blue_size;
               green_shift = blue_size;
               if((planeCount == 24) & (red_mask == 0xff)) {
               /* this is SUN Solaris doing it backwards: BGR  */
                 red_shift = 0; green_shift = red_size;
                 blue_shift = green_size + red_size; }

	       /* DANGER! Modify the code below with care: 
		  gcc 2.7.2 generates bad code if the masks are not used as below. */
               for (i=0;i != colorCount;i++) {
                 if((planeCount == 16) || (planeCount ==15)) {
                   grPixels[i] =  (long)(((*p++) >> (8 - red_size))
                     << (green_size + blue_size)) & red_mask;       /* red */
                   grPixels[i] |= (long)(((*p++) >> (8 - green_size))
                     << blue_size) & green_mask;                    /* green */
                   grPixels[i] |= (long)((*p++) >> (8 - blue_size)) & blue_mask; /* blue */
	         }
                 else if((planeCount == 24) & (red_mask == 0xff)) {
                   /* this is SUN Solaris doing it backwards: BGR  */
                   grPixels[i] = (long)((*p++) & red_mask);
		   /* here is where gcc really goes wrong (sign extends) */
                   grPixels[i] |= (long)(((*p++) << green_shift) & green_mask);
                   grPixels[i] |= (long)(((*p++) << blue_shift) & blue_mask);
                 }
                 else {
                   grPixels[i] =  (long)(((*p++)<< red_shift) & red_mask);
                   grPixels[i] |= (long)(((*p++)<< green_shift) & green_mask);
                   grPixels[i] |= (long)((*p++) & blue_mask);
                 }
               }
#ifdef HIRESDB
               TxPrintf("grPixels: %6x %6x %6x %6x\n", grPixels[0], grPixels[1],
                 grPixels[2], grPixels[3]);
#endif  /* HIRESDB */
               for(i=0; i < planeCount; i++) {
                    planes[i] = 1 << i;
                    grPlanes[i] = 0;
                    for(j=0;j != planeCount;j++) if(i & (1<<j)) {
                       grPlanes[i] |= planes[j]; }
                 }
               grCompleteMask = 0;
            }
            else { 
#endif  /* HIRES */
	       grCompleteMask = 0;
	       if (grNumBitPlanes > 7 || grNumBitPlanes <1)
	         {
	           TxError("display_styles must be 0 < p < 8 under X11");
	           GrX11Close();
	           MainExit(1);
	         }
	       if (grNumBitPlanes > planeCount)
	         {
	           TxError("Your display_styles uses %d planes but you only have %d\n",grNumBitPlanes,planeCount);
	           GrX11Close();
	           MainExit(1);
	         }
	       for (i=0;i != grNumBitPlanes;i++)
	         {
	           grCompleteMask |= planes[i];
	         }
	       grCompleteMask = AllPlanes & ~grCompleteMask;

	       for (i=0;i != colorCount;i++)
	         {
	           grPixels[i] = basepixel;
	           grPlanes[i] = grCompleteMask;
	           for (j=0;j != planeCount;j++)  if ( i & (1 <<j))
	             {
	     	       grPixels[i] |= planes[j];
		       grPlanes[i] |= planes[j];
	             } 
	       }
#ifdef HIRES
            }
#endif  /* HIRES */
       }
       else
       {
	  grPixels[0] = WhitePixel(grXdpy,grXscrn);
          grPixels[1] = BlackPixel(grXdpy,grXscrn);
          grPlanes[0] = 0;
          grPlanes[1] = AllPlanes;
       }
    }
    if (grCurrent.depth)
    {
       p = pmap;
       for( i = 0; i < realColors; i++) 
       {
          colors[ i ].pixel = grPixels[ i ];
          colors[ i ].red = *p++ << 8;
          colors[ i ].green = *p++ << 8;
          colors[ i ].blue = *p++ << 8;
	  colors[ i ].flags = DoRed|DoGreen|DoBlue;
       }
#ifdef HIRES
       if(planeCount <= 8) {
#ifdef HIRESDB
       TxPrintf("XStoreColors: planeCount %d, realColors %d\n", planeCount, realColors);
#endif  /* HIRESDB */
#endif  /* HIRES */
          XStoreColors(grXdpy, grXcmap, colors, realColors);
       }
    }
}

XSegment grx11Lines[X11_BATCH_SIZE];
int grx11NbLines=0;
XRectangle grx11Rects[X11_BATCH_SIZE];
int grx11NbRects=0;


/*---------------------------------------------------------
 * grxDrawLines:
 *	This routine draws a batch of lines.
 *
 * Results:	None.
 *
 * Side Effects:
 *	Draw a bunch of lines.
 *---------------------------------------------------------
 */
/* Void */
void
grx11DrawLines(lines, nb)
    XSegment lines[];
    int nb;
{
    XDrawSegments(grXdpy, grCurrent.window, grGCDraw,
	      lines, nb);
}

/*---------------------------------------------------------
 * grxDrawLine:
 *	This routine draws a line.
 *
 * Results:	None.
 *
 * Side Effects:
 *	Draw a line for (x1, y1) to (x2, y2) inclusive.
 *---------------------------------------------------------
 */
/* Void */
void
grx11DrawLine (x1, y1, x2, y2)
    int x1, y1;			/* Screen coordinates of first point. */
    int x2, y2;			/* Screen coordinates of second point. */
{
    if (grx11NbLines == X11_BATCH_SIZE) GR_X_FLUSH_LINES();
    grx11Lines[grx11NbLines].x1 = x1;
    grx11Lines[grx11NbLines].y1 = grMagicToX(y1);
    grx11Lines[grx11NbLines].x2 = x2;
    grx11Lines[grx11NbLines].y2 = grMagicToX(y2);
    grx11NbLines++;
}

/*---------------------------------------------------------
 * grxFillRects:
 *	This routine draws a bunch of solid rectangles.
 *
 * Results:	None.
 *
 * Side Effects:
 *	Drawing.
 *---------------------------------------------------------
 */

/* Void */
void
grx11FillRects(rects, nb)
    XRectangle rects[];
    int nb;
{
    XFillRectangles(grXdpy, grCurrent.window, grGCFill, rects, nb);
}

/*---------------------------------------------------------
 * grxFillRect:
 *	This routine draws a solid rectangle.
 *
 * Results:	None.
 *
 * Side Effects:
 *	Drawing.
 *---------------------------------------------------------
 */

/* Void */
void
grx11FillRect(r)
    register Rect *r;	/* Address of a rectangle in screen
			 * coordinates.
			 */
{
    if (grx11NbRects == X11_BATCH_SIZE) GR_X_FLUSH_RECTS();
    grx11Rects[grx11NbRects].x = r->r_xbot;
    grx11Rects[grx11NbRects].y = grMagicToX(r->r_ytop);
    grx11Rects[grx11NbRects].width = r->r_xtop - r->r_xbot + 1;
    grx11Rects[grx11NbRects].height = r->r_ytop - r->r_ybot + 1;
    grx11NbRects++;
}

#ifdef NONMANHATTAN

/*---------------------------------------------------------
 * grx11FillPolygon:
 *	This routine draws a solid polygon
 *
 * Results:     None.
 *
 * Side Effects:
 *	Drawing.
 *---------------------------------------------------------
 */

/* Void */
void
grx11FillPolygon(tp, np)
    Point *tp;
    int np;
{
    XPoint xp[5];
    int i;

    for (i = 0; i < np; i++)
    {
	xp[i].x = tp[i].p_x;
	xp[i].y = grMagicToX(tp[i].p_y);
    }
    XFillPolygon(grXdpy, grCurrent.window, grGCFill, xp, np,
		Convex, CoordModeOrigin);
}

#endif /* NONMANHATTAN */
