~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/clients/qmon/qmon_queue.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
10
 *  Sun Industry Standards Source License Version 1.2
 
11
 *  =================================================
 
12
 *  The contents of this file are subject to the Sun Industry Standards
 
13
 *  Source License Version 1.2 (the "License"); You may not use this file
 
14
 *  except in compliance with the License. You may obtain a copy of the
 
15
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
16
 * 
 
17
 *  Software provided under this License is provided on an "AS IS" basis,
 
18
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
19
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
20
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
21
 *  See the License for the specific provisions governing your rights and
 
22
 *  obligations concerning the Software.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
#include <X11/Xos.h>
 
33
#include <stdlib.h>
 
34
#include <ctype.h>
 
35
 
 
36
#include <Xm/Xm.h>
 
37
#include <Xm/PushB.h>
 
38
#include <Xm/ToggleB.h>
 
39
#include <Xm/DialogS.h>
 
40
#include <Xm/DrawingA.h>
 
41
#include <Xm/DrawnB.h>
 
42
#include <Xm/Label.h>
 
43
 
 
44
#include <Xmt/Xmt.h>
 
45
#include <Xmt/Menu.h>
 
46
#include <Xmt/Icon.h>
 
47
#include <Xmt/Hash.h>
 
48
#include <Xmt/Create.h>
 
49
#include <Xmt/Pixmap.h>
 
50
#include <Xmt/Layout.h>
 
51
#include <Xmt/Dialogs.h>
 
52
#include <Xmt/SetValue.h>
 
53
 
 
54
#include "sge_all_listsL.h"
 
55
#include "sge.h"
 
56
#include "sge_sched.h"
 
57
#include "qmon_rmon.h"
 
58
#include "qmon_queue.h"
 
59
#include "qmon_qaction.h"
 
60
#include "qmon_submit.h"
 
61
#include "qmon_menus.h"
 
62
#include "qmon_comm.h"
 
63
#include "qmon_timer.h"
 
64
#include "qmon_globals.h"
 
65
#include "qmon_init.h"
 
66
#include "qmon_ticket.h"
 
67
#include "qmon_util.h"
 
68
#include "qmon_appres.h"
 
69
#include "qmon_message.h"
 
70
#include "qmon_browser.h"
 
71
#include "qmon_qcustom.h"
 
72
#include "qmon_jobcustom.h"
 
73
#include "sge_feature.h"
 
74
#include "sge_qinstance.h"
 
75
#include "sge_qinstance_state.h"
 
76
#include "sge_host.h"
 
77
#include "sge_cqueue.h"
 
78
#include "sge_complex_schedd.h"
 
79
#include "Matrix.h"
 
80
#include "load_correction.h"
 
81
 
 
82
/*-------------------------------------------------------------------------*/
 
83
static void qmonBuildQBG(Widget parent, XtPointer cld, XtPointer cad);
 
84
static void qmonQueuePopdown(Widget w, XtPointer cld, XtPointer cad);
 
85
static void qmonQueueStartUpdate(Widget w, XtPointer cld, XtPointer cad);
 
86
static void qmonQueueStopUpdate(Widget w, XtPointer cld, XtPointer cad);
 
87
static void qmonQueueHash(lList *qlp, lList *hl);
 
88
static void qmonQueueSetPos(lList *qlp);
 
89
static void qmonQueueRemove(tQueueIcon *qI);
 
90
static char *qmonQueueGetArch(const char *qhostname);
 
91
static char *qmonQueueGetSymbol(char *arch);
 
92
static String qmonQueueShowBrowserInfo(lListElem *qep);
 
93
static void qmonDrawQueueButton(Widget w, XtPointer cld, XtPointer cad);
 
94
static void qmonQueueModify(Widget w, XtPointer cld, XtPointer cad);
 
95
static void qmonQueueDeleteQuick(Widget w, XtPointer cld, XtPointer cad);
 
96
static void qmonQueueChangeState(Widget w, XtPointer cld, XtPointer cad);
 
97
static void qmonChangeBackground(Widget w, int selected);
 
98
static void HandleButtonPress(Widget w, XtPointer cld, XEvent *event, Boolean *continue_to_dispatch);
 
99
static void HandleEnter(Widget w, XtPointer cld, XEvent *event, Boolean *continue_to_dispatch);
 
100
static void qmonCreateQueueControl(Widget w);
 
101
static void qmonQueueSetLoad(Widget matrix, lListElem *qep);
 
102
static void qmonQueueShowLoadEvent(Widget w, XtPointer cld, XEvent *event);
 
103
/* static void showQueueHashTable(XmtHashTable table, XtPointer key, XtPointer *data); */
 
104
 
 
105
/*-------------------------------------------------------------------------*/
 
106
static Widget qmon_queue = 0;
 
107
static Widget queue_da = 0;
 
108
static Widget queue_customize = 0;
 
109
 
 
110
static XmtHashTable QueueHashTable = NULL;
 
111
static tQueueButton* QBG[QUEUE_MAX_VERT];
 
112
 
 
113
static XmtMenuItem queue_popup_items[] = {
 
114
   {XmtMenuItemLabel, "@{@fBQUEUE ACTIONS}"},
 
115
   {XmtMenuItemSeparator},
 
116
   {XmtMenuItemPushButton, "@{Add}", 'A', "Meta<Key>A", "Meta+A",
 
117
         qmonQCPopup, NULL },
 
118
   {XmtMenuItemPushButton, "@{Modify}", 'M', "Meta<Key>M", "Meta+M",
 
119
         qmonQueueModify, NULL},
 
120
/*    {XmtMenuItemPushButton, "DeleteDialog", 'l', "Meta<Key>L", "Meta+L", */
 
121
/*          qmonQCPopup, (XtPointer)QC_DELETE }, */
 
122
   {XmtMenuItemPushButton, "@{Delete}", 'D', "Meta<Key>D", "Meta+D",
 
123
         qmonQueueDeleteQuick, NULL},
 
124
   {XmtMenuItemPushButton, "@{Suspend}", 'S', "Meta<Key>S", "Meta+S",
 
125
         qmonQueueChangeState, (XtPointer)QI_DO_SUSPEND},
 
126
   {XmtMenuItemPushButton, "@{Resume}", 'R', "Meta<Key>R", "Meta+R",
 
127
         qmonQueueChangeState, (XtPointer)QI_DO_UNSUSPEND},
 
128
   {XmtMenuItemPushButton, "@{Disable}", 'i', "Meta<Key>I", "Meta+I",
 
129
         qmonQueueChangeState, (XtPointer)QI_DO_DISABLE},
 
130
   {XmtMenuItemPushButton, "@{Enable}", 'E', "Meta<Key>E", "Meta+E",
 
131
         qmonQueueChangeState, (XtPointer)QI_DO_ENABLE}
 
132
};
 
133
 
 
134
 
 
135
#define WIDTH  "%s%-30.30s"
 
136
 
 
137
/*-------------------------------------------------------------------------*/
 
138
/*    P U B L I C    F U N C T I O N S                                     */
 
139
/*-------------------------------------------------------------------------*/
 
140
void qmonQueuePopup(Widget w, XtPointer cld, XtPointer cad)
 
141
{
 
142
   lList *alp = NULL;
 
143
   
 
144
   DENTER(GUI_LAYER, "qmonQueuePopup");
 
145
 
 
146
   /* set busy cursor */
 
147
   XmtDisplayBusyCursor(w);
 
148
 
 
149
   qmonMirrorMultiAnswer(CQUEUE_T | EXECHOST_T | CENTRY_T, &alp);
 
150
   if (alp) {
 
151
      qmonMessageBox(w, alp, 0);
 
152
      lFreeList(&alp);
 
153
      /* set busy cursor */
 
154
      XmtDisplayDefaultCursor(w);
 
155
      DEXIT;
 
156
      return;
 
157
   }
 
158
 
 
159
   if (!qmon_queue) {
 
160
 
 
161
      qmonCreateQueueControl(AppShell);
 
162
 
 
163
      /*
 
164
      ** create queue customize dialog
 
165
      */
 
166
/*       qmonCreateQCU(qmon_queue, NULL); */
 
167
 
 
168
      /* 
 
169
      ** set the close button callback 
 
170
      ** set the icon and icon name
 
171
      */
 
172
      XmtCreatePixmapIcon(qmon_queue, qmonGetIcon("toolbar_queue"), None); 
 
173
      XtVaSetValues(qmon_queue, XtNiconName, "qmon:Queue Control", NULL);
 
174
      XmtAddDeleteCallback(qmon_queue, XmDO_NOTHING, qmonQueuePopdown,  NULL);
 
175
      XtAddEventHandler(qmon_queue, StructureNotifyMask, False, 
 
176
                        SetMinShellSize, NULL);
 
177
      XtAddEventHandler(qmon_queue, StructureNotifyMask, False, 
 
178
                        SetMaxShellSize, (XtPointer) SHELL_WIDTH);
 
179
      
 
180
   }
 
181
 
 
182
   xmui_manage(qmon_queue);
 
183
/*    ForceUpdate(qmon_queue); */
 
184
 
 
185
   updateQueueList();
 
186
 
 
187
#if 0
 
188
   /*
 
189
   ** workaround for display problem of DrawingArea under some WMs
 
190
   */
 
191
   XtUnmapWidget(queue_da);
 
192
   XtMapWidget(queue_da);
 
193
#endif   
 
194
 
 
195
   /* set busy cursor */
 
196
   XmtDisplayDefaultCursor(w);
 
197
 
 
198
   DEXIT;
 
199
}
 
