Mercurial > hg > aim92
view 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 source
/* 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