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