Home | History | Annotate | Line # | Download | only in dist
      1 /* $Xorg: info.c,v 1.5 2001/02/09 02:05:59 xorgcvs Exp $ */
      2 /******************************************************************************
      3 
      4 Copyright 1993, 1998  The Open Group
      5 
      6 Permission to use, copy, modify, distribute, and sell this software and its
      7 documentation for any purpose is hereby granted without fee, provided that
      8 the above copyright notice appear in all copies and that both that
      9 copyright notice and this permission notice appear in supporting
     10 documentation.
     11 
     12 The above copyright notice and this permission notice shall be included in
     13 all copies or substantial portions of the Software.
     14 
     15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall not be
     23 used in advertising or otherwise to promote the sale, use or other dealings
     24 in this Software without prior written authorization from The Open Group.
     25 ******************************************************************************/
     26 /* $XFree86: xc/programs/xsm/info.c,v 1.5 2001/01/17 23:46:28 dawes Exp $ */
     27 
     28 #include "xsm.h"
     29 #include "restart.h"
     30 #include "popup.h"
     31 #include "info.h"
     32 #include "prop.h"
     33 
     34 #include <X11/Shell.h>
     35 #include <X11/Xaw/Form.h>
     36 #include <X11/Xaw/List.h>
     37 #include <X11/Xaw/Command.h>
     38 #include <X11/Xaw/SimpleMenu.h>
     39 #include <X11/Xaw/MenuButton.h>
     40 #include <X11/Xaw/SmeBSB.h>
     41 #include <X11/Xaw/AsciiText.h>
     42 
     43 static Pixmap checkBitmap;
     44 
     45 Widget clientInfoPopup;
     46 static Widget   clientInfoForm;
     47 static Widget     viewPropButton;
     48 static Widget	   cloneButton;
     49 static Widget	   killClientButton;
     50 static Widget	   clientInfoDoneButton;
     51 static Widget	   restartHintButton;
     52 static Widget	     restartHintMenu;
     53 static Widget		restartIfRunning;
     54 static Widget		restartAnyway;
     55 static Widget		restartImmediately;
     56 static Widget		restartNever;
     57 Widget clientListWidget;
     58 static Widget noClientsLabel;
     59 Widget manualRestartLabel;
     60 Widget manualRestartCommands;
     61 
     62 Widget clientPropPopup;
     63 static Widget clientPropForm;
     64 static Widget clientPropDoneButton;
     65 static Widget clientPropTextWidget;
     66 
     67 
     68 
     69 void
     71 ShowHint(ClientRec *client)
     72 {
     73     static Widget active = NULL;
     74     int hint = client->restartHint;
     75 
     76     if (active)
     77 	XtVaSetValues (active, XtNleftBitmap, None, NULL);
     78 
     79     if (hint == SmRestartIfRunning)
     80 	active = restartIfRunning;
     81     else if (hint == SmRestartAnyway)
     82 	active = restartAnyway;
     83     else if (hint == SmRestartImmediately)
     84 	active = restartImmediately;
     85     else if (hint == SmRestartNever)
     86 	active = restartNever;
     87 
     88     XtVaSetValues (active, XtNleftBitmap, checkBitmap, NULL);
     89 }
     90 
     91 
     92 
     93 typedef struct {
     95     char *bufStart;
     96     char *bufPtr;
     97     int bufSize;
     98     int bytesLeft;
     99 } Buffer;
    100 
    101 #define BUF_START_SIZE 1024
    102 #define BUF_GROW_SIZE 256
    103 
    104 
    105 static void
    106 AppendStr(Buffer *buffer, const char *str)
    107 {
    108     int len = strlen (str);
    109 
    110     if ((buffer->bytesLeft - 1) < len)
    111     {
    112 	int newBufSize = buffer->bufSize + len + BUF_GROW_SIZE;
    113 	int bytesUsed = buffer->bufPtr - buffer->bufStart;
    114 	char *newbuf = realloc (buffer->bufStart, newBufSize);
    115 	if (newbuf != NULL) {
    116 	    newbuf[bytesUsed] = '\0';
    117 	    buffer->bufStart = newbuf;
    118 	    buffer->bufPtr = newbuf + bytesUsed;
    119 	    buffer->bufSize = newBufSize;
    120 	    buffer->bytesLeft = newBufSize - bytesUsed;
    121 	} else {
    122 	    perror("realloc failed, aborting");
    123 	    exit(1);
    124 	}
    125     }
    126 
    127     strcat (buffer->bufPtr, str);
    128     buffer->bufPtr += len;
    129     buffer->bytesLeft -= len;
    130 }
    131 
    132 
    133 void
    134 DisplayProps(ClientRec *client)
    135 {
    136     int index;
    137     List *pl, *pj, *vl;
    138     PropValue *pval;
    139     Buffer buffer;
    140     static int first_time = 1;
    141 
    142     for (index = 0; index < numClientListNames; index++)
    143 	if (clientListRecs[index] == client)
    144 	    break;
    145 
    146     if (index >= numClientListNames)
    147 	return;
    148 
    149     buffer.bufStart = buffer.bufPtr = (char *) malloc (BUF_START_SIZE);
    150     buffer.bufSize = buffer.bytesLeft = BUF_START_SIZE;
    151     buffer.bufStart[0] = '\0';
    152 
    153     if (ListCount (client->props) > 0)
    154     {
    155 	char number[16];
    156 	char *ptr;
    157 
    158 	AppendStr (&buffer, "*** ID = ");
    159 	AppendStr (&buffer, client->clientId);
    160 	AppendStr (&buffer, " ***\n\n");
    161 
    162 	for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
    163 	{
    164 	    Prop *pprop = (Prop *) pl->thing;
    165 
    166 	    AppendStr (&buffer, "Name:		");
    167 	    AppendStr (&buffer, pprop->name);
    168 	    AppendStr (&buffer, "\n");
    169 	    AppendStr (&buffer, "Type:		");
    170 	    AppendStr (&buffer, pprop->type);
    171 	    AppendStr (&buffer, "\n");
    172 	    AppendStr (&buffer, "Num values:	");
    173 	    snprintf (number, sizeof(number), "%d", ListCount (pprop->values));
    174 	    AppendStr (&buffer, number);
    175 	    AppendStr (&buffer, "\n");
    176 
    177 	    if (strcmp (pprop->type, SmCARD8) == 0)
    178 	    {
    179 		char *card8;
    180 		int value;
    181 
    182 		vl = ListFirst (pprop->values);
    183 		pval = (PropValue *) vl->thing;
    184 
    185 		card8 = pval->value;
    186 		value = *card8;
    187 
    188 		AppendStr (&buffer, "Value 1:	");
    189 		snprintf (number, sizeof(number), "%d", value);
    190 		AppendStr (&buffer, number);
    191 
    192 		if (strcmp (pprop->name, SmRestartStyleHint) == 0)
    193 		{
    194 		    if (value == SmRestartAnyway)
    195 			AppendStr (&buffer, " (Restart Anyway)");
    196 		    else if (value == SmRestartImmediately)
    197 			AppendStr (&buffer, " (Restart Immediately)");
    198 		    else if (value == SmRestartNever)
    199 			AppendStr (&buffer, " (Restart Never)");
    200 		    else
    201 			AppendStr (&buffer, " (Restart If Running)");
    202 		}
    203 
    204 		AppendStr (&buffer, "\n");
    205 	    }
    206 	    else
    207 	    {
    208 		int propnum = 0;
    209 
    210 		for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj))
    211 		{
    212 		    propnum++;
    213 
    214 		    pval = (PropValue *) pj->thing;
    215 		    AppendStr (&buffer, "Value ");
    216 		    snprintf (number, sizeof(number), "%d", propnum);
    217 		    AppendStr (&buffer, number);
    218 		    AppendStr (&buffer, ":	");
    219 		    AppendStr (&buffer, (char *) pval->value);
    220 		    AppendStr (&buffer, "\n");
    221 		}
    222 	    }
    223 
    224 	    AppendStr (&buffer, "\n");
    225 	}
    226 
    227 	XtVaSetValues (clientPropTextWidget,
    228 	    XtNstring, buffer.bufStart,
    229 	    NULL);
    230 
    231 	snprintf (buffer.bufStart, buffer.bufSize,
    232 	    "SM Properties : %s", clientListNames[index]);
    233 
    234 	ptr = Strstr (buffer.bufStart, ")   Restart");
    235 	if (ptr) *(ptr + 1) = '\0';
    236 
    237 	XtVaSetValues (clientPropPopup,
    238 	    XtNtitle, buffer.bufStart,
    239 	    XtNiconName, buffer.bufStart,
    240 	    NULL);
    241 
    242 	if (client_prop_visible)
    243 	{
    244 	    /* Make sure it is visible */
    245 
    246 	    XMapRaised (XtDisplay (topLevel), XtWindow (clientPropPopup));
    247 	}
    248 	else
    249 	{
    250 	    PopupPopup (mainWindow, clientPropPopup,
    251 		False, first_time, 50, 150, "DelPropWinAction()");
    252 
    253 	    client_prop_visible = 1;
    254 
    255 	    if (first_time)
    256 		first_time = 0;
    257 	}
    258     }
    259 
    260     free (buffer.bufStart);
    261 }
    262 
    263 
    264 
    265 static void
    267 ClientListXtProc(Widget w, XtPointer client_data, XtPointer callData)
    268 {
    269     XawListReturnStruct *current = (XawListReturnStruct *) callData;
    270     ClientRec *client;
    271 
    272     if (!current || current->list_index < 0)
    273 	return;
    274 
    275     client = clientListRecs[current->list_index];
    276     ShowHint (client);
    277     current_client_selected = current->list_index;
    278     if (client_prop_visible)
    279 	DisplayProps (client);
    280 }
    281 
    282 
    283 
    284 
    285 static void
    287 ViewPropXtProc(Widget w, XtPointer client_data, XtPointer callData)
    288 {
    289     ClientRec *client;
    290     XawListReturnStruct *current;
    291 
    292     current = XawListShowCurrent (clientListWidget);
    293 
    294     if (!current || current->list_index < 0)
    295     {
    296 	if (current)
    297 	    XtFree ((char *) current);
    298 	return;
    299     }
    300 
    301     client = clientListRecs[current->list_index];
    302     DisplayProps (client);
    303     XtFree ((char *) current);
    304 }
    305 
    306 
    307 
    308 static void
    310 CloneXtProc(Widget w, XtPointer client_data, XtPointer callData)
    311 {
    312     ClientRec *client;
    313     XawListReturnStruct *current;
    314 
    315     current = XawListShowCurrent (clientListWidget);
    316 
    317     if (!current || current->list_index < 0)
    318     {
    319 	if (current)
    320 	    XtFree ((char *) current);
    321 	return;
    322     }
    323 
    324     client = clientListRecs[current->list_index];
    325 
    326     if (client)
    327 	Clone (client, False /* don't use saved state */);
    328 
    329     XtFree ((char *) current);
    330 }
    331 
    332 
    333 
    334 static void
    336 KillClientXtProc(Widget w, XtPointer client_data, XtPointer callData)
    337 {
    338     ClientRec *client;
    339     XawListReturnStruct *current;
    340 
    341     current = XawListShowCurrent (clientListWidget);
    342 
    343     if (!current || current->list_index < 0)
    344     {
    345 	if (current)
    346 	    XtFree ((char *) current);
    347 	return;
    348     }
    349 
    350     client = clientListRecs[current->list_index];
    351 
    352     SmsDie (client->smsConn);
    353 
    354     XtFree ((char *) current);
    355 }
    356 
    357 
    358 
    359 static void
    361 listDoneXtProc(Widget w, XtPointer client_data, XtPointer callData)
    362 {
    363     XtPopdown (clientInfoPopup);
    364     client_info_visible = 0;
    365 }
    366 
    367 
    368 
    369 char *
    371 GetProgramName(char *fullname)
    372 {
    373     char *lastSlash = NULL;
    374     int i;
    375 
    376     for (i = 0; i < (int) strlen (fullname); i++)
    377 	if (fullname[i] == '/')
    378 	    lastSlash = &fullname[i];
    379 
    380     if (lastSlash)
    381 	return (lastSlash + 1);
    382     else
    383 	return (fullname);
    384 }
    385 
    386 
    387 
    388 void
    390 UpdateClientList(void)
    391 {
    392     ClientRec *client;
    393     char *progName, *hostname, *tmp1, *tmp2;
    394     char *clientInfo;
    395     int maxlen1, maxlen2;
    396     char extraBuf1[80], extraBuf2[80];
    397     char *restart_service_prop;
    398     List *cl, *pl;
    399     int i, k;
    400     static int reenable_asap = 0;
    401 
    402     if (clientListNames)
    403     {
    404 	/*
    405 	 * Free the previous list of names.  Xaw doesn't make a copy of
    406 	 * our list, so we need to keep it around.
    407 	 */
    408 
    409 	for (i = 0; i < numClientListNames; i++)
    410 	    XtFree ((char *) clientListNames[i]);
    411 
    412 	XtFree ((char *) clientListNames);
    413 
    414 	clientListNames = NULL;
    415     }
    416 
    417     if (clientListRecs)
    418     {
    419 	/*
    420 	 * Free the mapping of client names to client records
    421 	 */
    422 
    423 	XtFree ((char *) clientListRecs);
    424 	clientListRecs = NULL;
    425     }
    426 
    427     maxlen1 = maxlen2 = 0;
    428     numClientListNames = 0;
    429 
    430     for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
    431     {
    432 	client = (ClientRec *) cl->thing;
    433 
    434 	progName = NULL;
    435 	restart_service_prop = NULL;
    436 
    437 	for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
    438 	{
    439 	    Prop *pprop = (Prop *) pl->thing;
    440 	    List *vl = ListFirst (pprop->values);
    441 	    if (vl != NULL)
    442 	    {
    443 	    	PropValue *pval = (PropValue *) vl->thing;
    444 
    445 	    	if (strcmp (pprop->name, SmProgram) == 0)
    446 	    	{
    447 			progName = GetProgramName ((char *) pval->value);
    448 
    449 			if ((int) strlen (progName) > maxlen1)
    450 			    maxlen1 = strlen (progName);
    451 	    	}
    452 	    	else if (strcmp (pprop->name, "_XC_RestartService") == 0)
    453 	    	{
    454 			restart_service_prop = (char *) pval->value;
    455 	    	}
    456 	    }
    457 	}
    458 
    459 	if (!progName)
    460 	    continue;
    461 
    462 	if (restart_service_prop)
    463 	    tmp1 = restart_service_prop;
    464 	else if (client->clientHostname)
    465 	    tmp1 = client->clientHostname;
    466 	else
    467 	    continue;
    468 
    469 	if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
    470 	    hostname = tmp1;
    471 	else
    472 	    hostname = tmp2 + 1;
    473 
    474 	if ((int) strlen (hostname) > maxlen2)
    475 	    maxlen2 = strlen (hostname);
    476 
    477 	numClientListNames++;
    478     }
    479 
    480     if (numClientListNames == 0)
    481     {
    482 	XtSetSensitive (viewPropButton, 0);
    483 	XtSetSensitive (cloneButton, 0);
    484 	XtSetSensitive (killClientButton, 0);
    485 	XtSetSensitive (restartHintButton, 0);
    486 
    487 	XtUnmanageChild (clientListWidget);
    488 	XtManageChild (noClientsLabel);
    489 
    490 	reenable_asap = 1;
    491 
    492 	return;
    493     }
    494 
    495     if (reenable_asap)
    496     {
    497 	XtSetSensitive (viewPropButton, 1);
    498 	XtSetSensitive (cloneButton, 1);
    499 	XtSetSensitive (killClientButton, 1);
    500 	XtSetSensitive (restartHintButton, 1);
    501 
    502 	XtUnmanageChild (noClientsLabel);
    503 	XtManageChild (clientListWidget);
    504 
    505 	reenable_asap = 0;
    506     }
    507 
    508     clientListNames = (String *) XtMalloc (
    509 	numClientListNames * sizeof (String));
    510     clientListRecs = (ClientRec **) XtMalloc (
    511 	numClientListNames * sizeof (ClientRec *));
    512 
    513     i = 0;
    514     for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
    515     {
    516 	ClientRec *client = (ClientRec *) cl->thing;
    517 	int extra1, extra2;
    518 	const char *hint;
    519 
    520 	progName = NULL;
    521 	restart_service_prop = NULL;
    522 
    523 	for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
    524 	{
    525 	    Prop *pprop = (Prop *) pl->thing;
    526 	    List *vl = ListFirst (pprop->values);
    527 
    528 	    if (vl != NULL)
    529 	    {
    530 	    	PropValue *pval = (PropValue *) vl->thing;
    531 	    	if (strcmp (pprop->name, SmProgram) == 0)
    532 	    	{
    533 			progName = GetProgramName ((char *) pval->value);
    534 	    	}
    535 	    	else if (strcmp (pprop->name, "_XC_RestartService") == 0)
    536 	    	{
    537 			restart_service_prop = (char *) pval->value;
    538 	    	}
    539 	    }
    540 	}
    541 
    542 	if (!progName)
    543 	    continue;
    544 
    545 	if (restart_service_prop)
    546 	    tmp1 = restart_service_prop;
    547 	else if (client->clientHostname)
    548 	    tmp1 = client->clientHostname;
    549 	else
    550 	    continue;
    551 
    552 	if ((tmp2 = (char *) strchr (tmp1, '/')) == NULL)
    553 	    hostname = tmp1;
    554 	else
    555 	    hostname = tmp2 + 1;
    556 
    557 	extra1 = maxlen1 - strlen (progName) + 5;
    558 	extra2 = maxlen2 - strlen (hostname);
    559 
    560 	if (client->restartHint == SmRestartIfRunning)
    561 	    hint = "Restart If Running";
    562 	else if (client->restartHint == SmRestartAnyway)
    563 	    hint = "Restart Anyway";
    564 	else if (client->restartHint == SmRestartImmediately)
    565 	    hint = "Restart Immediately";
    566 	else if (client->restartHint == SmRestartNever)
    567 	    hint = "Restart Never";
    568 	else
    569 	    hint = "";
    570 
    571 	for (k = 0; k < extra1; k++)
    572 	    extraBuf1[k] = ' ';
    573 	extraBuf1[extra1] = '\0';
    574 
    575 	for (k = 0; k < extra2; k++)
    576 	    extraBuf2[k] = ' ';
    577 	extraBuf2[extra2] = '\0';
    578 
    579 	XtAsprintf (&clientInfo, "%s%s (%s%s)   %s", progName, extraBuf1,
    580 	    hostname, extraBuf2, hint);
    581 
    582 	clientListRecs[i] = client;
    583 	clientListNames[i++] = clientInfo;
    584     }
    585 
    586     XawListChange (clientListWidget,
    587 	clientListNames, numClientListNames, 0, True);
    588 }
    589 
    590 
    591 
    592 static void
    594 RestartHintXtProc(Widget w, XtPointer client_data, XtPointer callData)
    595 {
    596     XawListReturnStruct *current;
    597     ClientRec *client;
    598     Widget active;
    599     int found = 0;
    600     List *pl;
    601     char hint;
    602 
    603     current = XawListShowCurrent (clientListWidget);
    604 
    605     if (!current || current->list_index < 0)
    606     {
    607 	if (current)
    608 	    XtFree ((char *) current);
    609 	return;
    610     }
    611 
    612     client = clientListRecs[current->list_index];
    613 
    614     active = XawSimpleMenuGetActiveEntry (restartHintMenu);
    615 
    616     if (active == restartIfRunning)
    617 	hint = SmRestartIfRunning;
    618     else if (active == restartAnyway)
    619 	hint = SmRestartAnyway;
    620     else if (active == restartImmediately)
    621 	hint = SmRestartImmediately;
    622     else if (active == restartNever)
    623 	hint = SmRestartNever;
    624     else
    625     {
    626 	XtFree ((char *) current);
    627 	return;
    628     }
    629 
    630     client->restartHint = hint;
    631 
    632     for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
    633     {
    634 	Prop *pprop = (Prop *) pl->thing;
    635 
    636 	if (strcmp (SmRestartStyleHint, pprop->name) == 0)
    637 	{
    638 	    List *vl = ListFirst (pprop->values);
    639 
    640 	    PropValue *pval = (PropValue *) vl->thing;
    641 
    642 	    *((char *) (pval->value)) = hint;
    643 	    found = 1;
    644 	    break;
    645 	}
    646     }
    647 
    648     if (!found)
    649     {
    650 	SmProp prop;
    651 	SmPropValue propval;
    652 
    653 	prop.name = SmRestartStyleHint;
    654 	prop.type = SmCARD8;
    655 	prop.num_vals = 1;
    656 	prop.vals = &propval;
    657 	propval.value = (SmPointer) &hint;
    658 	propval.length = 1;
    659 
    660 	SetProperty (client, &prop, False /* don't free it */);
    661     }
    662 
    663     UpdateClientList ();
    664     XawListHighlight (clientListWidget, current_client_selected);
    665     ShowHint (client);
    666 
    667     if (client_prop_visible && clientListRecs &&
    668 	clientListRecs[current_client_selected] == client)
    669     {
    670 	DisplayProps (client);
    671     }
    672 
    673     XtFree ((char *) current);
    674 }
    675 
    676 
    677 
    678 static void
    680 clientPropDoneXtProc(Widget w, XtPointer client_data, XtPointer callData)
    681 {
    682     XtPopdown (clientPropPopup);
    683     client_prop_visible = 0;
    684 }
    685 
    686 
    687 
    688 void
    690 ClientInfoStructureNotifyXtHandler(Widget w, XtPointer closure,
    691 				   XEvent *event,
    692 				   Boolean *continue_to_dispatch)
    693 {
    694     if (event->type == MapNotify)
    695     {
    696 	UpdateClientList ();
    697 
    698 	if (current_client_selected >= 0)
    699 	    XawListHighlight (clientListWidget, current_client_selected);
    700 
    701 	XtRemoveEventHandler (clientInfoPopup, StructureNotifyMask, False,
    702 	    ClientInfoStructureNotifyXtHandler, NULL);
    703     }
    704 }
    705 
    706 
    707 
    708 void
    710 ClientInfoXtProc(Widget w, XtPointer client_data, XtPointer callData)
    711 {
    712     static int first_time = 1;
    713 
    714     if (client_info_visible)
    715     {
    716 	/* Make sure it is visible */
    717 
    718 	XMapRaised (XtDisplay (topLevel), XtWindow (clientInfoPopup));
    719     }
    720     else
    721     {
    722 	UpdateClientList ();
    723 
    724 	if (clientListRecs && clientListRecs[0])
    725 	{
    726 	    current_client_selected = 0;
    727 	    XawListHighlight (clientListWidget, 0);
    728 	    ShowHint (clientListRecs[0]);
    729 	    if (client_prop_visible)
    730 		DisplayProps (clientListRecs[0]);
    731 	}
    732 	else
    733 	    current_client_selected = -1;
    734 
    735 	if (first_time && num_clients_in_last_session > 0 &&
    736 	    num_clients_in_last_session != numClientListNames)
    737 	{
    738 	    XtAddEventHandler (clientInfoPopup, StructureNotifyMask, False,
    739 	        ClientInfoStructureNotifyXtHandler, NULL);
    740 	}
    741 
    742 	PopupPopup (mainWindow, clientInfoPopup,
    743 	    False, first_time, 100, 50, "DelClientInfoWinAction()");
    744 
    745 	client_info_visible = 1;
    746 
    747 	if (first_time)
    748 	    first_time = 0;
    749     }
    750 }
    751 
    752 
    753 #define CHECK_WIDTH 9
    754 #define CHECK_HEIGHT 8
    755 
    756 static unsigned char check_bits[] = {
    757    0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00,
    758    0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00
    759 };
    760 
    761 
    762 
    763 static void
    765 DelClientInfoWinAction(Widget w, XEvent *event, String *params,
    766 		       Cardinal *num_params)
    767 {
    768     XtCallCallbacks (clientInfoDoneButton, XtNcallback, NULL);
    769 }
    770 
    771 
    772 
    773 static void
    775 DelPropWinAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
    776 {
    777     XtCallCallbacks (clientPropDoneButton, XtNcallback, NULL);
    778 }
    779 
    780 
    781 
    782 void
    784 create_client_info_popup(void)
    785 
    786 {
    787     /*
    788      * Install actions for WM_DELETE_WINDOW
    789      */
    790 
    791     static XtActionsRec actions[] = {
    792         {"DelClientInfoWinAction", DelClientInfoWinAction},
    793         {"DelPropWinAction", DelPropWinAction}
    794     };
    795 
    796     XtAppAddActions (appContext, actions, XtNumber (actions));
    797 
    798 
    799     /*
    800      * Make checkmark bitmap
    801      */
    802 
    803     checkBitmap = XCreateBitmapFromData (
    804 	XtDisplay (topLevel), RootWindowOfScreen (XtScreen (topLevel)),
    805 	(char *) check_bits, CHECK_WIDTH, CHECK_HEIGHT);
    806 
    807 
    808     /*
    809      * Pop up for List Clients button.
    810      */
    811 
    812     clientInfoPopup = XtVaCreatePopupShell (
    813 	"clientInfoPopup", topLevelShellWidgetClass, topLevel,
    814 	XtNallowShellResize, True,
    815 	NULL);
    816 
    817 
    818     clientInfoForm = XtVaCreateManagedWidget (
    819 	"clientInfoForm", formWidgetClass, clientInfoPopup,
    820 	NULL);
    821 
    822     viewPropButton = XtVaCreateManagedWidget (
    823 	"viewPropButton", commandWidgetClass, clientInfoForm,
    824         XtNfromHoriz, NULL,
    825         XtNfromVert, NULL,
    826 	XtNtop, XawChainTop,
    827 	XtNbottom, XawChainTop,
    828 	XtNleft, XawChainLeft,
    829 	XtNright, XawChainLeft,
    830         NULL);
    831 
    832     XtAddCallback (viewPropButton, XtNcallback, ViewPropXtProc, NULL);
    833 
    834 
    835     cloneButton = XtVaCreateManagedWidget (
    836 	"cloneButton", commandWidgetClass, clientInfoForm,
    837         XtNfromHoriz, viewPropButton,
    838         XtNfromVert, NULL,
    839 	XtNtop, XawChainTop,
    840 	XtNbottom, XawChainTop,
    841 	XtNleft, XawChainLeft,
    842 	XtNright, XawChainLeft,
    843         NULL);
    844 
    845     XtAddCallback (cloneButton, XtNcallback, CloneXtProc, NULL);
    846 
    847 
    848     killClientButton = XtVaCreateManagedWidget (
    849 	"killClientButton", commandWidgetClass, clientInfoForm,
    850         XtNfromHoriz, cloneButton,
    851         XtNfromVert, NULL,
    852 	XtNtop, XawChainTop,
    853 	XtNbottom, XawChainTop,
    854 	XtNleft, XawChainLeft,
    855 	XtNright, XawChainLeft,
    856         NULL);
    857 
    858     XtAddCallback (killClientButton, XtNcallback, KillClientXtProc, NULL);
    859 
    860 
    861     restartHintButton = XtVaCreateManagedWidget (
    862 	"restartHintButton", menuButtonWidgetClass, clientInfoForm,
    863 	XtNmenuName, "restartHintMenu",
    864         XtNfromHoriz, killClientButton,
    865         XtNfromVert, NULL,
    866 	XtNtop, XawChainTop,
    867 	XtNbottom, XawChainTop,
    868 	XtNleft, XawChainLeft,
    869 	XtNright, XawChainLeft,
    870 	NULL);
    871 
    872     restartHintMenu = XtVaCreatePopupShell (
    873 	"restartHintMenu", simpleMenuWidgetClass, clientInfoForm,
    874 	NULL);
    875 
    876     restartIfRunning = XtVaCreateManagedWidget (
    877 	"restartIfRunning", smeBSBObjectClass, restartHintMenu,
    878 	XtNleftMargin, 18,
    879 	NULL);
    880 
    881     restartAnyway = XtVaCreateManagedWidget (
    882 	"restartAnyway", smeBSBObjectClass, restartHintMenu,
    883 	XtNleftMargin, 18,
    884 	NULL);
    885 
    886     restartImmediately = XtVaCreateManagedWidget (
    887 	"restartImmediately", smeBSBObjectClass, restartHintMenu,
    888 	XtNleftMargin, 18,
    889 	NULL);
    890 
    891     restartNever = XtVaCreateManagedWidget (
    892 	"restartNever", smeBSBObjectClass, restartHintMenu,
    893 	XtNleftMargin, 18,
    894 	NULL);
    895 
    896     XtAddCallback (restartIfRunning, XtNcallback, RestartHintXtProc, NULL);
    897     XtAddCallback (restartAnyway, XtNcallback, RestartHintXtProc, NULL);
    898     XtAddCallback (restartImmediately, XtNcallback, RestartHintXtProc, NULL);
    899     XtAddCallback (restartNever, XtNcallback, RestartHintXtProc, NULL);
    900 
    901 
    902     clientInfoDoneButton = XtVaCreateManagedWidget (
    903 	"clientInfoDoneButton", commandWidgetClass, clientInfoForm,
    904         XtNfromHoriz, restartHintButton,
    905         XtNfromVert, NULL,
    906 	XtNtop, XawChainTop,
    907 	XtNbottom, XawChainTop,
    908 	XtNleft, XawChainLeft,
    909 	XtNright, XawChainLeft,
    910         NULL);
    911 
    912     XtAddCallback (clientInfoDoneButton, XtNcallback, listDoneXtProc, NULL);
    913 
    914 
    915     clientListWidget = XtVaCreateManagedWidget (
    916 	"clientListWidget", listWidgetClass, clientInfoForm,
    917         XtNdefaultColumns, 1,
    918 	XtNforceColumns, True,
    919         XtNfromHoriz, NULL,
    920         XtNfromVert, viewPropButton,
    921 	XtNresizable, True,
    922 	XtNtop, XawChainTop,
    923 	XtNbottom, XawChainTop,
    924 	NULL);
    925 
    926     XtAddCallback (clientListWidget, XtNcallback, ClientListXtProc, NULL);
    927 
    928     noClientsLabel = XtVaCreateWidget (
    929 	"noClientsLabel", labelWidgetClass, clientInfoForm,
    930         XtNfromHoriz, NULL,
    931         XtNfromVert, viewPropButton,
    932         XtNborderWidth, 0,
    933 	XtNtop, XawChainTop,
    934 	XtNbottom, XawChainTop,
    935 	NULL);
    936 
    937     manualRestartLabel = XtVaCreateManagedWidget (
    938 	"manualRestartLabel", labelWidgetClass, clientInfoForm,
    939         XtNfromHoriz, NULL,
    940         XtNfromVert, clientListWidget,
    941         XtNborderWidth, 0,
    942         XtNvertDistance, 20,
    943 	XtNtop, XawChainBottom,
    944 	XtNbottom, XawChainBottom,
    945 	XtNleft, XawChainLeft,
    946 	XtNright, XawChainLeft,
    947 	NULL);
    948 
    949     manualRestartCommands = XtVaCreateManagedWidget (
    950 	"manualRestartCommands", asciiTextWidgetClass, clientInfoForm,
    951         XtNfromHoriz, NULL,
    952         XtNfromVert, manualRestartLabel,
    953 	XtNeditType, XawtextEdit,
    954 	XtNresizable, True,
    955 	XtNresize, XawtextResizeWidth,
    956 	XtNscrollVertical, XawtextScrollAlways,
    957 	XtNwidth, 350,
    958 	XtNheight, 100,
    959 	XtNtop, XawChainBottom,
    960 	XtNbottom, XawChainBottom,
    961 	NULL);
    962 
    963     /*
    964      * Pop up for viewing client properties
    965      */
    966 
    967     clientPropPopup = XtVaCreatePopupShell (
    968 	"clientPropPopup", topLevelShellWidgetClass, topLevel,
    969 	XtNallowShellResize, True,
    970 	NULL);
    971 
    972 
    973     clientPropForm = XtVaCreateManagedWidget (
    974 	"clientPropForm", formWidgetClass, clientPropPopup,
    975 	NULL);
    976 
    977     clientPropDoneButton = XtVaCreateManagedWidget (
    978 	"clientPropDoneButton", commandWidgetClass, clientPropForm,
    979         XtNfromHoriz, NULL,
    980         XtNfromVert, NULL,
    981 	XtNtop, XawChainTop,
    982 	XtNbottom, XawChainTop,
    983 	XtNleft, XawChainLeft,
    984 	XtNright, XawChainLeft,
    985         NULL);
    986 
    987     XtAddCallback (clientPropDoneButton, XtNcallback, clientPropDoneXtProc, NULL);
    988 
    989 
    990     clientPropTextWidget = XtVaCreateManagedWidget (
    991 	"clientPropTextWidget", asciiTextWidgetClass, clientPropForm,
    992         XtNfromHoriz, NULL,
    993         XtNfromVert, clientPropDoneButton,
    994 	XtNeditType, XawtextRead,
    995         XtNdisplayCaret, False,
    996 	XtNscrollVertical, XawtextScrollWhenNeeded,
    997 	XtNscrollHorizontal, XawtextScrollWhenNeeded,
    998 	XtNresizable, True,
    999 	XtNtop, XawChainTop,
   1000 	XtNbottom, XawChainBottom,
   1001 	NULL);
   1002 }
   1003