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 #define offset(field) XtOffsetOf(struct _app_resources, field)
165 #define XtRARRAY8 "ARRAY8"
167 static XtResource resources[] = {
168 {"xdmAddress", "XdmAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
169 offset (xdmAddress), XtRString, NULL },
170 {"clientAddress", "ClientAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
171 offset (clientAddress), XtRString, NULL },
172 {"connectionType", "ConnectionType", XtRInt, sizeof (int),
173 offset (connectionType), XtRImmediate, (XtPointer) 0 }
177 static XrmOptionDescRec options[] = {
178 "-xdmaddress", "*xdmAddress", XrmoptionSepArg, NULL,
179 "-clientaddress", "*clientAddress", XrmoptionSepArg, NULL,
180 "-connectionType", "*connectionType", XrmoptionSepArg, NULL,
183 typedef struct _hostAddr {
184 struct _hostAddr *next;
185 struct sockaddr *addr;
190 static HostAddr *hostAddrdb;
192 typedef struct _hostName {
193 struct _hostName *next;
196 ARRAY8 hostname, status;
197 CARD16 connectionType;
201 static HostName *hostNamedb;
207 #define PING_INTERVAL 2000
210 static XdmcpBuffer directBuffer, broadcastBuffer;
211 static XdmcpBuffer buffer;
216 PingHosts (closure, 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);
237 HostnameCompare (a, b)
238 #if defined(__STDC__)
244 return strcmp (*(char **)a, *(char **)b);
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 (size)
310 newTable = (char **) malloc (size * sizeof (char *));
313 for (names = hostNamedb, i = 0; names; names = names->next, i++)
314 newTable[i] = names->fullname;
315 qsort (newTable, size, sizeof (char *), HostnameCompare);
318 for (i = 0; i < size; i++) {
319 tempString = XmStringCreateLocalized(newTable[i]);
320 if ((position = XmListItemPos(chooser_list, tempString)) == 0) {
321 /****************************/
322 /** need to add a new host **/
323 /****************************/
324 XmListAddItemUnselected(chooser_list, tempString, (i+1));
325 XmStringFree(tempString);
328 XmStringFree(tempString);
332 free ((char *) NameTable);
333 NameTable = newTable;
334 NameTableSize = size;
339 AddHostname (hostname, status, addr, willing)
340 ARRAY8Ptr hostname, status;
341 struct sockaddr *addr;
344 HostName *new, **names, *name;
346 CARD16 connectionType;
350 switch (addr->sa_family)
353 hostAddr.data = (CARD8 *) &((struct sockaddr_in *) addr)->sin_addr;
355 connectionType = FamilyInternet;
358 hostAddr.data = (CARD8 *) "";
360 connectionType = FamilyLocal;
363 for (names = &hostNamedb; *names; names = & (*names)->next)
366 if (connectionType == name->connectionType &&
367 XdmcpARRAY8Equal (&hostAddr, &name->hostaddr))
369 if (XdmcpARRAY8Equal (status, &name->status))
379 new = (HostName *) malloc (sizeof (HostName));
382 if (hostname->length)
384 switch (addr->sa_family)
388 struct hostent *hostent;
391 hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, AF_INET);
394 XdmcpDisposeARRAY8 (hostname);
395 host = hostent->h_name;
396 XdmcpAllocARRAY8 (hostname, strlen (host));
397 memmove( hostname->data, host, hostname->length);
402 if (!XdmcpAllocARRAY8 (&new->hostaddr, hostAddr.length))
404 free ((char *) new->fullname);
408 memmove( new->hostaddr.data, hostAddr.data, hostAddr.length);
409 new->connectionType = connectionType;
410 new->hostname = *hostname;
419 free (new->fullname);
420 XdmcpDisposeARRAY8 (&new->status);
421 XdmcpDisposeARRAY8 (hostname);
423 new->willing = willing;
424 new->status = *status;
426 hostname = &new->hostname;
427 fulllen = hostname->length;
430 new->fullname = malloc (fulllen + status->length + 10);
433 new->fullname = "Unknown";
437 sprintf (new->fullname, "%-30.*s %*.*s",
438 hostname->length, hostname->data,
439 status->length, status->length, status->data);
442 RebuildTable (NameTableSize);
444 RebuildTableAdd (NameTableSize);
449 DisposeHostname (host)
452 XdmcpDisposeARRAY8 (&host->hostname);
453 XdmcpDisposeARRAY8 (&host->hostaddr);
454 XdmcpDisposeARRAY8 (&host->status);
455 free ((char *) host->fullname);
456 free ((char *) host);
460 RemoveHostname (host)
463 HostName **prev, *hosts;
466 for (hosts = hostNamedb; hosts; hosts = hosts->next)
475 DisposeHostname (host);
477 RebuildTable (NameTableSize);
483 HostName *hosts, *next;
485 for (hosts = hostNamedb; hosts; hosts = next)
488 DisposeHostname (hosts);
492 RebuildTable (NameTableSize);
497 ReceivePacket (closure, source, id)
503 ARRAY8 authenticationName;
506 int saveHostname = 0;
507 struct sockaddr addr;
510 addrlen = sizeof (addr);
511 if (!XdmcpFill (socketFD, &buffer, &addr, &addrlen))
513 if (!XdmcpReadHeader (&buffer, &header))
515 if (header.version != XDM_PROTOCOL_VERSION)
519 authenticationName.data = 0;
520 switch (header.opcode) {
522 if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
523 XdmcpReadARRAY8 (&buffer, &hostname) &&
524 XdmcpReadARRAY8 (&buffer, &status))
526 if (header.length == 6 + authenticationName.length +
527 hostname.length + status.length)
529 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
533 XdmcpDisposeARRAY8 (&authenticationName);
536 if (XdmcpReadARRAY8 (&buffer, &hostname) &&
537 XdmcpReadARRAY8 (&buffer, &status))
539 if (header.length == 4 + hostname.length + status.length)
541 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
552 XdmcpDisposeARRAY8 (&hostname);
553 XdmcpDisposeARRAY8 (&status);
557 RegisterHostaddr (addr, len, type)
558 struct sockaddr *addr;
562 HostAddr *host, **prev;
564 host = (HostAddr *) malloc (sizeof (HostAddr));
567 host->addr = (struct sockaddr *) malloc (len);
570 free ((char *) host);
573 memmove( (char *) host->addr, (char *) addr, len);
576 for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
583 * Register the address for this host.
584 * Called with each of the names on the command line.
585 * The special name "BROADCAST" looks up all the broadcast
586 * addresses on the local host.
589 RegisterHostname (name)
592 struct hostent *hostent;
593 struct sockaddr_in in_addr;
595 register struct ifreq *ifr;
596 struct sockaddr broad_addr;
600 if (!strcmp (name, BROADCAST_HOSTNAME))
602 ifc.ifc_len = sizeof (buf);
604 if (ioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
606 for (ifr = ifc.ifc_req
607 #if defined (__bsdi__) || defined(__NetBSD__)
608 ; (char *)ifr < ifc.ifc_buf + ifc.ifc_len;
609 ifr = (struct ifreq *)((char *)ifr + sizeof (struct ifreq) +
610 (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr) ?
611 ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr) : 0))
613 , n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++
617 if (ifr->ifr_addr.sa_family != AF_INET)
620 broad_addr = ifr->ifr_addr;
621 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
622 htonl (INADDR_BROADCAST);
623 #ifdef SIOCGIFBRDADDR
625 struct ifreq broad_req;
628 if (ioctl (socketFD, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
629 (broad_req.ifr_flags & IFF_BROADCAST) &&
630 (broad_req.ifr_flags & IFF_UP)
634 if (ioctl (socketFD, SIOCGIFBRDADDR, &broad_req) != -1)
635 broad_addr = broad_req.ifr_addr;
643 in_addr = *((struct sockaddr_in *) &broad_addr);
644 in_addr.sin_port = htons (XDM_UDP_PORT);
646 in_addr.sin_len = sizeof(in_addr);
648 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
655 /* address as hex string, e.g., "12180022" (depreciated) */
656 if (strlen(name) == 8 &&
657 FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
659 in_addr.sin_family = AF_INET;
661 /* Per RFC 1123, check first for IP address in dotted-decimal form */
662 else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
663 in_addr.sin_family = AF_INET;
666 hostent = gethostbyname (name);
669 if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
671 in_addr.sin_family = hostent->h_addrtype;
672 memmove( &in_addr.sin_addr, hostent->h_addr, 4);
674 in_addr.sin_port = htons (XDM_UDP_PORT);
676 in_addr.sin_len = sizeof(in_addr);
678 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
683 static ARRAYofARRAY8 AuthenticationNames;
685 RegisterAuthenticationName (name, namelen)
690 if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
691 AuthenticationNames.length + 1))
693 authName = &AuthenticationNames.data[AuthenticationNames.length-1];
694 if (!XdmcpAllocARRAY8 (authName, namelen))
696 memmove( authName->data, name, namelen);
707 header.version = XDM_PROTOCOL_VERSION;
708 header.opcode = (CARD16) BROADCAST_QUERY;
710 for (i = 0; i < (int)AuthenticationNames.length; i++)
711 header.length += 2 + AuthenticationNames.data[i].length;
712 XdmcpWriteHeader (&broadcastBuffer, &header);
713 XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);
715 header.version = XDM_PROTOCOL_VERSION;
716 header.opcode = (CARD16) QUERY;
718 for (i = 0; i < (int)AuthenticationNames.length; i++)
719 header.length += 2 + AuthenticationNames.data[i].length;
720 XdmcpWriteHeader (&directBuffer, &header);
721 XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
722 if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
726 if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, sizeof (soopts)) < 0)
727 perror ("setsockopt");
730 XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
734 RegisterHostname (*argv);
738 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
746 if (app_resources.xdmAddress)
748 struct sockaddr_in in_addr;
749 struct sockaddr *addr;
757 xdm = (char *) app_resources.xdmAddress->data;
758 family = (xdm[0] << 8) + xdm[1];
762 in_addr.sin_len = sizeof(in_addr);
764 in_addr.sin_family = family;
765 memmove( &in_addr.sin_port, xdm + 2, 2);
766 memmove( &in_addr.sin_addr, xdm + 4, 4);
767 addr = (struct sockaddr *) &in_addr;
768 len = sizeof (in_addr);
771 if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
773 fprintf (stderr, "Cannot create response socket\n");
774 exit (REMANAGE_DISPLAY);
776 if (connect (fd, addr, len) == -1)
778 fprintf (stderr, "Cannot connect to xdm\n");
779 exit (REMANAGE_DISPLAY);
781 buffer.data = (BYTE *) buf;
782 buffer.size = sizeof (buf);
785 XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
786 XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
787 XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
788 write (fd, (char *)buffer.data, buffer.pointer);
795 printf ("%u\n", h->connectionType);
796 for (i = 0; i < (int)h->hostaddr.length; i++)
797 printf ("%u%s", h->hostaddr.data[i],
798 i == h->hostaddr.length - 1 ? "\n" : " ");
804 DoAccept (w, event, params, num_params)
808 Cardinal *num_params;
811 XmStringTable selectedItem;
816 /*********************************/
817 /** see if anything is selected **/
818 /*********************************/
820 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
821 XtGetValues(chooser_list, chooserArgs, i);
822 if (selectedCount != 1) {
823 XBell (XtDisplay (toplevel), 0);
827 /**********************************************/
828 /** retrieve the selected item from the list **/
829 /**********************************************/
831 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
832 XtGetValues(chooser_list, chooserArgs, i);
833 text = (char*) _XmStringUngenerate(
834 selectedItem[0], NULL,
835 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
836 if (NULL == text) return;
838 for (h = hostNamedb; h; h = h->next)
839 if (!strcmp (text, h->fullname))
843 if (NULL != text) XtFree(text);
844 exit (OBEYSESS_DISPLAY);
849 DoCheckWilling (w, event, params, num_params)
853 Cardinal *num_params;
856 XmStringTable selectedItem;
861 /*********************************/
862 /** see if anything is selected **/
863 /*********************************/
865 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
866 XtGetValues(chooser_list, chooserArgs, i);
867 if (selectedCount != 1) {
871 /**********************************************/
872 /** retrieve the selected item from the list **/
873 /**********************************************/
875 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
876 XtGetValues(chooser_list, chooserArgs, i);
877 text = (char*) _XmStringUngenerate(
878 selectedItem[0], NULL,
879 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
880 if (NULL == text) return;
882 for (h = hostNamedb; h; h = h->next)
883 if (!strcmp (text, h->fullname))
885 XmListDeselectAllItems (chooser_list);
887 if (NULL != text) XtFree(text);
892 DoCancel (w, event, params, num_params)
896 Cardinal *num_params;
898 exit (OBEYSESS_DISPLAY);
903 DoPing (w, event, params, num_params)
907 Cardinal *num_params;
911 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
914 static XtActionsRec app_actions[] = {
917 "CheckWilling", DoCheckWilling,
925 Dimension width, height;
930 /******************************/
931 /** set the locale, and **/
932 /** open the message catalog **/
933 /******************************/
935 setlocale(LC_ALL, "");
936 XtSetLanguageProc( NULL, NULL, NULL );
937 langenv = getenv("LANG");
939 /******************************************/
940 /** set the font paths **/
941 /******************************************/
942 if ( (xsetup = getenv("XSETUP")) != NULL)
943 if(system(xsetup) == -1)
944 fprintf (stderr, "dtchooser: Cannot source %s\n",xsetup);
946 /******************************************/
947 /** save argc and argv for RespondLangCB **/
948 /******************************************/
949 amChooser = 1; /** tell RespondLangCB we are a chooser **/
951 orig_argv = (char **)malloc(sizeof(char *) * (orig_argc+1));
952 for (i = 0; i < orig_argc; i++) {
953 orig_argv[i] = argv[i];
955 orig_argv[orig_argc] = NULL;
957 toplevel = XtInitialize (argv[0], "Dtlogin", options, XtNumber(options),
960 XtVaSetValues(XmGetXmDisplay(XtDisplay(toplevel)),
961 XmNdragInitiatorProtocolStyle, XmDRAG_NONE,
964 XtAddConverter(XtRString, XtRARRAY8, CvtStringToARRAY8, NULL, 0);
966 XtGetApplicationResources (toplevel, (XtPointer) &app_resources, resources,
967 XtNumber (resources), NULL, (Cardinal) 0);
969 dpyinfo.dpy = XtDisplay(toplevel);
970 /* dpyinfo.name = "";*/
971 dpyinfo.screen = DefaultScreen(dpyinfo.dpy);
972 dpyinfo.root = RootWindow (dpyinfo.dpy, dpyinfo.screen);
973 dpyinfo.depth = DefaultDepth (dpyinfo.dpy, dpyinfo.screen);
974 dpyinfo.width = DisplayWidth (dpyinfo.dpy, dpyinfo.screen);
975 dpyinfo.height = DisplayHeight(dpyinfo.dpy, dpyinfo.screen);
976 dpyinfo.black_pixel = BlackPixel (dpyinfo.dpy, dpyinfo.screen);
977 dpyinfo.visual = DefaultVisual(dpyinfo.dpy, dpyinfo.screen);
983 MakeBackground(); /* login_shell, table, matte */
984 MakeLogo(); /* logo, logo_pixmap, logo_shadow */
985 MakeButtons(); /* Push Buttons */
986 MakeChooser(); /* Chooser List ... */
988 if (appInfo.optionsDelay == 0 )
989 MakeOptionsMenu(); /* make option_button pop-up menu */
991 XtAddTimeOut((unsigned long) appInfo.optionsDelay * 1000, MakeOptionsProc, NULL);
995 * center ourselves on the screen
997 XtSetMappedWhenManaged(toplevel, FALSE);
998 XtRealizeWidget (toplevel);
1000 XtRealizeWidget (login_shell);
1001 XtPopup(login_shell, XtGrabNone);
1003 XtSetArg (position[0], XtNwidth, &width);
1004 XtSetArg (position[1], XtNheight, &height);
1005 XtGetValues (login_shell, position, (Cardinal) 2);
1006 x = (Position)(WidthOfScreen (XtScreen (toplevel)) - width) / 2;
1007 y = (Position)(HeightOfScreen (XtScreen (toplevel)) - height) / 3;
1008 XtSetArg (position[0], XtNx, x);
1009 XtSetArg (position[1], XtNy, y);
1010 XtSetValues (login_shell, position, (Cardinal) 2);
1017 XtMapWidget(toplevel);
1019 InitXDMCP (argv + 1);
1025 /* Converts the hex string s of length len into the byte array d.
1026 Returns 0 if s was a legal hex string, 1 otherwise.
1034 int ret = len&1; /* odd-length hex strings are illegal */
1037 #define HexChar(c) ('0' <= (c) && (c) <= '9' ? (c) - '0' : (c) - 'a' + 10)
1039 if (!ishexdigit(*s))
1041 t = HexChar (*s) << 4;
1043 if (!ishexdigit(*s))
1055 CvtStringToARRAY8 (args, num_args, fromVal, toVal)
1058 XrmValuePtr fromVal;
1061 static ARRAY8Ptr dest;
1065 dest = (ARRAY8Ptr) XtMalloc (sizeof (ARRAY8));
1066 len = fromVal->size;
1067 s = (char *) fromVal->addr;
1068 if (!XdmcpAllocARRAY8 (dest, len >> 1))
1069 XtStringConversionWarning ((char *) fromVal->addr, XtRARRAY8);
1072 FromHex (s, (char *) dest->data, len);
1074 toVal->addr = (caddr_t) &dest;
1075 toVal->size = sizeof (ARRAY8Ptr);