200
 
 
201
/*-------------------------------------------------------------------------*/
 
202
void updateQueueList(void)
 
203
{
 
204
   lList *qlp = NULL;
 
205
   lList *hl = NULL;
 
206
   lList *rl = NULL;
 
207
   lList *cl = NULL;
 
208
   lEnumeration *whatall = NULL;
 
209
   lCondition *where = NULL;
 
210
   static Boolean filter_on = False;
 
211
   
 
212
   DENTER(GUI_LAYER, "updateQueueList");
 
213
 
 
214
   cl = qmonMirrorList(SGE_CENTRY_LIST);
 
215
   /*
 
216
   ** copy of host list
 
217
   */
 
218
   hl = lCopyList("HL", qmonMirrorList(SGE_EXECHOST_LIST));
 
219
 
 
220
   /* 
 
221
   **
 
222
   ** select a subset of the whole queue list (->where) 
 
223
   ** and get the list sorted 
 
224
   **
 
225
   */
 
226
#ifdef FIXME   
 
227
   where = lWhere("%T(%I!=%s)", QU_Type, QU_qname, QU_TEMPLATE);
 
228
   whatall = lWhat("%T(ALL)", QU_Type);
 
229
#else   
 
230
   whatall = lWhat("%T(ALL)", CQ_Type);
 
231
#endif  
 
232
   qlp = lSelect("SQL", qmonMirrorList(SGE_CQUEUE_LIST), where, whatall); 
 
233
   lFreeWhere(&where);
 
234
   lFreeWhat(&whatall);
 
235
 
 
236
#ifdef FIXME
 
237
   /*
 
238
   ** additional filtering
 
239
   */
 
240
   rl = qmonQFilterRequest();
 
241
   if (rl) {
 
242
      if (!filter_on) {
 
243
         setButtonLabel(queue_customize, "@{Customize +}");
 
244
         filter_on = True;
 
245
      }
 
246
      match_queue(&qlp, rl, cl, hl);
 
247
   }  
 
248
   else {
 
249
      if (filter_on) {
 
250
         setButtonLabel(queue_customize, "@{Customize}");
 
251
         filter_on = False;
 
252
      }
 
253
   }
 
254
   
 
255
   /*
 
256
   ** sort the queues according to sequence number and alphabetically
 
257
   */
 
258
   lPSortList(qlp, "%I+ %I+ %I+", QU_seq_no, QU_qhostname, QU_qname);
 
259
#endif
 
260
   /*
 
261
   ** save the queue in hash table
 
262
   */
 
263
   qmonQueueHash(qlp, hl);
 
264
 
 
265
   qmonQueueSetPos(qlp);
 
266
 
 
267
   /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
 
268
   ** qlp must not be freed it is referenced in qmonHashQueue
 
269
   ** and freed there
 
270
   */
 
271
   
 
272
   DEXIT;
 
273
}
 
274
 
 
275
/*-------------------------------------------------------------------------*/
 
276
void updateQueueListCB(Widget w, XtPointer cld, XtPointer cad)
 
277
{
 
278
 
 
279
   lList *alp = NULL;
 
280
 
 
281
   if (qmon_queue) {
 
282
      qmonMirrorMultiAnswer(CQUEUE_T | EXECHOST_T | CENTRY_T, &alp);
 
283
      if (alp) {
 
284
         qmonMessageBox(w, alp, 0);
 
285
         lFreeList(&alp);
 
286
         return;
 
287
      }
 
288
      updateQueueList();
 
289
   }
 
290
}
 
291
 
 
292
/*-------------------------------------------------------------------------*/
 
293
/*    P R I V A T E   F U N C T I O N S                                    */
 
294
/*-------------------------------------------------------------------------*/
 
295
static void qmonQueuePopdown(Widget w, XtPointer cld, XtPointer cad)
 
296
{
 
297
   DENTER(GUI_LAYER, "qmonQueuePopdown");
 
298
 
 
299
   qmonQCPopdown(w, NULL, NULL);
 
300
   xmui_unmanage(qmon_queue);
 
301
 
 
302
   DEXIT;
 
303
}
 
304
 
 
305
/*-------------------------------------------------------------------------*/
 
306
static void qmonQueueStartUpdate(Widget w, XtPointer cld, XtPointer cad)
 
307
{
 
308
   DENTER(GUI_LAYER, "qmonQueueStartUpdate");
 
309
  
 
310
   /* 
 
311
    * register the update procedure
 
312
    * start queue timer for queue info and exechost timer for infos
 
313
    * of host that the queue is attached to
 
314
    */
 
315
   qmonTimerAddUpdateProc(CQUEUE_T, "updateQueueList", updateQueueList);
 
316
   qmonStartTimer(CQUEUE_T | EXECHOST_T | CENTRY_T);
 
317
   
 
318
   DEXIT;
 
319
}
 
320
 
 
321
 
 
322
/*-------------------------------------------------------------------------*/
 
323
static void qmonQueueStopUpdate(Widget w, XtPointer cld, XtPointer cad)
 
324
{
 
325
   DENTER(GUI_LAYER, "qmonQueueStopUpdate");
 
326
  
 
327
   /* 
 
328
    * remove the update procedure
 
329
    * stop queue timer for queue info and exechost timer for infos
 
330
    * of host that the queue is attached to
 
331
    */
 
332
   qmonStopTimer(CQUEUE_T | EXECHOST_T | CENTRY_T);
 
333
   qmonTimerRmUpdateProc(CQUEUE_T, "updateQueueList");
 
334
   
 
335
   DEXIT;
 
336
}
 
337
 
 
338
/*-------------------------------------------------------------------------*/
 
339
static void qmonCreateQueueControl(
 
340
Widget parent 
 
341
) {
 
342
   Widget  queue_add, queue_modify, queue_update, 
 
343
           queue_delete, queue_done, queue_suspend, queue_unsuspend,
 
344
           queue_enable, queue_disable, queue_reschedule, 
 
345
           queue_error, queue_tickets, queue_main_link;
 
346
   
 
347
   DENTER(GUI_LAYER, "qmonCreateQueueControl");
 
348
 
 
349
   qmon_queue = XmtBuildQueryToplevel( parent, "qmon_queue",
 
350
                                     "queue_da", &queue_da,
 
351
                                     "queue_add", &queue_add,
 
352
                                     "queue_modify", &queue_modify,
 
353
                                     "queue_customize", &queue_customize,
 
354
                                     "queue_done", &queue_done,
 
355
                                     "queue_update", &queue_update,
 
356
                                     "queue_delete", &queue_delete,
 
357
                                     "queue_suspend", &queue_suspend,
 
358
                                     "queue_unsuspend", &queue_unsuspend,
 
359
                                     "queue_enable", &queue_enable,
 
360
                                     "queue_disable", &queue_disable,
 
361
                                     "queue_reschedule", &queue_reschedule,
 
362
                                     "queue_error", &queue_error,
 
363
                                     "queue_tickets", &queue_tickets,
 
364
                                     "queue_main_link", &queue_main_link,
 
365
                                     NULL);
 
366
 
 
367
 
 
368
   XtAddCallback(queue_tickets, XmNactivateCallback,
 
369
                  qmonPopupTicketOverview, NULL);
 
370
 
 
371
   XtAddCallback(queue_add, XmNactivateCallback, 
 
372
                     qmonQCPopup, NULL);
 
373
   XtAddCallback(queue_modify, XmNactivateCallback, 
 
374
                     qmonQueueModify, NULL);
 
375
   XtAddCallback(queue_customize, XmNactivateCallback, 
 
376
                     qmonPopupQCU, NULL); 
 
377
   XtAddCallback(queue_done, XmNactivateCallback, 
 
378
                     qmonQueuePopdown, NULL);
 
379
   XtAddCallback(queue_main_link, XmNactivateCallback, 
 
380
                     qmonMainControlRaise, NULL);
 
381
   XtAddCallback(queue_update, XmNactivateCallback, 
 
382
                     updateQueueListCB, NULL);
 
383
   XtAddCallback(queue_delete, XmNactivateCallback, 
 
384
                     qmonQueueDeleteQuick, NULL);
 
385
   XtAddCallback(queue_suspend, XmNactivateCallback, 
 
386
                     qmonQueueChangeState, (XtPointer)QI_DO_SUSPEND);
 
387
   XtAddCallback(queue_unsuspend, XmNactivateCallback, 
 
388
                     qmonQueueChangeState, (XtPointer)QI_DO_UNSUSPEND);
 
389
   XtAddCallback(queue_disable, XmNactivateCallback, 
 
390
                     qmonQueueChangeState, (XtPointer)QI_DO_DISABLE);
 
391
   XtAddCallback(queue_enable, XmNactivateCallback, 
 
392
                     qmonQueueChangeState, (XtPointer)QI_DO_ENABLE);
 
393
   XtAddCallback(queue_reschedule, XmNactivateCallback, 
 
394
                     qmonQueueChangeState, (XtPointer)QI_DO_RESCHEDULE);
 
395
   XtAddCallback(queue_error, XmNactivateCallback, 
 
396
                     qmonQueueChangeState, (XtPointer)QI_DO_CLEARERROR);
 
397
/*    XtAddCallback(queue_load, XmNvalueChangedCallback,  */
 
398
/*                      qmonQueueToggleLoad, NULL); */
 
399
 
 
400
#ifdef FIXME
 
401
   /* start the needed timers and the corresponding update routines */
 
402
   XtAddCallback(qmon_queue, XmNpopupCallback, 
 
403
                     qmonQueueStartUpdate, NULL);
 
404
   XtAddCallback(qmon_queue, XmNpopdownCallback,
 
405
                     qmonQueueStopUpdate, NULL);
 
406
#endif
 
407
 
 
408
   /* register event handler for queue popup */
 
409
   qmonCreatePopup(queue_da, "QueuePopup", queue_popup_items, 
 
410
                           XtNumber(queue_popup_items));
 
411
   qmonBuildQBG(queue_da, NULL, NULL);
 
412
   XtManageChild(queue_da);
 
413
 
 
414
   DEXIT;
 
415
}
 
