Mercurial > hg > aim92
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 |