diff glib/X.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/glib/X.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,1459 @@
+
+/*
+    Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
+    ===========================================================================
+
+    Permission to use, copy, modify, and distribute this software without fee
+    is hereby granted for research purposes, provided that this copyright
+    notice appears in all copies and in all supporting documentation, and that
+    the software is not redistributed for any fee (except for a nominal shipping
+    charge). Anyone wanting to incorporate all or part of this software in a
+    commercial product must obtain a license from the Medical Research Council.
+
+    The MRC makes no representations about the suitability of this
+    software for any purpose.  It is provided "as is" without express or implied
+    warranty.
+*/
+
+/*******************************************************************************************
+
+ X.c      A GENERIC X-WINDOWS REAR-END FOR THE WINDOWS.H INTERFACE.
+
+
+ This module is derived from the x10.c module, written by John Holdsworth, and the subsequent
+ x11.c module, which was ported by Paul Manson. It attempts to combine the x10/x11 code in
+ such a way as to provide a single uniform application with the minimal amount of #ifdef
+ "noise". It expects to have either X10 or X11 defined as symbols by the preprocessor -- in the
+ event that neither of these is defined, it produces an error message and causes the compiler
+ to exit; ie. there is NO DEFAULT.
+
+ Written: May 3rd. by Paul Manson (but see credits above)
+
+ Edited:
+
+ 15   May   1989  (Paul Manson) -- Altered the <pixels> argument to use <pixels>-1 in the
+                                   newDisplay window call. On X11, pixels of 0 means "use
+                                   thin lines", which always work correctly. Values greater
+                                   than 0 imply "thick lines", which appear to over-write
+                                   each other.
+
+ 05  June   1989  (Paul Manson) -- Removed the offending "warning" message from axes();.
+
+ 27  July   1989  (Johh Holdsworth) -- put in addition loops to segment line drawing
+				   operations for very long lines and put XFlush() in
+				   before pausing. A bug remains in the segentation of
+				   hidden line removal. The Fill operation Paint to hide
+				   lines lower than that just drawn can remove part of
+				   that line - very tricky to avoid. The same problem
+				   seem to be present in ps.c.
+
+ 18 August  1989  (Paul Manson) -- Altered to accomodate the Pixmap/newWindowWindow entry
+                                   which forces un-resizable windows on us with X11.
+
+ 21 August  1989  (Paul Manson) -- Also altered "Clear" so that it does a FillRectangle in
+                                   preference to a ClearWindow. The latter call doesn't work
+				   for Pixmaps (see newWindowWindow, etc).
+
+ 22 August  1989  (Paul Manson) -- In a similar vein to the above, I have altered X.c so that
+                                   two global variables Foreground and Background are used to
+				   determine the colours for drawing and filling.
+
+ 04 September 1989 (Paul Manson) - Altered so that the GXmodes are used to modify the GC for
+                                   clear, draw, etc operations. This seems to be a much more
+				   reliable way in which to manipulate these settings.
+
+ 31 July 1990 (John Holdsworth)  - Extensive changes to remove previous change. GXcopy
+				   now used with foreground appropiately set. This has
+				   proved more portable particularly for Multiplane displays.
+
+
+ 26th May 1993 (Mitch d'Souza & M Akeroyd) - added an extra include - sys/types.h - so that the
+                                   gcc would work on a decstation.
+
+ 3rd August 1993 (M. Akeroyd)   - Removed the 'XAllPlanes' bist of the XGetImage routines,
+                                  so that monochrome bitmaps could be made on colour 
+				  computers.
+				  Also included new SilentOptions :
+				      mono_ctn
+				      colour_ctn
+				      planemask_ctn
+
+ 20th August 1993 (M.Akeroyd)  - First attempt at colour images: two new options fg_col and 
+                                 bg_col, and a complementary procedure define_colour().
+				 These do NOT work with view=grayscale.
+
+                                 ********************************************************************************************/
+
+
+#if !defined(X11) && !defined(X10)
+#define X11
+#endif
+
+#if !defined(X10) && !defined(X11)
+#include "-- YOU MUST DEFINE EITHER X10 or X11 TO USE THIS MODULE"
+#endif
+
+#include <stdio.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include "options.h"        /* Added: MAA 3-8-1993 */
+#if defined(X11)
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>  /* MAA: 20-8-1993. For colour */
+#include <X11/Xos.h>    /* MAA: 20-8-1993. For colour */
+
+
+#else
+#if defined(X10)
+#include <X/Xlib.h>
+#endif
+#endif
+
+#include "windows.h"
+#include "grey.h"
+
+#define FALSE (0)
+#define TRUE  (1)
+#define MAX_FILES   (20)
+#define MAX_SEGMENT (5000)
+#define MAX_ROW     (100)
+#define MAX_COL     (1000)
+#define MAX_IMAGE   (1500)
+#define DITHER_SIZE (8)
+
+extern char *monostr, *colourstr, *planemaskstr;  /* Added: MAA 3-8-1993 */
+int planemask;
+
+static Display *theDisplay = (Display *) 0;   /* The Display Variable */
+static int      theWidth, theHeight;   /* The Width and Height of the Screen in Pixels     */
+
+#define MIN(X,Y) (((X) < (Y)) ? (X) : (Y))
+
+#define USE_PIXMAPS
+
+#if defined(X11)
+static int      theScreen                 ;   /* The associated screen no. */
+static int      synchronous = FALSE ;
+static unsigned long theForeground, theBackground;
+#else
+static char *marker_font_name = "6x10" ;
+static FontInfo *marker_font = ( FontInfo * ) 0 ;
+#endif
+
+typedef struct {
+  windowEntries *entries ;
+  Window w ;
+  int pixels, width, height, hide ;
+  int x, y ;
+#if defined(X11)
+  GC foregroundGC ;
+  GC backgroundGC ;
+  int isMapped ;
+#ifdef USE_PIXMAPS
+  Pixmap imageData[ MAX_IMAGE ];
+#else
+  XImage *imageData[ MAX_IMAGE ];
+#endif
+  XImage *theImage;                  /* Used only for Read operations; The wind__write */
+                                     /* entry point actually creates & destroys images */
+  XImage *rowImage, *colImage ;
+#else
+  int foreground, background ;
+  short *imageData[ MAX_IMAGE ];
+  short *theImage              ;
+#endif
+  struct _lookup *lookup       ;    /* Dithering */
+  int   **diths                ;    /* Dithering */
+  short  *data                 ;    /* Dithering */
+  int     greylength ;
+  int     imageNum ;
+  int     imageSize;
+} *XWindowObject ;
+
+#ifndef  lint
+static char *sccs_id = "@(#)X.c	1.38 Paul Manson, John Holdsworth (MRC-APU) 5/31/91" ;
+#endif
+
+#if defined(X11)
+
+
+
+
+/* MAA: Added 20-8-1993 
+* Colour ....
+* Copied off example 7.2 of Xlib Vol 1. 
+*/
+
+extern char *fgcolourstr;
+extern char *bgcolourstr;
+
+void define_colours()
+{
+  int default_depth;
+  Visual *default_visual;
+  XColor exact_def;
+  Colormap default_cmap;
+  int i=5;
+  XVisualInfo visual_info;
+
+
+  default_depth = DefaultDepth(theDisplay, theScreen);
+  default_visual = DefaultVisual(theDisplay, theScreen);
+  default_cmap = DefaultColormap(theDisplay, theScreen);
+
+/* MAA: Removed this. */
+/*  if (default_depth == 1) {*/
+    /* Black-White Only */
+/*    theForeground = BlackPixel(theDisplay, theScreen);*/
+/*    theBackground = WhitePixel(theDisplay, theScreen);}*/
+
+  /* i = visual class */
+  while (!XMatchVisualInfo(theDisplay, theScreen, default_depth, i--, &visual_info))
+    ;
+
+  if (i<StaticColor) {
+    theForeground = BlackPixel(theDisplay, theScreen);
+    theBackground = WhitePixel(theDisplay, theScreen);}
+
+  else {
+
+    /* Foreground */
+    if (!XParseColor(theDisplay, default_cmap, fgcolourstr, &exact_def)){
+      fprintf(stderr, "Unable to find colour %s in database. Using Black instead. \n", fgcolourstr);
+      theForeground = BlackPixel(theDisplay, theScreen);}
+    else 
+      if (XAllocColor(theDisplay, default_cmap, &exact_def))
+        theForeground = exact_def.pixel;
+      else {
+        fprintf(stderr, "Unable to alloc colour %s. Using Black instead. \n", fgcolourstr);
+        theForeground = BlackPixel(theDisplay, theScreen);}
+    
+    /* Background */
+    if (!XParseColor(theDisplay, default_cmap, bgcolourstr, &exact_def)){
+      fprintf(stderr, "Unable to find colour %s in database. Using White instead. \n", bgcolourstr);
+      theBackground = WhitePixel(theDisplay, theScreen);}
+    else 
+      if (XAllocColor(theDisplay, default_cmap, &exact_def))
+        theBackground = exact_def.pixel;
+      else {
+        fprintf(stderr, "Unable to alloc colour %s. Using White instead. \n", bgcolourstr);
+        theBackground = WhitePixel(theDisplay, theScreen);}
+  }
+}
+
+
+
+
+extern void InitializeX(display, screen, foreground, background)
+     Display      *display   ;
+     int           screen    ;
+     unsigned long foreground;
+     unsigned long background;
+{
+  if (theDisplay == (Display *) 0) {
+    theDisplay    = display   ;
+    theScreen     = screen    ;
+    theForeground = foreground;
+    theBackground = background;
+  }
+  else {
+    (void) fprintf(stderr, "Error! The X.c Display Variable has already been set...\nIt is invalid to call InitializeX after this has happened (eg. by a call to newDisplayWindow).\n");
+    exit(1);
+  }
+}
+
+/* not a nice routine to wait untill window is actually mapped before returning it's size */
+
+static void waitTillMapped( info )
+XWindowObject info ;
+{
+    XWindowAttributes at ;
+
+    if( !info->isMapped ) {
+	do
+	    XGetWindowAttributes( theDisplay, info->w, &at ) ;
+	while ( at.map_state == IsUnmapped ) ;
+
+	info->isMapped = 1 ;
+
+	info->width  = at.width  ;
+	info->height = at.height ;
+    }
+
+    return ;
+}
+
+/* ---------------- Beware! This function may be the most dangerous thing ---------------
+   ----------------         to ever appear on a DecStation... it makes    ---------------
+   ----------------         sweeping assumptions about the way that data  ---------------
+   ----------------         is stored in the X server. If it EVER happens ---------------
+   ----------------         that the X Consortium write routines for I/O  ---------------
+   ----------------         of Screen Images, THROW THIS AWAY!            --------------- */
+static int ImageSizeInBytes(image)
+     XImage *image;
+{
+
+   /* Cribbed from X11R3/.../xwd.c */
+
+   return(image->bytes_per_line * image->height * image->depth);
+
+}
+
+
+static setupImage( w )
+XWindowObject w ;
+{
+    if( w->theImage == ( XImage * ) 0 ) {
+	w->theImage = XGetImage(theDisplay, w->w, 0, 0, w->entries->width(w),
+			       w->entries->height(w), planemask, XYPixmap);
+	w->imageSize = ImageSizeInBytes(w->theImage);
+    }
+}
+
+
+
+#endif
+
+static short window__x( info )
+XWindowObject info ;
+{
+#if defined(OldX11)
+    XWindowAttributes winfo;
+
+    (void) XGetWindowAttributes( theDisplay, info->w, &winfo );
+
+    return ((short) winfo.x);
+#else
+#if defined(X11)
+    return ((short) info->x);
+#else
+    WindowInfo winfo;
+
+    XQueryWindow(info->w, &winfo);
+
+    return (winfo.x);
+#endif
+#endif
+}
+
+static short window__y( info )
+XWindowObject info ;
+{
+#if defined(OldX11)
+    XWindowAttributes winfo;
+
+    (void) XGetWindowAttributes( theDisplay, info->w, &winfo );
+
+    return ((short) winfo.y);
+#else
+#if defined(X11)
+    return ((short) info->y);
+#else
+    WindowInfo winfo;
+
+    XQueryWindow(info->w, &winfo);
+
+    return (winfo.y);
+#endif
+#endif
+}
+
+static short window__width( info )
+XWindowObject info ;
+{
+#if defined(X11)
+    waitTillMapped(info) ;
+#endif
+
+    return( info->width ) ;
+}
+
+static short window__height( info )
+XWindowObject info ;
+{
+#if defined(X11)
+    waitTillMapped(info) ;
+#endif
+
+    return( info->height ) ;
+}
+
+static void window__draw( info, xs, ys, pointsFlag )
+XWindowObject info ;
+short xs[], ys[] ;
+int pointsFlag ;
+{
+#if defined(X11)
+    XPoint vs[MAX_SEGMENT], *vptr;
+#else
+    Vertex vs[MAX_SEGMENT], *vptr;
+#endif
+    register int point, count ;
+    register int points = abs( pointsFlag ) ;
+    register short h ;
+
+#if defined(X11)
+    if (synchronous) {
+      (void) XSynchronize(theDisplay, FALSE);
+      XFlush(theDisplay);
+      synchronous = FALSE;
+    }
+
+    waitTillMapped(info) ;
+#else
+    int i ;
+#endif
+
+    h = info->entries->height( info );
+
+    for( point = 0 ; point < points - 1 ; point += count - 1 ) {
+
+	vptr = vs ;
+
+	for( count=0 ; count < MAX_SEGMENT && point + count < points ; count++ ) {
+
+	    vptr->x =     xs[ point+count ] ;
+	    vptr->y = h - ys[ point+count ] ;
+#if defined(X10)
+	    vptr->flags = pointsFlag > 0 ? 0 : 0 ;
+#endif
+	    vptr++;
+	}
+
+	if( info->hide && pointsFlag > 0 && vs[0].x == vptr[-1].x &&
+					    vs[0].y == vptr[-1].y )
+#if defined(X11)
+	    XFillPolygon( theDisplay, info->w, info->backgroundGC, vs, vptr-vs, Complex, CoordModeOrigin);
+
+	if( pointsFlag > 0 )
+	    XDrawLines( theDisplay, info->w, info->foregroundGC, vs, vptr-vs, CoordModeOrigin);
+	else
+	    XDrawPoints(theDisplay, info->w, info->foregroundGC, vs, vptr-vs, CoordModeOrigin);
+
+	XFlush(theDisplay);
+#else
+	    XDrawFilled( info->w, vs, vptr-vs, info->background, GXcopy, AllPlanes ) ;
+
+	if( pointsFlag > 0 )
+	    XDraw(info->w, vs, vptr-vs, info->pixels, info->pixels, info->foreground, GXcopy, AllPlanes);
+	else
+	    for( i=0 ; i<count ; i++ )
+		XPixSet( info->w, vs[i].x, vs[i].y, info->pixels, info->pixels, info->foreground ) ;
+#endif
+    }
+
+    return;
+}
+
+static void checkGeometry( info )
+XWindowObject info ;
+{
+#if defined(X11)
+    return;
+#else
+#if defined(OldX11)
+    XWindowAttributes winfo;
+
+    (void) XGetWindowAttributes( theDisplay, info->w, &winfo );
+#else
+    WindowInfo winfo;
+
+    XQueryWindow(info->w, &winfo);
+#endif
+
+    info->width  = winfo.width ;
+    info->height = winfo.height ;
+
+    return ;
+#endif
+}
+
+static void window__clear( info )
+XWindowObject info ;
+{
+
+    checkGeometry( info ) ;
+
+#if defined(OldX11)
+    XClearWindow(theDisplay, info->w);
+    XFlush(theDisplay);
+#else
+#if defined(X11)
+    XFlush(theDisplay);
+    XFillRectangle( theDisplay, info->w, info->backgroundGC, 0, 0, info->width, info->height ) ;
+    XFlush(theDisplay);
+#else
+    XClear(info->w);
+#endif
+#endif
+
+    return ;
+}
+
+static void window__close( info )
+XWindowObject info ;
+{
+    if (info != (XWindowObject )0)
+#if defined(X11)
+	XFreeGC( theDisplay, info->foregroundGC ) ;
+	XFreeGC( theDisplay, info->backgroundGC ) ;
+        XDestroyWindow(theDisplay, info->w);
+#else
+        XDestroyWindow(info->w);
+#endif
+    free( (char *) info ) ;
+
+    return ;
+}
+
+static int window__store( info )
+XWindowObject info ;
+{
+    if (info->imageNum > MAX_IMAGE) {
+      (void) fprintf(stderr,
+		     "windows: Sorry, you can currently store only %i images per window.\n",
+		     MAX_IMAGE);
+      return(FALSE);
+    }
+#if defined(X11)
+    if (!synchronous) {
+      (void) XSynchronize(theDisplay, TRUE);
+      XFlush(theDisplay);
+      synchronous = TRUE;
+    }
+
+    waitTillMapped(info) ;
+
+#ifdef USE_PIXMAPS
+    info->imageData[ info->imageNum ] = XCreatePixmap(theDisplay, info->w, Width( info ), Height( info ), DisplayPlanes( theDisplay, theScreen ) ) ;
+    XCopyArea( theDisplay, info->w, info->imageData[ info->imageNum ], info->foregroundGC, 0, 0, Width( info), Height( info ), 0, 0 ) ;
+#else
+    info->imageData[ info->imageNum ] = XGetImage(theDisplay, info->w, 0, 0,
+					  info->entries->width(info),
+					  info->entries->height(info),
+					  planemask,
+					  XYPixmap);
+#endif
+#else
+    if((info->imageData[info->imageNum] = (short *) malloc(info->imageSize)) == (short *) 0) {
+	(void) fprintf(stderr, "Insufficient memory to store %dth image of size %d\n",
+		       info->imageNum+1, info->imageSize);
+	return(FALSE);
+      }
+    else
+	XPixmapGetXY( info->w, 0, 0, info->entries->width(info),
+		     info->entries->height(info), info->imageData[ info->imageNum ] ) ;
+#endif
+    info->imageNum++;
+
+    return ( info->imageNum ) ;
+}
+
+WindowImage window__current_image( info )
+XWindowObject info ;
+{
+    static struct _window_image image_info ;
+#if defined(X11)
+#if !defined( USE_PIXMAPS)
+    XImage *image_ptr = info->imageData[ info->imageNum-1 ] ;
+
+    image_info.data           = image_ptr->data ;
+    image_info.bytes_per_line = image_ptr->bytes_per_line ;
+    image_info.height         = image_ptr->height ;
+
+    image_info.left_bit  = 1<<0 ;
+    image_info.right_bit = 1<<7  ;
+    image_info.start_bit = image_info.left_bit<<image_ptr->xoffset ;
+#endif
+#else
+    short *image_ptr = info->imageData[ info->imageNum-1 ] ;
+
+    image_info.data = ( char *) image_ptr ;
+    image_info.height = info->height ;
+    image_info.bytes_per_line = ( info->width + 15 ) / 16 * sizeof (*image_ptr) ;
+
+    image_info.left_bit  = 1<<0 ;
+    image_info.right_bit = 1<<7  ;
+    image_info.start_bit = image_info.left_bit ;
+
+#endif
+
+    return ( &image_info ) ;
+}
+
+static void window__recall( info, which )
+XWindowObject info ;
+int which ;
+{
+
+#if defined(X11)
+    if (synchronous) {
+      (void) XSynchronize(theDisplay, FALSE);
+      XFlush(theDisplay);
+      synchronous = FALSE;
+    }
+#endif
+    if( which > info->imageNum )
+	(void) fprintf( stderr, "Invalid Pixmap number %d(%d)\n", which, info->imageNum ) ;
+    else
+#if defined(X11)
+#ifdef USE_PIXMAPS
+        XCopyArea( theDisplay, info->imageData[ which-1 ], info->w, info->foregroundGC, 
+		0, 0, Width( info), Height( info ), 0, 0 ) ;
+#else
+	XPutImage(theDisplay, info->w, info->foregroundGC, info->imageData[which-1], 0, 0, 0, 0,
+		  info->entries->width(info), info->entries->height(info));
+#endif  
+	XFlush(theDisplay) ;
+#else
+	XPixmapBitsPutXY(info->w, 0, 0, info->entries->width(info), info->entries->height(info),
+			 info->imageData[ which-1 ], (Bitmap) 0, GXcopy, AllPlanes);
+#endif
+    return  ;
+}
+
+#define MAX_COLORS 62
+
+static char *cmap( npixels )
+int *npixels ;
+{
+    int plane_masks[1], pix_num ;
+    char *pixvals ;
+#if defined(X11)
+	Visual *visual = DefaultVisual( theDisplay, theScreen ) ;
+    Colormap theColormap = DefaultColormap( theDisplay, theScreen ) ;
+    XColor exact_defs[MAX_COLORS] ;
+    unsigned long colors[MAX_COLORS] ;
+
+	switch( visual->class ) {	
+		case StaticGray :
+		
+			*npixels = 1 << DisplayPlanes( theDisplay, theScreen ) ;
+		    pixvals = malloc( (unsigned) *npixels ) ;
+
+    		for( pix_num=0 ; pix_num < *npixels ; pix_num++ )
+				pixvals[pix_num] = pix_num ;
+
+			break ;
+			
+		case PseudoColor :
+		
+    for( *npixels=MAX_COLORS; *npixels > 2 ; (*npixels)-- ) 
+        if( XAllocColorCells( theDisplay, theColormap, False, plane_masks, 0, colors, *npixels ) ) 
+            break ;
+
+    pixvals = malloc( (unsigned) *npixels + 2 ) ;
+    
+    pixvals[0] = BlackPixel( theDisplay, theScreen ) ;
+    
+    for( pix_num=0 ; pix_num < *npixels ; pix_num++ ) {
+        pixvals[pix_num+1] = 
+        exact_defs[pix_num].pixel = colors[ pix_num ] ;
+ 
+        exact_defs[pix_num].red   = 
+        exact_defs[pix_num].green = 
+        exact_defs[pix_num].blue  = 65535 * ( pix_num + 1 ) / ( *npixels + 1 ) ;
+
+        exact_defs[pix_num].flags = DoRed | DoGreen | DoBlue ;
+   }
+    
+    pixvals[*npixels+1] = WhitePixel( theDisplay, theScreen ) ;
+
+    XStoreColors( theDisplay, theColormap, exact_defs, *npixels ) ;
+
+    XFreeColors( theDisplay, theColormap, colors, *npixels, 0l ) ;
+
+    *npixels += 2 ;
+	
+	break ;
+	}
+#else
+    Color defs[256] ;
+    int pixels[256] ;
+    int planes ;
+    
+    *npixels = ( 1 << DisplayPlanes() ) - 2 ;
+
+    while( !XGetColorCells( 0, *npixels, 0, & planes, pixels ) && *npixels > 0 )
+    	*npixels-- ;
+	
+    pixvals = malloc( (unsigned) *npixels + 2 ) ;
+
+    pixvals[ 0 ] = BlackPixel ;
+           
+    for( pix_num=0 ; pix_num < *npixels ; pix_num++ ) {
+
+	pixvals[pix_num+1]  =
+
+	defs[pix_num].pixel = pixels[pix_num] ;
+
+	defs[pix_num].red   = 0 ;
+	defs[pix_num].green = 65535 * (pix_num+1) / (*npixels+1) ;
+	defs[pix_num].blue  = 0 ;
+
+    }
+
+    pixvals[ *npixels+1 ] = WhitePixel ;
+
+    XStoreColors( *npixels, defs ) ;
+
+    XFreeColors( pixels, *npixels, planes ) ;
+
+    XFlush() ;
+
+    *npixels += 2 ;
+#endif
+    return ( pixvals ) ;
+}
+
+static void ColorColumn( info, col, input, black, white, match, length, row_flag )
+XWindowObject info ;
+int col ;
+short *input ;
+int black, white ;
+int *match, length ;
+int row_flag ;
+{
+    register int i ;
+    char *data ;
+
+    if( info->lookup == 0 || length != info->greylength ) {
+
+	if( info->lookup != 0 )
+	    freeLookup( info->lookup ) ;
+
+	info->lookup = makeLookup( cmap, black, white, length ) ;
+
+#if defined(X11)
+        if( row_flag )
+            info->rowImage = XGetImage( theDisplay, info->w, 0, 0, Width(info),  1, planemask, ZPixmap );
+	else
+            info->colImage = XGetImage( theDisplay, info->w, 0, 0, 1, Height(info), planemask, ZPixmap );
+
+	info->greylength = length ;
+#endif
+    }
+
+    data = Lookup( col, info->lookup, input, match, length ) ;
+
+#if defined(X11)
+     if( row_flag ) {
+	 for( i=0 ; i<Width(info) ; i++ )
+             XPutPixel( info->rowImage, i, 0, (unsigned long) data[i] ) ;
+
+        XPutImage(theDisplay, info->w, info->foregroundGC, info->rowImage, 0, 0, 0, col-1, Width(info), 1 );
+     }
+     else {
+   	 for( i=0 ; i<Height(info) ; i++) 
+            XPutPixel( info->colImage, 0, i, (unsigned long) data[i] ) ;
+
+         XPutImage(theDisplay, info->w, info->foregroundGC, info->colImage, 0, 0, col-1, 0, 1, Height(info) );
+     }
+#else
+    if( row_flag )
+	XPixmapBitsPutZ( info->w, 0, col, length, 1, data, (Bitmap) 0, GXcopy, AllPlanes ) ;
+    else
+	XPixmapBitsPutZ( info->w, col, 0, 1, length, data, (Bitmap) 0, GXcopy, AllPlanes ) ;
+    XFlush() ;
+#endif
+        return ;
+}
+
+static void DitherColumn( info, col, input, black, white, match, length, row_flag )
+XWindowObject info ;
+int col ;
+short *input ;
+int black, white ;
+int *match, length ;
+int row_flag ;
+{
+    register int *mptr = match ;
+    register int *mend = match + length ;
+    register int x, bit, *dptr ;
+#if defined(X11)
+    XPoint pts[2000] ;
+    int count = 0 ;
+#endif
+
+    if( info->data == ( short * ) 0 || length != info->greylength ) {
+
+	if( info->data != ( short * ) 0 ) {
+	    free( ( char * ) info->data ) ;
+	    FreeDithers( info->diths, DITHER_SIZE ) ;
+	}
+
+	info->data  = (short *) malloc( (unsigned) length * sizeof( *info->data ) ) ;
+	info->diths = Dithers( DITHER_SIZE, length, black, white ) ;
+
+	info->greylength = length ;
+    }
+
+    dptr = info->diths[ col%DITHER_SIZE ] ;
+
+#if defined(X11)
+    if( row_flag ) {
+	while( mptr < mend )
+	    if( input[ *mptr++ ] > *dptr++ ) {
+		pts[count].x = mptr - match ;
+		pts[count].y = col-1 ;
+		count++ ;
+	    }
+    }
+    else {
+	while( mptr < mend )
+	    if( input[ *mptr++ ] > *dptr++ ) {
+		pts[count].x = col-1 ;
+		pts[count].y = mptr - match ;
+		count++ ;
+	    }
+    }
+
+    XDrawPoints(theDisplay, info->w, info->foregroundGC, pts, count, CoordModeOrigin ) ;
+#else
+    if( row_flag ) {
+	while( mptr < mend ) {
+
+	    x = mptr - match ;
+
+	    if( x%16 == 0 )
+		info->data[x/16] = 0 ;
+
+	    if( input[ *mptr++ ] <= *dptr++ )
+		info->data[x/16] |= 1<<x%16 ;
+	}
+
+	XPixmapBitsPutXY( info->w, 0, col, length, 1, info->data, (Bitmap) 0, GXcopy, AllPlanes ) ;
+    }
+    else {
+	while( mptr < mend )
+	    info->data[mptr-match] = input[ *mptr++ ] <= *dptr++ ;
+
+	XPixmapBitsPutXY( info->w, col, 0, 1, length, info->data, (Bitmap) 0, GXcopy, AllPlanes ) ;
+    }
+#endif
+
+    return ;
+}
+
+
+static void window__fill( info, col, input, black, white, match, length, row_flag )
+XWindowObject info ;
+int col;
+short *input;
+int black, white ;
+int *match, length ;
+int row_flag ;
+{
+    int chans, chan, y, blacky;
+
+#if defined(X11)
+    waitTillMapped(info) ;
+#endif
+
+    if (info->pixels == 0 || 1 )
+
+#if !defined(X11)
+     if (DisplayPlanes() > 1)
+#else
+     if( DisplayPlanes( theDisplay, theScreen ) > 1 && 
+	     DisplayPlanes( theDisplay, theScreen ) != 4 )
+#endif
+	ColorColumn(  info, col, input, black, white, match, length, row_flag );
+      else
+	DitherColumn( info, col, input, black, white, match, length, row_flag );
+
+    else { /* old line drawing simulation code to be removed */
+      chans = match[length - 1] + 1;
+
+      blacky = length;
+
+      for (chan = 0; chan < chans; chan++) {
+	y = length - length * chan / chans;
+	y -= (input[chan] - black) * length / (white - black) / chans;
+
+	if( y < blacky || !info->hide ) {
+#if defined(X11)
+	  XDrawPoint(theDisplay, info->w, info->foregroundGC, col, y);
+#else
+	  XPixSet(info->w, col, y, info->pixels, info->pixels, info->foreground ) ;
+#endif
+	  blacky = y;
+	}
+      }
+    }
+
+    return;
+}
+
+static void window__fillCol( info, col, input, black, white, match, length)
+XWindowObject info ;
+int col;
+short *input ;
+int black, white ;
+int *match, length ;
+{
+    window__fill( info, col, input, black, white, match, length, 0 ) ;
+
+    return ;
+}
+
+static void window__fillRow( info, col, input, black, white, match, length)
+XWindowObject info ;
+int col;
+short *input;
+int black, white ;
+int *match, length ;
+{
+    window__fill( info, col, input, black, white, match, length, 1 ) ;
+
+    return ;
+}
+
+static void window__function( info, ys, segment, skip, offset, yspan, start, points )
+XWindowObject info ;
+short *ys ;
+int segment, skip ;
+double offset, yspan ;
+int start, points ;
+{
+#if defined(X11)
+    XPoint vs[ MAX_SEGMENT+4 ], *vptr ;
+#else
+    Vertex vs[ MAX_SEGMENT+4 ], *vptr ;
+#endif
+    register long x, dx, yscale ;
+    register int yoffset, point, count ;
+    register short *yptr ;
+    static long shift = 16 ;
+    static long round = 1l << 15 ;
+
+#if defined(X11)
+    if (synchronous) {
+      (void) XSynchronize(theDisplay, FALSE);
+      XFlush(theDisplay);
+      synchronous = FALSE;
+    }
+
+    waitTillMapped(info) ;
+#endif
+
+    points = abs(points);
+
+    if( points <= 1 )
+	return ;
+
+    yoffset = info->entries->height( info ) - offset ;
+
+    dx = (  double ) ( ( info->entries->width(  info ) - 1 ) << shift ) / ( points - 1 ) + 0.5 ;
+    x  = dx * start + ( 1 << shift ) + round ;
+
+    yscale =         ( ( info->entries->height( info )     ) << shift ) / yspan  + 0.5 ;
+
+    yptr = ys ;
+
+    for( point=0 ; point < segment-1 ; point += count-1 ) {
+
+	vptr = vs ;
+
+	for( count=0 ; count < MAX_SEGMENT && point + count < segment ; count++ ) {
+
+	    vptr->x = x >> shift ;
+	    vptr->y = yoffset - ( *yptr * yscale + round >> shift ) ;
+#if defined(X10)
+	    vptr->flags = 0;
+#endif
+	    vptr++ ;
+
+	    if( count+1 < MAX_SEGMENT && point + count+1 < segment ) {
+		x    += dx   ;
+		yptr += skip ;
+	    }
+	}
+
+	if( info->hide ) {
+
+	    vptr->x = vptr[-1].x ;
+	    vptr->y = 1 + yoffset ;
+#if defined(X10)
+	    vptr->flags = 0 ;
+#endif
+	    vptr++ ;
+
+	    vptr->x = vs[0].x ;
+	    vptr->y = vptr[-1].y ;
+#if defined(X10)
+	    vptr->flags = 0 ;
+#endif
+	    vptr++ ;
+
+	    vptr->x = vs[0].x ;
+	    vptr->y = vs[0].y ;
+#if defined(X10)
+	    vptr->flags = 0 ;
+#endif
+	    vptr++ ;
+
+#if defined(X11)
+	    XFillPolygon(   theDisplay, info->w, info->backgroundGC, vs, vptr-vs, Complex, CoordModeOrigin);
+	}
+
+	XDrawLines(theDisplay, info->w, info->foregroundGC, vs, count, CoordModeOrigin);
+	XFlush(theDisplay);
+#else
+	    XDrawFilled( info->w, vs, vptr-vs, info->background, GXcopy, AllPlanes ) ;
+	}
+
+	XDraw( info->w, vs, count, info->pixels, info->pixels, info->foreground, GXcopy, AllPlanes ) ;
+#endif
+    }
+
+    return ;
+}
+
+typedef struct {
+    FILE *imageFilePtr                ;     /* The File Pointer       */
+    int   imageFilePreviousFrame      ;     /* The last image read    */
+} ReadingData;
+
+static ReadingData readingFiles[MAX_FILES], *current;
+static int         numReadingFiles = 0              ;
+static int         window__writing = 1              ;
+
+/* --------------------------------------------------------------------
+
+   Search in the readingFiles[] array for the given filePtr. If found,
+   return its index; otherwise return FAILURE (-1).
+
+   -------------------------------------------------------------------- */
+
+static int findReadingFile( filePtr )
+FILE *filePtr;
+{
+	int i;
+
+    for (i = 0; i < numReadingFiles; i++)
+    	if (readingFiles[i].imageFilePtr == filePtr)
+    		return (i);
+
+	return (-1);
+
+}
+
+static int window__read(w, filePtr, which)
+XWindowObject w    ;
+FILE        *filePtr;
+int          which  ;
+{
+  int    readingFileIndex ;
+  long   filePosBeforeSeek;
+
+#if defined(X11)
+  if (!synchronous) {
+    (void) XSynchronize(theDisplay, TRUE);
+    XFlush(theDisplay);
+    synchronous = TRUE;
+  }
+
+    waitTillMapped(w) ;
+
+    setupImage( w ) ;
+#else
+    if( w->theImage == (short *) 0 ) {
+	if((w->theImage = (short *) malloc(w->imageSize)) == NULL) {
+	    (void) fprintf(stderr, "windows: Insufficient memory to malloc %i bytes for a Pixmap.\n",
+		     w->imageSize);
+	    exit(1);
+	}
+    }
+#endif
+
+  if (numReadingFiles == 0 || current->imageFilePtr != filePtr) {
+    if (numReadingFiles > 0 &&
+       (readingFileIndex = findReadingFile(filePtr)) >= 0)
+    	current  = &readingFiles[readingFileIndex];
+    else {
+    	/* The First Read Operation (on this file) */
+        if (numReadingFiles >= MAX_FILES) {
+        	fprintf(stderr,
+			"windows: Sorry, you can only have %i files open for reading at once.\n",
+			MAX_FILES);
+        	fprintf(stderr, "         Hit <return> to exit.\n");
+        	getchar();
+        	exit(1);
+        }
+        current = &readingFiles[numReadingFiles] ;
+       	current->imageFilePtr           = filePtr;
+       	current->imageFilePreviousFrame = 0      ;
+     	numReadingFiles++;
+    }
+  }
+
+  filePosBeforeSeek = ftell(current->imageFilePtr);
+
+  /* Now Read and Display it */
+
+  if (fseek(current->imageFilePtr,
+          ((long) which - current->imageFilePreviousFrame - (long) 1) * w->imageSize, 1))
+            return (FALSE);
+
+#if defined(X11)
+  if (fread(w->theImage->data, 1, w->imageSize, current->imageFilePtr) != w->imageSize) {
+#else
+  if (fread(w->theImage, 1, w->imageSize, current->imageFilePtr) != w->imageSize) {
+#endif
+        /* Reposition the filePointer to enable future Reads */
+        if (fseek(current->imageFilePtr, filePosBeforeSeek, 0)) {
+        	(void) fprintf(stderr,
+			       "windows: Unable to reposition the file after a failed Read.\n");
+        	exit(1);
+        }
+    	return (FALSE);
+      }
+
+#if defined(X11)
+  XPutImage(theDisplay, w->w, w->foregroundGC, w->theImage, 0, 0, 0, 0, w->entries->width(w),
+	    w->entries->height(w));
+#else
+  XPixmapBitsPutXY(w->w, 0, 0, w->entries->width(w), w->entries->height(w),
+		   w->theImage, (Bitmap) 0, GXcopy, AllPlanes);
+#endif
+
+  current->imageFilePreviousFrame = which;
+
+  return (TRUE);
+}
+
+
+static void window__write(w, filePtr)
+XWindowObject w;
+FILE        *filePtr;
+{
+#if defined(X11)
+    int    imageSize;
+    XImage *theImage;
+
+    theImage = XGetImage(theDisplay, w->w, 0, 0, w->entries->width(w), w->entries->height(w),
+			 planemask, XYPixmap);
+
+    imageSize = ImageSizeInBytes(theImage);
+
+    if (fwrite(theImage->data, 1, imageSize, filePtr) != imageSize) {
+    	fprintf(stderr,
+		"window: WARNING! Failed to write %i bytes to Image File as image number %i.\n",
+     	        imageSize, window__writing);
+    	fprintf(stderr, "        Hit <return> to continue.\n");
+    	getchar();
+    }
+
+    window__writing++;
+
+    (void) XDestroyImage(theImage);
+#else
+    if( w->theImage == ( short * ) 0 ) {
+	if((w->theImage = (short *) malloc(w->imageSize)) == NULL) {
+	    (void) fprintf(stderr, "windows: Insufficient memory to malloc %i bytes for a Pixmap.\n",
+		     w->imageSize);
+	    exit(1);
+	}
+    }
+
+    XPixmapGetXY(w->w, 0, 0, w->entries->width(w), w->entries->height(w), w->theImage) ;
+
+    (void) fwrite((char *) w->theImage, 1, (int) w->imageSize/DisplayPlanes(), filePtr) ;
+#endif
+
+    return;
+}
+
+
+static char window__pause(info)
+XWindowObject info ;
+{
+  char line[256];
+
+#if defined(X11)
+    XFlush(theDisplay);
+#else
+    XFlush();
+#endif
+
+  (void) gets(line);
+
+  if (line[0] == '\000' || line[0] == '\r' || line[0] == '\n')
+    return (' ');
+  else
+    return (line[0]);
+}
+
+static void window__axes(info, title, xmin, xmax, xtitle, ymin, ymax, ytitle)
+XWindowObject info;
+     char *title, *xtitle, *ytitle;
+     char *xmin, *xmax, *ymin, *ymax;
+{
+  return;
+}
+
+static void window__marker( info, label, p, points )
+XWindowObject info ;
+char *label ;
+int p, points ;
+{
+    short pos = ( info->entries->width( info ) * p + points / 2 ) / points ;
+
+#if defined( X11 )
+    XDrawLine(theDisplay, info->w, info->foregroundGC, pos, 1, pos, info->entries->height(info));
+#else
+    XLine( info->w, pos, 1, pos, info->entries->height( info ), info->pixels, info->pixels, info->foreground, GXcopy, AllPlanes ) ;
+
+    if( marker_font == ( FontInfo * ) 0 )
+	marker_font = XOpenFont( marker_font_name ) ;
+
+    if( marker_font == ( FontInfo * ) 0 )
+	(void) fprintf( stderr, "Unable to use font %s for marker %s\n", marker_font_name, label ) ;
+    else
+	XTextMaskPad( info->w, pos - 1 - XQueryWidth( label, marker_font->id ), 1,
+	      label, strlen( label ), marker_font->id, 0, 0, info->foreground, GXxor, AllPlanes ) ;
+#endif
+
+    return ;
+}
+
+static int window__special( info, code, data )
+XWindowObject info ;
+int code ;
+char *data ;
+{
+    return 0 ;
+}
+
+
+WindowObject newWindowWindow( window, default_x, default_y, default_width, default_height, pixels )
+Window window ;
+int default_x, default_y, default_width, default_height ;
+int pixels ;
+{
+    static windowEntries entries = { window__x, window__y, window__width, window__height,
+				     window__draw, window__clear, window__close, window__store,
+				     window__recall, window__fillRow, window__fillCol,
+				     window__function, window__read, window__write,
+				     window__pause, window__axes, window__marker, window__special } ;
+    XWindowObject info ;
+#if defined( X11 )
+    XGCValues GCTemplate;
+#endif
+
+    if ((info = (XWindowObject ) malloc( sizeof(*info) )) == (XWindowObject )0) {
+      (void) fprintf(stderr, "windows: Insufficient memory to allocate WindowObject.\n");
+      exit(1);
+    }
+
+    info->entries = &entries ;
+    info->w       = window   ;
+
+    if( pixels < 0 )
+	info->pixels = -pixels ;
+    else
+	info->pixels = pixels ;
+
+    info->hide    = pixels < 0 ;
+
+#if defined(X11)
+    info->isMapped = 1 ;
+
+    /* Initialise a Graphics Context for lines and points */
+
+    GCTemplate.function   = GXcopy ;
+
+    GCTemplate.foreground = theForeground ;
+    GCTemplate.background = theBackground ;
+
+    GCTemplate.line_width = info->pixels ;
+
+    if( GCTemplate.line_width == 1 )
+	GCTemplate.line_width =  0 ; /* use "thin" lines */
+
+    info->foregroundGC = XCreateGC( theDisplay, info->w,
+	 GCFunction|GCForeground|GCBackground|GCLineWidth, &GCTemplate ) ;
+
+    /* A second GC for clearing and hiding lines */
+
+    GCTemplate.foreground = theBackground ;
+    GCTemplate.background = theForeground ;
+
+    info->backgroundGC = XCreateGC( theDisplay, info->w,
+	 GCFunction|GCForeground|GCBackground|GCLineWidth, &GCTemplate ) ;
+
+#else
+    info->foreground = WhitePixel ;
+    info->background = BlackPixel ;
+    info->lookup = 0;
+#endif
+
+    info->data = (short *) 0 ;
+    info->greylength = 0 ;
+
+    /* update width and height fields */
+
+    info->x      = default_x     ;
+    info->y      = default_y     ;
+    info->width  = default_width ;
+    info->height = default_height;
+
+    checkGeometry( info ) ;
+
+    /* Initialise the Image Data Structure for later read operations */
+
+#if defined(X11)
+    info->theImage = info->rowImage = info->colImage = (XImage *) 0 ;
+#else
+    info->imageSize = XYPixmapSize(info->entries->width(info), info->entries->height(info), DisplayPlanes());
+    info->theImage = ( short * ) 0 ;
+#endif
+
+    info->imageNum = 0 ;
+
+    /* MAA: 3-8-1993 
+     * The planemask bits might as well go here as anywhere else 
+     */
+
+    if ( isON(colourstr) ) 
+      planemask = AllPlanes;
+    else
+      planemask = atoi(planemaskstr);
+
+    return ( (WindowObject) info ) ;
+}
+
+    /* Since the <name> argument is always passed to newDisplayWindow as NULL, and
+       the ASP modules don't have any concept of a configurable <display> option (the
+       display is either ON or OFF), the <name> argument is redundant. The <name> argument
+       still has a sensible use as the name of the Window which is being created, and
+       its use has been modified as such in genbmm, revbmm, gensai and revsai... */
+
+
+WindowObject newXWindow( name, default_x, default_y, default_width, default_height, pixels )
+char *name ;
+int default_x, default_y, default_width, default_height ;
+int pixels ;
+{
+    Window w ;
+    XWindowObject info;
+
+#if defined(X11)
+
+    if (theDisplay == (Display *) 0) {
+      if ((theDisplay = XOpenDisplay(NULL)) == (Display *) 0) {  /* Was name */
+	(void) fprintf(stderr, "X11: Unable to do XOpenDisplay of display %s.\n",
+		       getenv("DISPLAY"));
+	exit(1);
+      }
+
+      theScreen  = XDefaultScreen( theDisplay ) ;
+      
+      /* MAA: 20-8-1993 
+       * lets put the colour bits here */
+      
+      define_colours();
+
+#ifndef SLAVE
+      if (!synchronous) {
+        (void) XSynchronize(theDisplay, TRUE);
+        XFlush(theDisplay);
+        synchronous = TRUE;
+      }
+#endif
+    }
+
+    /* Need to reset these every time, in case the screen is initialized
+       independently via InitializeX */
+
+    theWidth  = XDisplayWidth (theDisplay, theScreen);
+    theHeight = XDisplayHeight(theDisplay, theScreen);
+
+    /* Perform "centering" calculations */
+
+    if (default_x < 0) {
+      /* Center in the x dimension */
+      default_width = (MIN(default_width, theWidth));
+      default_x     = (theWidth - default_width) / 2;
+    }
+
+    if (default_y < 0) {
+      /* Center in the y dimension */
+      default_height = (MIN(default_height, theHeight));
+      default_y      = (theHeight - default_height) / 2;
+    }
+
+    /* End of "centering" calculations */
+#else
+    if( theDisplay == (Display *) 0 )
+	if( ( theDisplay = XOpenDisplay(NULL) ) == (Display *) 0  ) {
+	  (void) fprintf(stderr, "Could not open DISPLAY \"%s\"\n", getenv("DISPLAY"));
+	  exit(1);
+	}
+
+#endif
+
+
+
+#if defined(X11)
+    if( default_width == 0 && default_height == 0 )
+	w = XDefaultRootWindow(theDisplay);
+    else
+	if ((w = XCreateSimpleWindow(theDisplay, XDefaultRootWindow(theDisplay),
+				 default_x, default_y,
+				 (unsigned) default_width, (unsigned) default_height, 1,
+				 theForeground, theBackground)) != (Window) 0) {
+/*
+         XSizeHints hints ;
+
+	hints.flags = PPosition | PSize ;
+
+	hints.x = default_x ;
+	hints.y = default_y ;
+	hints.width  = default_width ;
+	hints.height = default_height ;	
+	XSetStrandardProperties( theDisplay, w, name, name, None, name, 1, &hints ) ;
+*/
+	XStoreName(theDisplay, w, name);
+	XMapRaised(theDisplay, w);
+	XFlush(    theDisplay);
+	}
+#else
+    if( default_width == 0 && default_height == 0 )
+	w = RootWindow ;
+    else
+	if( ( w = XCreateWindow( RootWindow, abs( default_x ), abs( default_y ),
+				      default_width, default_height, 0, WhitePixmap,
+				      BlackPixmap ) ) != ( Window ) 0 ) {
+	    XStoreName( w, name ) ;
+	    XMapWindow( w ) ;
+	    XFlush() ;
+	}
+#endif
+	else {
+		(void) fprintf( stderr,
+			  "Could not create window of size %dx%d at position %d,%d\n",
+			   default_width, default_height, default_x, default_y ) ;
+	}
+
+    info = (XWindowObject) newWindowWindow(w, default_x, default_y, default_width, default_height, pixels);
+#if defined(X11)
+    info->isMapped = 0 ;
+#endif
+    info->entries->clear(info);
+
+    return((WindowObject)info);
+
+}
+
+#ifndef SLAVE
+WindowObject newDisplayWindow( name, default_x, default_y, default_width, default_height, pixels )
+char *name ;
+int default_x, default_y, default_width, default_height ;
+int pixels ;
+{
+    return ( newXWindow( name, default_x, default_y, default_width, default_height, pixels ) ) ;
+}
+#endif