416
 
 
417
 
 
418
   
 
419
/*-------------------------------------------------------------------------*
 
420
 * 
 
421
 * In order to bypass annoying flickering effects, we manage a whole
 
422
 * bunch of PushB's, but they are all unmapped. By looping through
 
423
 * the actual list we give the actual queue a grid position and
 
424
 * map the corresponding PushB, changing its labelString or labelPixmap
 
425
 * We register an enter/leave Event Handler to have the ability to
 
426
 * show some additional useful information about the queue (->Browser)
 
427
 * The handle to the information is a Quark build from qhostname and qname
 
428
 * therefore we need the same qname/qhostname in distinct accesses to the
 
429
 * hash table through the quark mechanism. (->tolower(qhostname),if there
 
430
 * are several versions of qhostname (FRODO.adomain, frodo.adomain))
 
431
 * The QueueButtonGrid (QBG) sizes are settable through resources at startup
 
432
 * of the application.
 
433
 *
 
434
 *-------------------------------------------------------------------------*/
 
435
static void qmonBuildQBG(
 
436
Widget parent,
 
437
XtPointer cld,
 
438
XtPointer cad 
 
439
) {
 
440
   int i, j;
 
441
   int x, y;
 
442
   int x0 = (QUEUE_GRID_WIDTH - QUEUE_BUTTON_WIDTH) / 2;
 
443
   int y0 = (QUEUE_GRID_HEIGHT - QUEUE_BUTTON_HEIGHT) / 2;
 
444
 
 
445
   DENTER(GUI_LAYER, "qmonBuildQBG");
 
446
 
 
447
   for (i=0; i<QUEUE_MAX_VERT; i++) {
 
448
      QBG[i] = (tQueueButton*) XtMalloc(sizeof(tQueueButton) *
 
449
                                                QUEUE_MAX_HORIZ);
 
450
   }         
 
451
   
 
452
   for (i=0; i<QUEUE_MAX_VERT; i++) {
 
453
      for (j=0; j< QUEUE_MAX_HORIZ; j++) {
 
454
         x = QUEUE_GRID_XOFFSET + j * QUEUE_GRID_WIDTH;
 
455
         y = QUEUE_GRID_YOFFSET + i * QUEUE_GRID_HEIGHT;
 
456
 
 
457
         QBG[i][j].qI = NULL;        
 
458
         QBG[i][j].bgid = XtVaCreateWidget(
 
459
                                    "QBG", 
 
460
                                    xmDrawingAreaWidgetClass,
 
461
                                    parent,
 
462
                                    XmNborderWidth, 0,
 
463
                                    XmNmarginWidth, 0,
 
464
                                    XmNmarginHeight, 0,
 
465
                                    XmNx, x,
 
466
                                    XmNy, y,
 
467
                                    XmNheight, QUEUE_GRID_HEIGHT,
 
468
                                    XmNwidth, QUEUE_GRID_WIDTH,
 
469
                                    XmNresizePolicy, XmRESIZE_NONE,
 
470
                                    XmNshadowThickness, 0,
 
471
                                    XmNhighlightThickness, 0,
 
472
                                    NULL);
 
473
 
 
474
         XtAddEventHandler(QBG[i][j].bgid, 
 
475
                        ButtonPressMask, 
 
476
                        False, HandleButtonPress, 
 
477
                        (XtPointer)&QBG[i][j]);
 
478
 
 
479
         QBG[i][j].id = XtVaCreateManagedWidget("QBG", 
 
480
                                                xmDrawnButtonWidgetClass,
 
481
                                                QBG[i][j].bgid,
 
482
                                                XmNmappedWhenManaged, False,
 
483
                                                XmNx, x0,
 
484
                                                XmNy, y0,
 
485
                                                XmNheight, QUEUE_BUTTON_HEIGHT,
 
486
                                                XmNwidth, QUEUE_BUTTON_WIDTH,
 
487
                                                XmNrecomputeSize, False,
 
488
                                                NULL);
 
489
         XtAddCallback( QBG[i][j].id, 
 
490
                     XmNexposeCallback, 
 
491
                     qmonDrawQueueButton, 
 
492
                     (XtPointer)&QBG[i][j]);
 
493
 
 
494
         XtAddEventHandler(QBG[i][j].id, 
 
495
                        ButtonPressMask, 
 
496
                        False, HandleButtonPress, 
 
497
                        (XtPointer)&QBG[i][j]);
 
498
 
 
499
         XtAddEventHandler(QBG[i][j].id,
 
500
                        EnterWindowMask | LeaveWindowMask,
 
501
                        False, HandleEnter,
 
502
                        (XtPointer)&QBG[i][j]);
 
503
 
 
504
/*          XtRealizeWidget(QBG[i][j].bgid); */
 
505
         XtManageChild(QBG[i][j].bgid);
 
506
         
 
507
/*
 
508
         XtAddCallback(QBG[i][j].id, XmNarmCallback,
 
509
                           qmonQueueShowLoadCB, (XtPointer)&QBG[i][j]); 
 
510
         XtAddCallback(QBG[i][j].id, XmNdisarmCallback,
 
511
                           qmonQueueShowLoadCB, (XtPointer)&QBG[i][j]); 
 
512
*/    
 
513
      }
 
514
   }
 
515
 
 
516
   DEXIT;
 
517
}
 
518
 
 
519
 
 
520
/*-------------------------------------------------------------------------*/
 
521
static void qmonQueueHash(
 
522
lList *new_ql,
 
523
lList *new_hl 
 
524
) {
 
525
 
 
526
   static lList *prev_ql = NULL;
 
527
   static lList *prev_hl = NULL;
 
528
   lListElem *qep;
 
529
   tQueueIcon *queueIcon;
 
530
   long id;
 
531
   const char *qname, *qhostname;
 
532
   Boolean already_hashed;
 
533
   
 
534
   DENTER(GUI_LAYER, "qmonQueueHash");
 
535
 
 
536
   /* Create QueueHashTable if necessary */
 
537
   if (!QueueHashTable)
 
538
      QueueHashTable = XmtHashTableCreate(5);
 
539
 
 
540
   for_each(qep, new_ql) {
 
541
 
 
542
      qname = lGetString(qep, CQ_name);
 
543
      /* quarkify  CQ_name */
 
544
      id = (long) XrmStringToQuark(qname);
 
545
      
 
546
      /*
 
547
       * if the queue has already been hashed XmtHashTableLookup()
 
548
       * returns True 
 
549
       * 
 
550
       */
 
551
      already_hashed = XmtHashTableLookup(QueueHashTable,
 
552
                                          (XtPointer)id,
 
553
                                          (XtPointer*) &queueIcon);
 
554
      if (already_hashed) {
 
555
         queueIcon->qp = qep;
 
556
#ifdef FIXME         
 
557
         if (!queueIcon->arch)
 
558
            queueIcon->arch = qmonQueueGetArch(qhostname);
 
559
#endif            
 
560
      }
 
561
      else {
 
562
         /* create a new tQueueIcon structure */
 
563
         queueIcon = (tQueueIcon *)XtMalloc(sizeof(tQueueIcon));
 
564
         /* initialize */
 
565
         queueIcon->quark = id;
 
566
         queueIcon->grid_x = 0;
 
567
         queueIcon->grid_y = 0;
 
568
         queueIcon->selected = False;
 
569
         queueIcon->deleted = False;
 
570
         queueIcon->pixmap = 0;
 
571
         queueIcon->arch = "solaris"; /* qmonQueueGetArch(qhostname); */
 
572
         queueIcon->qp = qep; 
 
573
         XmtHashTableStore(QueueHashTable, 
 
574
                           (XtPointer) id, 
 
575
                           (XtPointer) queueIcon);
 
576
      }
 
577
      
 
578
      /* remove element from previous ql */
 
579
      lDelElemStr(&prev_ql, CQ_name, qname);
 
580
   }
 
581
 
 
582
   /* 
 
583
   ** remove the no longer used Hash entries 
 
584
   ** free the tQueueIcon structs
 
585
   */
 
586
   for_each(qep, prev_ql) {
 
587
      qname = lGetString(qep, CQ_name);
 
588
      id = (long) XrmStringToQuark(qname);
 
589
      if (XmtHashTableLookup( QueueHashTable, (XtPointer) id,
 
590
                                 (XtPointer *)&queueIcon)) {
 
591
         qmonQueueRemove(queueIcon);
 
592
      }
 
593
   }
 
594
 
 
595
   /*
 
596
   ** free the previously referenced queue elements
 
597
   */
 
598
   lFreeList(&prev_ql);
 
599
   lFreeList(&prev_hl);
 
600
 
 
601
   /* now the new_ql becomes the prev_ql */
 
602
   prev_ql = new_ql;
 
603
   prev_hl = new_hl;
 
604
   
 
605
/*    XmtHashTableForEach(QueueHashTable, showQueueHashTable); */
 
606
   
 
607
   DEXIT;
 
608
}
 
