1 /*
2    Copyright (c) 1991 - 1994 Michael Schoene & Heinz W. Werntges.
3    All rights reserved. Distributed by Free Software Foundation, Inc.
4 
5 This file is part of HP2xx.
6 
7 HP2xx is distributed in the hope that it will be useful, but
8 WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
9 to anyone for the consequences of using it or for whether it serves any
10 particular purpose or works at all, unless he says so in writing.  Refer
11 to the GNU General Public License, Version 2 or later, for full details.
12 
13 Everyone is granted permission to copy, modify and redistribute
14 HP2xx, but only under the conditions described in the GNU General Public
15 License.  A copy of this license is supposed to have been
16 given to you along with HP2xx so you can know your rights and
17 responsibilities.  It should be in a file named COPYING.  Among other
18 things, the copyright notice and this notice must be preserved on all
19 copies.
20 
21 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22 */
23 
24 /** to_x11.c: X11 preview part of project "hp2xx" (UNIX only)
25  **
26  ** 92/01/15  V 1.00  HWW  Derived from to_vga.c (V1.01b)
27  **			  X11 essentials due to M. Schoene
28  ** 92/01/28  V 1.01  HWW  Window offset user-defined via -o -O
29  ** 92/02/03  V 1.02  HWW  bug fixes, error handling
30  ** 92/05/19  V 1.02b HWW  Abort if color mode
31  ** 92/05/25  V 1.10  HWW  8 Colors supported
32  ** 93/01/06  V 1.10b HWW  Improved selection of foreground color
33  ** 94/02/14  V 1.20a HWW  Adapted to changes in hp2xx.h;
34  **		           improvements by Eigil Krogh Sorensen <eks@aar-vki.dk>
35  **
36  **	      NOTE: Color assignment leaves something to be desired
37  **		    with some X11 servers.
38  **/
39 
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <X11/Xlib.h>
44 #include <X11/Xutil.h>
45 
46 #include "bresnham.h"
47 #include "hp2xx.h"
48 #include "x11.h"
49 
50 
51 
52 
53 #define WIN_NAME	"x11"		/* Window name 		*/
54 #define PROG_NAME	"hp2xx"		/* Program name			*/
55 
56 
57 
58 /**
59  ** Global variables for X11
60  **/
61 
62 static Display*		XDisplay = NULL;	/* Workstation id	*/
63 static int		XScreen;
64 static Window		XRoot;			/* Number of root window	*/
65 static Visual*		XVisual = NULL;
66 
67 static GC		XGcWin;
68 static Window		XWin;			/* Window id		*/
69 
70 static	unsigned long	col_table[CMS_SIZE];
71 static	XColor		Xcol;
72 static	Colormap	def_cmap;
73 
74 /**
75  ** Screen sizes
76  **/
77 
78 static int	scr_width;
79 static int	scr_height;
80 
81 
82 /**
83  ** Window sizes
84  **/
85 
86 static int	width;
87 static int	bytes;
88 static int	height;
89 
90 
91 
92 /**
93  ** Initialize X11 and open window
94  **/
95 
96 static int
win_open(int x,int y,int w,int h)97 win_open( int x, int y, int w, int h )
98 {
99 	char*			DisplayName = NULL;
100 	char**			argv;
101 	XSizeHints		Hints;
102 	unsigned long		ValueMask;
103 	XSetWindowAttributes	WinAttr;
104 	XEvent			Event;
105 
106 
107 	/**
108 	 ** Simulate command line arguments
109 	 **/
110 
111 	argv = (char**) malloc( 2 * sizeof( char* ) );
112 	argv[0] = PROG_NAME;
113 	argv[1] = NULL;
114 
115 	/**
116 	 ** X11 server reachable ?
117 	 **/
118 
119     if ((XDisplay = (Display *) XOpenDisplay( DisplayName )) == NULL)
120 	{
121 		Eprintf ("No X11 server found !\n" );
122 		return( NO_SERVER );
123 	}
124 
125 	XScreen		= DefaultScreen( XDisplay );
126 	XRoot		= RootWindow( XDisplay, XScreen );
127 	XVisual		= DefaultVisual( XDisplay, XScreen );
128 	XGcWin		= DefaultGC( XDisplay, XScreen );
129 
130 	scr_width	= WidthOfScreen( ScreenOfDisplay( XDisplay, XScreen ) );
131 	scr_height	= HeightOfScreen(ScreenOfDisplay( XDisplay, XScreen ) );
132 	if (x+w > scr_width || y+h > scr_height)
133 	{
134 		Eprintf ("Window exceeds screen limits !\n" );
135 		return( SIZE );
136 	}
137 
138 	/**
139 	 ** Set window attributes
140 	 **/
141 
142 	WinAttr.background_pixel= WhitePixel( XDisplay, XScreen );
143 	WinAttr.border_pixel	= WhitePixel( XDisplay, XScreen );
144 	WinAttr.backing_store	= Always;
145 	ValueMask = CWBackPixel | CWBorderPixel | CWBackingStore;
146 
147 	/**
148 	 ** Create Window
149 	 **/
150 
151 	XWin = XCreateWindow( XDisplay, XRoot,
152 						  x, y, w, h,
153 						  1, 0,
154 						  CopyFromParent,
155 						  CopyFromParent,
156 						  ValueMask, &WinAttr );
157 
158 	/**
159 	 ** Define window properties
160 	 **/
161 
162 	Hints.flags = PSize | PMinSize | PMaxSize | USPosition;
163 	Hints.x		= x;
164 	Hints.y		= y;
165 	Hints.width	= Hints.min_width  = Hints.max_width  = w;
166 	Hints.height= Hints.min_height = Hints.max_height = h;
167 
168 	XSetStandardProperties( XDisplay, XWin,
169 					WIN_NAME, WIN_NAME, NULL,
170 					argv, 1, &Hints );
171 
172 /**
173  ** Define color table (compatible to SunView and Turbo-C usage)
174  **/
175 
176   def_cmap    = DefaultColormap( XDisplay, XScreen );
177   if (DefaultDepth( XDisplay, XScreen ) < 4)
178   {
179 	col_table[BLACK]	= WhitePixel( XDisplay, XScreen );
180 	col_table[WHITE]	= BlackPixel( XDisplay, XScreen );
181 	col_table[GRAY]		= col_table[WHITE];
182 	col_table[RED]		= col_table[WHITE];
183 	col_table[GREEN]	= col_table[WHITE];
184 	col_table[BLUE]		= col_table[WHITE];
185 	col_table[CYAN]		= col_table[WHITE];
186 	col_table[MAGENTA]	= col_table[WHITE];
187 	col_table[YELLOW]	= col_table[WHITE];
188 	col_table[LIGHTGRAY]	= col_table[WHITE];
189 	col_table[LIGHTRED]	= col_table[WHITE];
190 	col_table[LIGHTGREEN]	= col_table[WHITE];
191 	col_table[LIGHTBLUE]	= col_table[WHITE];
192 	col_table[LIGHTCYAN]	= col_table[WHITE];
193 	col_table[LIGHTMAGENTA]	= col_table[WHITE];
194   }
195   else
196   {
197 	XParseColor( XDisplay, def_cmap, "gray",&Xcol );
198 	XAllocColor( XDisplay, def_cmap, &Xcol );
199 	col_table[GRAY] = Xcol.pixel;
200 
201 	XParseColor( XDisplay, def_cmap, "orange red",&Xcol );
202 	XAllocColor( XDisplay, def_cmap, &Xcol );
203 	col_table[RED] = Xcol.pixel;
204 
205 	XParseColor( XDisplay, def_cmap, "pale green",&Xcol );
206 	XAllocColor( XDisplay, def_cmap, &Xcol );
207 	col_table[GREEN] = Xcol.pixel;
208 
209 	XParseColor( XDisplay, def_cmap, "medium blue",&Xcol );
210 	XAllocColor( XDisplay, def_cmap, &Xcol );
211 	col_table[BLUE] = Xcol.pixel;
212 
213 	XParseColor( XDisplay, def_cmap, "medium aquamarine",&Xcol );
214 	XAllocColor( XDisplay, def_cmap, &Xcol );
215 	col_table[CYAN] = Xcol.pixel;
216 
217 	XParseColor( XDisplay, def_cmap, "medium violet red",&Xcol );
218 	XAllocColor( XDisplay, def_cmap, &Xcol );
219 	col_table[MAGENTA] = Xcol.pixel;
220 
221 	XParseColor( XDisplay, def_cmap, "yellow",&Xcol );
222 	XAllocColor( XDisplay, def_cmap, &Xcol );
223 	col_table[YELLOW] = Xcol.pixel;
224 
225 	XParseColor( XDisplay, def_cmap, "light gray",&Xcol );
226 	XAllocColor( XDisplay, def_cmap, &Xcol );
227 	col_table[LIGHTGRAY] = Xcol.pixel;
228 
229 	XParseColor( XDisplay, def_cmap, "red",&Xcol );
230 	XAllocColor( XDisplay, def_cmap, &Xcol );
231 	col_table[LIGHTRED] = Xcol.pixel;
232 
233 	XParseColor( XDisplay, def_cmap, "green",&Xcol );
234 	XAllocColor( XDisplay, def_cmap, &Xcol );
235 	col_table[LIGHTGREEN] = Xcol.pixel;
236 
237 	XParseColor( XDisplay, def_cmap, "blue",&Xcol );
238 	XAllocColor( XDisplay, def_cmap, &Xcol );
239 	col_table[LIGHTBLUE] = Xcol.pixel;
240 
241 	XParseColor( XDisplay, def_cmap, "cyan",&Xcol );
242 	XAllocColor( XDisplay, def_cmap, &Xcol );
243 	col_table[LIGHTCYAN] = Xcol.pixel;
244 
245 	XParseColor( XDisplay, def_cmap, "magenta",&Xcol );
246 	XAllocColor( XDisplay, def_cmap, &Xcol );
247 	col_table[LIGHTMAGENTA] = Xcol.pixel;
248 
249 	XParseColor( XDisplay, def_cmap, "black",&Xcol );
250 	XAllocColor( XDisplay, def_cmap, &Xcol );
251 	col_table[WHITE] = Xcol.pixel;
252 
253 	XParseColor( XDisplay, def_cmap, "white",&Xcol );
254 	XAllocColor( XDisplay, def_cmap, &Xcol );
255 	col_table[BLACK] = Xcol.pixel;
256   }
257 
258 	/**
259 	 **  Set foreground and background colors
260 	 **/
261 
262 	XSetState ( 	XDisplay, XGcWin,
263 			col_table[BLACK], col_table[WHITE],
264 			GXcopy, AllPlanes );
265 
266 	/**
267 	 ** Define permitted events for this window
268 	 **/
269 
270 /* 23.jan.94 eks */
271 	XSelectInput( XDisplay, XWin, ExposureMask | VisibilityChangeMask | StructureNotifyMask);
272 /*	XSelectInput( XDisplay, XWin, ExposureMask | VisibilityChangeMask); */
273 
274 	/**
275 	 ** Display window
276 	 **/
277 
278 	XMapWindow( XDisplay, XWin );
279 	do {
280 		XNextEvent( XDisplay, &Event);
281 	} while (Event.type != Expose && Event.type != VisibilityNotify);
282 
283 	width	= w;
284 	height	= h;
285 	bytes	= (w + 7) / 8;
286 
287 	free( (char*) argv );
288 	return( 0 );
289 }
290 
291 
292 
293 static void
win_close()294 win_close()
295 {
296 	XDestroyWindow( XDisplay, XWin );
297 	XCloseDisplay( XDisplay );
298 }
299 
300 
301 
302 
303 #define	setXcolor(col) XSetForeground (XDisplay, XGcWin, col_table[col])
304 
305 
306 
307 
308 int
PicBuf_to_X11(const GEN_PAR * pg,const OUT_PAR * po)309 PicBuf_to_X11 (const GEN_PAR *pg, const OUT_PAR *po)
310 /**
311  ** Interface to higher-level routines,
312  **   similar in structure to other previewers
313  **/
314 {
315 int		row_c, x, y;
316 XEvent		Event;
317 const RowBuf	*row = NULL;
318 const PicBuf	*pb;
319 
320   if (pg == NULL || po == NULL)
321 	return ERROR;
322   pb = po->picbuf;
323   if (pb == NULL)
324 	return ERROR;
325 
326   if (!pg->quiet)
327   {
328 	Eprintf ("\nX11 preview follows.\n");
329 /* 24.jan.94 eks */
330 /*	Eprintf ("Press <return> to end graphics mode\n");*/
331   }
332 
333   if (win_open( (int)(po->xoff * po->dpi_x / 25.4),
334 		(int)(po->yoff * po->dpi_y / 25.4),
335 		pb->nb << 3, pb->nr ) )
336 	return ERROR;
337 
338   /* Backward since highest index is lowest line on screen! */
339   for (row_c=0, y=pb->nr-1; row_c < pb->nr; row_c++, y--)
340   {
341 	row = get_RowBuf (pb, row_c);
342 	if (row == NULL)
343 		continue;
344 	for (x=0; x < pb->nc; x++)
345 	{
346 		switch (index_from_RowBuf(row, x, pb))
347 		{
348 		case xxBackground:			continue;
349 		case xxForeground:setXcolor (WHITE);	break;
350 		case xxRed:	setXcolor (RED);	break;
351 		case xxGreen:	setXcolor (GREEN);	break;
352 		case xxBlue:	setXcolor (BLUE);	break;
353 		case xxCyan:	setXcolor (CYAN);	break;
354 		case xxMagenta:	setXcolor (MAGENTA);	break;
355 		case xxYellow:	setXcolor (YELLOW);	break;
356 		default:				continue;
357 		}
358 		XDrawPoint (XDisplay, XWin, XGcWin, x, y);
359 	}
360   }
361 
362   XFlush( XDisplay );
363 
364 /*  23.jan.94 eks  */
365 
366 /* Vent pe destroy event */
367 do
368 {
369  XWindowEvent( XDisplay, XWin, StructureNotifyMask,&Event );
370  } while (Event.type != DestroyNotify);
371 
372 /*while (!XCheckTypedWindowEvent( XDisplay, XWin, DestroyNotify, &Event ));*/
373 /*  SilentWait();*/
374 win_close();
375 return 0;
376 }
377 /*
378 	XDestroyWindow( XDisplay, XWin );
379 	XCloseDisplay( XDisplay );
380 */
381 
382