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