609
 
 
610
/*-------------------------------------------------------------------------*/
 
611
static void qmonQueueRemove(
 
612
tQueueIcon *qI 
 
613
) {
 
614
   DENTER(GUI_LAYER, "qmonQueueRemove");
 
615
 
 
616
   XmtHashTableDelete(QueueHashTable, (XtPointer)qI->quark);
 
617
   
 
618
   /* 
 
619
   ** free architecture entry 
 
620
   */
 
621
#ifdef FIXME   
 
622
   if (qI->arch)
 
623
      XtFree((char*) qI->arch);
 
624
#endif   
 
625
   qI->arch = NULL;
 
626
 
 
627
   /*
 
628
   ** release reference to queue element
 
629
   ** queue element is freed in qmonQueueHash
 
630
   */
 
631
   qI->qp = NULL;
 
632
 
 
633
   /*
 
634
   ** free tQueueIcon struct
 
635
   */
 
636
   XtFree((char*)qI);
 
637
 
 
638
   DEXIT;
 
639
}
 
640
 
 
641
 
 
642
/*-------------------------------------------------------------------------*/
 
643
static void qmonQueueSetPos(
 
644
lList *qlp 
 
645
) {
 
646
   lListElem *ep = NULL;
 
647
   int grid_x = 0;
 
648
   int grid_y = 0;
 
649
   long q;
 
650
   const char *qname = NULL;
 
651
   tQueueIcon *qI = NULL;
 
652
   int i, j;
 
653
   int max_count = 0;
 
654
   
 
655
   DENTER(GUI_LAYER, "qmonQueueSetPos");
 
656
 
 
657
   /*
 
658
    * every element in the list is attached to a special grid position
 
659
    */
 
660
 
 
661
   /* 
 
662
   ** delete previously attached queues  
 
663
   ** we release here only the references, the corresponding data
 
664
   ** are freed in qmonQueueHash
 
665
   */
 
666
   for (i=0; i<QUEUE_MAX_VERT; i++)
 
667
      for (j=0; j<QUEUE_MAX_HORIZ; j++) 
 
668
         QBG[i][j].qI = NULL; 
 
669
 
 
670
   for_each(ep, qlp) {
 
671
 
 
672
      /*
 
673
      ** FIXME: workaround for exceeding the max number of queues
 
674
      **        exceeding queues are not displayed
 
675
      */
 
676
      max_count++;
 
677
      if (max_count >= QUEUE_MAX_HORIZ * QUEUE_MAX_VERT)
 
678
            break; 
 
679
 
 
680
      /* lookup queue struct qI */
 
681
      qname = lGetString(ep, CQ_name);
 
682
      q = (long) XrmStringToQuark(qname);
 
683
/* printf("----> q = %ld\n", q); */
 
684
/*    XmtHashTableForEach(QueueHashTable, showQueueHashTable); */
 
685
/* printf("---->\n"); */
 
686
 
 
687
      if (!XmtHashTableLookup(QueueHashTable, (XtPointer) q, (XtPointer*) &qI))
 
688
         fprintf(stderr, "++++++++++++Hash Table Failure++++++++++++++++\n");
 
689
      
 
690
      /* the algorithm to attach the q to a special pos */
 
691
      if (grid_x == QUEUE_MAX_HORIZ) {
 
692
         grid_x = 0;
 
693
         grid_y++;
 
694
      }
 
695
 
 
696
      if (qI) {
 
697
         qI->grid_x = grid_x++;
 
698
         qI->grid_y = grid_y;
 
699
         /* map/unmap Buttons if qI is set/NULL; reset selection state */
 
700
         QBG[qI->grid_y][qI->grid_x].qI = qI; 
 
701
      }   
 
702
   }
 
703
 
 
704
   /* loop through the button list and map/unmap */
 
705
   for (i=0; i<QUEUE_MAX_VERT; i++) {
 
706
      for (j=0; j<QUEUE_MAX_HORIZ; j++) {
 
707
         if (QBG[i][j].qI)
 
708
            XtSetMappedWhenManaged(QBG[i][j].id, True);
 
709
         else
 
710
            XtSetMappedWhenManaged(QBG[i][j].id, False);
 
711
 
 
712
         if (QBG[i][j].qI && QBG[i][j].qI->selected 
 
713
            && XtWindow(QBG[i][j].bgid))
 
714
            qmonChangeBackground(QBG[i][j].bgid, True);
 
715
         else
 
716
            qmonChangeBackground(QBG[i][j].bgid, False);
 
717
         /* we need qI->deleted in qmonDrawQueueButton */
 
718
         if (QBG[i][j].qI && XtWindow(QBG[i][j].id))
 
719
            qmonDrawQueueButton(QBG[i][j].id, 
 
720
                               (XtPointer) &QBG[i][j], 
 
721
                               (XtPointer) NULL);
 
722
 
 
723
         if (QBG[i][j].qI && QBG[i][j].qI->deleted) 
 
724
            XtSetSensitive(QBG[i][j].id, False);
 
725
         else
 
726
            XtSetSensitive(QBG[i][j].id, True);
 
727
      } 
 
728
   }
 
729
   XmUpdateDisplay(AppShell);
 
730
   
 
731
/*    XmtHashTableForEach(QueueHashTable, showQueueHashTable); */
 
732
   
 
733
   DEXIT;
 
734
}
 
735
 
 
736
 
 
737
/*-------------------------------------------------------------------------*/
 
738
static void HandleEnter(
 
739
Widget w,
 
740
XtPointer cld,
 
741
XEvent *ev,
 
742
Boolean *ctd 
 
743
) {
 
744
   tQueueButton *qB = (tQueueButton*)cld;
 
745
 
 
746
 
 
747
   char info[BUFSIZ];
 
748
   String browser_info;
 
749
   
 
750
   DENTER(GUI_LAYER, "HandleEnter");
 
751
 
 
752
   if (ev->type == EnterNotify) {
 
753
      if (qB->qI) { 
 
754
         if (qmonBrowserObjectEnabled(BROWSE_QUEUE)) {
 
755
            sprintf(info, "+++++++++++++++++++++++++++++++++++++++++++\n");  
 
756
            qmonBrowserShow(info);
 
757
            {
 
758
               lListElem *qp;
 
759
               for_each(qp, lGetList(qB->qI->qp, CQ_qinstances)) {
 
760
                  browser_info = qmonQueueShowBrowserInfo(qp); 
 
761
               }
 
762
            }   
 
763
            qmonBrowserShow(browser_info);
 
764
            sprintf(info, "+++++++++++++++++++++++++++++++++++++++++++\n");  
 
765
            qmonBrowserShow(info);
 
766
         }
 
767
         /*
 
768
         if (show_load) {
 
769
            qmonQueueShowLoadEvent(w, cld, ev);
 
770
         }
 
771
         */
 
772
      }
 
773
   }
 
774
   
 
775
#if 0   
 
776
   if (ev->type == LeaveNotify) {
 
777
      qmonQueueDeleteLoadEvent(w, cld, ev);
 
778
   }   
 
779
#endif   
 
780
      
 
781
   DEXIT;
 
782
}
 
783
 
 
784
/*-------------------------------------------------------------------------*/
 
785
static void qmonQueueShowLoadEvent(
 
786
Widget w,
 
787
XtPointer cld,
 
788
XEvent *event 
 
789
) {
 
790
   tQueueButton *qb = (tQueueButton*) cld;
 
791
   Widget parent = w;
 
792
   static Widget lmon=0;
 
793
   static Widget matrix;
 
794
   
 
795
   DENTER(GUI_LAYER, "qmonQueueShowLoadEvent");
 
796
   
 
797
   if (!qb->qI) {
 
798
      DEXIT;
 
799
      return;
 
800
   }
 
801
 
 
802
   parent = XmtNameToWidget(w, "~*queue_sw");
 
803
 
 
804
   if (!lmon)
 
805
      lmon = XmtBuildQueryDialog(parent, "lmon_shell", 
 
806
                                       NULL, 0,
 
807
                                       "lmon_matrix", &matrix,
 
808
                                       NULL);
 
809
 
 
810
#if 0
 
811
   qmonQueueSetLoad(matrix, qb->qI->qp);
 
812
   XtManageChild(lmon);
 
813
#else
 
814
   updateQueueListCB(w, NULL, NULL);
 
815
   XtManageChild(lmon);
 
816
   qmonQueueSetLoad(matrix, qb->qI->qp);
 
817
#endif
 
818
 
 
819
   XtAddEventHandler(XtParent(lmon), StructureNotifyMask, False, 
 
820
                        SetMinShellSize, (XtPointer) SHELL_WIDTH);
 
821
   XtAddEventHandler(XtParent(lmon), StructureNotifyMask, False, 
 
822
                        SetMaxShellSize, (XtPointer) SHELL_WIDTH);
 
823
 
 
824
   DEXIT;
 
825
}
 
