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: }
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1577
Valid CSS Valid XHTML 1.0 Strict