comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:5242703e91d3
1
2 /*
3 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
4 ===========================================================================
5
6 Permission to use, copy, modify, and distribute this software without fee
7 is hereby granted for research purposes, provided that this copyright
8 notice appears in all copies and in all supporting documentation, and that
9 the software is not redistributed for any fee (except for a nominal shipping
10 charge). Anyone wanting to incorporate all or part of this software in a
11 commercial product must obtain a license from the Medical Research Council.
12
13 The MRC makes no representations about the suitability of this
14 software for any purpose. It is provided "as is" without express or implied
15 warranty.
16 */
17
18 /*******************************************************************************************
19
20 X.c A GENERIC X-WINDOWS REAR-END FOR THE WINDOWS.H INTERFACE.
21
22
23 This module is derived from the x10.c module, written by John Holdsworth, and the subsequent
24 x11.c module, which was ported by Paul Manson. It attempts to combine the x10/x11 code in
25 such a way as to provide a single uniform application with the minimal amount of #ifdef
26 "noise". It expects to have either X10 or X11 defined as symbols by the preprocessor -- in the
27 event that neither of these is defined, it produces an error message and causes the compiler
28 to exit; ie. there is NO DEFAULT.
29
30 Written: May 3rd. by Paul Manson (but see credits above)
31
32 Edited:
33
34 15 May 1989 (Paul Manson) -- Altered the <pixels> argument to use <pixels>-1 in the
35 newDisplay window call. On X11, pixels of 0 means "use
36 thin lines", which always work correctly. Values greater
37 than 0 imply "thick lines", which appear to over-write
38 each other.
39
40 05 June 1989 (Paul Manson) -- Removed the offending "warning" message from axes();.
41
42 27 July 1989 (Johh Holdsworth) -- put in addition loops to segment line drawing
43 operations for very long lines and put XFlush() in
44 before pausing. A bug remains in the segentation of
45 hidden line removal. The Fill operation Paint to hide
46 lines lower than that just drawn can remove part of
47 that line - very tricky to avoid. The same problem
48 seem to be present in ps.c.
49
50 18 August 1989 (Paul Manson) -- Altered to accomodate the Pixmap/newWindowWindow entry
51 which forces un-resizable windows on us with X11.
52
53 21 August 1989 (Paul Manson) -- Also altered "Clear" so that it does a FillRectangle in
54 preference to a ClearWindow. The latter call doesn't work
55 for Pixmaps (see newWindowWindow, etc).
56
57 22 August 1989 (Paul Manson) -- In a similar vein to the above, I have altered X.c so that
58 two global variables Foreground and Background are used to
59 determine the colours for drawing and filling.
60
61 04 September 1989 (Paul Manson) - Altered so that the GXmodes are used to modify the GC for
62 clear, draw, etc operations. This seems to be a much more
63 reliable way in which to manipulate these settings.
64
65 31 July 1990 (John Holdsworth) - Extensive changes to remove previous change. GXcopy
66 now used with foreground appropiately set. This has
67 proved more portable particularly for Multiplane displays.
68
69
70 26th May 1993 (Mitch d'Souza & M Akeroyd) - added an extra include - sys/types.h - so that the
71 gcc would work on a decstation.
72
73 3rd August 1993 (M. Akeroyd) - Removed the 'XAllPlanes' bist of the XGetImage routines,
74 so that monochrome bitmaps could be made on colour
75 computers.
76 Also included new SilentOptions :
77 mono_ctn
78 colour_ctn
79 planemask_ctn
80
81 20th August 1993 (M.Akeroyd) - First attempt at colour images: two new options fg_col and
82 bg_col, and a complementary procedure define_colour().
83 These do NOT work with view=grayscale.
84
85 ********************************************************************************************/
86
87
88 #if !defined(X11) && !defined(X10)
89 #define X11
90 #endif
91
92 #if !defined(X10) && !defined(X11)
93 #include "-- YOU MUST DEFINE EITHER X10 or X11 TO USE THIS MODULE"
94 #endif
95
96 #include <stdio.h>
97 #include <malloc.h>
98 #include <sys/types.h>
99 #include "options.h" /* Added: MAA 3-8-1993 */
100 #if defined(X11)
101 #include <X11/X.h>
102 #include <X11/Xlib.h>
103 #include <X11/Xutil.h> /* MAA: 20-8-1993. For colour */
104 #include <X11/Xos.h> /* MAA: 20-8-1993. For colour */
105
106
107 #else
108 #if defined(X10)
109 #include <X/Xlib.h>
110 #endif
111 #endif
112
113 #include "windows.h"
114 #include "grey.h"
115
116 #define FALSE (0)
117 #define TRUE (1)
118 #define MAX_FILES (20)
119 #define MAX_SEGMENT (5000)
120 #define MAX_ROW (100)
121 #define MAX_COL (1000)
122 #define MAX_IMAGE (1500)
123 #define DITHER_SIZE (8)
124
125 extern char *monostr, *colourstr, *planemaskstr; /* Added: MAA 3-8-1993 */
126 int planemask;
127
128 static Display *theDisplay = (Display *) 0; /* The Display Variable */
129 static int theWidth, theHeight; /* The Width and Height of the Screen in Pixels */
130
131 #define MIN(X,Y) (((X) < (Y)) ? (X) : (Y))
132
133 #define USE_PIXMAPS
134
135 #if defined(X11)
136 static int theScreen ; /* The associated screen no. */
137 static int synchronous = FALSE ;
138 static unsigned long theForeground, theBackground;
139 #else
140 static char *marker_font_name = "6x10" ;
141 static FontInfo *marker_font = ( FontInfo * ) 0 ;
142 #endif
143
144 typedef struct {
145 windowEntries *entries ;
146 Window w ;
147 int pixels, width, height, hide ;
148 int x, y ;
149 #if defined(X11)
150 GC foregroundGC ;
151 GC backgroundGC ;
152 int isMapped ;
153 #ifdef USE_PIXMAPS
154 Pixmap imageData[ MAX_IMAGE ];
155 #else
156 XImage *imageData[ MAX_IMAGE ];
157 #endif
158 XImage *theImage; /* Used only for Read operations; The wind__write */
159 /* entry point actually creates & destroys images */
160 XImage *rowImage, *colImage ;
161 #else
162 int foreground, background ;
163 short *imageData[ MAX_IMAGE ];
164 short *theImage ;
165 #endif
166 struct _lookup *lookup ; /* Dithering */
167 int **diths ; /* Dithering */
168 short *data ; /* Dithering */
169 int greylength ;
170 int imageNum ;
171 int imageSize;
172 } *XWindowObject ;
173
174 #ifndef lint
175 static char *sccs_id = "@(#)X.c 1.38 Paul Manson, John Holdsworth (MRC-APU) 5/31/91" ;
176 #endif
177
178 #if defined(X11)
179
180
181
182
183 /* MAA: Added 20-8-1993
184 * Colour ....
185 * Copied off example 7.2 of Xlib Vol 1.
186 */
187
188 extern char *fgcolourstr;
189 extern char *bgcolourstr;
190
191 void define_colours()
192 {
193 int default_depth;
194 Visual *default_visual;
195 XColor exact_def;
196 Colormap default_cmap;
197 int i=5;
198 XVisualInfo visual_info;
199
200
201 default_depth = DefaultDepth(theDisplay, theScreen);
202 default_visual = DefaultVisual(theDisplay, theScreen);
203 default_cmap = DefaultColormap(theDisplay, theScreen);
204
205 /* MAA: Removed this. */
206 /* if (default_depth == 1) {*/
207 /* Black-White Only */
208 /* theForeground = BlackPixel(theDisplay, theScreen);*/
209 /* theBackground = WhitePixel(theDisplay, theScreen);}*/
210
211 /* i = visual class */
212 while (!XMatchVisualInfo(theDisplay, theScreen, default_depth, i--, &visual_info))
213 ;
214
215 if (i<StaticColor) {
216 theForeground = BlackPixel(theDisplay, theScreen);
217 theBackground = WhitePixel(theDisplay, theScreen);}
218
219 else {
220
221 /* Foreground */
222 if (!XParseColor(theDisplay, default_cmap, fgcolourstr, &exact_def)){
223 fprintf(stderr, "Unable to find colour %s in database. Using Black instead. \n", fgcolourstr);
224 theForeground = BlackPixel(theDisplay, theScreen);}
225 else
226 if (XAllocColor(theDisplay, default_cmap, &exact_def))
227 theForeground = exact_def.pixel;
228 else {
229 fprintf(stderr, "Unable to alloc colour %s. Using Black instead. \n", fgcolourstr);
230 theForeground = BlackPixel(theDisplay, theScreen);}
231
232 /* Background */
233 if (!XParseColor(theDisplay, default_cmap, bgcolourstr, &exact_def)){
234 fprintf(stderr, "Unable to find colour %s in database. Using White instead. \n", bgcolourstr);
235 theBackground = WhitePixel(theDisplay, theScreen);}
236 else
237 if (XAllocColor(theDisplay, default_cmap, &exact_def))
238 theBackground = exact_def.pixel;
239 else {
240 fprintf(stderr, "Unable to alloc colour %s. Using White instead. \n", bgcolourstr);
241 theBackground = WhitePixel(theDisplay, theScreen);}
242 }
243 }
244
245
246
247
248 extern void InitializeX(display, screen, foreground, background)
249 Display *display ;
250 int screen ;
251 unsigned long foreground;
252 unsigned long background;
253 {
254 if (theDisplay == (Display *) 0) {
255 theDisplay = display ;
256 theScreen = screen ;
257 theForeground = foreground;
258 theBackground = background;
259 }
260 else {
261 (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");
262 exit(1);
263 }
264 }
265
266 /* not a nice routine to wait untill window is actually mapped before returning it's size */
267
268 static void waitTillMapped( info )
269 XWindowObject info ;
270 {
271 XWindowAttributes at ;
272
273 if( !info->isMapped ) {
274 do
275 XGetWindowAttributes( theDisplay, info->w, &at ) ;
276 while ( at.map_state == IsUnmapped ) ;
277
278 info->isMapped = 1 ;
279
280 info->width = at.width ;
281 info->height = at.height ;
282 }
283
284 return ;
285 }
286
287 /* ---------------- Beware! This function may be the most dangerous thing ---------------
288 ---------------- to ever appear on a DecStation... it makes ---------------
289 ---------------- sweeping assumptions about the way that data ---------------
290 ---------------- is stored in the X server. If it EVER happens ---------------
291 ---------------- that the X Consortium write routines for I/O ---------------
292 ---------------- of Screen Images, THROW THIS AWAY! --------------- */
293 static int ImageSizeInBytes(image)
294 XImage *image;
295 {
296
297 /* Cribbed from X11R3/.../xwd.c */
298
299 return(image->bytes_per_line * image->height * image->depth);
300
301 }
302
303
304 static setupImage( w )
305 XWindowObject w ;
306 {
307 if( w->theImage == ( XImage * ) 0 ) {
308 w->theImage = XGetImage(theDisplay, w->w, 0, 0, w->entries->width(w),
309 w->entries->height(w), planemask, XYPixmap);
310 w->imageSize = ImageSizeInBytes(w->theImage);
311 }
312 }
313
314
315
316 #endif
317
318 static short window__x( info )
319 XWindowObject info ;
320 {
321 #if defined(OldX11)
322 XWindowAttributes winfo;
323
324 (void) XGetWindowAttributes( theDisplay, info->w, &winfo );
325
326 return ((short) winfo.x);
327 #else
328 #if defined(X11)
329 return ((short) info->x);
330 #else
331 WindowInfo winfo;
332
333 XQueryWindow(info->w, &winfo);
334
335 return (winfo.x);
336 #endif
337 #endif
338 }
339
340 static short window__y( info )
341 XWindowObject info ;
342 {
343 #if defined(OldX11)
344 XWindowAttributes winfo;
345
346 (void) XGetWindowAttributes( theDisplay, info->w, &winfo );
347
348 return ((short) winfo.y);
349 #else
350 #if defined(X11)
351 return ((short) info->y);
352 #else
353 WindowInfo winfo;
354
355 XQueryWindow(info->w, &winfo);
356
357 return (winfo.y);
358 #endif
359 #endif
360 }
361
362 static short window__width( info )
363 XWindowObject info ;
364 {
365 #if defined(X11)
366 waitTillMapped(info) ;
367 #endif
368
369 return( info->width ) ;
370 }
371
372 static short window__height( info )
373 XWindowObject info ;
374 {
375 #if defined(X11)
376 waitTillMapped(info) ;
377 #endif
378
379 return( info->height ) ;
380 }
381
382 static void window__draw( info, xs, ys, pointsFlag )
383 XWindowObject info ;
384 short xs[], ys[] ;
385 int pointsFlag ;
386 {
387 #if defined(X11)
388 XPoint vs[MAX_SEGMENT], *vptr;
389 #else
390 Vertex vs[MAX_SEGMENT], *vptr;
391 #endif
392 register int point, count ;
393 register int points = abs( pointsFlag ) ;
394 register short h ;
395
396 #if defined(X11)
397 if (synchronous) {
398 (void) XSynchronize(theDisplay, FALSE);
399 XFlush(theDisplay);
400 synchronous = FALSE;
401 }
402
403 waitTillMapped(info) ;
404 #else
405 int i ;
406 #endif
407
408 h = info->entries->height( info );
409
410 for( point = 0 ; point < points - 1 ; point += count - 1 ) {
411
412 vptr = vs ;
413
414 for( count=0 ; count < MAX_SEGMENT && point + count < points ; count++ ) {
415
416 vptr->x = xs[ point+count ] ;
417 vptr->y = h - ys[ point+count ] ;
418 #if defined(X10)
419 vptr->flags = pointsFlag > 0 ? 0 : 0 ;
420 #endif
421 vptr++;
422 }
423
424 if( info->hide && pointsFlag > 0 && vs[0].x == vptr[-1].x &&
425 vs[0].y == vptr[-1].y )
426 #if defined(X11)
427 XFillPolygon( theDisplay, info->w, info->backgroundGC, vs, vptr-vs, Complex, CoordModeOrigin);
428
429 if( pointsFlag > 0 )
430 XDrawLines( theDisplay, info->w, info->foregroundGC, vs, vptr-vs, CoordModeOrigin);
431 else
432 XDrawPoints(theDisplay, info->w, info->foregroundGC, vs, vptr-vs, CoordModeOrigin);
433
434 XFlush(theDisplay);
435 #else
436 XDrawFilled( info->w, vs, vptr-vs, info->background, GXcopy, AllPlanes ) ;
437
438 if( pointsFlag > 0 )
439 XDraw(info->w, vs, vptr-vs, info->pixels, info->pixels, info->foreground, GXcopy, AllPlanes);
440 else
441 for( i=0 ; i<count ; i++ )
442 XPixSet( info->w, vs[i].x, vs[i].y, info->pixels, info->pixels, info->foreground ) ;
443 #endif
444 }
445
446 return;
447 }
448
449 static void checkGeometry( info )
450 XWindowObject info ;
451 {
452 #if defined(X11)
453 return;
454 #else
455 #if defined(OldX11)
456 XWindowAttributes winfo;
457
458 (void) XGetWindowAttributes( theDisplay, info->w, &winfo );
459 #else
460 WindowInfo winfo;
461
462 XQueryWindow(info->w, &winfo);
463 #endif
464
465 info->width = winfo.width ;
466 info->height = winfo.height ;
467
468 return ;
469 #endif
470 }
471
472 static void window__clear( info )
473 XWindowObject info ;
474 {
475
476 checkGeometry( info ) ;
477
478 #if defined(OldX11)
479 XClearWindow(theDisplay, info->w);
480 XFlush(theDisplay);
481 #else
482 #if defined(X11)
483 XFlush(theDisplay);
484 XFillRectangle( theDisplay, info->w, info->backgroundGC, 0, 0, info->width, info->height ) ;
485 XFlush(theDisplay);
486 #else
487 XClear(info->w);
488 #endif
489 #endif
490
491 return ;
492 }
493
494 static void window__close( info )
495 XWindowObject info ;
496 {
497 if (info != (XWindowObject )0)
498 #if defined(X11)
499 XFreeGC( theDisplay, info->foregroundGC ) ;
500 XFreeGC( theDisplay, info->backgroundGC ) ;
501 XDestroyWindow(theDisplay, info->w);
502 #else
503 XDestroyWindow(info->w);
504 #endif
505 free( (char *) info ) ;
506
507 return ;
508 }
509
510 static int window__store( info )
511 XWindowObject info ;
512 {
513 if (info->imageNum > MAX_IMAGE) {
514 (void) fprintf(stderr,
515 "windows: Sorry, you can currently store only %i images per window.\n",
516 MAX_IMAGE);
517 return(FALSE);
518 }
519 #if defined(X11)
520 if (!synchronous) {
521 (void) XSynchronize(theDisplay, TRUE);
522 XFlush(theDisplay);
523 synchronous = TRUE;
524 }
525
526 waitTillMapped(info) ;
527
528 #ifdef USE_PIXMAPS
529 info->imageData[ info->imageNum ] = XCreatePixmap(theDisplay, info->w, Width( info ), Height( info ), DisplayPlanes( theDisplay, theScreen ) ) ;
530 XCopyArea( theDisplay, info->w, info->imageData[ info->imageNum ], info->foregroundGC, 0, 0, Width( info), Height( info ), 0, 0 ) ;
531 #else
532 info->imageData[ info->imageNum ] = XGetImage(theDisplay, info->w, 0, 0,
533 info->entries->width(info),
534 info->entries->height(info),
535 planemask,
536 XYPixmap);
537 #endif
538 #else
539 if((info->imageData[info->imageNum] = (short *) malloc(info->imageSize)) == (short *) 0) {
540 (void) fprintf(stderr, "Insufficient memory to store %dth image of size %d\n",
541 info->imageNum+1, info->imageSize);
542 return(FALSE);
543 }
544 else
545 XPixmapGetXY( info->w, 0, 0, info->entries->width(info),
546 info->entries->height(info), info->imageData[ info->imageNum ] ) ;
547 #endif
548 info->imageNum++;
549
550 return ( info->imageNum ) ;
551 }
552
553 WindowImage window__current_image( info )
554 XWindowObject info ;
555 {
556 static struct _window_image image_info ;
557 #if defined(X11)
558 #if !defined( USE_PIXMAPS)
559 XImage *image_ptr = info->imageData[ info->imageNum-1 ] ;
560
561 image_info.data = image_ptr->data ;
562 image_info.bytes_per_line = image_ptr->bytes_per_line ;
563 image_info.height = image_ptr->height ;
564
565 image_info.left_bit = 1<<0 ;
566 image_info.right_bit = 1<<7 ;
567 image_info.start_bit = image_info.left_bit<<image_ptr->xoffset ;
568 #endif
569 #else
570 short *image_ptr = info->imageData[ info->imageNum-1 ] ;
571
572 image_info.data = ( char *) image_ptr ;
573 image_info.height = info->height ;
574 image_info.bytes_per_line = ( info->width + 15 ) / 16 * sizeof (*image_ptr) ;
575
576 image_info.left_bit = 1<<0 ;
577 image_info.right_bit = 1<<7 ;
578 image_info.start_bit = image_info.left_bit ;
579
580 #endif
581
582 return ( &image_info ) ;
583 }
584
585 static void window__recall( info, which )
586 XWindowObject info ;
587 int which ;
588 {
589
590 #if defined(X11)
591 if (synchronous) {
592 (void) XSynchronize(theDisplay, FALSE);
593 XFlush(theDisplay);
594 synchronous = FALSE;
595 }
596 #endif
597 if( which > info->imageNum )
598 (void) fprintf( stderr, "Invalid Pixmap number %d(%d)\n", which, info->imageNum ) ;
599 else
600 #if defined(X11)
601 #ifdef USE_PIXMAPS
602 XCopyArea( theDisplay, info->imageData[ which-1 ], info->w, info->foregroundGC,
603 0, 0, Width( info), Height( info ), 0, 0 ) ;
604 #else
605 XPutImage(theDisplay, info->w, info->foregroundGC, info->imageData[which-1], 0, 0, 0, 0,
606 info->entries->width(info), info->entries->height(info));
607 #endif
608 XFlush(theDisplay) ;
609 #else
610 XPixmapBitsPutXY(info->w, 0, 0, info->entries->width(info), info->entries->height(info),
611 info->imageData[ which-1 ], (Bitmap) 0, GXcopy, AllPlanes);
612 #endif
613 return ;
614 }
615
616 #define MAX_COLORS 62
617
618 static char *cmap( npixels )
619 int *npixels ;
620 {
621 int plane_masks[1], pix_num ;
622 char *pixvals ;
623 #if defined(X11)
624 Visual *visual = DefaultVisual( theDisplay, theScreen ) ;
625 Colormap theColormap = DefaultColormap( theDisplay, theScreen ) ;
626 XColor exact_defs[MAX_COLORS] ;
627 unsigned long colors[MAX_COLORS] ;
628
629 switch( visual->class ) {
630 case StaticGray :
631
632 *npixels = 1 << DisplayPlanes( theDisplay, theScreen ) ;
633 pixvals = malloc( (unsigned) *npixels ) ;
634
635 for( pix_num=0 ; pix_num < *npixels ; pix_num++ )
636 pixvals[pix_num] = pix_num ;
637
638 break ;
639
640 case PseudoColor :
641
642 for( *npixels=MAX_COLORS; *npixels > 2 ; (*npixels)-- )
643 if( XAllocColorCells( theDisplay, theColormap, False, plane_masks, 0, colors, *npixels ) )
644 break ;
645
646 pixvals = malloc( (unsigned) *npixels + 2 ) ;
647
648 pixvals[0] = BlackPixel( theDisplay, theScreen ) ;
649
650 for( pix_num=0 ; pix_num < *npixels ; pix_num++ ) {
651 pixvals[pix_num+1] =
652 exact_defs[pix_num].pixel = colors[ pix_num ] ;
653
654 exact_defs[pix_num].red =
655 exact_defs[pix_num].green =
656 exact_defs[pix_num].blue = 65535 * ( pix_num + 1 ) / ( *npixels + 1 ) ;
657
658 exact_defs[pix_num].flags = DoRed | DoGreen | DoBlue ;
659 }
660
661 pixvals[*npixels+1] = WhitePixel( theDisplay, theScreen ) ;
662
663 XStoreColors( theDisplay, theColormap, exact_defs, *npixels ) ;
664
665 XFreeColors( theDisplay, theColormap, colors, *npixels, 0l ) ;
666
667 *npixels += 2 ;
668
669 break ;
670 }
671 #else
672 Color defs[256] ;
673 int pixels[256] ;
674 int planes ;
675
676 *npixels = ( 1 << DisplayPlanes() ) - 2 ;
677
678 while( !XGetColorCells( 0, *npixels, 0, & planes, pixels ) && *npixels > 0 )
679 *npixels-- ;
680
681 pixvals = malloc( (unsigned) *npixels + 2 ) ;
682
683 pixvals[ 0 ] = BlackPixel ;
684
685 for( pix_num=0 ; pix_num < *npixels ; pix_num++ ) {
686
687 pixvals[pix_num+1] =
688
689 defs[pix_num].pixel = pixels[pix_num] ;
690
691 defs[pix_num].red = 0 ;
692 defs[pix_num].green = 65535 * (pix_num+1) / (*npixels+1) ;
693 defs[pix_num].blue = 0 ;
694
695 }
696
697 pixvals[ *npixels+1 ] = WhitePixel ;
698
699 XStoreColors( *npixels, defs ) ;
700
701 XFreeColors( pixels, *npixels, planes ) ;
702
703 XFlush() ;
704
705 *npixels += 2 ;
706 #endif
707 return ( pixvals ) ;
708 }
709
710 static void ColorColumn( info, col, input, black, white, match, length, row_flag )
711 XWindowObject info ;
712 int col ;
713 short *input ;
714 int black, white ;
715 int *match, length ;
716 int row_flag ;
717 {
718 register int i ;
719 char *data ;
720
721 if( info->lookup == 0 || length != info->greylength ) {
722
723 if( info->lookup != 0 )
724 freeLookup( info->lookup ) ;
725
726 info->lookup = makeLookup( cmap, black, white, length ) ;
727
728 #if defined(X11)
729 if( row_flag )
730 info->rowImage = XGetImage( theDisplay, info->w, 0, 0, Width(info), 1, planemask, ZPixmap );
731 else
732 info->colImage = XGetImage( theDisplay, info->w, 0, 0, 1, Height(info), planemask, ZPixmap );
733
734 info->greylength = length ;
735 #endif
736 }
737
738 data = Lookup( col, info->lookup, input, match, length ) ;
739
740 #if defined(X11)
741 if( row_flag ) {
742 for( i=0 ; i<Width(info) ; i++ )
743 XPutPixel( info->rowImage, i, 0, (unsigned long) data[i] ) ;
744
745 XPutImage(theDisplay, info->w, info->foregroundGC, info->rowImage, 0, 0, 0, col-1, Width(info), 1 );
746 }
747 else {
748 for( i=0 ; i<Height(info) ; i++)
749 XPutPixel( info->colImage, 0, i, (unsigned long) data[i] ) ;
750
751 XPutImage(theDisplay, info->w, info->foregroundGC, info->colImage, 0, 0, col-1, 0, 1, Height(info) );
752 }
753 #else
754 if( row_flag )
755 XPixmapBitsPutZ( info->w, 0, col, length, 1, data, (Bitmap) 0, GXcopy, AllPlanes ) ;
756 else
757 XPixmapBitsPutZ( info->w, col, 0, 1, length, data, (Bitmap) 0, GXcopy, AllPlanes ) ;
758 XFlush() ;
759 #endif
760 return ;
761 }
762
763 static void DitherColumn( info, col, input, black, white, match, length, row_flag )
764 XWindowObject info ;
765 int col ;
766 short *input ;
767 int black, white ;
768 int *match, length ;
769 int row_flag ;
770 {
771 register int *mptr = match ;
772 register int *mend = match + length ;
773 register int x, bit, *dptr ;
774 #if defined(X11)
775 XPoint pts[2000] ;
776 int count = 0 ;
777 #endif
778
779 if( info->data == ( short * ) 0 || length != info->greylength ) {
780
781 if( info->data != ( short * ) 0 ) {
782 free( ( char * ) info->data ) ;
783 FreeDithers( info->diths, DITHER_SIZE ) ;
784 }
785
786 info->data = (short *) malloc( (unsigned) length * sizeof( *info->data ) ) ;
787 info->diths = Dithers( DITHER_SIZE, length, black, white ) ;
788
789 info->greylength = length ;
790 }
791
792 dptr = info->diths[ col%DITHER_SIZE ] ;
793
794 #if defined(X11)
795 if( row_flag ) {
796 while( mptr < mend )
797 if( input[ *mptr++ ] > *dptr++ ) {
798 pts[count].x = mptr - match ;
799 pts[count].y = col-1 ;
800 count++ ;
801 }
802 }
803 else {
804 while( mptr < mend )
805 if( input[ *mptr++ ] > *dptr++ ) {
806 pts[count].x = col-1 ;
807 pts[count].y = mptr - match ;
808 count++ ;
809 }
810 }
811
812 XDrawPoints(theDisplay, info->w, info->foregroundGC, pts, count, CoordModeOrigin ) ;
813 #else
814 if( row_flag ) {
815 while( mptr < mend ) {
816
817 x = mptr - match ;
818
819 if( x%16 == 0 )
820 info->data[x/16] = 0 ;
821
822 if( input[ *mptr++ ] <= *dptr++ )
823 info->data[x/16] |= 1<<x%16 ;
824 }
825
826 XPixmapBitsPutXY( info->w, 0, col, length, 1, info->data, (Bitmap) 0, GXcopy, AllPlanes ) ;
827 }
828 else {
829 while( mptr < mend )
830 info->data[mptr-match] = input[ *mptr++ ] <= *dptr++ ;
831
832 XPixmapBitsPutXY( info->w, col, 0, 1, length, info->data, (Bitmap) 0, GXcopy, AllPlanes ) ;
833 }
834 #endif
835
836 return ;
837 }
838
839
840 static void window__fill( info, col, input, black, white, match, length, row_flag )
841 XWindowObject info ;
842 int col;
843 short *input;
844 int black, white ;
845 int *match, length ;
846 int row_flag ;
847 {
848 int chans, chan, y, blacky;
849
850 #if defined(X11)
851 waitTillMapped(info) ;
852 #endif
853
854 if (info->pixels == 0 || 1 )
855
856 #if !defined(X11)
857 if (DisplayPlanes() > 1)
858 #else
859 if( DisplayPlanes( theDisplay, theScreen ) > 1 &&
860 DisplayPlanes( theDisplay, theScreen ) != 4 )
861 #endif
862 ColorColumn( info, col, input, black, white, match, length, row_flag );
863 else
864 DitherColumn( info, col, input, black, white, match, length, row_flag );
865
866 else { /* old line drawing simulation code to be removed */
867 chans = match[length - 1] + 1;
868
869 blacky = length;
870
871 for (chan = 0; chan < chans; chan++) {
872 y = length - length * chan / chans;
873 y -= (input[chan] - black) * length / (white - black) / chans;
874
875 if( y < blacky || !info->hide ) {
876 #if defined(X11)
877 XDrawPoint(theDisplay, info->w, info->foregroundGC, col, y);
878 #else
879 XPixSet(info->w, col, y, info->pixels, info->pixels, info->foreground ) ;
880 #endif
881 blacky = y;
882 }
883 }
884 }
885
886 return;
887 }
888
889 static void window__fillCol( info, col, input, black, white, match, length)
890 XWindowObject info ;
891 int col;
892 short *input ;
893 int black, white ;
894 int *match, length ;
895 {
896 window__fill( info, col, input, black, white, match, length, 0 ) ;
897
898 return ;
899 }
900
901 static void window__fillRow( info, col, input, black, white, match, length)
902 XWindowObject info ;
903 int col;
904 short *input;
905 int black, white ;
906 int *match, length ;
907 {
908 window__fill( info, col, input, black, white, match, length, 1 ) ;
909
910 return ;
911 }
912
913 static void window__function( info, ys, segment, skip, offset, yspan, start, points )
914 XWindowObject info ;
915 short *ys ;
916 int segment, skip ;
917 double offset, yspan ;
918 int start, points ;
919 {
920 #if defined(X11)
921 XPoint vs[ MAX_SEGMENT+4 ], *vptr ;
922 #else
923 Vertex vs[ MAX_SEGMENT+4 ], *vptr ;
924 #endif
925 register long x, dx, yscale ;
926 register int yoffset, point, count ;
927 register short *yptr ;
928 static long shift = 16 ;
929 static long round = 1l << 15 ;
930
931 #if defined(X11)
932 if (synchronous) {
933 (void) XSynchronize(theDisplay, FALSE);
934 XFlush(theDisplay);
935 synchronous = FALSE;
936 }
937
938 waitTillMapped(info) ;
939 #endif
940
941 points = abs(points);
942
943 if( points <= 1 )
944 return ;
945
946 yoffset = info->entries->height( info ) - offset ;
947
948 dx = ( double ) ( ( info->entries->width( info ) - 1 ) << shift ) / ( points - 1 ) + 0.5 ;
949 x = dx * start + ( 1 << shift ) + round ;
950
951 yscale = ( ( info->entries->height( info ) ) << shift ) / yspan + 0.5 ;
952
953 yptr = ys ;
954
955 for( point=0 ; point < segment-1 ; point += count-1 ) {
956
957 vptr = vs ;
958
959 for( count=0 ; count < MAX_SEGMENT && point + count < segment ; count++ ) {
960
961 vptr->x = x >> shift ;
962 vptr->y = yoffset - ( *yptr * yscale + round >> shift ) ;
963 #if defined(X10)
964 vptr->flags = 0;
965 #endif
966 vptr++ ;
967
968 if( count+1 < MAX_SEGMENT && point + count+1 < segment ) {
969 x += dx ;
970 yptr += skip ;
971 }
972 }
973
974 if( info->hide ) {
975
976 vptr->x = vptr[-1].x ;
977 vptr->y = 1 + yoffset ;
978 #if defined(X10)
979 vptr->flags = 0 ;
980 #endif
981 vptr++ ;
982
983 vptr->x = vs[0].x ;
984 vptr->y = vptr[-1].y ;
985 #if defined(X10)
986 vptr->flags = 0 ;
987 #endif
988 vptr++ ;
989
990 vptr->x = vs[0].x ;
991 vptr->y = vs[0].y ;
992 #if defined(X10)
993 vptr->flags = 0 ;
994 #endif
995 vptr++ ;
996
997 #if defined(X11)
998 XFillPolygon( theDisplay, info->w, info->backgroundGC, vs, vptr-vs, Complex, CoordModeOrigin);
999 }
1000
1001 XDrawLines(theDisplay, info->w, info->foregroundGC, vs, count, CoordModeOrigin);
1002 XFlush(theDisplay);
1003 #else
1004 XDrawFilled( info->w, vs, vptr-vs, info->background, GXcopy, AllPlanes ) ;
1005 }
1006
1007 XDraw( info->w, vs, count, info->pixels, info->pixels, info->foreground, GXcopy, AllPlanes ) ;
1008 #endif
1009 }
1010
1011 return ;
1012 }
1013
1014 typedef struct {
1015 FILE *imageFilePtr ; /* The File Pointer */
1016 int imageFilePreviousFrame ; /* The last image read */
1017 } ReadingData;
1018
1019 static ReadingData readingFiles[MAX_FILES], *current;
1020 static int numReadingFiles = 0 ;
1021 static int window__writing = 1 ;
1022
1023 /* --------------------------------------------------------------------
1024
1025 Search in the readingFiles[] array for the given filePtr. If found,
1026 return its index; otherwise return FAILURE (-1).
1027
1028 -------------------------------------------------------------------- */
1029
1030 static int findReadingFile( filePtr )
1031 FILE *filePtr;
1032 {
1033 int i;
1034
1035 for (i = 0; i < numReadingFiles; i++)
1036 if (readingFiles[i].imageFilePtr == filePtr)
1037 return (i);
1038
1039 return (-1);
1040
1041 }
1042
1043 static int window__read(w, filePtr, which)
1044 XWindowObject w ;
1045 FILE *filePtr;
1046 int which ;
1047 {
1048 int readingFileIndex ;
1049 long filePosBeforeSeek;
1050
1051 #if defined(X11)
1052 if (!synchronous) {
1053 (void) XSynchronize(theDisplay, TRUE);
1054 XFlush(theDisplay);
1055 synchronous = TRUE;
1056 }
1057
1058 waitTillMapped(w) ;
1059
1060 setupImage( w ) ;
1061 #else
1062 if( w->theImage == (short *) 0 ) {
1063 if((w->theImage = (short *) malloc(w->imageSize)) == NULL) {
1064 (void) fprintf(stderr, "windows: Insufficient memory to malloc %i bytes for a Pixmap.\n",
1065 w->imageSize);
1066 exit(1);
1067 }
1068 }
1069 #endif
1070
1071 if (numReadingFiles == 0 || current->imageFilePtr != filePtr) {
1072 if (numReadingFiles > 0 &&
1073 (readingFileIndex = findReadingFile(filePtr)) >= 0)
1074 current = &readingFiles[readingFileIndex];
1075 else {
1076 /* The First Read Operation (on this file) */
1077 if (numReadingFiles >= MAX_FILES) {
1078 fprintf(stderr,
1079 "windows: Sorry, you can only have %i files open for reading at once.\n",
1080 MAX_FILES);
1081 fprintf(stderr, " Hit <return> to exit.\n");
1082 getchar();
1083 exit(1);
1084 }
1085 current = &readingFiles[numReadingFiles] ;
1086 current->imageFilePtr = filePtr;
1087 current->imageFilePreviousFrame = 0 ;
1088 numReadingFiles++;
1089 }
1090 }
1091
1092 filePosBeforeSeek = ftell(current->imageFilePtr);
1093
1094 /* Now Read and Display it */
1095
1096 if (fseek(current->imageFilePtr,
1097 ((long) which - current->imageFilePreviousFrame - (long) 1) * w->imageSize, 1))
1098 return (FALSE);
1099
1100 #if defined(X11)
1101 if (fread(w->theImage->data, 1, w->imageSize, current->imageFilePtr) != w->imageSize) {
1102 #else
1103 if (fread(w->theImage, 1, w->imageSize, current->imageFilePtr) != w->imageSize) {
1104 #endif
1105 /* Reposition the filePointer to enable future Reads */
1106 if (fseek(current->imageFilePtr, filePosBeforeSeek, 0)) {
1107 (void) fprintf(stderr,
1108 "windows: Unable to reposition the file after a failed Read.\n");
1109 exit(1);
1110 }
1111 return (FALSE);
1112 }
1113
1114 #if defined(X11)
1115 XPutImage(theDisplay, w->w, w->foregroundGC, w->theImage, 0, 0, 0, 0, w->entries->width(w),
1116 w->entries->height(w));
1117 #else
1118 XPixmapBitsPutXY(w->w, 0, 0, w->entries->width(w), w->entries->height(w),
1119 w->theImage, (Bitmap) 0, GXcopy, AllPlanes);
1120 #endif
1121
1122 current->imageFilePreviousFrame = which;
1123
1124 return (TRUE);
1125 }
1126
1127
1128 static void window__write(w, filePtr)
1129 XWindowObject w;
1130 FILE *filePtr;
1131 {
1132 #if defined(X11)
1133 int imageSize;
1134 XImage *theImage;
1135
1136 theImage = XGetImage(theDisplay, w->w, 0, 0, w->entries->width(w), w->entries->height(w),
1137 planemask, XYPixmap);
1138
1139 imageSize = ImageSizeInBytes(theImage);
1140
1141 if (fwrite(theImage->data, 1, imageSize, filePtr) != imageSize) {
1142 fprintf(stderr,
1143 "window: WARNING! Failed to write %i bytes to Image File as image number %i.\n",
1144 imageSize, window__writing);
1145 fprintf(stderr, " Hit <return> to continue.\n");
1146 getchar();
1147 }
1148
1149 window__writing++;
1150
1151 (void) XDestroyImage(theImage);
1152 #else
1153 if( w->theImage == ( short * ) 0 ) {
1154 if((w->theImage = (short *) malloc(w->imageSize)) == NULL) {
1155 (void) fprintf(stderr, "windows: Insufficient memory to malloc %i bytes for a Pixmap.\n",
1156 w->imageSize);
1157 exit(1);
1158 }
1159 }
1160
1161 XPixmapGetXY(w->w, 0, 0, w->entries->width(w), w->entries->height(w), w->theImage) ;
1162
1163 (void) fwrite((char *) w->theImage, 1, (int) w->imageSize/DisplayPlanes(), filePtr) ;
1164 #endif
1165
1166 return;
1167 }
1168
1169
1170 static char window__pause(info)
1171 XWindowObject info ;
1172 {
1173 char line[256];
1174
1175 #if defined(X11)
1176 XFlush(theDisplay);
1177 #else
1178 XFlush();
1179 #endif
1180
1181 (void) gets(line);
1182
1183 if (line[0] == '\000' || line[0] == '\r' || line[0] == '\n')
1184 return (' ');
1185 else
1186 return (line[0]);
1187 }
1188
1189 static void window__axes(info, title, xmin, xmax, xtitle, ymin, ymax, ytitle)
1190 XWindowObject info;
1191 char *title, *xtitle, *ytitle;
1192 char *xmin, *xmax, *ymin, *ymax;
1193 {
1194 return;
1195 }
1196
1197 static void window__marker( info, label, p, points )
1198 XWindowObject info ;
1199 char *label ;
1200 int p, points ;
1201 {
1202 short pos = ( info->entries->width( info ) * p + points / 2 ) / points ;
1203
1204 #if defined( X11 )
1205 XDrawLine(theDisplay, info->w, info->foregroundGC, pos, 1, pos, info->entries->height(info));
1206 #else
1207 XLine( info->w, pos, 1, pos, info->entries->height( info ), info->pixels, info->pixels, info->foreground, GXcopy, AllPlanes ) ;
1208
1209 if( marker_font == ( FontInfo * ) 0 )
1210 marker_font = XOpenFont( marker_font_name ) ;
1211
1212 if( marker_font == ( FontInfo * ) 0 )
1213 (void) fprintf( stderr, "Unable to use font %s for marker %s\n", marker_font_name, label ) ;
1214 else
1215 XTextMaskPad( info->w, pos - 1 - XQueryWidth( label, marker_font->id ), 1,
1216 label, strlen( label ), marker_font->id, 0, 0, info->foreground, GXxor, AllPlanes ) ;
1217 #endif
1218
1219 return ;
1220 }
1221
1222 static int window__special( info, code, data )
1223 XWindowObject info ;
1224 int code ;
1225 char *data ;
1226 {
1227 return 0 ;
1228 }
1229
1230
1231 WindowObject newWindowWindow( window, default_x, default_y, default_width, default_height, pixels )
1232 Window window ;
1233 int default_x, default_y, default_width, default_height ;
1234 int pixels ;
1235 {
1236 static windowEntries entries = { window__x, window__y, window__width, window__height,
1237 window__draw, window__clear, window__close, window__store,
1238 window__recall, window__fillRow, window__fillCol,
1239 window__function, window__read, window__write,
1240 window__pause, window__axes, window__marker, window__special } ;
1241 XWindowObject info ;
1242 #if defined( X11 )
1243 XGCValues GCTemplate;
1244 #endif
1245
1246 if ((info = (XWindowObject ) malloc( sizeof(*info) )) == (XWindowObject )0) {
1247 (void) fprintf(stderr, "windows: Insufficient memory to allocate WindowObject.\n");
1248 exit(1);
1249 }
1250
1251 info->entries = &entries ;
1252 info->w = window ;
1253
1254 if( pixels < 0 )
1255 info->pixels = -pixels ;
1256 else
1257 info->pixels = pixels ;
1258
1259 info->hide = pixels < 0 ;
1260
1261 #if defined(X11)
1262 info->isMapped = 1 ;
1263
1264 /* Initialise a Graphics Context for lines and points */
1265
1266 GCTemplate.function = GXcopy ;
1267
1268 GCTemplate.foreground = theForeground ;
1269 GCTemplate.background = theBackground ;
1270
1271 GCTemplate.line_width = info->pixels ;
1272
1273 if( GCTemplate.line_width == 1 )
1274 GCTemplate.line_width = 0 ; /* use "thin" lines */
1275
1276 info->foregroundGC = XCreateGC( theDisplay, info->w,
1277 GCFunction|GCForeground|GCBackground|GCLineWidth, &GCTemplate ) ;
1278
1279 /* A second GC for clearing and hiding lines */
1280
1281 GCTemplate.foreground = theBackground ;
1282 GCTemplate.background = theForeground ;
1283
1284 info->backgroundGC = XCreateGC( theDisplay, info->w,
1285 GCFunction|GCForeground|GCBackground|GCLineWidth, &GCTemplate ) ;
1286
1287 #else
1288 info->foreground = WhitePixel ;
1289 info->background = BlackPixel ;
1290 info->lookup = 0;
1291 #endif
1292
1293 info->data = (short *) 0 ;
1294 info->greylength = 0 ;
1295
1296 /* update width and height fields */
1297
1298 info->x = default_x ;
1299 info->y = default_y ;
1300 info->width = default_width ;
1301 info->height = default_height;
1302
1303 checkGeometry( info ) ;
1304
1305 /* Initialise the Image Data Structure for later read operations */
1306
1307 #if defined(X11)
1308 info->theImage = info->rowImage = info->colImage = (XImage *) 0 ;
1309 #else
1310 info->imageSize = XYPixmapSize(info->entries->width(info), info->entries->height(info), DisplayPlanes());
1311 info->theImage = ( short * ) 0 ;
1312 #endif
1313
1314 info->imageNum = 0 ;
1315
1316 /* MAA: 3-8-1993
1317 * The planemask bits might as well go here as anywhere else
1318 */
1319
1320 if ( isON(colourstr) )
1321 planemask = AllPlanes;
1322 else
1323 planemask = atoi(planemaskstr);
1324
1325 return ( (WindowObject) info ) ;
1326 }
1327
1328 /* Since the <name> argument is always passed to newDisplayWindow as NULL, and
1329 the ASP modules don't have any concept of a configurable <display> option (the
1330 display is either ON or OFF), the <name> argument is redundant. The <name> argument
1331 still has a sensible use as the name of the Window which is being created, and
1332 its use has been modified as such in genbmm, revbmm, gensai and revsai... */
1333
1334
1335 WindowObject newXWindow( name, default_x, default_y, default_width, default_height, pixels )
1336 char *name ;
1337 int default_x, default_y, default_width, default_height ;
1338 int pixels ;
1339 {
1340 Window w ;
1341 XWindowObject info;
1342
1343 #if defined(X11)
1344
1345 if (theDisplay == (Display *) 0) {
1346 if ((theDisplay = XOpenDisplay(NULL)) == (Display *) 0) { /* Was name */
1347 (void) fprintf(stderr, "X11: Unable to do XOpenDisplay of display %s.\n",
1348 getenv("DISPLAY"));
1349 exit(1);
1350 }
1351
1352 theScreen = XDefaultScreen( theDisplay ) ;
1353
1354 /* MAA: 20-8-1993
1355 * lets put the colour bits here */
1356
1357 define_colours();
1358
1359 #ifndef SLAVE
1360 if (!synchronous) {
1361 (void) XSynchronize(theDisplay, TRUE);
1362 XFlush(theDisplay);
1363 synchronous = TRUE;
1364 }
1365 #endif
1366 }
1367
1368 /* Need to reset these every time, in case the screen is initialized
1369 independently via InitializeX */
1370
1371 theWidth = XDisplayWidth (theDisplay, theScreen);
1372 theHeight = XDisplayHeight(theDisplay, theScreen);
1373
1374 /* Perform "centering" calculations */
1375
1376 if (default_x < 0) {
1377 /* Center in the x dimension */
1378 default_width = (MIN(default_width, theWidth));
1379 default_x = (theWidth - default_width) / 2;
1380 }
1381
1382 if (default_y < 0) {
1383 /* Center in the y dimension */
1384 default_height = (MIN(default_height, theHeight));
1385 default_y = (theHeight - default_height) / 2;
1386 }
1387
1388 /* End of "centering" calculations */
1389 #else
1390 if( theDisplay == (Display *) 0 )
1391 if( ( theDisplay = XOpenDisplay(NULL) ) == (Display *) 0 ) {
1392 (void) fprintf(stderr, "Could not open DISPLAY \"%s\"\n", getenv("DISPLAY"));
1393 exit(1);
1394 }
1395
1396 #endif
1397
1398
1399
1400 #if defined(X11)
1401 if( default_width == 0 && default_height == 0 )
1402 w = XDefaultRootWindow(theDisplay);
1403 else
1404 if ((w = XCreateSimpleWindow(theDisplay, XDefaultRootWindow(theDisplay),
1405 default_x, default_y,
1406 (unsigned) default_width, (unsigned) default_height, 1,
1407 theForeground, theBackground)) != (Window) 0) {
1408 /*
1409 XSizeHints hints ;
1410
1411 hints.flags = PPosition | PSize ;
1412
1413 hints.x = default_x ;
1414 hints.y = default_y ;
1415 hints.width = default_width ;
1416 hints.height = default_height ;
1417 XSetStrandardProperties( theDisplay, w, name, name, None, name, 1, &hints ) ;
1418 */
1419 XStoreName(theDisplay, w, name);
1420 XMapRaised(theDisplay, w);
1421 XFlush( theDisplay);
1422 }
1423 #else
1424 if( default_width == 0 && default_height == 0 )
1425 w = RootWindow ;
1426 else
1427 if( ( w = XCreateWindow( RootWindow, abs( default_x ), abs( default_y ),
1428 default_width, default_height, 0, WhitePixmap,
1429 BlackPixmap ) ) != ( Window ) 0 ) {
1430 XStoreName( w, name ) ;
1431 XMapWindow( w ) ;
1432 XFlush() ;
1433 }
1434 #endif
1435 else {
1436 (void) fprintf( stderr,
1437 "Could not create window of size %dx%d at position %d,%d\n",
1438 default_width, default_height, default_x, default_y ) ;
1439 }
1440
1441 info = (XWindowObject) newWindowWindow(w, default_x, default_y, default_width, default_height, pixels);
1442 #if defined(X11)
1443 info->isMapped = 0 ;
1444 #endif
1445 info->entries->clear(info);
1446
1447 return((WindowObject)info);
1448
1449 }
1450
1451 #ifndef SLAVE
1452 WindowObject newDisplayWindow( name, default_x, default_y, default_width, default_height, pixels )
1453 char *name ;
1454 int default_x, default_y, default_width, default_height ;
1455 int pixels ;
1456 {
1457 return ( newXWindow( name, default_x, default_y, default_width, default_height, pixels ) ) ;
1458 }
1459 #endif