826
 
 
827
/*-------------------------------------------------------------------------*/
 
828
static void qmonQueueSetLoad(
 
829
Widget matrix,
 
830
lListElem *qep 
 
831
) {
 
832
   static char info[10000];
 
833
   lListElem *ep;
 
834
   lList *ncl = NULL;
 
835
   lList *ehl = NULL;
 
836
   lList *cl = NULL; 
 
837
   StringConst new_row[3];
 
838
   int rows;
 
839
   float fval;
 
840
   XmString xstr;
 
841
 
 
842
   DENTER(GUI_LAYER, "qmonQueueSetLoad");
 
843
 
 
844
   ehl = qmonMirrorList(SGE_EXECHOST_LIST);
 
845
   cl = qmonMirrorList(SGE_CENTRY_LIST);
 
846
 
 
847
   correct_capacities(ehl, cl);
 
848
   queue_complexes2scheduler(&ncl, qep, ehl, cl);
 
849
 
 
850
   sprintf(info, "%s %s", XmtLocalize(matrix, "Attributes for queue", "Attributes for queue"), lGetString(qep, QU_qname));
 
851
 
 
852
   xstr = XmtCreateXmString(info);
 
853
   XtVaSetValues(XtParent(matrix), XmNdialogTitle, xstr, NULL);
 
854
   XmStringFree(xstr);
 
855
 
 
856
   rows = XbaeMatrixNumRows(matrix);
 
857
   XbaeMatrixDeleteRows(matrix, 0, rows);
 
858
 
 
859
   rows = 0;
 
860
   for_each_rev (ep, ncl) {
 
861
      int n;
 
862
      u_long32 type;
 
863
      char unit;
 
864
      StringConst name;
 
865
      StringConst slot_limit;
 
866
      StringConst job_limit;
 
867
      if (!(name = lGetString(ep, CE_name))) 
 
868
         continue;
 
869
      /* don't view value entry from complex */
 
870
      slot_limit = (lGetUlong(ep, CE_dominant)&DOMINANT_TYPE_VALUE)?
 
871
                        NULL:lGetString(ep, CE_stringval);
 
872
      type = lGetUlong(ep, CE_valtype);
 
873
      if (slot_limit && (type == TYPE_MEM || type == TYPE_DOUBLE) &&
 
874
         (n=sscanf(slot_limit, "%f%c", &fval, &unit))>=1) {
 
875
         sprintf(info, "%8.3f%c", fval, (n>1) ? unit : '\0');
 
876
         lSetString(ep, CE_stringval, info);
 
877
         slot_limit = lGetString(ep, CE_stringval);
 
878
      }
 
879
      if (slot_limit)
 
880
         while (*slot_limit && isspace(*slot_limit))
 
881
            slot_limit++;
 
882
 
 
883
      job_limit = lGetString(ep, CE_pj_stringval);
 
884
      type = lGetUlong(ep, CE_valtype);
 
885
      if (job_limit && (type == TYPE_MEM || type == TYPE_DOUBLE) &&
 
886
         (n = sscanf(job_limit, "%f%c", &fval, &unit))>=1) {
 
887
         sprintf(info, "%8.3f%c", fval, (n>1) ? unit : '\0');
 
888
         lSetString(ep, CE_pj_stringval, info);
 
889
         job_limit = lGetString(ep, CE_pj_stringval);
 
890
      }
 
891
 
 
892
      if (job_limit)
 
893
         while (*job_limit && isspace(*job_limit))
 
894
            job_limit++;
 
895
 
 
896
      new_row[0] = name; 
 
897
      new_row[1] = slot_limit ? slot_limit : "";
 
898
      new_row[2] = job_limit ? job_limit : ""; 
 
899
      /* FIX_CONST_GUI */
 
900
      XbaeMatrixAddRows(matrix, 0, (String*) new_row, NULL, NULL, 1); 
 
901
 
 
902
      rows++;
 
903
   }
 
904
 
 
905
   lFreeList(&ncl);
 
906
   
 
907
   DEXIT;
 
908
}
 
909
 
 
910
/*-------------------------------------------------------------------------*/
 
911
static String qmonQueueShowBrowserInfo(
 
912
lListElem *qep 
 
913
) {
 
914
 
 
915
   static char info[60000];
 
916
   lListElem *ep;
 
917
   int qtype;
 
918
   const char *str, *str2;
 
919
 
 
920
   DENTER(GUI_LAYER, "qmonQueueShowBrowserInfo");
 
921
 
 
922
   sprintf(info, WIDTH"%s\n", "\n","Queue:", lGetString(qep, QU_full_name));
 
923
 
 
924
   qtype = lGetUlong(qep, QU_qtype);
 
925
 
 
926
   {
 
927
      dstring type_buffer = DSTRING_INIT;
 
928
 
 
929
      qinstance_print_qtype_to_dstring(qep, &type_buffer, false);
 
930
      sprintf(info, WIDTH"%s\n", info, "Type:", 
 
931
              sge_dstring_get_string(&type_buffer));
 
932
      sge_dstring_free(&type_buffer);
 
933
   }
 
934
   sprintf(info, WIDTH"%d\n", info, "Sequence Nr:", 
 
935
                           (int)lGetUlong(qep, QU_seq_no));
 
936
 
 
937
   str = lGetString(qep, QU_tmpdir);
 
938
   sprintf(info, WIDTH"%s\n", info, "tmpdir:", str ? str : ""); 
 
939
   str = lGetString(qep, QU_shell);
 
940
   sprintf(info, WIDTH"%s\n", info, "Shell:", str ? str : ""); 
 
941
   sprintf(info, WIDTH"%d\n", info, "Job Slots:", 
 
942
                     (int)lGetUlong(qep, QU_job_slots));
 
943
   sprintf(info, WIDTH"%d\n", info, "Job Slots Used:", qinstance_slots_used(qep));
 
944
   str = lGetString(qep, QU_priority);
 
945
   sprintf(info, WIDTH"%s\n", info, "Priority:", str?str:"");
 
946
   sprintf(info, WIDTH"", info, "Load Thresholds:");
 
947
   for_each(ep, lGetList(qep, QU_load_thresholds)) {
 
948
      str = lGetString(ep, CE_name);
 
949
      str2 = lGetString(ep, CE_stringval);
 
950
      sprintf(info, "%s%s = %s ", info, str?str:"", str2?str2:"");
 
951
   }
 
952
   sprintf(info, "%s\n", info); 
 
953
 
 
954
   sprintf(info, WIDTH"%s\n", info, "Rerun Job:", 
 
955
                     lGetBool(qep, QU_rerun) ? "True" : "False");
 
956
 
 
957
   str = lGetString(qep, QU_notify);
 
958
   sprintf(info, WIDTH"%s\n", info, "Notify Job Interval:",  str ? str : ""); 
 
959
 
 
960
   str = lGetString(qep, QU_processors);
 
961
   sprintf(info, WIDTH"%s\n", info, "Processors:", str ? str : ""); 
 
962
 
 
963
   str = lGetString(qep, QU_s_rt);
 
964
   sprintf(info, WIDTH"%s\n", info, "Soft Real Time:", str ? str : ""); 
 
965
   str = lGetString(qep, QU_h_rt);
 
966
   sprintf(info, WIDTH"%s\n", info, "Hard Real Time:", str ? str : ""); 
 
967
   str = lGetString(qep, QU_s_cpu);
 
968
   sprintf(info, WIDTH"%s\n", info, "Soft Cpu:", str ? str : ""); 
 
969
   str = lGetString(qep, QU_h_cpu);
 
970
   sprintf(info, WIDTH"%s\n", info, "Hard Cpu:", str ? str : "");
 
971
   str = lGetString(qep, QU_s_fsize);
 
972
   sprintf(info, WIDTH"%s\n", info, "Soft File Size:", str ? str : "");
 
973
   str = lGetString(qep, QU_h_fsize);
 
974
   sprintf(info, WIDTH"%s\n", info, "Hard File Size:", str ? str : "");
 
975
   str = lGetString(qep, QU_s_data);
 
976
   sprintf(info, WIDTH"%s\n", info, "Soft Data Size:", str ? str : "");
 
977
   str = lGetString(qep, QU_h_data);
 
978
   sprintf(info, WIDTH"%s\n", info, "Hard Data Size:", str ? str : "");
 
979
   str = lGetString(qep, QU_s_stack);
 
980
   sprintf(info, WIDTH"%s\n", info, "Soft Stack Size:", str ? str : "");
 
981
   str = lGetString(qep, QU_h_stack);
 
982
   sprintf(info, WIDTH"%s\n", info, "Hard Stack Size:", str ? str : "");
 
983
   str = lGetString(qep, QU_s_core);
 
984
   sprintf(info, WIDTH"%s\n", info, "Soft Core Size:", str ? str : "");
 
985
   str = lGetString(qep, QU_h_core);
 
986
   sprintf(info, WIDTH"%s\n", info, "Hard Core Size:", str ? str : "");
 
987
   str = lGetString(qep, QU_s_rss);
 
988
   sprintf(info, WIDTH"%s\n", info, "Soft Resident Set Size:", str ? str : "");
 
989
   str = lGetString(qep, QU_h_rss);
 
990
   sprintf(info, WIDTH"%s\n", info, "Hard Resident Set Size:", str ? str : "");
 
991
 
 
992
   str = lGetString(qep, QU_min_cpu_interval);
 
993
   sprintf(info, WIDTH"%s\n", info, "Min Cpu Interval:", str ? str : "");
 
994
 
 
995
   sprintf(info, WIDTH"", info, "Access List:");
 
996
   for_each(ep, lGetList(qep, QU_acl)) {
 
997
      sprintf(info, "%s%s ", info, lGetString(ep, US_name));
 
998
   }
 
999
   sprintf(info, "%s\n", info); 
 
1000
   sprintf(info, WIDTH"", info, "No Access List:");
 
1001
   for_each(ep, lGetList(qep, QU_xacl)) {
 
1002
      sprintf(info, "%s%s ", info, lGetString(ep, US_name));
 
1003
   }
 
1004
   sprintf(info, "%s\n", info); 
 
1005
 
 
1006
   DPRINTF(("info is %d long\n", strlen(info)));
 
1007
   
 
1008
   DEXIT;
 
1009
   return info;
 
1010
}
 
