1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 
11 #if defined(DX_NATIVE_WINDOWS)
12 
13 #include <dx/dx.h>
_dxf_ExInitStatus(int n,int flag)14 Error _dxf_ExInitStatus (int n, int flag)
15 {
16     DXSetError(ERROR_INTERNAL, "No X stuff!!");
17     return ERROR;
18 }
19 
20 #else /* !DX_NATIVE_WINDOWS */
21 
22 #define Screen DXScreenHack	/* hack to get around libdx Screen def */
23 #include <dx/dx.h>
24 #undef Screen
25 
26 #include <stdlib.h>
27 
28 #if DXD_PROCESSOR_STATUS
29 #include <X11/Xatom.h>
30 #include <X11/Xlib.h>
31 #include <X11/Xutil.h>
32 #include <stdio.h>
33 #if sgi
34 #include <limits.h>
35 #endif
36 
37 #if defined(HAVE_SYS_SIGNAL_H)
38 #include <sys/signal.h>
39 #endif
40 
41 #if defined(HAVE_SIGNAL_H)
42 #include <signal.h>
43 #endif
44 
45 #if defined(HAVE_UNISTD_H)
46 #include <unistd.h>
47 #endif
48 
49 #include "utils.h"
50 #include "status.h"
51 
52 int             *_dxd_exProcessorStatus=NULL;
53 static int	*old_status		= NULL;
54 static int	nproc			= 4;
55 int		_dxd_exStatusPID		= 0;
56 
57 void _dxf_ExInitStatusW (int n);
58 void _dxf_ExReportStatus ();
59 
60 /*
61  * Initialize the processor status window.  Fork a subprocess to watch
62  * for status changes and update the window.
63  */
_dxf_ExInitStatus(int n,int flag)64 Error _dxf_ExInitStatus (int n, int flag)
65 {
66     int i;
67 
68     nproc = n;
69 
70     _dxd_exProcessorStatus = (int *) DXAllocate (n * sizeof (int));
71     old_status = (int *) DXAllocate (n * sizeof (int));
72 
73     if (_dxd_exProcessorStatus == NULL || old_status == NULL)
74 	return (ERROR);
75 
76 
77     for (i = 0; i < n; i++)
78     {
79 	_dxd_exProcessorStatus[i] = PS_EXECUTIVE;
80 	old_status[i] = PS_NONE;
81     }
82 
83     if (flag)
84     {
85 	/*
86 	 * This was calling memfork... that's unnecessary; memfork handles the
87 	 * run queue pipes, which this doesn't need. GDA
88 	 *
89 	 *      switch (_dxd_exStatusPID = DXmemfork (-1))
90 	 */
91 	switch (_dxd_exStatusPID = fork())
92 	{
93 	    case -1:
94 		_dxd_exStatusPID = 0;
95 		perror ("_dxf_ExInitStatus:  fork");
96 		break;
97 
98 	    case 0:
99 		_dxf_ExInitStatusW (n);
100 		_dxf_ExReportStatus ();
101 		break;
102 
103 	    default:
104 		break;
105 	}
106     }
107 
108     return (OK);
109 }
110 
111 
112 /*
113  * DXFree global memory and kill of the window update process.
114  */
_dxf_ExCleanupStatus()115 void _dxf_ExCleanupStatus ()
116 {
117     if (_dxd_exStatusPID)
118 #ifdef _WIN32
119 	kill (_dxd_exStatusPID, SIGTERM);
120 #else
121 	kill (_dxd_exStatusPID, SIGKILL);
122 #endif
123     if (_dxd_exProcessorStatus)
124 	DXFree ((Pointer) _dxd_exProcessorStatus);
125     if (old_status)
126 	DXFree ((Pointer) old_status);
127 }
128 
129 
130 /**************************************************************************/
131 
132 typedef struct
133 {
134     int		status;
135     char	*name;
136     long	pixel;
137 } s_color;
138 
139 static s_color	s_data[] =
140 {
141     {PS_MIN,		"White"},
142     {PS_NONE,		"White"},
143     {PS_EXECUTIVE,	"Blue"},
144     {PS_PARSE,		"Turquoise"},
145     {PS_GRAPHGEN,	"MediumTurquoise"},
146     {PS_GRAPHQUEUE,	"DarkTurquoise"},
147     {PS_RUN,		"Green"},
148     {PS_RECLAIM,	"Red"},
149     {PS_JOINWAIT,	"Yellow"},
150     {PS_NAPPING,	"NavyBlue"},
151     {PS_DEAD,		"Magenta"},
152     {PS_MAX,		"White"}
153 };
154 
155 #define	INITX		30
156 #define	INITY		50
157 #define	TITLE		"Processor Status"
158 #define	OBORDER		2
159 #define	SEPARATE	10
160 #define	LBORDER		SEPARATE
161 #define	RBORDER		SEPARATE
162 #define	TBORDER		SEPARATE
163 #define	BBORDER		SEPARATE
164 #define	WIDTH		20
165 #define	HEIGHT		20
166 
167 #define	RX(i)		(LBORDER + i * (WIDTH + SEPARATE))
168 #define	RY(i)		TBORDER
169 #define	RW(i)		WIDTH
170 #define	RH(i)		HEIGHT
171 
172 
173 static Display		*s_disp = NULL;
174 static Window		s_wind  = 0;
175 static GC		s_gc	= NULL;
176 
177 void _dxf_ExCleanupStatusW (void);
178 
179 /*
180  * Open a connection to the X server.  The environment variable DISPLAY_S
181  * can be use to specify a specific display server for the status display.
182  * Otherwise, the DISPLAY environment variable is used.
183  */
open_status_display(void)184 static Display *open_status_display (void)
185 {
186     char	*name;
187     Display	*disp;
188 
189     if ((name = getenv ("DISPLAY_S")) == (char *) NULL)
190 	if ((name = getenv ("DISPLAY")) == (char *) NULL)
191 	    name = "unix:0.0";
192 
193     if ((disp = XOpenDisplay (name)) == (Display *) NULL)
194     {
195 	fprintf (stderr, "%2d: _dxf_ExInitStatus:  can't open display '%s'\n",
196 		_dxd_exMyPID, name);
197 	return ((Display *) NULL);
198     }
199 
200     return (disp);
201 }
202 
203 
204 /*
205  * Initialize the status process.  Open an X window and allocate the color
206  * cells we need to show the different processor states.
207  */
_dxf_ExInitStatusW(int n)208 void _dxf_ExInitStatusW (int n)
209 {
210     int		x, y;
211     int		w, h;
212     int		border;
213     XSizeHints	hint;
214     static char	title[] = TITLE;
215     Colormap	colors;
216     XColor	shade;
217     XColor	exact;
218     int		i;
219     XGCValues	val;
220     long	flags;
221 
222 
223 #if 0
224     ExSignal (SIGTERM, _dxf_ExCleanupStatusW);
225     ExSignal (SIGINT,  _dxf_ExCleanupStatusW);
226 #endif
227 
228     if ((s_disp = open_status_display ()) == (Display *) NULL)
229 	return;
230 
231     x 	   = INITX;
232     y 	   = INITY;
233     w 	   = LBORDER + n * WIDTH + (n - 1) * SEPARATE + RBORDER;
234     h	   = TBORDER + HEIGHT + BBORDER;
235     border = OBORDER;
236 
237     hint.x		= x;
238     hint.y		= y;
239     hint.width		= w;
240     hint.height		= h;
241     hint.min_width	= w;
242     hint.min_height	= h;
243     hint.max_width	= w;
244     hint.max_height	= h;
245     hint.flags		= PPosition | PSize | USPosition | USSize;
246 
247     s_wind = XCreateSimpleWindow (s_disp,
248 				  DefaultRootWindow (s_disp),
249 				  x,
250 				  y,
251 				  w,
252 				  h,
253 				  border,
254 				  WhitePixel (s_disp, DefaultScreen (s_disp)),
255 				  BlackPixel (s_disp, DefaultScreen (s_disp)));
256 
257     XSetStandardProperties (s_disp, s_wind, title, title, None, NULL, 0, &hint);
258     XMapRaised (s_disp, s_wind);
259 
260     /*
261      * Now get the pixel values for the colormaps and create the GCs
262      */
263 
264     val.background = BlackPixel (s_disp, DefaultScreen (s_disp));
265     flags = GCForeground | GCBackground;
266     colors = DefaultColormap (s_disp, DefaultScreen (s_disp));
267 
268     s_gc    = XCreateGC (s_disp, s_wind, flags, &val);
269 
270     for (i = PS_MIN; i < PS_MAX; i++)
271     {
272 	if (XAllocNamedColor (s_disp, colors, s_data[i].name, &shade, &exact))
273 	{
274 	    s_data[i].pixel = shade.pixel;
275 	}
276 	else
277 	{
278 	    fprintf (stderr,
279 		    "_dxf_ExInitStatus:  can't allocate color '%s', using white\n",
280 		    s_data[i].name);
281 	    s_data[i].pixel = WhitePixel (s_disp, DefaultScreen (s_disp));
282 	}
283     }
284 
285     XSync (s_disp, 0);
286 }
287 
288 /*
289  * Close the display window and free associated X paraphenalia.
290  */
_dxf_ExCleanupStatusW(void)291 void _dxf_ExCleanupStatusW (void)
292 {
293     if (s_wind == (Window)NULL)
294 	return;
295 
296     XFreeGC (s_disp, s_gc);
297 
298     XDestroyWindow (s_disp, s_wind);
299     XCloseDisplay (s_disp);
300 
301     exit (0);
302 }
303 
304 /*
305  * Run forever.  This process watches for changes in the processors' status
306  * flags and updates the window appropriately.
307  */
_dxf_ExReportStatus()308 void _dxf_ExReportStatus ()
309 {
310     int		i;
311     int		status;
312     int		didSomething;
313 #if sgi
314     int	naptime;
315 
316     naptime = CLK_TCK / 10;
317 #endif
318 
319     /*
320      * Couldn't open the status display, thus we can't report anything.
321      */
322 
323     if (s_disp == (Display *) NULL)
324 #if defined(ibmpvs)
325 #define LONGTIME 0x7FFFFFFF  /* largest positive signed integer */
326         sleep (LONGTIME) ;   /* sleep a long time */
327 #else
328 	pause ();            /* sleep forever */
329 #endif
330 
331     for (;;)
332     {
333 #if sgi
334 	sginap (naptime);
335 #endif
336 
337 	/*
338 	 * Loop over the processor status flags and update window if anything
339 	 * has changes since the last time we looked.
340 	 */
341 	didSomething = FALSE;
342 	for (i=0; i < nproc; i++)
343 	{
344 	    status = _dxd_exProcessorStatus[i];
345 
346 	    if (old_status[i] == status || status <= PS_MIN || status >= PS_MAX)
347 		continue;
348 
349 	    didSomething = TRUE;
350 
351 	    XSetForeground (s_disp, s_gc, s_data[status].pixel);
352 
353 	    XFillRectangle (s_disp, s_wind, s_gc, RX(i), RY(i), RW(i), RH(i));
354 
355 	    old_status[i] = status;
356 	}
357 
358 	if (didSomething)
359 	{
360 	    DXsyncmem ();
361 	    XSync(s_disp, 0);
362 	}
363     }
364 }
365 #endif
366 
367 #endif /* DX_NATIVE_WINDOWS */
368