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 librararies 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, hosts->addr, hosts->addrlen);
227 XdmcpFlush (socketFD, &broadcastBuffer, 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))
400 free ((char *) new->fullname);
404 memmove( new->hostaddr.data, hostAddr.data, hostAddr.length);
405 new->connectionType = connectionType;
406 new->hostname = *hostname;
415 free (new->fullname);
416 XdmcpDisposeARRAY8 (&new->status);
417 XdmcpDisposeARRAY8 (hostname);
419 new->willing = willing;
420 new->status = *status;
422 hostname = &new->hostname;
423 fulllen = hostname->length;
426 new->fullname = malloc (fulllen + status->length + 10);
429 new->fullname = "Unknown";
433 sprintf (new->fullname, "%-30.*s %*.*s",
434 hostname->length, hostname->data,
435 status->length, status->length, status->data);
438 RebuildTable (NameTableSize);
440 RebuildTableAdd (NameTableSize);
445 DisposeHostname (HostName *host)
447 XdmcpDisposeARRAY8 (&host->hostname);
448 XdmcpDisposeARRAY8 (&host->hostaddr);
449 XdmcpDisposeARRAY8 (&host->status);
450 free ((char *) host->fullname);
451 free ((char *) host);
455 RemoveHostname (HostName *host)
457 HostName **prev, *hosts;
460 for (hosts = hostNamedb; hosts; hosts = hosts->next)
469 DisposeHostname (host);
471 RebuildTable (NameTableSize);
477 EmptyHostnames (void)
479 HostName *hosts, *next;
481 for (hosts = hostNamedb; hosts; hosts = next)
484 DisposeHostname (hosts);
488 RebuildTable (NameTableSize);
493 ReceivePacket (XtPointer closure, int *source, XtInputId *id)
496 ARRAY8 authenticationName;
499 int saveHostname = 0;
500 struct sockaddr addr;
503 addrlen = sizeof (addr);
504 if (!XdmcpFill (socketFD, &buffer, &addr, &addrlen))
506 if (!XdmcpReadHeader (&buffer, &header))
508 if (header.version != XDM_PROTOCOL_VERSION)
512 authenticationName.data = 0;
513 switch (header.opcode) {
515 if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
516 XdmcpReadARRAY8 (&buffer, &hostname) &&
517 XdmcpReadARRAY8 (&buffer, &status))
519 if (header.length == 6 + authenticationName.length +
520 hostname.length + status.length)
522 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
526 XdmcpDisposeARRAY8 (&authenticationName);
529 if (XdmcpReadARRAY8 (&buffer, &hostname) &&
530 XdmcpReadARRAY8 (&buffer, &status))
532 if (header.length == 4 + hostname.length + status.length)
534 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
545 XdmcpDisposeARRAY8 (&hostname);
546 XdmcpDisposeARRAY8 (&status);
551 RegisterHostaddr (struct sockaddr *addr, int len, xdmOpCode type)
553 HostAddr *host, **prev;
555 host = (HostAddr *) malloc (sizeof (HostAddr));
558 host->addr = (struct sockaddr *) malloc (len);
561 free ((char *) host);
564 memmove( (char *) host->addr, (char *) addr, len);
567 for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
575 * Register the address for this host.
576 * Called with each of the names on the command line.
577 * The special name "BROADCAST" looks up all the broadcast
578 * addresses on the local host.
581 RegisterHostname (char *name)
583 struct hostent *hostent;
584 struct sockaddr_in in_addr;
586 register struct ifreq *ifr;
587 struct sockaddr broad_addr;
591 if (!strcmp (name, BROADCAST_HOSTNAME))
593 ifc.ifc_len = sizeof (buf);
595 if (ioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
597 for (ifr = ifc.ifc_req
598 #if defined (__bsdi__) || defined(__NetBSD__)
599 ; (char *)ifr < ifc.ifc_buf + ifc.ifc_len;
600 ifr = (struct ifreq *)((char *)ifr + sizeof (struct ifreq) +
601 (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr) ?
602 ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr) : 0))
604 , n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++
608 if (ifr->ifr_addr.sa_family != AF_INET)
611 broad_addr = ifr->ifr_addr;
612 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
613 htonl (INADDR_BROADCAST);
614 #ifdef SIOCGIFBRDADDR
616 struct ifreq broad_req;
619 if (ioctl (socketFD, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
620 (broad_req.ifr_flags & IFF_BROADCAST) &&
621 (broad_req.ifr_flags & IFF_UP)
625 if (ioctl (socketFD, SIOCGIFBRDADDR, &broad_req) != -1)
626 broad_addr = broad_req.ifr_addr;
634 in_addr = *((struct sockaddr_in *) &broad_addr);
635 in_addr.sin_port = htons (XDM_UDP_PORT);
637 in_addr.sin_len = sizeof(in_addr);
639 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
646 /* address as hex string, e.g., "12180022" (depreciated) */
647 if (strlen(name) == 8 &&
648 FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
650 in_addr.sin_family = AF_INET;
652 /* Per RFC 1123, check first for IP address in dotted-decimal form */
653 else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
654 in_addr.sin_family = AF_INET;
657 hostent = gethostbyname (name);
660 if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
662 in_addr.sin_family = hostent->h_addrtype;
663 memmove( &in_addr.sin_addr, hostent->h_addr, 4);
665 in_addr.sin_port = htons (XDM_UDP_PORT);
667 in_addr.sin_len = sizeof(in_addr);
669 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
675 static ARRAYofARRAY8 AuthenticationNames;
678 RegisterAuthenticationName (char *name, int namelen)
681 if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
682 AuthenticationNames.length + 1))
684 authName = &AuthenticationNames.data[AuthenticationNames.length-1];
685 if (!XdmcpAllocARRAY8 (authName, namelen))
687 memmove( authName->data, name, namelen);
693 InitXDMCP (char **argv)
700 header.version = XDM_PROTOCOL_VERSION;
701 header.opcode = (CARD16) BROADCAST_QUERY;
703 for (i = 0; i < (int)AuthenticationNames.length; i++)
704 header.length += 2 + AuthenticationNames.data[i].length;
705 XdmcpWriteHeader (&broadcastBuffer, &header);
706 XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);
708 header.version = XDM_PROTOCOL_VERSION;
709 header.opcode = (CARD16) QUERY;
711 for (i = 0; i < (int)AuthenticationNames.length; i++)
712 header.length += 2 + AuthenticationNames.data[i].length;
713 XdmcpWriteHeader (&directBuffer, &header);
714 XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
715 if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
719 if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, sizeof (soopts)) < 0)
720 perror ("setsockopt");
723 XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
727 RegisterHostname (*argv);
731 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
738 if (app_resources.xdmAddress)
740 struct sockaddr_in in_addr;
741 struct sockaddr *addr;
749 xdm = (char *) app_resources.xdmAddress->data;
750 family = (xdm[0] << 8) + xdm[1];
754 in_addr.sin_len = sizeof(in_addr);
756 in_addr.sin_family = family;
757 memmove( &in_addr.sin_port, xdm + 2, 2);
758 memmove( &in_addr.sin_addr, xdm + 4, 4);
759 addr = (struct sockaddr *) &in_addr;
760 len = sizeof (in_addr);
763 if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
765 fprintf (stderr, "Cannot create response socket\n");
766 exit (REMANAGE_DISPLAY);
768 if (connect (fd, addr, len) == -1)
770 fprintf (stderr, "Cannot connect to xdm\n");
771 exit (REMANAGE_DISPLAY);
773 buffer.data = (BYTE *) buf;
774 buffer.size = sizeof (buf);
777 XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
778 XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
779 XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
780 if(-1 == write (fd, (char *)buffer.data, buffer.pointer)) {
781 perror(strerror(errno));
789 printf ("%u\n", h->connectionType);
790 for (i = 0; i < (int)h->hostaddr.length; i++)
791 printf ("%u%s", h->hostaddr.data[i],
792 i == h->hostaddr.length - 1 ? "\n" : " ");
798 DoAccept (Widget w, XEvent *event, String *params, Cardinal *num_params)
801 XmStringTable selectedItem;
806 /*********************************/
807 /** see if anything is selected **/
808 /*********************************/
810 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
811 XtGetValues(chooser_list, chooserArgs, i);
812 if (selectedCount != 1) {
813 XBell (XtDisplay (toplevel), 0);
817 /**********************************************/
818 /** retrieve the selected item from the list **/
819 /**********************************************/
821 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
822 XtGetValues(chooser_list, chooserArgs, i);
823 text = (char*) _XmStringUngenerate(
824 selectedItem[0], NULL,
825 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
826 if (NULL == text) return;
828 for (h = hostNamedb; h; h = h->next)
829 if (!strcmp (text, h->fullname))
833 if (NULL != text) XtFree(text);
834 exit (OBEYSESS_DISPLAY);
839 DoCheckWilling (Widget w, XEvent *event, String *params, Cardinal *num_params)
842 XmStringTable selectedItem;
847 /*********************************/
848 /** see if anything is selected **/
849 /*********************************/
851 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
852 XtGetValues(chooser_list, chooserArgs, i);
853 if (selectedCount != 1) {
857 /**********************************************/
858 /** retrieve the selected item from the list **/
859 /**********************************************/
861 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
862 XtGetValues(chooser_list, chooserArgs, i);
863 text = (char*) _XmStringUngenerate(
864 selectedItem[0], NULL,
865 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
866 if (NULL == text) return;
868 for (h = hostNamedb; h; h = h->next)
869 if (!strcmp (text, h->fullname))
871 XmListDeselectAllItems (chooser_list);
873 if (NULL != text) XtFree(text);
878 DoCancel (Widget w, XEvent *event, String *params, Cardinal *num_params)
880 exit (OBEYSESS_DISPLAY);
885 DoPing (Widget w, XEvent *event, String *params, Cardinal *num_params)
889 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
892 static XtActionsRec app_actions[] = {
895 "CheckWilling", DoCheckWilling,
900 main (int argc, char **argv)
903 Dimension width, height;
908 /******************************/
909 /** set the locale, and **/
910 /** open the message catalog **/
911 /******************************/
913 setlocale(LC_ALL, "");
914 XtSetLanguageProc( NULL, NULL, NULL );
915 langenv = getenv("LANG");
917 /******************************************/
918 /** set the font paths **/
919 /******************************************/
920 if ( (xsetup = getenv("XSETUP")) != NULL)
921 if(system(xsetup) == -1)
922 fprintf (stderr, "dtchooser: Cannot source %s\n",xsetup);
924 /******************************************/
925 /** save argc and argv for RespondLangCB **/
926 /******************************************/
927 amChooser = 1; /** tell RespondLangCB we are a chooser **/
929 orig_argv = (char **)malloc(sizeof(char *) * (orig_argc+1));
930 for (i = 0; i < orig_argc; i++) {
931 orig_argv[i] = argv[i];
933 orig_argv[orig_argc] = NULL;
935 toplevel = XtInitialize (argv[0], "Dtlogin", options, XtNumber(options),
938 XtVaSetValues(XmGetXmDisplay(XtDisplay(toplevel)),
939 XmNdragInitiatorProtocolStyle, XmDRAG_NONE,
942 XtAddConverter(XtRString, XtRARRAY8, CvtStringToARRAY8, NULL, 0);
944 XtGetApplicationResources (toplevel, (XtPointer) &app_resources, resources,
945 XtNumber (resources), NULL, (Cardinal) 0);
947 dpyinfo.dpy = XtDisplay(toplevel);
948 /* dpyinfo.name = "";*/
949 dpyinfo.screen = DefaultScreen(dpyinfo.dpy);
950 dpyinfo.root = RootWindow (dpyinfo.dpy, dpyinfo.screen);
951 dpyinfo.depth = DefaultDepth (dpyinfo.dpy, dpyinfo.screen);
952 dpyinfo.width = DisplayWidth (dpyinfo.dpy, dpyinfo.screen);
953 dpyinfo.height = DisplayHeight(dpyinfo.dpy, dpyinfo.screen);
954 dpyinfo.black_pixel = BlackPixel (dpyinfo.dpy, dpyinfo.screen);
955 dpyinfo.visual = DefaultVisual(dpyinfo.dpy, dpyinfo.screen);
961 MakeBackground(); /* login_shell, table, matte */
962 MakeLogo(); /* logo, logo_pixmap, logo_shadow */
963 MakeButtons(); /* Push Buttons */
964 MakeChooser(); /* Chooser List ... */
966 if (appInfo.optionsDelay == 0 )
967 MakeOptionsMenu(); /* make option_button pop-up menu */
969 XtAddTimeOut((unsigned long) appInfo.optionsDelay * 1000, MakeOptionsProc, NULL);
973 * center ourselves on the screen
975 XtSetMappedWhenManaged(toplevel, FALSE);
976 XtRealizeWidget (toplevel);
978 XtRealizeWidget (login_shell);
979 XtPopup(login_shell, XtGrabNone);
981 XtSetArg (position[0], XtNwidth, &width);
982 XtSetArg (position[1], XtNheight, &height);
983 XtGetValues (login_shell, position, (Cardinal) 2);
984 x = (Position)(WidthOfScreen (XtScreen (toplevel)) - width) / 2;
985 y = (Position)(HeightOfScreen (XtScreen (toplevel)) - height) / 3;
986 XtSetArg (position[0], XtNx, x);
987 XtSetArg (position[1], XtNy, y);
988 XtSetValues (login_shell, position, (Cardinal) 2);
995 XtMapWidget(toplevel);
997 InitXDMCP (argv + 1);
1003 /* Converts the hex string s of length len into the byte array d.
1004 Returns 0 if s was a legal hex string, 1 otherwise.
1007 FromHex (char *s, char *d, int len)
1010 int ret = len&1; /* odd-length hex strings are illegal */
1013 #define HexChar(c) ('0' <= (c) && (c) <= '9' ? (c) - '0' : (c) - 'a' + 10)
1015 if (!ishexdigit(*s))
1017 t = HexChar (*s) << 4;
1019 if (!ishexdigit(*s))
1031 CvtStringToARRAY8 (XrmValuePtr args, Cardinal *num_args, XrmValuePtr fromVal, XrmValuePtr toVal)
1033 static ARRAY8Ptr dest;
1037 dest = (ARRAY8Ptr) XtMalloc (sizeof (ARRAY8));
1038 len = fromVal->size;
1039 s = (char *) fromVal->addr;
1040 if (!XdmcpAllocARRAY8 (dest, len >> 1))
1041 XtStringConversionWarning ((char *) fromVal->addr, XtRARRAY8);
1044 FromHex (s, (char *) dest->data, len);
1046 toVal->addr = (caddr_t) &dest;
1047 toVal->size = sizeof (ARRAY8Ptr);