1011
 
 
1012
/*-------------------------------------------------------------------------*/
 
1013
static void HandleButtonPress(
 
1014
Widget w,
 
1015
XtPointer cld,
 
1016
XEvent *ev,
 
1017
Boolean *ctd 
 
1018
) {
 
1019
   tQueueButton *qB = (tQueueButton*) cld;
 
1020
   
 
1021
   DENTER(GUI_LAYER, "HandleButtonPress");
 
1022
   
 
1023
   switch (ev->type) {
 
1024
      case ButtonPress:
 
1025
         switch ( ev->xbutton.button ) { 
 
1026
            case Button1:
 
1027
               if (ev->xbutton.state & ShiftMask) {
 
1028
                  qmonQueueShowLoadEvent(w, cld, ev);
 
1029
               }
 
1030
               else if (ev->xbutton.state & ControlMask) {
 
1031
                  char hostname[SGE_PATH_MAX];
 
1032
 
 
1033
                  strcpy(hostname, "global");
 
1034
                  if (qB && qB->qI && qB->qI->qp) {
 
1035
                     sge_strlcpy(hostname, lGetHost(qB->qI->qp, QU_qhostname),
 
1036
                                 SGE_PATH_MAX);
 
1037
                     strtok(hostname, ".");
 
1038
                  }
 
1039
                  qmonBrowserMessages(w, (XtPointer)hostname, NULL);
 
1040
               }
 
1041
               else {
 
1042
                  if (qB->qI) {
 
1043
                     qB->qI->selected = !(qB->qI->selected);
 
1044
                     qmonChangeBackground(qB->bgid, qB->qI->selected ); 
 
1045
                  }
 
1046
               }
 
1047
               
 
1048
               break;
 
1049
         }
 
1050
         break;
 
1051
   }
 
1052
 
 
1053
   /*
 
1054
   ** call no other event handler
 
1055
   */
 
1056
   ctd = False;
 
1057
 
 
1058
   DEXIT;
 
1059
}
 
1060
 
 
1061
/*-------------------------------------------------------------------------*/
 
1062
static void qmonChangeBackground(
 
1063
Widget w,
 
1064
int selected 
 
1065
) {
 
1066
   static int first_time = 1;
 
1067
   static Pixel background;
 
1068
   
 
1069
   DENTER(BASIS_LAYER, "qmonChangeBackground");
 
1070
   
 
1071
   if (first_time) {
 
1072
      first_time = 0;
 
1073
      XtVaGetValues( w, 
 
1074
                     XmNbackground, &background, 
 
1075
                     NULL);
 
1076
   }
 
1077
 
 
1078
   XtVaSetValues( w, 
 
1079
                  XmNbackground, selected ? QueueSelectedPixel : background, 
 
1080
                  NULL);
 
1081
 
 
1082
   DEXIT;
 
1083
}
 
1084
 
 
1085
 
 
1086
/*-------------------------------------------------------------------------*/
 
1087
static void qmonDrawQueueButton(Widget w, XtPointer cld, XtPointer cad)
 
