2 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
3 * (c) Copyright 1993, 1994 International Business Machines Corp. *
4 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
5 * (c) Copyright 1993, 1994 Novell, Inc. *
8 * $TOG: chooser.c /main/8 1998/03/04 19:26:30 mgreess $
10 Copyright (c) 1990 X Consortium
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
19 The above copyright notice and this permission notice shall be included in
20 all copies or substantial portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 Except as contained in this notice, the name of the X Consortium shall not be
30 used in advertising or otherwise to promote the sale, use or other dealings
31 in this Software without prior written authorization from the X Consortium.
33 * Author: Keith Packard, MIT X Consortium
37 * Chooser - display a menu of names and let the user select one
43 * +--------------------------------------------------+
44 * | +------------------+ |
46 * | +------------------+ |
47 * | +-+--------------+ |
54 * | +----------------+ |
55 * | cancel accept ping |
56 * +--------------------------------------------------+
59 #include <X11/Intrinsic.h>
60 #include <X11/StringDefs.h>
61 #include <X11/Xatom.h>
75 #include <X11/Xdmcp.h>
77 #include <sys/types.h>
83 #define NL_CAT_LOCALE 0
87 #include <sys/sockio.h>
89 #include <sys/socket.h>
90 #include <netinet/in.h>
91 #include <sys/ioctl.h>
96 extern XtPointer _XmStringUngenerate (
100 XmTextType output_type);
102 #define BROADCAST_HOSTNAME "BROADCAST"
105 #define ishexdigit(c) (isdigit(c) || 'a' <= (c) && (c) <= 'f')
109 # include <sys/utsname.h>
115 # include <sync/queue.h>
116 # include <sync/sema.h>
123 Widget toplevel, label, viewport, paned, list, box, cancel, acceptit, ping;
125 extern Widget chooser_list;
126 extern int orig_argc;
127 extern char **orig_argv;
128 extern int amChooser;
129 extern void MakeOptionsProc();
131 static Arg chooserArgs[25]; /** Hopefully enough args **/
133 static void CvtStringToARRAY8();
135 static struct _app_resources {
136 ARRAY8Ptr xdmAddress;
137 ARRAY8Ptr clientAddress;
141 #define offset(field) XtOffsetOf(struct _app_resources, field)
143 #define XtRARRAY8 "ARRAY8"
145 static XtResource resources[] = {
146 {"xdmAddress", "XdmAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
147 offset (xdmAddress), XtRString, NULL },
148 {"clientAddress", "ClientAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
149 offset (clientAddress), XtRString, NULL },
150 {"connectionType", "ConnectionType", XtRInt, sizeof (int),
151 offset (connectionType), XtRImmediate, (XtPointer) 0 }
155 static XrmOptionDescRec options[] = {
156 "-xdmaddress", "*xdmAddress", XrmoptionSepArg, NULL,
157 "-clientaddress", "*clientAddress", XrmoptionSepArg, NULL,
158 "-connectionType", "*connectionType", XrmoptionSepArg, NULL,
161 typedef struct _hostAddr {
162 struct _hostAddr *next;
163 struct sockaddr *addr;
168 static HostAddr *hostAddrdb;
170 typedef struct _hostName {
171 struct _hostName *next;
174 ARRAY8 hostname, status;
175 CARD16 connectionType;
179 static HostName *hostNamedb;
185 #define PING_INTERVAL 2000
188 static XdmcpBuffer directBuffer, broadcastBuffer;
189 static XdmcpBuffer buffer;
194 PingHosts (closure, id)
200 for (hosts = hostAddrdb; hosts; hosts = hosts->next)
202 if (hosts->type == QUERY)
203 XdmcpFlush (socketFD, &directBuffer, hosts->addr, hosts->addrlen);
205 XdmcpFlush (socketFD, &broadcastBuffer, hosts->addr, hosts->addrlen);
207 if (++pingTry < TRIES)
208 XtAddTimeOut (PING_INTERVAL, PingHosts, (XtPointer) 0);
215 HostnameCompare (a, b)
216 #if defined(__STDC__)
222 return strcmp (*(char **)a, *(char **)b);
231 XmStringTable newStringTable;
237 newTable = (char **) malloc (size * sizeof (char *));
240 for (names = hostNamedb, i = 0; names; names = names->next, i++)
241 newTable[i] = names->fullname;
242 qsort (newTable, size, sizeof (char *), HostnameCompare);
245 XmListDeleteAllItems(chooser_list);
247 free((char *)NameTable);
252 /***********************************/
253 /** Reload the data in the XmList **/
254 /***********************************/
255 newStringTable = (XmStringTable)malloc(size * sizeof(XmString));
256 if (!newStringTable) {
257 free((char *)newTable);
260 for (i = 0; i < size; i++) {
261 newStringTable[i] = XmStringCreateLocalized(newTable[i]);
264 XtSetArg(listArgs[numArgs], XmNitemCount, size); numArgs++;
265 XtSetArg(listArgs[numArgs], XmNitems, newStringTable); numArgs++;
266 XtSetValues(chooser_list, listArgs, numArgs);
268 free((char *) newStringTable);
271 free ((char *) NameTable);
272 NameTable = newTable;
273 NameTableSize = size;
277 RebuildTableAdd (size)
288 newTable = (char **) malloc (size * sizeof (char *));
291 for (names = hostNamedb, i = 0; names; names = names->next, i++)
292 newTable[i] = names->fullname;
293 qsort (newTable, size, sizeof (char *), HostnameCompare);
296 for (i = 0; i < size; i++) {
297 tempString = XmStringCreateLocalized(newTable[i]);
298 if ((position = XmListItemPos(chooser_list, tempString)) == 0) {
299 /****************************/
300 /** need to add a new host **/
301 /****************************/
302 XmListAddItemUnselected(chooser_list, tempString, (i+1));
303 XmStringFree(tempString);
306 XmStringFree(tempString);
310 free ((char *) NameTable);
311 NameTable = newTable;
312 NameTableSize = size;
317 AddHostname (hostname, status, addr, willing)
318 ARRAY8Ptr hostname, status;
319 struct sockaddr *addr;
322 HostName *new, **names, *name;
324 CARD16 connectionType;
328 switch (addr->sa_family)
331 hostAddr.data = (CARD8 *) &((struct sockaddr_in *) addr)->sin_addr;
333 connectionType = FamilyInternet;
336 hostAddr.data = (CARD8 *) "";
338 connectionType = FamilyLocal;
341 for (names = &hostNamedb; *names; names = & (*names)->next)
344 if (connectionType == name->connectionType &&
345 XdmcpARRAY8Equal (&hostAddr, &name->hostaddr))
347 if (XdmcpARRAY8Equal (status, &name->status))
357 new = (HostName *) malloc (sizeof (HostName));
360 if (hostname->length)
362 switch (addr->sa_family)
366 struct hostent *hostent;
369 hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, AF_INET);
372 XdmcpDisposeARRAY8 (hostname);
373 host = hostent->h_name;
374 XdmcpAllocARRAY8 (hostname, strlen (host));
375 memmove( hostname->data, host, hostname->length);
380 if (!XdmcpAllocARRAY8 (&new->hostaddr, hostAddr.length))
382 free ((char *) new->fullname);
386 memmove( new->hostaddr.data, hostAddr.data, hostAddr.length);
387 new->connectionType = connectionType;
388 new->hostname = *hostname;
397 free (new->fullname);
398 XdmcpDisposeARRAY8 (&new->status);
399 XdmcpDisposeARRAY8 (hostname);
401 new->willing = willing;
402 new->status = *status;
404 hostname = &new->hostname;
405 fulllen = hostname->length;
408 new->fullname = malloc (fulllen + status->length + 10);
411 new->fullname = "Unknown";
415 sprintf (new->fullname, "%-30.*s %*.*s",
416 hostname->length, hostname->data,
417 status->length, status->length, status->data);
420 RebuildTable (NameTableSize);
422 RebuildTableAdd (NameTableSize);
427 DisposeHostname (host)
430 XdmcpDisposeARRAY8 (&host->hostname);
431 XdmcpDisposeARRAY8 (&host->hostaddr);
432 XdmcpDisposeARRAY8 (&host->status);
433 free ((char *) host->fullname);
434 free ((char *) host);
438 RemoveHostname (host)
441 HostName **prev, *hosts;
444 for (hosts = hostNamedb; hosts; hosts = hosts->next)
453 DisposeHostname (host);
455 RebuildTable (NameTableSize);
461 HostName *hosts, *next;
463 for (hosts = hostNamedb; hosts; hosts = next)
466 DisposeHostname (hosts);
470 RebuildTable (NameTableSize);
475 ReceivePacket (closure, source, id)
481 ARRAY8 authenticationName;
484 int saveHostname = 0;
485 struct sockaddr addr;
488 addrlen = sizeof (addr);
489 if (!XdmcpFill (socketFD, &buffer, &addr, &addrlen))
491 if (!XdmcpReadHeader (&buffer, &header))
493 if (header.version != XDM_PROTOCOL_VERSION)
497 authenticationName.data = 0;
498 switch (header.opcode) {
500 if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
501 XdmcpReadARRAY8 (&buffer, &hostname) &&
502 XdmcpReadARRAY8 (&buffer, &status))
504 if (header.length == 6 + authenticationName.length +
505 hostname.length + status.length)
507 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
511 XdmcpDisposeARRAY8 (&authenticationName);
514 if (XdmcpReadARRAY8 (&buffer, &hostname) &&
515 XdmcpReadARRAY8 (&buffer, &status))
517 if (header.length == 4 + hostname.length + status.length)
519 if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
530 XdmcpDisposeARRAY8 (&hostname);
531 XdmcpDisposeARRAY8 (&status);
535 RegisterHostaddr (addr, len, type)
536 struct sockaddr *addr;
540 HostAddr *host, **prev;
542 host = (HostAddr *) malloc (sizeof (HostAddr));
545 host->addr = (struct sockaddr *) malloc (len);
548 free ((char *) host);
551 memmove( (char *) host->addr, (char *) addr, len);
554 for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
561 * Register the address for this host.
562 * Called with each of the names on the command line.
563 * The special name "BROADCAST" looks up all the broadcast
564 * addresses on the local host.
567 RegisterHostname (name)
570 struct hostent *hostent;
571 struct sockaddr_in in_addr;
573 register struct ifreq *ifr;
574 struct sockaddr broad_addr;
578 if (!strcmp (name, BROADCAST_HOSTNAME))
580 ifc.ifc_len = sizeof (buf);
582 if (ioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
584 for (ifr = ifc.ifc_req
585 #if defined (__bsdi__) || defined(__NetBSD__)
586 ; (char *)ifr < ifc.ifc_buf + ifc.ifc_len;
587 ifr = (struct ifreq *)((char *)ifr + sizeof (struct ifreq) +
588 (ifr->ifr_addr.sa_len > sizeof (ifr->ifr_addr) ?
589 ifr->ifr_addr.sa_len - sizeof (ifr->ifr_addr) : 0))
591 , n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++
595 if (ifr->ifr_addr.sa_family != AF_INET)
598 broad_addr = ifr->ifr_addr;
599 ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
600 htonl (INADDR_BROADCAST);
601 #ifdef SIOCGIFBRDADDR
603 struct ifreq broad_req;
606 if (ioctl (socketFD, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
607 (broad_req.ifr_flags & IFF_BROADCAST) &&
608 (broad_req.ifr_flags & IFF_UP)
612 if (ioctl (socketFD, SIOCGIFBRDADDR, &broad_req) != -1)
613 broad_addr = broad_req.ifr_addr;
621 in_addr = *((struct sockaddr_in *) &broad_addr);
622 in_addr.sin_port = htons (XDM_UDP_PORT);
624 in_addr.sin_len = sizeof(in_addr);
626 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
633 /* address as hex string, e.g., "12180022" (depreciated) */
634 if (strlen(name) == 8 &&
635 FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
637 in_addr.sin_family = AF_INET;
639 /* Per RFC 1123, check first for IP address in dotted-decimal form */
640 else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
641 in_addr.sin_family = AF_INET;
644 hostent = gethostbyname (name);
647 if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
649 in_addr.sin_family = hostent->h_addrtype;
650 memmove( &in_addr.sin_addr, hostent->h_addr, 4);
652 in_addr.sin_port = htons (XDM_UDP_PORT);
654 in_addr.sin_len = sizeof(in_addr);
656 RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
661 static ARRAYofARRAY8 AuthenticationNames;
663 RegisterAuthenticationName (name, namelen)
668 if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
669 AuthenticationNames.length + 1))
671 authName = &AuthenticationNames.data[AuthenticationNames.length-1];
672 if (!XdmcpAllocARRAY8 (authName, namelen))
674 memmove( authName->data, name, namelen);
685 header.version = XDM_PROTOCOL_VERSION;
686 header.opcode = (CARD16) BROADCAST_QUERY;
688 for (i = 0; i < (int)AuthenticationNames.length; i++)
689 header.length += 2 + AuthenticationNames.data[i].length;
690 XdmcpWriteHeader (&broadcastBuffer, &header);
691 XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);
693 header.version = XDM_PROTOCOL_VERSION;
694 header.opcode = (CARD16) QUERY;
696 for (i = 0; i < (int)AuthenticationNames.length; i++)
697 header.length += 2 + AuthenticationNames.data[i].length;
698 XdmcpWriteHeader (&directBuffer, &header);
699 XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
700 if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
704 if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, sizeof (soopts)) < 0)
705 perror ("setsockopt");
708 XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
712 RegisterHostname (*argv);
716 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
724 if (app_resources.xdmAddress)
726 struct sockaddr_in in_addr;
727 struct sockaddr *addr;
735 xdm = (char *) app_resources.xdmAddress->data;
736 family = (xdm[0] << 8) + xdm[1];
740 in_addr.sin_len = sizeof(in_addr);
742 in_addr.sin_family = family;
743 memmove( &in_addr.sin_port, xdm + 2, 2);
744 memmove( &in_addr.sin_addr, xdm + 4, 4);
745 addr = (struct sockaddr *) &in_addr;
746 len = sizeof (in_addr);
749 if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
751 fprintf (stderr, "Cannot create response socket\n");
752 exit (REMANAGE_DISPLAY);
754 if (connect (fd, addr, len) == -1)
756 fprintf (stderr, "Cannot connect to xdm\n");
757 exit (REMANAGE_DISPLAY);
759 buffer.data = (BYTE *) buf;
760 buffer.size = sizeof (buf);
763 XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
764 XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
765 XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
766 write (fd, (char *)buffer.data, buffer.pointer);
773 printf ("%u\n", h->connectionType);
774 for (i = 0; i < (int)h->hostaddr.length; i++)
775 printf ("%u%s", h->hostaddr.data[i],
776 i == h->hostaddr.length - 1 ? "\n" : " ");
782 DoAccept (w, event, params, num_params)
786 Cardinal *num_params;
789 XmStringTable selectedItem;
794 /*********************************/
795 /** see if anything is selected **/
796 /*********************************/
798 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
799 XtGetValues(chooser_list, chooserArgs, i);
800 if (selectedCount != 1) {
801 XBell (XtDisplay (toplevel), 0);
805 /**********************************************/
806 /** retrieve the selected item from the list **/
807 /**********************************************/
809 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
810 XtGetValues(chooser_list, chooserArgs, i);
811 text = (char*) _XmStringUngenerate(
812 selectedItem[0], NULL,
813 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
814 if (NULL == text) return;
816 for (h = hostNamedb; h; h = h->next)
817 if (!strcmp (text, h->fullname))
821 if (NULL != text) XtFree(text);
822 exit (OBEYSESS_DISPLAY);
827 DoCheckWilling (w, event, params, num_params)
831 Cardinal *num_params;
834 XmStringTable selectedItem;
839 /*********************************/
840 /** see if anything is selected **/
841 /*********************************/
843 XtSetArg(chooserArgs[i], XmNselectedItemCount, &selectedCount); i++;
844 XtGetValues(chooser_list, chooserArgs, i);
845 if (selectedCount != 1) {
849 /**********************************************/
850 /** retrieve the selected item from the list **/
851 /**********************************************/
853 XtSetArg(chooserArgs[i], XmNselectedItems, &selectedItem); i++;
854 XtGetValues(chooser_list, chooserArgs, i);
855 text = (char*) _XmStringUngenerate(
856 selectedItem[0], NULL,
857 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
858 if (NULL == text) return;
860 for (h = hostNamedb; h; h = h->next)
861 if (!strcmp (text, h->fullname))
863 XmListDeselectAllItems (chooser_list);
865 if (NULL != text) XtFree(text);
870 DoCancel (w, event, params, num_params)
874 Cardinal *num_params;
876 exit (OBEYSESS_DISPLAY);
881 DoPing (w, event, params, num_params)
885 Cardinal *num_params;
889 PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
892 static XtActionsRec app_actions[] = {
895 "CheckWilling", DoCheckWilling,
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.
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 (args, num_args, fromVal, toVal)
1036 XrmValuePtr fromVal;
1039 static ARRAY8Ptr dest;
1043 dest = (ARRAY8Ptr) XtMalloc (sizeof (ARRAY8));
1044 len = fromVal->size;
1045 s = (char *) fromVal->addr;
1046 if (!XdmcpAllocARRAY8 (dest, len >> 1))
1047 XtStringConversionWarning ((char *) fromVal->addr, XtRARRAY8);
1050 FromHex (s, (char *) dest->data, len);
1052 toVal->addr = (caddr_t) &dest;
1053 toVal->size = sizeof (ARRAY8Ptr);