2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
25 * (c) Copyright 1993, 1994 International Business Machines Corp. *
26 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
27 * (c) Copyright 1993, 1994 Novell, Inc. *
30 * $TOG: chooser.c /main/8 1998/03/04 19:26:30 mgreess $
32 Copyright (c) 1990 X Consortium
34 Permission is hereby granted, free of charge, to any person obtaining a copy
35 of this software and associated documentation files (the "Software"), to deal
36 in the Software without restriction, including without limitation the rights
37 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38 copies of the Software, and to permit persons to whom the Software is
39 furnished to do so, subject to the following conditions:
41 The above copyright notice and this permission notice shall be included in
42 all copies or substantial portions of the Software.
44 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51 Except as contained in this notice, the name of the X Consortium shall not be
52 used in advertising or otherwise to promote the sale, use or other dealings
53 in this Software without prior written authorization from the X Consortium.
55 * Author: Keith Packard, MIT X Consortium
59 * Chooser - display a menu of names and let the user select one
65 * +--------------------------------------------------+
66 * | +------------------+ |
68 * | +------------------+ |
69 * | +-+--------------+ |
76 * | +----------------+ |
77 * | cancel accept ping |
78 * +--------------------------------------------------+
81 #include <X11/Intrinsic.h>
82 #include <X11/StringDefs.h>
83 #include <X11/Xatom.h>
97 #include <X11/Xdmcp.h>
99 #include <sys/types.h>
103 #include <nl_types.h>
104 #ifndef NL_CAT_LOCALE
105 #define NL_CAT_LOCALE 0
109 #include <sys/sockio.h>
111 #include <sys/socket.h>
112 #include <netinet/in.h>
113 #include <sys/ioctl.h>
116 * From Xm/XmStringI.h
118 extern XtPointer _XmStringUngenerate (
122 XmTextType output_type);
124 #define BROADCAST_HOSTNAME "BROADCAST"
127 #define ishexdigit(c) (isdigit(c) || 'a' <= (c) && (c) <= 'f')
131 # include <sys/utsname.h>
137 # include <sync/queue.h>
138 # include <sync/sema.h>
145 Widget toplevel, label, viewport, paned, list, box, cancel, acceptit, ping;
147 extern Widget chooser_list;
148 extern int orig_argc;
149 extern char **orig_argv;
150 extern int amChooser;
151 extern void MakeOptionsProc();
153 static Arg chooserArgs[25]; /** Hopefully enough args **/
155 static void CvtStringToARRAY8();
157 static struct _app_resources {
158 ARRAY8Ptr xdmAddress;
159 ARRAY8Ptr clientAddress;
163 static int FromHex (char *s, char *d, int len);
165 #define offset(field) XtOffsetOf(struct _app_resources, field)
167 #define XtRARRAY8 "ARRAY8"
169 static XtResource resources[] = {
170 {"xdmAddress", "XdmAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
171 offset (xdmAddress), XtRString, NULL },
172 {"clientAddress", "ClientAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
173 offset (clientAddress), XtRString, NULL },
174 {"connectionType", "ConnectionType", XtRInt, sizeof (int),
175 offset (connectionType), XtRImmediate, (XtPointer) 0 }
179 static XrmOptionDescRec options[] = {
180 "-xdmaddress", "*xdmAddress", XrmoptionSepArg, NULL,
181 "-clientaddress", "*clientAddress", XrmoptionSepArg, NULL,
182 "-connectionType", "*connectionType", XrmoptionSepArg, NULL,
185 typedef struct _hostAddr {
186 struct _hostAddr *next;
187 struct sockaddr *addr;
192 static HostAddr *hostAddrdb;
194 typedef struct _hostName {
195 struct _hostName *next;
198 ARRAY8 hostname, status;
199 CARD16 connectionType;
203 static HostName *hostNamedb;
209 #define PING_INTERVAL 2000
212 static XdmcpBuffer directBuffer, broadcastBuffer;
213 static XdmcpBuffer buffer;
218 PingHosts (XtPointer closure, XtIntervalId *id)
222 for (hosts = hostAddrdb; hosts; hosts = hosts->next)
224 if (hosts->type == QUERY)
225 XdmcpFlush (socketFD, &directBuffer, (XdmcpNetaddr) hosts->addr, hosts->addrlen);
227 XdmcpFlush (socketFD, &broadcastBuffer, (XdmcpNetaddr) hosts->addr, hosts->addrlen);
229 if (++pingTry < TRIES)
230 XtAddTimeOut (PING_INTERVAL, PingHosts, (XtPointer) 0);
236 #if defined(__STDC__)
238 HostnameCompare (const void *a, const void *b)
241 HostnameCompare (char *a, char *b)
244 return strcmp (*(char **)a, *(char **)b);
248 RebuildTable (int size)
253 XmStringTable newStringTable;
259 newTable = (char **) malloc (size * sizeof (char *));
262 for (names = hostNamedb, i = 0; names; names = names->next, i++)
263 newTable[i] = names->fullname;
264 qsort (newTable, size, sizeof (char *), HostnameCompare);
267 XmListDeleteAllItems(chooser_list);
269 free((char *)NameTable);
274 /***********************************/
275 /** Reload the data in the XmList **/
276 /***********************************/
277 newStringTable = (XmStringTable)malloc(size * sizeof(XmString));
278 if (!newStringTable) {
279 free((char *)newTable);
282 for (i = 0; i < size; i++) {
283 newStringTable[i] = XmStringCreateLocalized(newTable[i]);
286 XtSetArg(listArgs[numArgs], XmNitemCount, size); numArgs++;
287 XtSetArg(listArgs[numArgs], XmNitems, newStringTable); numArgs++;
288 XtSetValues(chooser_list, listArgs, numArgs);
290 free((char *) newStringTable);
293 free ((char *) NameTable);
294 NameTable = newTable;
295 NameTableSize = size;
299 RebuildTableAdd (int size)
309 newTable = (char **) malloc (size * sizeof (char *));
312 for (names = hostNamedb, i = 0; names; names = names->next, i++)
313 newTable[i] = names->fullname;
314 qsort (newTable, size, sizeof (char *), HostnameCompare);
317 for (i = 0; i < size; i++) {
318 tempString = XmStringCreateLocalized(newTable[i]);
319 if ((position = XmListItemPos(chooser_list, tempString)) == 0) {
320 /****************************/
321 /** need to add a new host **/
322 /****************************/
323 XmListAddItemUnselected(chooser_list, tempString, (i+1));
324 XmStringFree(tempString);
327 XmStringFree(tempString);
331 free ((char *) NameTable);
332 NameTable = newTable;
333 NameTableSize = size;
338 AddHostname (ARRAY8Ptr hostname, ARRAY8Ptr status, struct sockaddr *addr, int willing)
340 HostName *new, **names, *name;
342 CARD16 connectionType;
346 switch (addr->sa_family)
349 hostAddr.data = (CARD8 *) &((struct sockaddr_in *) addr)->sin_addr;
351 connectionType = FamilyInternet;
354 hostAddr.data = (CARD8 *) "";
356 connectionType = FamilyLocal;
359 for (names = &hostNamedb; *names; names = & (*names)->next)
362 if (connectionType == name->connectionType &&
363 XdmcpARRAY8Equal (&hostAddr, &name->hostaddr))
365 if (XdmcpARRAY8Equal (status, &name->status))
375 new = (HostName *) malloc (sizeof (HostName));
378 if (hostname->length)
380 switch (addr->sa_family)
384 struct hostent *hostent;
387 hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, AF_INET);
390 XdmcpDisposeARRAY8 (hostname);
391 host = hostent->h_name;
392 XdmcpAllocARRAY8 (hostname, strlen (host));
393 memmove( hostname->data, host, hostname->length);
398 if (!XdmcpAllocARRAY8 (&new->hostaddr, hostAddr.length))
403 memmove( new->hostaddr.data, hostAddr.data, hostAddr.length);
404 new->connectionType = connectionType;
405 new->hostname = *hostname;
414 free (new->fullname);
415 XdmcpDisposeARRAY8 (&new->status);
416 XdmcpDisposeARRAY8 (hostname);
418 new->willing = willing;
419 new->status = *status;
421 hostname = &new->hostname;
422 fulllen = hostname->length;
425 new->fullname = malloc (fulllen + status->length + 10);
428 new->fullname = "Unknown";
432 sprintf (new->fullname, "%-30.*s %*.*s",
433 hostname->length, hostname->data,
434 status->length, status->length, status->data);
437 RebuildTable (NameTableSize);
439 RebuildTableAdd (NameTableSize);
444 DisposeHostname (HostName *host)
446 XdmcpDisposeARRAY8 (&host->hostname);
447 XdmcpDisposeARRAY8 (&host->hostaddr);
448 XdmcpDisposeARRAY8 (&host->status);
449 free ((char *) host->fullname);
450 free ((char *) host);
454 RemoveHostname (HostName *host)
456 HostName **prev, *hosts;
459 for (hosts = hostNamedb; hosts; hosts = hosts->next)
468 DisposeHostname (host);
470 RebuildTable (NameTableSize);
476 EmptyHostnames (void)
478 HostName *hosts, *next;
480 for (hosts = hostNamedb; hosts; hosts = next)
483 DisposeHostname (hosts);
487 RebuildTable (NameTableSize);
492 ReceivePacket (XtPointer closure, int *source, XtInputId *id)
495 ARRAY8 authenticationName;
498 int saveHostname = 0;
499 struct sockaddr addr;
502 addrlen = sizeof (addr);
503 if (!XdmcpFill (socketFD, &buffer, (XdmcpNetaddr) &addr, &addrlen))
505 if (!XdmcpReadHeader (&buffer, &header))
507 if (header.version != XDM_PROTOCOL_VERSION)
511 authenticationName.data = 0;
512 switch (header.opcode) {
514 if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
515 XdmcpReadARRAY8 (&buffer, &hostname) &&
516 XdmcpReadARRAY8 (&buffer, &status))
518 if (header.length == 6 + authenticationName.length +
519 hostname.length + status.length)
521 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
525 XdmcpDisposeARRAY8 (&authenticationName);
528 if (XdmcpReadARRAY8 (&buffer, &hostname) &&
529 XdmcpReadARRAY8 (&buffer, &status))
531 if (header.length == 4 + hostname.length + status.length)
533 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
544 XdmcpDisposeARRAY8 (&hostname);
545 XdmcpDisposeARRAY8 (&status);
550 RegisterHostaddr (struct sockaddr *addr, int len, xdmOpCode type)
552 HostAddr *host, **prev;
554 host = (HostAddr *) malloc (sizeof (HostAddr));
557 host->addr = (struct sockaddr *) malloc (len);
560 free ((char *) host);
563 memmove( (char *) host->addr, (char *) addr, len);
566 for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
574 * Register the address for this host.
575 * Called with each of the names on the command line.
576 * The special name "BROADCAST" looks up all the broadcast
577 * addresses on the local host.
580 RegisterHostname (char *name)
582 struct hostent *hostent;
583 struct sockaddr_in in_addr;
585 register struct ifreq *ifr;
586 struct sockaddr broad_addr;
590 if (!strcmp (name, BROADCAST_HOSTNAME))
592 ifc.ifc_len = sizeof (buf);
594 if (ioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
596 for (ifr = ifc.ifc_req
597 #if defined (__bsdi__) || defined(__NetBSD__)
598 ; (char *)ifr < ifc.ifc_buf + ifc.ifc_len;
599 ifr = (struct ifreq *)((char *)ifr + sizeof (struct ifreq) +
600 (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr) ?
601 ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr) : 0))
603 , n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++
607 if (ifr->ifr_addr.sa_family != AF_INET)
610 broad_addr = ifr->ifr_addr;
611 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
612 htonl (INADDR_BROADCAST);
613 #ifdef SIOCGIFBRDADDR
615 struct ifreq broad_req;
618 if (ioctl (socketFD, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
619 (broad_req.ifr_flags & IFF_BROADCAST) &&
620 (broad_req.ifr_flags & IFF_UP)
624 if (ioctl (socketFD, SIOCGIFBRDADDR, &broad_req) != -1)
625 broad_addr = broad_req.ifr_addr;
633 in_addr = *((struct sockaddr_in *) &broad_addr);
634 in_addr.sin_port = htons (XDM_UDP_PORT);
636 in_addr.sin_len = sizeof(in_addr);
638 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
645 /* address as hex string, e.g., "12180022" (depreciated) */
646 if (strlen(name) == 8 &&
647 FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
649 in_addr.sin_family = AF_INET;
651 /* Per RFC 1123, check first for IP address in dotted-decimal form */
652 else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
653 in_addr.sin_family = AF_INET;
656 hostent = gethostbyname (name);
659 if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
661 in_addr.sin_family = hostent->h_addrtype;
662 memmove( &in_addr.sin_addr, hostent->h_addr, 4);
664 in_addr.sin_port = htons (XDM_UDP_PORT);
666 in_addr.sin_len = sizeof(in_addr);
668 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
674 static ARRAYofARRAY8 AuthenticationNames;
677 RegisterAuthenticationName (char *name, int namelen)
680 if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
681 AuthenticationNames.length + 1))
683 authName = &AuthenticationNames.data[AuthenticationNames.length-1];
684 if (!XdmcpAllocARRAY8 (authName, namelen))
686 memmove( authName->data, name, namelen);
692 InitXDMCP (char **argv)
699 header.version = XDM_PROTOCOL_VERSION;
700 header.opcode = (CARD16) BROADCAST_QUERY;
702 for (i = 0; i < (int)AuthenticationNames.length; i++)
703 header.length += 2 + AuthenticationNames.data[i].length;
704 XdmcpWriteHeader (&broadcastBuffer, &header);
705 XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);
707 header.version = XDM_PROTOCOL_VERSION;
708 header.opcode = (CARD16) QUERY;
710 for (i = 0; i < (int)AuthenticationNames.length; i++)
711 header.length += 2 + AuthenticationNames.data[i].length;
712 XdmcpWriteHeader (&directBuffer, &header);
713 XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
714 if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
718 if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, sizeof (soopts)) < 0)
719 perror ("setsockopt");
722 XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
726 RegisterHostname (*argv);
730 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
737 if (app_resources.xdmAddress)
739 struct sockaddr_in in_addr;
740 struct sockaddr *addr;
748 xdm = (char *) app_resources.xdmAddress->data;
749 family = (xdm[0] << 8) + xdm[1];
753 in_addr.sin_len = sizeof(in_addr);
755 in_addr.sin_family = family;
756 memmove( &in_addr.sin_port, xdm + 2, 2);
757 memmove( &in_addr.sin_addr, xdm + 4, 4);
758 addr = (struct sockaddr *) &in_addr;
759 len = sizeof (in_addr);
762 fprintf (stderr, "Unhandled protocol family %d\n", family);
763 exit (REMANAGE_DISPLAY);
765 if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
767 fprintf (stderr, "Cannot create response socket\n");
768 exit (REMANAGE_DISPLAY);
770 if (connect (fd, addr, len) == -1)
772 fprintf (stderr, "Cannot connect to xdm\n");
773 exit (REMANAGE_DISPLAY);
775 buffer.data = (BYTE *) buf;
776 buffer.size = sizeof (buf);
779 XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
780 XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
781 XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
782 if(-1 == write (fd, (char *)buffer.data, buffer.pointer)) {
783 perror(strerror(errno));
791 printf ("%u\n", h->connectionType);
792 for (i = 0; i < (int)h->hostaddr.length; i++)
793 printf ("%u%s", h->hostaddr.data[i],
794 i == h->hostaddr.length - 1 ? "\n" : " ");
800 DoAccept (Widget w, XEvent *event, String *params, Cardinal *num_params)
803 XmStringTable selectedItem;
808 /*********************************/
809 /** see if anything is selected **/
810 /*********************************/
812 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
813 XtGetValues(chooser_list, chooserArgs, i);
814 if (selectedCount != 1) {
815 XBell (XtDisplay (toplevel), 0);
819 /**********************************************/
820 /** retrieve the selected item from the list **/
821 /**********************************************/
823 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
824 XtGetValues(chooser_list, chooserArgs, i);
825 text = (char*) _XmStringUngenerate(
826 selectedItem[0], NULL,
827 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
828 if (NULL == text) return;
830 for (h = hostNamedb; h; h = h->next)
831 if (!strcmp (text, h->fullname))
835 if (NULL != text) XtFree(text);
836 exit (OBEYSESS_DISPLAY);
841 DoCheckWilling (Widget w, XEvent *event, String *params, Cardinal *num_params)
844 XmStringTable selectedItem;
849 /*********************************/
850 /** see if anything is selected **/
851 /*********************************/
853 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
854 XtGetValues(chooser_list, chooserArgs, i);
855 if (selectedCount != 1) {
859 /**********************************************/
860 /** retrieve the selected item from the list **/
861 /**********************************************/
863 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
864 XtGetValues(chooser_list, chooserArgs, i);
865 text = (char*) _XmStringUngenerate(
866 selectedItem[0], NULL,
867 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
868 if (NULL == text) return;
870 for (h = hostNamedb; h; h = h->next)
871 if (!strcmp (text, h->fullname))
873 XmListDeselectAllItems (chooser_list);
875 if (NULL != text) XtFree(text);
880 DoCancel (Widget w, XEvent *event, String *params, Cardinal *num_params)
882 exit (OBEYSESS_DISPLAY);
887 DoPing (Widget w, XEvent *event, String *params, Cardinal *num_params)
891 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
894 static XtActionsRec app_actions[] = {
897 "CheckWilling", DoCheckWilling,
902 main (int argc, char **argv)
905 Dimension width, height;
910 /******************************/
911 /** set the locale, and **/
912 /** open the message catalog **/
913 /******************************/
915 setlocale(LC_ALL, "");
916 XtSetLanguageProc( NULL, NULL, NULL );
917 langenv = getenv("LANG");
919 /******************************************/
920 /** set the font paths **/
921 /******************************************/
922 if ( (xsetup = getenv("XSETUP")) != NULL)
923 if(system(xsetup) == -1)
924 fprintf (stderr, "dtchooser: Cannot source %s\n",xsetup);
926 /******************************************/
927 /** save argc and argv for RespondLangCB **/
928 /******************************************/
929 amChooser = 1; /** tell RespondLangCB we are a chooser **/
931 orig_argv = (char **)malloc(sizeof(char *) * (orig_argc+1));
932 for (i = 0; i < orig_argc; i++) {
933 orig_argv[i] = argv[i];
935 orig_argv[orig_argc] = NULL;
937 toplevel = XtInitialize (argv[0], "Dtlogin", options, XtNumber(options),
940 XtVaSetValues(XmGetXmDisplay(XtDisplay(toplevel)),
941 XmNdragInitiatorProtocolStyle, XmDRAG_NONE,
944 XtAddConverter(XtRString, XtRARRAY8, CvtStringToARRAY8, NULL, 0);
946 XtGetApplicationResources (toplevel, (XtPointer) &app_resources, resources,
947 XtNumber (resources), NULL, (Cardinal) 0);
949 dpyinfo.dpy = XtDisplay(toplevel);
950 /* dpyinfo.name = "";*/
951 dpyinfo.screen = DefaultScreen(dpyinfo.dpy);
952 dpyinfo.root = RootWindow (dpyinfo.dpy, dpyinfo.screen);
953 dpyinfo.depth = DefaultDepth (dpyinfo.dpy, dpyinfo.screen);
954 dpyinfo.width = DisplayWidth (dpyinfo.dpy, dpyinfo.screen);
955 dpyinfo.height = DisplayHeight(dpyinfo.dpy, dpyinfo.screen);
956 dpyinfo.black_pixel = BlackPixel (dpyinfo.dpy, dpyinfo.screen);
957 dpyinfo.visual = DefaultVisual(dpyinfo.dpy, dpyinfo.screen);
963 MakeBackground(); /* login_shell, table, matte */
964 MakeLogo(); /* logo, logo_pixmap, logo_shadow */
965 MakeButtons(); /* Push Buttons */
966 MakeChooser(); /* Chooser List ... */
968 if (appInfo.optionsDelay == 0 )
969 MakeOptionsMenu(); /* make option_button pop-up menu */
971 XtAddTimeOut((unsigned long) appInfo.optionsDelay * 1000, MakeOptionsProc, NULL);
975 * center ourselves on the screen
977 XtSetMappedWhenManaged(toplevel, FALSE);
978 XtRealizeWidget (toplevel);
980 XtRealizeWidget (login_shell);
981 XtPopup(login_shell, XtGrabNone);
983 XtSetArg (position[0], XtNwidth, &width);
984 XtSetArg (position[1], XtNheight, &height);
985 XtGetValues (login_shell, position, (Cardinal) 2);
986 x = (Position)(WidthOfScreen (XtScreen (toplevel)) - width) / 2;
987 y = (Position)(HeightOfScreen (XtScreen (toplevel)) - height) / 3;
988 XtSetArg (position[0], XtNx, x);
989 XtSetArg (position[1], XtNy, y);
990 XtSetValues (login_shell, position, (Cardinal) 2);
997 XtMapWidget(toplevel);
999 InitXDMCP (argv + 1);
1005 /* Converts the hex string s of length len into the byte array d.
1006 Returns 0 if s was a legal hex string, 1 otherwise.
1009 FromHex (char *s, char *d, int len)
1012 int ret = len&1; /* odd-length hex strings are illegal */
1015 #define HexChar(c) ('0' <= (c) && (c) <= '9' ? (c) - '0' : (c) - 'a' + 10)
1017 if (!ishexdigit(*s))
1019 t = HexChar (*s) << 4;
1021 if (!ishexdigit(*s))
1033 CvtStringToARRAY8 (XrmValuePtr args, Cardinal *num_args, XrmValuePtr fromVal, XrmValuePtr toVal)
1035 static ARRAY8Ptr dest;
1039 dest = (ARRAY8Ptr) XtMalloc (sizeof (ARRAY8));
1040 len = fromVal->size;
1041 s = (char *) fromVal->addr;
1042 if (!XdmcpAllocARRAY8 (dest, len >> 1))
1043 XtStringConversionWarning ((char *) fromVal->addr, XtRARRAY8);
1046 FromHex (s, (char *) dest->data, len);
1048 toVal->addr = (caddr_t) &dest;
1049 toVal->size = sizeof (ARRAY8Ptr);