1088
{
 
1089
   static XmFontList defaultFontList = NULL;
 
1090
   tQueueButton *qB = (tQueueButton*) cld;
 
1091
   Dimension ht, st, bw, width, height, sw, sh;
 
1092
   int sbh, sbw;
 
1093
   Window root;
 
1094
   unsigned int border_width, depth;
 
1095
   Position x, y;
 
1096
   XmString str = NULL;
 
1097
   XRectangle rect;
 
1098
   char buf[BUFSIZ];
 
1099
   char hostname[128];
 
1100
   const char *qname = NULL, *qhostname = NULL;
 
1101
   unsigned long job_slots = 0, job_slots_used = 0;
 
1102
   unsigned long alarm_set = 0, suspend_threshold_alarm = 0;
 
1103
   double load = 0.0;
 
1104
   u_long32 is_load_available = 0;
 
1105
   u_long32 used = 0;
 
1106
   u_long32 total = 0;
 
1107
   u_long32 suspend_manual = 0;
 
1108
   u_long32 suspend_threshold = 0;
 
1109
   u_long32 suspend_on_subordinate = 0;
 
1110
   u_long32 suspend_calendar = 0;
 
1111
   u_long32 unknown = 0;
 
1112
   u_long32 load_alarm = 0;
 
1113
   u_long32 disabled_manual = 0;
 
1114
   u_long32 disabled_calendar = 0;
 
1115
   u_long32 ambiguous = 0;
 
1116
   u_long32 orphaned = 0;
 
1117
   u_long32 error = 0;
 
1118
   u_long32 available = 0;
 
1119
   u_long32 temp_disabled = 0;
 
1120
   u_long32 manual_intervention = 0;
 
1121
   int i; 
 
1122
   GC draw_gc = qb_gc;
 
1123
   lList *ehl = NULL;
 
1124
   lList *cl = NULL;
 
1125
   lListElem *q = NULL;
 
1126
   
 
1127
   DENTER(GUI_LAYER, "qmonDrawQueueButton");
 
1128
 
 
1129
   if (!defaultFontList) {
 
1130
      XmFontList theFontList = NULL;
 
1131
      XmFontContext fc = NULL;
 
1132
      XtVaGetValues(w, XmNfontList, &theFontList, NULL);
 
1133
      if (XmFontListInitFontContext(&fc, theFontList)) {
 
1134
         XmFontListEntry entry;
 
1135
         while ((entry = XmFontListNextEntry(fc))) {
 
1136
            char *tag = XmFontListEntryGetTag(entry);
 
1137
            DPRINTF(("tag = %s\n", tag ? tag : ""));
 
1138
            if (!strcmp(tag, "QUEUEICON")){
 
1139
               defaultFontList = XmFontListAppendEntry(NULL, entry); 
 
1140
               break;
 
1141
            }   
 
1142
         }     
 
1143
         XmFontListFreeFontContext(fc);
 
1144
      }
 
1145
      if (!defaultFontList) {
 
1146
         XmFontListEntry entry = XmFontListEntryLoad(XtDisplay(w),
 
1147
                                    "-*-helvetica-medium-r-*-*-*-60-*-*-*-*-*-*",
 
1148
                                    XmFONT_IS_FONT,
 
1149
                                    XmFONTLIST_DEFAULT_TAG);
 
1150
         defaultFontList = XmFontListAppendEntry(NULL, entry);
 
1151
         XmFontListEntryFree(&entry);
 
1152
      }   
 
1153
   }
 
1154
 
 
1155
   /* Button active ? */ 
 
1156
   if (qB->qI) {
 
1157
      /* 
 
1158
      ** get info from queue 
 
1159
      */
 
1160
      if (qB->qI->qp) {
 
1161
         ehl = qmonMirrorList(SGE_EXECHOST_LIST);
 
1162
         cl = qmonMirrorList(SGE_CENTRY_LIST);
 
1163
         q = qB->qI->qp;
 
1164
 
 
1165
         qname     = lGetString(q, CQ_name);
 
1166
#ifdef FIXME         
 
1167
         cqueue_calculate_summary(q, ehl, cl, 
 
1168
                                  &load, &is_load_available, &used, &total,
 
1169
                                  &suspend_manual, &suspend_threshold,
 
1170
                                  &suspend_on_subordinate, &suspend_calendar,
 
1171
                                  &unknown, &load_alarm, &disabled_manual,
 
1172
                                  &disabled_calendar, &ambiguous, &orphaned,
 
1173
                                  &error, &available, &temp_disabled,
 
1174
                                  &manual_intervention);
 
1175
 
 
1176
         DPRINTF(("<<Queue: %s/%f/%d/%d>>\n", qname, load, used, total);
 
1177
#endif         
 
1178
      } 
 
1179
      else {
 
1180
         DPRINTF(("Queue Button Grid corrupted\n"));
 
1181
         DEXIT;
 
1182
         return;   
 
1183
      }
 
1184
      
 
1185
      /*
 
1186
      ** get the right pixmap and get the size
 
1187
      */
 
1188
      qB->qI->pixmap = qmonGetIcon(qmonQueueGetSymbol(qB->qI->arch));
 
1189
      XGetGeometry( XtDisplay(qB->id), 
 
1190
                              qB->qI->pixmap,
 
1191
                              &root, &(qB->qI->x), &(qB->qI->y), 
 
1192
                              &(qB->qI->icon_width), &(qB->qI->icon_height), 
 
1193
                              &border_width, &depth );
 
1194
      /*
 
1195
      ** get the dimensions of the button
 
1196
      */
 
1197
      XtVaGetValues( w,
 
1198
                     XmNwidth, &width,
 
1199
                     XmNheight, &height,
 
1200
                     XmNborderWidth, &bw,
 
1201
                     XmNhighlightThickness, &ht,
 
1202
                     XmNshadowThickness, &st,
 
1203
                     NULL);
 
1204
 
 
1205
      bw = bw + st + ht;
 
1206
 
 
1207
      if (bw == 0)
 
1208
         bw = 2;
 
1209
 
 
1210
      /*
 
1211
      ** Clear the effective drawing area
 
1212
      */
 
1213
      XClearArea(XtDisplay(w), XtWindow(w), bw, bw, width-2*bw, 
 
1214
                  height-2*bw, False);
 
1215
 
 
1216
      /*
 
1217
      ** Center the icon horizontally
 
1218
      */
 
1219
      x =  (width - qB->qI->icon_width)/2; 
 
1220
      XCopyArea( XtDisplay(w), qB->qI->pixmap, XtWindow(w),
 
1221
                  DefaultGCOfScreen(XtScreen(w)), 
 
1222
                  0, 0, qB->qI->icon_width - bw, qB->qI->icon_height - bw, 
 
1223
                  bw + x, bw);
 
1224
 
 
1225
      /* draw a string into the pixmap */
 
1226
      sprintf(buf, "@f[SMALL]%s\nSlots: " sge_u32 "("sge_u32")", 
 
1227
                  qname, used, total);
 
1228
                  
 
1229
      str = XmtCreateXmString(buf);
 
1230
      XmStringExtent(defaultFontList, str, &sw, &sh);
 
1231
      rect.x = bw;
 
1232
      rect.y = bw;
 
1233
      rect.width = width - 2 * bw;
 
1234
      rect.height = height - 2 * bw;
 
1235
 
 
1236
#ifdef FIXME
 
1237
      /* if string is to long use unqualified hostname */
 
1238
      if (sw > rect.width) {
 
1239
         XmStringFree(str);
 
1240
         for (i=0; qhostname[i] != '.' && i < strlen(qhostname) && i<128; i++) 
 
1241
            hostname[i] = qhostname[i];
 
1242
         hostname[i] = '\0';
 
1243
         sprintf(buf,"@f[SMALL]%s\n%s\nSlots: %ld (%ld)", 
 
1244
                  qname, hostname, job_slots_used, 
 
1245
                  job_slots);
 
1246
         str = XmtCreateXmString(buf);
 
1247
         XmStringExtent(defaultFontList, str, &sw, &sh);
 
1248
      }
 
1249
#endif
 
1250
 
 
1251
      /*
 
1252
      ** draw the status bar if necessary
 
1253
      */
 
1254
      sbh = (width - 2 * bw - qB->qI->icon_height - sh)/2;
 
1255
      sbw = (width - 2 * bw)/9;
 
1256
      
 
1257
      x = bw + sbw; 
 
1258
      y = height - 2 * bw - sbh;
 
1259
      
 
1260
#ifdef FIXME      
 
1261
      if (!qinstance_state_is_unknown(q)) {
 
1262
 
 
1263
         for (i=0; i<7; i++) {
 
1264
            XDrawRectangle(XtDisplay(w), XtWindow(w), qb_gc, 
 
1265
                              x + sbw * i, y,
 
1266
                              sbw - 1, sbh);
 
1267
         }
 
1268
 
 
1269
         /* jobs are running */
 
1270
         if (job_slots_used)
 
1271
            XFillRectangle(XtDisplay(w), XtWindow(w), running_gc,
 
1272
                              x + 1, y + 1,
 
1273
                              sbw - 1, sbh - 1); 
 
1274
 
 
1275
         /* queue suspended */
 
1276
         if (qinstance_state_is_susp_on_sub(q))
 
1277
            XFillRectangle(XtDisplay(w), XtWindow(w), suspend_gc,
 
1278
                              x + 1 * sbw + 1, y + 1,
 
1279
                              sbw - 2, (sbh/2 + sbh % 2)); 
 
1280
 
 
1281
         /* queue suspended */
 
1282
         if (suspend_threshold_alarm) {
 
1283
            XFillRectangle(XtDisplay(w), XtWindow(w), suspend_gc,
 
1284
                              x + 1 * sbw + 1, y + (sbh/2 + sbh % 2),
 
1285
                              sbw - 2, (sbh/2 + sbh % 2 - 1));
 
1286
         }
 
1287
         /* queue suspended */
 
1288
         if (qinstance_state_is_manual_suspended(q)) 
 
1289
            XFillRectangle(XtDisplay(w), XtWindow(w), suspend_gc,
 
1290
                              x + 1 * sbw + 1, y + 1,
 
1291
                              sbw - 1, sbh - 1); 
 
1292
 
 
1293
         /* queue disabled */
 
1294
         if (qinstance_state_is_manual_disabled(q))
 
1295
            XFillRectangle(XtDisplay(w), XtWindow(w), disable_gc,
 
1296
                              x + 2 * sbw + 1, y + 1,
 
1297
                              sbw - 1, sbh - 1); 
 
1298
         if (alarm_set)
 
1299
            XFillRectangle(XtDisplay(w), XtWindow(w), alarm_gc,
 
1300
                              x + 3 * sbw + 1, y + 1,
 
1301
                              sbw - 1, sbh - 1); 
 
1302
 
 
1303
         if (qinstance_state_is_error(q))
 
1304
            XFillRectangle(XtDisplay(w), XtWindow(w), error_gc,
 
1305
                              x + 4 * sbw + 1, y + 1,
 
1306
                              sbw - 1, sbh - 1); 
 
1307
 
 
1308
         if (qinstance_state_is_cal_suspended(q))
 
1309
            XFillRectangle(XtDisplay(w), XtWindow(w), calsuspend_gc,
 
1310
                              x + 5 * sbw + 1, y + 1,
 
1311
                              sbw - 1, sbh - 1); 
 
1312
 
 
1313
         if (qinstance_state_is_cal_disabled(q))
 
1314
            XFillRectangle(XtDisplay(w), XtWindow(w), caldisable_gc,
 
1315
                              x + 6 * sbw + 1, y + 1,
 
1316
                              sbw - 2, sbh - 1); 
 
1317
 
 
1318
      }
 
1319
         
 
1320
      
 
1321
      x = rect.x + (rect.width - sw)/2;
 
1322
      y = height - sh - 2 * sbh - bw;
 
1323
      
 
1324
      if (qinstance_state_is_unknown(q))
 
1325
         draw_gc = error_gc;
 
1326
      else
 
1327
         draw_gc = qb_gc;
 
1328
#endif
 
1329
 
 
1330
      qmonXmStringDraw( XtDisplay(w), XtWindow(w), draw_gc, x, y, 
 
1331
                        defaultFontList, str, XmALIGNMENT_CENTER , 
 
1332
                        &rect, &sw, &sh) ;
 
1333
      XmStringFree(str); 
 
1334
      if (qB->qI->deleted) {
 
1335
         XPoint p[4];
 
1336
         p[0].x = bw;
 
1337
         p[0].y = bw;
 
1338
         p[1].x = width - bw;
 
1339
         p[1].y = height - bw;
 
1340
         p[2].x = width - bw;
 
1341
         p[2].y = bw;
 
1342
         p[3].x = bw;
 
1343
         p[3].y = height - bw;
 
1344
/*          XSetForeground(XtDisplay(w), qb_gc, 50);     */
 
1345
         XDrawLines( XtDisplay(w), XtWindow(w), qb_gc, 
 
1346
                     p, XtNumber(p), CoordModeOrigin );
 
1347
      }
 
1348
   } 
 
1349
   DEXIT;
 
1350
}
 
1351
 
 
1352
/*-------------------------------------------------------------------------*/
 
1353
static void qmonQueueModify(Widget w, XtPointer cld, XtPointer cad)
 
1354
{
 
1355
   int n = 0, i, j;
 
1356
   lList *lp = NULL;
 
1357
   
 
1358
   DENTER(GUI_LAYER, "qmonQueueModify");
 
1359
 
 
1360
   /* 
 
1361
   ** get the selected queues 
 
1362
   */
 
1363
   for (i=0; i<QUEUE_MAX_VERT; i++) {
 
1364
      for (j=0; j<QUEUE_MAX_HORIZ; j++) {
 
1365
         if (QBG[i][j].qI && QBG[i][j].qI->selected) {
 
1366
            if (!lp) {
 
1367
               lp = lCreateList("DQ", CQ_Type);
 
1368
            }
 
1369
            lAppendElem(lp, lCopyElem(QBG[i][j].qI->qp));
 
1370
         }
 
1371
      }
 
1372
   }
 
1373
 
 
1374
   if (lp && ((n = lGetNumberOfElem(lp)) == 1)) {
 
1375
      /* 
 
1376
      ** open up the queue configuration dialog and give him a list 
 
1377
      ** of queues to modify
 
1378
      */
 
1379
      qmonQCPopup(w, (XtPointer)lGetString(lFirst(lp), CQ_name), NULL);
 
1380
   }
 
1381
   else {
 
1382
      if (n > 1)
 
1383
         qmonMessageShow(w, True, "@{Select only one queue !}");
 
1384
      else
 
1385
         qmonMessageShow(w, True, "@{To modify a queue select this queue !}");
 
1386
   }
 
1387
 
 
1388
   DEXIT;
 
1389
}
 
1390
 
 
1391
 
 
1392
/*-------------------------------------------------------------------------*/
 
1393
static void qmonQueueDeleteQuick(Widget w, XtPointer cld, XtPointer cad)
 
1394
{
 
1395
   int i, j;
 
1396
   lList *lp = NULL;
 
1397
   lList *alp = NULL;
 
1398
   static lEnumeration *what = NULL;
 
1399
   Boolean status, answer;
 
1400
   
 
1401
   
 
1402
   DENTER(GUI_LAYER, "qmonQueueDeleteQuick");
 
1403
   
 
1404
   
 
1405
   /* 
 
1406
   ** we need only the queue name 
 
1407
   */
 
1408
   if (!what)
 
1409
      what = lWhat("%T(%I)", CQ_Type, CQ_name);
 
1410
   
 
1411
   /* 
 
1412
   ** get the selected queues 
 
1413
   */
 
1414
   for (i=0; i<QUEUE_MAX_VERT; i++) {
 
1415
      for (j=0; j<QUEUE_MAX_HORIZ; j++) {
 
1416
         if (QBG[i][j].qI && QBG[i][j].qI->selected) {
 
1417
            if (!lp) {
 
1418
               lp = lCreateList("DQ", CQ_Type);
 
1419
            }
 
1420
            lAppendElem(lp, lCopyElem(QBG[i][j].qI->qp));
 
1421
         }
 
1422
      }
 
1423
   }
 
1424
 
 
1425
   if (lp && (lGetNumberOfElem(lp) > 0)) {
 
1426
      status = XmtAskForBoolean(w, "xmtBooleanDialog", 
 
1427
                     "@{queue.askdel.Do you really want to\ndelete the selected queues ?}", 
 
1428
                     "@{Delete}", "@{Cancel}", NULL, XmtNoButton, XmDIALOG_WARNING, 
 
1429
                     False, &answer, NULL);
 
1430
         
 
1431
      if (answer) { 
 
1432
         alp = qmonDelList(SGE_CQUEUE_LIST, qmonMirrorListRef(SGE_CQUEUE_LIST), 
 
1433
                           CQ_name, &lp, NULL, what);
 
1434
 
 
1435
         qmonMessageBox(w, alp, 0);
 
1436
 
 
1437
         lFreeList(&alp);
 
1438
      }
 
1439
      lFreeList(&lp);
 
1440
 
 
1441
      updateQueueList();
 
1442
/*       updateQCQ(); */
 
1443
   }
 
1444
 
 
1445
   DEXIT;
 
1446
}
 
1447
 
 
1448
/*-------------------------------------------------------------------------*/
 
1449
static void qmonQueueChangeState(Widget w, XtPointer cld, XtPointer cad)
 
1450
{
 
1451
   int i, j;
 
1452
   lList *ql = NULL;
 
1453
   lList *alp = NULL;
 
1454
   lListElem *qep = NULL;
 
1455
   int force = 0;
 
1456
   long action = (long) cld;
 
1457
   Widget force_toggle;
 
1458
   
 
1459
   DENTER(GUI_LAYER, "qmonQueueChangeState");
 
1460
 
 
1461
   /*
 
1462
   ** cld contains the action we need, check if a force is involved
 
1463
   */
 
1464
   force_toggle = XmtNameToWidget(w, "*queue_force"); 
 
1465
   force = XmToggleButtonGetState(force_toggle);
 
1466
   
 
1467
   /* 
 
1468
   ** get the selected queues 
 
1469
   */
 
1470
   for (i=0; i<QUEUE_MAX_VERT; i++) {
 
1471
      for (j=0; j<QUEUE_MAX_HORIZ; j++) {
 
1472
         if (QBG[i][j].qI && QBG[i][j].qI->selected) {
 
1473
            if (!ql) {
 
1474
               ql = lCreateList("CQ", ST_Type);
 
1475
            }
 
1476
            qep = lCreateElem(ST_Type);
 
1477
            lSetString(qep, ST_name, lGetString(QBG[i][j].qI->qp, CQ_name));
 
1478
            lAppendElem(ql, qep);
 
1479
         }
 
1480
      }
 
1481
   }
 
1482
 
 
1483
   if (ql) {
 
1484
      alp = qmonChangeStateList(SGE_CQUEUE_LIST, ql, force, action); 
 
1485
   
 
1486
      qmonMessageBox(w, alp, 0);
 
1487
 
 
1488
      updateQueueList();
 
1489
 
 
1490
      lFreeList(&ql);
 
1491
      lFreeList(&alp);
 
1492
   }
 
1493
   
 
1494
      
 
1495
   DEXIT;
 
1496
}
 
1497
 
 
1498
 
 
1499
/*-------------------------------------------------------------------------*/
 
1500
static char *qmonQueueGetArch(
 
1501
const char *qhostname 
 
1502
) {
 
1503
   lList *ehl = NULL;
 
1504
   lListElem *ehp = NULL;
 
1505
   lListElem *lep = NULL;
 
1506
   char *arch = NULL;
 
1507
   
 
1508
   DENTER(GUI_LAYER, "qmonQueueGetArch");
 
1509
 
 
1510
   if (!qhostname) {
 
1511
      DPRINTF(("no qhostname\n"));
 
1512
      DEXIT;
 
1513
      return NULL;
 
1514
   }
 
1515
   
 
1516
   ehl = qmonMirrorList(SGE_EXECHOST_LIST);
 
1517
   ehp = host_list_locate(ehl, qhostname);
 
1518
   if (ehp)
 
1519
      lep = lGetSubStr(ehp, HL_name, "arch", EH_load_list);
 
1520
 
 
1521
   if (!lep || !ehp) {
 
1522
      DPRINTF(("no load arch\n"));
 
1523
      DEXIT;
 
1524
      return NULL;
 
1525
   }
 
1526
 
 
1527
   arch = XtNewString(lGetString(lep, HL_value));
 
1528
 
 
1529
   DEXIT;
 
1530
   return arch;
 
1531
}
 
1532
 
 
1533
/*-------------------------------------------------------------------------*/
 
1534
static char *qmonQueueGetSymbol(
 
1535
char *arch 
 
1536
) {
 
1537
   static char *ICONS[] =  {  
 
1538
      "xterm", 
 
1539
      "xterm-dec", 
 
1540
      "xterm-sgi", 
 
1541
      "xterm-sun", 
 
1542
      "xterm-axp", 
 
1543
      "xterm-sol", 
 
1544
      "xterm-hp", 
 
1545
      "xterm-linux", 
 
1546
      "xterm-ibm", 
 
1547
      "xterm-cray"
 
1548
   };
 
1549
   int index;
 
1550
 
 
1551
   DENTER(GUI_LAYER, "qmonQueueGetSymbol");
 
1552
   
 
1553
   if (!arch) {
 
1554
      DEXIT;
 
1555
      return ICONS[0];
 
1556
   }
 
1557
 
 
1558
   if (!strncmp(arch, "irix", 4))
 
1559
      index = 2;
 
1560
   else if (!strncmp(arch, "sgi", 3))
 
1561
      index = 2;
 
1562
   else if (!strncmp(arch, "osf", 3))
 
1563
      index = 1;
 
1564
   else if (!strncmp(arch, "sun", 3))
 
1565
      index = 3;
 
1566
   else if (!strncmp(arch, "axp", 3))
 
1567
      index = 4;
 
1568
   else if (!strncmp(arch, "solaris", 7))
 
1569
      index = 5;
 
1570
   else if (!strncmp(arch, "hp", 2))
 
1571
      index = 6;
 
1572
   else if (!strncmp(arch, "linux", 5))
 
1573
      index = 7;
 
1574
   else if (!strncmp(arch, "alinux", 6))
 
1575
      index = 7;
 
1576
   else if (!strncmp(arch, "glinux", 6))
 
1577
      index = 7;
 
1578
   else if (!strncmp(arch, "slinux", 6))
 
1579
      index = 7;
 
1580
   else if (!strncmp(arch, "rs6000", 6))
 
1581
      index = 8;
 
1582
   else if (!strncmp(arch, "aix4", 4))
 
1583
      index = 8;
 
1584
   else if (!strncmp(arch, "unicos", 6))
 
1585
      index = 9;
 
1586
   else if (!strncmp(arch, "cray", 4))
 
1587
      index = 9;
 
1588
   else
 
1589
      index = 0;
 
1590
   
 
1591
   DPRINTF(("+++++++++++ARCH: %s, %d\n", arch, index));
 
1592
 
 
1593
   DEXIT;
 
1594
   return ICONS[index];
 
1595
}
 
1596
 
 
1597
#if 0
 
1598
/* don't remove this function */
 
1599
static void showQueueHashTable(XmtHashTable table, XtPointer key, XtPointer *data)
 
1600
{
 
1601
   printf("%s(%ld)\n", XrmQuarkToString((long)key), (long)key);
 
1602
}   
 
1603
#endif
 
1604