2
* $Xorg: chooser.c,v 1.4 2001/02/09 02:05:40 xorgcvs Exp $
4
Copyright 1990, 1998 The Open Group
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
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
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.
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.
26
* Author: Keith Packard, MIT X Consortium
29
/* $XFree86: xc/programs/xdm/chooser.c,v 3.24 2001/12/14 20:01:20 dawes Exp $ */
32
* Chooser - display a menu of names and let the user select one
38
* +--------------------------------------------------+
39
* | +------------------+ |
41
* | +------------------+ |
42
* | +-+--------------+ |
49
* | +----------------+ |
50
* | cancel accept ping |
51
* +--------------------------------------------------+
54
#include <X11/Intrinsic.h>
55
#include <X11/StringDefs.h>
56
#include <X11/Xatom.h>
58
#include <X11/Xaw/Paned.h>
59
#include <X11/Xaw/Label.h>
60
#include <X11/Xaw/Viewport.h>
61
#include <X11/Xaw/List.h>
62
#include <X11/Xaw/Box.h>
63
#include <X11/Xaw/Command.h>
67
#include <X11/Xdmcp.h>
69
#include <sys/types.h>
74
#include <X11/extensions/Xinerama.h>
77
#if defined(SVR4) && !defined(SCO325)
78
#include <sys/sockio.h>
80
#if defined(SVR4) && defined(PowerMAX_OS)
81
#include <sys/stropts.h>
83
#if defined(SYSV) && defined(i386)
84
#include <sys/stream.h>
86
#include <sys/sioctl.h>
87
#include <sys/stropts.h>
91
#include "dm_socket.h"
93
#include <arpa/inet.h>
95
#include <sys/ioctl.h>
97
#ifdef WINTCP /* NCR with Wollongong TCP */
98
#include <netinet/ip.h>
102
#include <netconfig.h>
107
#include <sys/param.h>
109
#define VARIABLE_IFREQ
114
#include <X11/extensions/XKBbells.h>
117
#define BROADCAST_HOSTNAME "BROADCAST"
120
#define ishexdigit(c) (isdigit(c) || ('a' <= (c) && (c) <= 'f'))
124
# include <sys/utsname.h>
130
# include <sync/queue.h>
131
# include <sync/sema.h>
140
static int FromHex (char *s, char *d, int len);
142
Widget toplevel, label, viewport, paned, list, box, cancel, acceptit, ping;
144
static void CvtStringToARRAY8(
150
static struct _app_resources {
151
ARRAY8Ptr xdmAddress;
152
ARRAY8Ptr clientAddress;
156
#define offset(field) XtOffsetOf(struct _app_resources, field)
158
#define XtRARRAY8 "ARRAY8"
160
static XtResource resources[] = {
161
{"xdmAddress", "XdmAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
162
offset (xdmAddress), XtRString, NULL },
163
{"clientAddress", "ClientAddress", XtRARRAY8, sizeof (ARRAY8Ptr),
164
offset (clientAddress), XtRString, NULL },
165
{"connectionType", "ConnectionType", XtRInt, sizeof (int),
166
offset (connectionType), XtRImmediate, (XtPointer) 0 }
170
static XrmOptionDescRec options[] = {
171
{ "-xdmaddress", "*xdmAddress", XrmoptionSepArg, NULL },
172
{ "-clientaddress", "*clientAddress", XrmoptionSepArg, NULL },
173
{ "-connectionType","*connectionType", XrmoptionSepArg, NULL },
176
typedef struct _hostAddr {
177
struct _hostAddr *next;
178
struct sockaddr *addr;
183
static HostAddr *hostAddrdb;
185
typedef struct _hostName {
186
struct _hostName *next;
189
ARRAY8 hostname, status;
190
CARD16 connectionType;
194
static HostName *hostNamedb;
200
#define PING_INTERVAL 2000
203
static XdmcpBuffer directBuffer, broadcastBuffer;
204
static XdmcpBuffer buffer;
206
#if ((defined(SVR4) && !defined(sun) && !defined(__sgi) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF)
208
/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
211
ifioctl (int fd, int cmd, char *arg)
216
bzero((char *) &ioc, sizeof(ioc));
219
if (cmd == SIOCGIFCONF)
221
ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
222
ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
224
/* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
225
* buffer must contain the ifconf structure as header. Ifc_req
226
* is also not a pointer but a one element array of ifreq
227
* structures. On return this array is extended by enough
228
* ifreq fields to hold all interfaces. The return buffer length
229
* is placed in the buffer header.
231
((struct ifconf *) ioc.ic_dp)->ifc_len =
232
ioc.ic_len - sizeof(struct ifconf);
237
ioc.ic_len = sizeof(struct ifreq);
240
ret = ioctl(fd, I_STR, (char *) &ioc);
241
if (ret >= 0 && cmd == SIOCGIFCONF)
243
((struct ifconf *) arg)->ifc_len = ioc.ic_len;
247
((struct ifconf *) arg)->ifc_len =
248
((struct ifconf *)ioc.ic_dp)->ifc_len;
249
((struct ifconf *) arg)->ifc_buf =
250
(caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req;
255
#else /* ((SVR4 && !sun && !NCR) || ISC) && SIOCGIFCONF */
256
#define ifioctl ioctl
257
#endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
262
PingHosts (XtPointer closure, XtIntervalId *id)
266
for (hosts = hostAddrdb; hosts; hosts = hosts->next)
268
if (hosts->type == QUERY)
269
XdmcpFlush (socketFD, &directBuffer, (XdmcpNetaddr) hosts->addr, hosts->addrlen);
271
XdmcpFlush (socketFD, &broadcastBuffer, (XdmcpNetaddr) hosts->addr, hosts->addrlen);
273
if (++pingTry < TRIES)
274
XtAddTimeOut (PING_INTERVAL, PingHosts, (XtPointer) 0);
281
HostnameCompare (const void *a, const void *b)
283
return strcmp (*(char **)a, *(char **)b);
287
RebuildTable (int size)
295
newTable = (char **) malloc (size * sizeof (char *));
298
for (names = hostNamedb, i = 0; names; names = names->next, i++)
299
newTable[i] = names->fullname;
300
qsort (newTable, size, sizeof (char *), HostnameCompare);
302
XawListChange (list, newTable, size, 0, TRUE);
304
free ((char *) NameTable);
305
NameTable = newTable;
306
NameTableSize = size;
310
AddHostname (ARRAY8Ptr hostname, ARRAY8Ptr status, struct sockaddr *addr, int willing)
312
HostName *new, **names, *name;
314
CARD16 connectionType;
317
switch (addr->sa_family)
320
hostAddr.data = (CARD8 *) &((struct sockaddr_in *) addr)->sin_addr;
322
connectionType = FamilyInternet;
325
hostAddr.data = (CARD8 *) "";
327
connectionType = FamilyLocal;
330
for (names = &hostNamedb; *names; names = & (*names)->next)
333
if (connectionType == name->connectionType &&
334
XdmcpARRAY8Equal (&hostAddr, &name->hostaddr))
336
if (XdmcpARRAY8Equal (status, &name->status))
345
new = (HostName *) malloc (sizeof (HostName));
348
if (hostname->length)
350
switch (addr->sa_family)
354
struct hostent *hostent;
357
hostent = gethostbyaddr ((char *)hostAddr.data, hostAddr.length, AF_INET);
360
XdmcpDisposeARRAY8 (hostname);
361
host = (char *)hostent->h_name;
362
XdmcpAllocARRAY8 (hostname, strlen (host));
363
memmove( hostname->data, host, hostname->length);
368
if (!XdmcpAllocARRAY8 (&new->hostaddr, hostAddr.length))
370
free ((char *) new->fullname);
374
memmove( new->hostaddr.data, hostAddr.data, hostAddr.length);
375
new->connectionType = connectionType;
376
new->hostname = *hostname;
385
free (new->fullname);
386
XdmcpDisposeARRAY8 (&new->status);
387
XdmcpDisposeARRAY8 (hostname);
389
new->willing = willing;
390
new->status = *status;
392
hostname = &new->hostname;
393
fulllen = hostname->length;
396
new->fullname = malloc (fulllen + status->length + 10);
399
new->fullname = "Unknown";
403
sprintf (new->fullname, "%-30.*s %*.*s",
404
hostname->length, hostname->data,
405
status->length, status->length, status->data);
407
RebuildTable (NameTableSize);
412
DisposeHostname (HostName *host)
414
XdmcpDisposeARRAY8 (&host->hostname);
415
XdmcpDisposeARRAY8 (&host->hostaddr);
416
XdmcpDisposeARRAY8 (&host->status);
417
free ((char *) host->fullname);
418
free ((char *) host);
423
RemoveHostname (HostName *host)
425
HostName **prev, *hosts;
428
for (hosts = hostNamedb; hosts; hosts = hosts->next)
437
DisposeHostname (host);
439
RebuildTable (NameTableSize);
444
EmptyHostnames (void)
446
HostName *hosts, *next;
448
for (hosts = hostNamedb; hosts; hosts = next)
451
DisposeHostname (hosts);
455
RebuildTable (NameTableSize);
460
ReceivePacket (XtPointer closure, int *source, XtInputId *id)
463
ARRAY8 authenticationName;
466
int saveHostname = 0;
467
struct sockaddr addr;
470
addrlen = sizeof (addr);
471
if (!XdmcpFill (socketFD, &buffer, (XdmcpNetaddr) &addr, &addrlen))
473
if (!XdmcpReadHeader (&buffer, &header))
475
if (header.version != XDM_PROTOCOL_VERSION)
479
authenticationName.data = 0;
480
switch (header.opcode) {
482
if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
483
XdmcpReadARRAY8 (&buffer, &hostname) &&
484
XdmcpReadARRAY8 (&buffer, &status))
486
if (header.length == 6 + authenticationName.length +
487
hostname.length + status.length)
489
if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
493
XdmcpDisposeARRAY8 (&authenticationName);
496
if (XdmcpReadARRAY8 (&buffer, &hostname) &&
497
XdmcpReadARRAY8 (&buffer, &status))
499
if (header.length == 4 + hostname.length + status.length)
501
if (AddHostname (&hostname, &status, &addr, header.opcode == (int) WILLING))
512
XdmcpDisposeARRAY8 (&hostname);
513
XdmcpDisposeARRAY8 (&status);
518
RegisterHostaddr (struct sockaddr *addr, int len, xdmOpCode type)
520
HostAddr *host, **prev;
522
host = (HostAddr *) malloc (sizeof (HostAddr));
525
host->addr = (struct sockaddr *) malloc (len);
528
free ((char *) host);
531
memmove( (char *) host->addr, (char *) addr, len);
534
for (prev = &hostAddrdb; *prev; prev = &(*prev)->next)
541
* Register the address for this host.
542
* Called with each of the names on the command line.
543
* The special name "BROADCAST" looks up all the broadcast
544
* addresses on the local host.
547
#if !defined(__GNU__)
549
/* Handle variable length ifreq in BNR2 and later */
550
#ifdef VARIABLE_IFREQ
551
#define ifr_size(p) (sizeof (struct ifreq) + \
552
(p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
553
p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
555
#define ifr_size(p) (sizeof (struct ifreq))
559
RegisterHostname (char *name)
561
struct hostent *hostent;
562
struct sockaddr_in in_addr;
564
register struct ifreq *ifr;
565
struct sockaddr broad_addr;
566
char buf[2048], *cp, *cplim;
568
if (!strcmp (name, BROADCAST_HOSTNAME))
570
#ifdef WINTCP /* NCR with Wollongong TCP */
576
ifcp = (struct ifconf *)buf;
577
ifcp->ifc_buf = buf+4;
578
ifcp->ifc_len = sizeof (buf) - 4;
580
if ((ipfd=open( "/dev/ip", O_RDONLY )) < 0 )
582
t_error( "RegisterHostname() t_open(/dev/ip) failed" );
586
ioc.ic_cmd = IPIOC_GETIFCONF;
588
ioc.ic_len = sizeof( buf );
589
ioc.ic_dp = (char *)ifcp;
591
if (ioctl (ipfd, (int) I_STR, (char *) &ioc) < 0)
593
perror( "RegisterHostname() ioctl(I_STR(IPIOC_GETIFCONF)) failed" );
598
for (ifr = ifcp->ifc_req, n = ifcp->ifc_len / sizeof (struct ifreq);
602
ifc.ifc_len = sizeof (buf);
604
if (ifioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
608
#define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf
610
#define IFC_IFC_REQ ifc.ifc_req
613
cplim = (char *) IFC_IFC_REQ + ifc.ifc_len;
615
for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
619
ifr = (struct ifreq *) cp;
621
if (ifr->ifr_addr.sa_family != AF_INET)
624
broad_addr = ifr->ifr_addr;
625
((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
626
htonl (INADDR_BROADCAST);
627
#ifdef SIOCGIFBRDADDR
629
struct ifreq broad_req;
632
#ifdef WINTCP /* NCR with Wollongong TCP */
633
ioc.ic_cmd = IPIOC_GETIFFLAGS;
635
ioc.ic_len = sizeof( broad_req );
636
ioc.ic_dp = (char *)&broad_req;
638
if (ioctl (ipfd, I_STR, (char *) &ioc) != -1 &&
640
if (ifioctl (socketFD, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
642
(broad_req.ifr_flags & IFF_BROADCAST) &&
643
(broad_req.ifr_flags & IFF_UP)
647
#ifdef WINTCP /* NCR with Wollongong TCP */
648
ioc.ic_cmd = IPIOC_GETIFBRDADDR;
650
ioc.ic_len = sizeof( broad_req );
651
ioc.ic_dp = (char *)&broad_req;
653
if (ioctl (ipfd, I_STR, (char *) &ioc) != -1)
655
if (ifioctl (socketFD, SIOCGIFBRDADDR, &broad_req) != -1)
657
broad_addr = broad_req.ifr_addr;
665
in_addr = *((struct sockaddr_in *) &broad_addr);
666
in_addr.sin_port = htons (XDM_UDP_PORT);
668
in_addr.sin_len = sizeof(in_addr);
670
RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
677
/* address as hex string, e.g., "12180022" (depreciated) */
678
if (strlen(name) == 8 &&
679
FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
681
in_addr.sin_family = AF_INET;
683
/* Per RFC 1123, check first for IP address in dotted-decimal form */
684
else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
685
in_addr.sin_family = AF_INET;
688
hostent = gethostbyname (name);
691
if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
693
in_addr.sin_family = hostent->h_addrtype;
694
memmove( &in_addr.sin_addr, hostent->h_addr, 4);
696
in_addr.sin_port = htons (XDM_UDP_PORT);
698
in_addr.sin_len = sizeof(in_addr);
700
RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
706
RegisterHostname (char *name)
708
struct hostent *hostent;
709
struct sockaddr_in in_addr;
711
if (!strcmp (name, BROADCAST_HOSTNAME))
713
in_addr.sin_addr.s_addr= htonl(0xFFFFFFFF);
714
in_addr.sin_port = htons (XDM_UDP_PORT);
715
RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
721
/* address as hex string, e.g., "12180022" (depreciated) */
722
if (strlen(name) == 8 &&
723
FromHex(name, (char *)&in_addr.sin_addr, strlen(name)) == 0)
725
in_addr.sin_family = AF_INET;
727
/* Per RFC 1123, check first for IP address in dotted-decimal form */
728
else if ((in_addr.sin_addr.s_addr = inet_addr(name)) != -1)
729
in_addr.sin_family = AF_INET;
732
hostent = gethostbyname (name);
735
if (hostent->h_addrtype != AF_INET || hostent->h_length != 4)
737
in_addr.sin_family = hostent->h_addrtype;
738
memmove( &in_addr.sin_addr, hostent->h_addr, 4);
740
in_addr.sin_port = htons (XDM_UDP_PORT);
741
RegisterHostaddr ((struct sockaddr *)&in_addr, sizeof (in_addr),
747
static ARRAYofARRAY8 AuthenticationNames;
751
RegisterAuthenticationName (char *name, int namelen)
754
if (!XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
755
AuthenticationNames.length + 1))
757
authName = &AuthenticationNames.data[AuthenticationNames.length-1];
758
if (!XdmcpAllocARRAY8 (authName, namelen))
760
memmove( authName->data, name, namelen);
765
InitXDMCP (char **argv)
771
header.version = XDM_PROTOCOL_VERSION;
772
header.opcode = (CARD16) BROADCAST_QUERY;
774
for (i = 0; i < (int)AuthenticationNames.length; i++)
775
header.length += 2 + AuthenticationNames.data[i].length;
776
XdmcpWriteHeader (&broadcastBuffer, &header);
777
XdmcpWriteARRAYofARRAY8 (&broadcastBuffer, &AuthenticationNames);
779
header.version = XDM_PROTOCOL_VERSION;
780
header.opcode = (CARD16) QUERY;
782
for (i = 0; i < (int)AuthenticationNames.length; i++)
783
header.length += 2 + AuthenticationNames.data[i].length;
784
XdmcpWriteHeader (&directBuffer, &header);
785
XdmcpWriteARRAYofARRAY8 (&directBuffer, &AuthenticationNames);
786
#if defined(STREAMSCONN)
787
if ((socketFD = t_open ("/dev/udp", O_RDWR, 0)) < 0)
790
if (t_bind( socketFD, NULL, NULL ) < 0)
797
* This part of the code looks contrived. It will actually fit in nicely
798
* when the CLTS part of Xtrans is implemented.
801
struct netconfig *nconf;
803
if( (nconf=getnetconfigent("udp")) == NULL )
810
if( netdir_options(nconf, ND_SET_BROADCAST, socketFD, NULL) )
812
freenetconfigent(nconf);
818
freenetconfigent(nconf);
821
if ((socketFD = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
827
if (setsockopt (socketFD, SOL_SOCKET, SO_BROADCAST, (char *)&soopts, sizeof (soopts)) < 0)
828
perror ("setsockopt");
832
XtAddInput (socketFD, (XtPointer) XtInputReadMask, ReceivePacket,
836
RegisterHostname (*argv);
840
PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
847
if (app_resources.xdmAddress)
849
struct sockaddr_in in_addr;
850
struct sockaddr *addr = NULL;
857
#if defined(STREAMSCONN)
858
struct t_call call, rcv;
861
xdm = (char *) app_resources.xdmAddress->data;
862
family = (xdm[0] << 8) + xdm[1];
866
in_addr.sin_len = sizeof(in_addr);
868
in_addr.sin_family = family;
869
memmove( &in_addr.sin_port, xdm + 2, 2);
870
memmove( &in_addr.sin_addr, xdm + 4, 4);
871
addr = (struct sockaddr *) &in_addr;
872
len = sizeof (in_addr);
875
#if defined(STREAMSCONN)
876
if ((fd = t_open ("/dev/tcp", O_RDWR, NULL)) == -1)
878
fprintf (stderr, "Cannot create response endpoint\n");
880
exit (REMANAGE_DISPLAY);
882
if (t_bind (fd, NULL, NULL) == -1)
884
fprintf (stderr, "Cannot bind response endpoint\n");
887
exit (REMANAGE_DISPLAY);
889
call.addr.buf=(char *)addr;
891
call.addr.maxlen=len;
896
if (t_connect (fd, &call, NULL) == -1)
898
t_error ("Cannot connect to xdm\n");
902
exit (REMANAGE_DISPLAY);
905
if ((fd = socket (family, SOCK_STREAM, 0)) == -1)
907
fprintf (stderr, "Cannot create response socket\n");
908
exit (REMANAGE_DISPLAY);
910
if (connect (fd, addr, len) == -1)
912
fprintf (stderr, "Cannot connect to xdm\n");
913
exit (REMANAGE_DISPLAY);
916
buffer.data = (BYTE *) buf;
917
buffer.size = sizeof (buf);
920
XdmcpWriteARRAY8 (&buffer, app_resources.clientAddress);
921
XdmcpWriteCARD16 (&buffer, (CARD16) app_resources.connectionType);
922
XdmcpWriteARRAY8 (&buffer, &h->hostaddr);
923
#if defined(STREAMSCONN)
924
if( t_snd (fd, (char *)buffer.data, buffer.pointer, 0) < 0 )
926
fprintf (stderr, "Cannot send to xdm\n");
930
exit (REMANAGE_DISPLAY);
932
sleep(5); /* Hack because sometimes the connection gets
933
closed before the data arrives on the other end. */
938
write (fd, (char *)buffer.data, buffer.pointer);
946
printf ("%u\n", h->connectionType);
947
for (i = 0; i < (int)h->hostaddr.length; i++)
948
printf ("%u%s", h->hostaddr.data[i],
949
i == h->hostaddr.length - 1 ? "\n" : " ");
955
DoAccept (Widget w, XEvent *event, String *params, Cardinal *num_params)
957
XawListReturnStruct *r;
960
r = XawListShowCurrent (list);
961
if (r->list_index == XAW_LIST_NONE)
963
XkbStdBell(XtDisplay(toplevel),XtWindow(w),0,XkbBI_MinorError);
965
XBell (XtDisplay (toplevel), 0);
969
for (h = hostNamedb; h; h = h->next)
970
if (!strcmp (r->string, h->fullname))
974
exit (OBEYSESS_DISPLAY);
980
DoCheckWilling (Widget w, XEvent *event, String *params, Cardinal *num_params)
982
XawListReturnStruct *r;
985
r = XawListShowCurrent (list);
986
if (r->list_index == XAW_LIST_NONE)
988
for (h = hostNamedb; h; h = h->next)
989
if (!strcmp (r->string, h->fullname))
991
XawListUnhighlight (list);
996
DoCancel (Widget w, XEvent *event, String *params, Cardinal *num_params)
998
exit (OBEYSESS_DISPLAY);
1003
DoPing (Widget w, XEvent *event, String *params, Cardinal *num_params)
1007
PingHosts ((XtPointer)NULL, (XtIntervalId *)NULL);
1010
static XtActionsRec app_actions[] = {
1011
{ "Accept", DoAccept },
1012
{ "Cancel", DoCancel },
1013
{ "CheckWilling", DoCheckWilling },
1018
main (int argc, char **argv)
1021
Dimension width, height;
1024
XineramaScreenInfo *screens;
1029
toplevel = XtInitialize (argv[0], "Chooser", options, XtNumber(options), &argc, argv);
1031
XtAddConverter(XtRString, XtRARRAY8, CvtStringToARRAY8, NULL, 0);
1033
XtGetApplicationResources (toplevel, (XtPointer) &app_resources, resources,
1034
XtNumber (resources), NULL, (Cardinal) 0);
1036
XtAddActions (app_actions, XtNumber (app_actions));
1037
paned = XtCreateManagedWidget ("paned", panedWidgetClass, toplevel, NULL, 0);
1038
label = XtCreateManagedWidget ("label", labelWidgetClass, paned, NULL, 0);
1039
viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, paned, NULL, 0);
1040
list = XtCreateManagedWidget ("list", listWidgetClass, viewport, NULL, 0);
1041
box = XtCreateManagedWidget ("box", boxWidgetClass, paned, NULL, 0);
1042
cancel = XtCreateManagedWidget ("cancel", commandWidgetClass, box, NULL, 0);
1043
acceptit = XtCreateManagedWidget ("accept", commandWidgetClass, box, NULL, 0);
1044
ping = XtCreateManagedWidget ("ping", commandWidgetClass, box, NULL, 0);
1047
* center ourselves on the screen
1049
XtSetMappedWhenManaged(toplevel, FALSE);
1050
XtRealizeWidget (toplevel);
1052
XtSetArg (position[0], XtNwidth, &width);
1053
XtSetArg (position[1], XtNheight, &height);
1054
XtGetValues (toplevel, position, (Cardinal) 2);
1057
XineramaIsActive(XtDisplay(toplevel)) &&
1058
(screens = XineramaQueryScreens(XtDisplay(toplevel), &s_num)) != NULL
1061
x = (Position)(screens[0].x_org + (screens[0].width - width) / 2);
1062
y = (Position)(screens[0].y_org + (screens[0].height - height) / 3);
1069
x = (Position)(WidthOfScreen (XtScreen (toplevel)) - width) / 2;
1070
y = (Position)(HeightOfScreen (XtScreen (toplevel)) - height) / 3;
1072
XtSetArg (position[0], XtNx, x);
1073
XtSetArg (position[1], XtNy, y);
1074
XtSetValues (toplevel, position, (Cardinal) 2);
1079
XtMapWidget(toplevel);
1080
InitXDMCP (argv + 1);
1086
/* Converts the hex string s of length len into the byte array d.
1087
Returns 0 if s was a legal hex string, 1 otherwise.
1090
FromHex (char *s, char *d, int len)
1093
int ret = len&1; /* odd-length hex strings are illegal */
1096
#define HexChar(c) ('0' <= (c) && (c) <= '9' ? (c) - '0' : (c) - 'a' + 10)
1098
if (!ishexdigit(*s))
1100
t = HexChar (*s) << 4;
1102
if (!ishexdigit(*s))
1114
CvtStringToARRAY8 (XrmValuePtr args, Cardinal *num_args, XrmValuePtr fromVal, XrmValuePtr toVal)
1116
static ARRAY8Ptr dest;
1120
dest = (ARRAY8Ptr) XtMalloc (sizeof (ARRAY8));
1121
len = fromVal->size;
1122
s = (char *) fromVal->addr;
1123
if (!XdmcpAllocARRAY8 (dest, len >> 1))
1124
XtStringConversionWarning ((char *) fromVal->addr, XtRARRAY8);
1127
FromHex (s, (char *) dest->data, len);
1129
toVal->addr = (caddr_t) &dest;
1130
toVal->size = sizeof (ARRAY8Ptr);