|
|
1.1 root 1: #include <X/mit-copyright.h>
2: /* $Header: XOpenDisplay.c,v 10.12 86/12/24 09:07:53 swick Exp $ */
3: /* Copyright Massachusetts Institute of Technology 1985 */
4:
5: #include "XlibInternal.h"
6: #include <sys/socket.h>
7: #include <strings.h>
8: #include <sys/un.h>
9:
10: /*
11: * Connects to a server, creates a Display object and returns a pointer to
12: * the newly created Display back to the caller.
13: */
14: Display *XOpenDisplay (display)
15: register char *display;
16: {
17: register Display *dpy; /* New Display object being created. */
18: char displaybuf[256]; /* Display string buffer. */
19: register char *displayptr; /* Display string buffer pointer. */
20: char buf[4]; /* place to form display string */
21: struct sockaddr_in inaddr; /* INET socket address. */
22: struct sockaddr_un unaddr; /* UNIX socket address. */
23: struct sockaddr *addr; /* address to connect to */
24: int addrlen; /* length of address */
25: int dispnum; /* display number. */
26: int indian; /* to determine which indian. */
27: struct hostent *host_ptr;
28: #ifdef DNETCONN
29: char objname[20]; /* Object name buffer */
30: int dnet = 0; /* flag to indicate DECnet connect */
31: #endif
32:
33: register XReq *req; /* XReq request packet pointer. */
34: XRep rep; /* XRep reply packet. */
35:
36: /* External declarations. */
37: extern char *getenv();
38: extern char *malloc();
39: extern struct hostent *gethostbyname();
40:
41: /*
42: * Extract the host name and display number from the display
43: * specifier string. The display specifier string is supplied
44: * as an argument to this routine. If it is NULL or a pointer
45: * to NULL
46: */
47: if (display == NULL || *display == '\0') {
48: strncpy (displaybuf, XDisplayName(display), sizeof(displaybuf));
49: if (*displaybuf == '\0') return (NULL);
50: }
51: else {
52: /* Display is non-NULL, copy it into the display buffer. */
53: strncpy(displaybuf, display, sizeof(displaybuf));
54: }
55: /*
56: * Find the ':' seperator and cut out the hostname and the
57: * display number.
58: * NOTE - if DECnet is to be used, the display name is formated
59: * as "host::number"
60: */
61: if ((displayptr = index(displaybuf,':')) == NULL) return (NULL);
62: #ifdef DNETCONN
63: if (*(displayptr + 1) == ':') {
64: dnet++;
65: *(displayptr++) = '\0';
66: }
67: #endif
68: *(displayptr++) = '\0';
69:
70: /* displaybuf now contains only a null-terminated host name;
71: * displayptr points to the display number */
72:
73: /* If the display number is missing there is an error.
74: * Otherwise, convert string to an integer we can use */
75: if (*displayptr == '\0') return(NULL);
76: dispnum = atoi(displayptr);
77:
78: if (strcmp("unix", displaybuf) == 0) {
79: /* Connect locally using Unix domain. */
80: unaddr.sun_family = AF_UNIX;
81: strcpy(unaddr.sun_path, X_UNIX_PATH);
82: strcat(unaddr.sun_path, displayptr);
83: addr = (struct sockaddr *) &unaddr;
84: addrlen = strlen(unaddr.sun_path) + 2;
85: } else {
86: #ifdef DNETCONN
87: if (!dnet) {
88: #endif
89: /* If the hostname is missing default to the local host. */
90: if (displaybuf[0] == '\0')
91: gethostname (displaybuf, sizeof (displaybuf));
92: /* Get the statistics on the specified host. */
93: if ((inaddr.sin_addr.s_addr = inet_addr(displaybuf)) == -1) {
94: if ((host_ptr = gethostbyname(displaybuf)) == NULL) {
95: /* No such host! */
96: errno = EINVAL;
97: return(NULL);
98: }
99: /* Check the address type for an internet host. */
100: if (host_ptr->h_addrtype != AF_INET) {
101: /* Not an Internet host! */
102: errno = EPROTOTYPE;
103: return(NULL);
104: }
105:
106: /* Set up the socket data. */
107: inaddr.sin_family = host_ptr->h_addrtype;
108: bcopy((char *)host_ptr->h_addr,
109: (char *)&inaddr.sin_addr,
110: sizeof(inaddr.sin_addr));
111: } else {
112: inaddr.sin_family = AF_INET;
113: }
114: addr = (struct sockaddr *) &inaddr;
115: addrlen = sizeof (struct sockaddr_in);
116: inaddr.sin_port = dispnum;
117: indian = 1;
118: if (*(char *) &indian)
119: inaddr.sin_port += X_TCP_LI_PORT;
120: else
121: inaddr.sin_port += X_TCP_BI_PORT;
122: inaddr.sin_port = htons(inaddr.sin_port);
123: #ifdef DNETCONN
124: } else {
125: /* If the nodename is missing default to the local node. */
126: if (displaybuf[0] == '\0')
127: strcpy (displaybuf, "0");
128: /* build the target object name. */
129: sprintf (objname, "X%d", dispnum);
130: }
131: #endif
132: }
133:
134: /* Malloc the new Display. */
135: if ((dpy = (Display *)malloc(sizeof(Display))) == NULL) {
136: /* Malloc call failed! */
137: errno = ENOMEM;
138: return(NULL);
139: }
140:
141: dpy->height = dpy->width = 0;
142: /* If DisplayWidth or DisplayWidth is subsequently called,
143: these will be replaced by "real" values. */
144:
145: /* Open the network socket. */
146: #ifdef DNETCONN
147: if (!dnet) {
148: #endif
149: if ((dpy->fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) {
150: /* Socket call failed! */
151: /* errno set by system call. */
152: free ((char *)dpy);
153: return(NULL);
154: }
155:
156: /* Open the connection to the specified X server. */
157: if (connect(dpy->fd, addr, addrlen) == -1) {
158: /* Connection call failed! */
159: /* errno set by system call. */
160: close (dpy->fd);
161: free ((char *)dpy);
162: return(NULL);
163: }
164: #ifdef DNETCONN
165: } else {
166: if ((dpy->fd = dnet_conn(displaybuf, objname, SOCK_STREAM, 0, 0, 0, 0)) < 0) {
167: /* connect failed! */
168: /* errno set by dnet_conn. */
169: free ((char *)dpy);
170: return(NULL);
171: }
172: }
173: #endif
174:
175: /* Salt away the host:display string for later use */
176: buf[0] = ':';
177: #ifdef DNETCONN
178: {
179: int b = 1;
180: if (dnet) buf[b++] = ':';
181: buf[b++] = '0' + dispnum;
182: buf[b] = '\0';
183: }
184: #else DNETCONN
185: buf[2] = '\0';
186: buf[1] = '0' + dispnum;
187: #endif DNETCONN
188: strcat(displaybuf, buf);
189: if ((dpy->displayname = malloc(strlen(displaybuf) + 1)) == NULL) {
190: close (dpy->fd);
191: free ((char *)dpy);
192: errno = ENOMEM;
193: return(NULL);
194: }
195: strcpy (dpy->displayname, displaybuf);
196:
197: /* Set up the output buffers. */
198: if ((dpy->bufptr = dpy->buffer = malloc(BUFSIZE)) == NULL) {
199: /* Malloc call failed! */
200: close (dpy->fd);
201: free ((char *)dpy);
202: errno = ENOMEM;
203: return(NULL);
204: }
205: dpy->bufmax = dpy->buffer + BUFSIZE;
206:
207: /* Set up the input event queue and input event queue parameters. */
208: dpy->head = dpy->tail = NULL;
209: dpy->qlen = 0;
210: /* Initialize MouseMoved event squishing. */
211: dpy->squish = 1;
212:
213: _XlibCurrentDisplay = dpy;
214:
215: /* Send an X_SetUp request to the server. */
216: GetReq(X_SetUp, 0);
217:
218: /* Send X_MakePixmap requests to get black and white
219: * constant tile Pixmaps */
220: GetReq(X_MakePixmap, 0);
221: req->param.l[0] = 0; /* no bitmap */
222: req->paramu2 = BlackPixel;
223: GetReq(X_MakePixmap, 0);
224: req->param.l[0] = 0;
225: req->paramu2 = WhitePixel;
226:
227: /* The following is needed to synchronize properly with errors,
228: * since three requests are outstanding and no replies have
229: * yet been read
230: */
231: dpy->request = 1;
232:
233: /* Get reply to X_SetUp */
234: if (!_XReply(dpy, &rep)) {
235: /* There was an error in retrieving the reply. */
236: close (dpy->fd);
237: free (dpy->buffer);
238: free ((char *)dpy);
239: return(NULL);
240: }
241:
242: /* Set the Display data returned by the X_SetUp call. */
243: dpy->root = rep.param.l[0]; /* Root window id. */
244: dpy->vnumber = rep.params2; /* X protocol version number. */
245: dpy->dtype = rep.params3; /* Server's display type. */
246: dpy->dplanes = rep.params4; /* Number of display bit planes. */
247: dpy->dcells = rep.paramu5; /* Number of display color map cell. */
248:
249: /* Get reply to MakePixmap (black) */
250: dpy->request++;
251: if (!_XReply (dpy, &rep)) {
252: close (dpy->fd);
253: free (dpy->buffer);
254: free ((char *)dpy);
255: return (NULL);
256: }
257: dpy->black = rep.param.l[0];
258:
259: /* Get reply to MakePixmap (white) */
260: dpy->request++;
261: if (!_XReply (dpy, &rep)) {
262: close (dpy->fd);
263: free (dpy->buffer);
264: free ((char *)dpy);
265: return (NULL);
266: }
267: dpy->white = rep.param.l[0];
268:
269: return(dpy);
270: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.