1: #include <X/mit-copyright.h>
   2: 
   3: /* Copyright    Massachusetts Institute of Technology    1985, 1986	*/
   4: 
   5: /* Initialization and socket routines */
   6: 
   7: #ifndef lint
   8: static char *rcsid_main_c = "$Header: main.c,v 10.15 86/02/06 09:13:00 jg Exp $";
   9: #endif
  10: 
  11: #include <dbm.h>
  12: #undef NULL
  13: #include "Xint.h"
  14: #include <errno.h>
  15: #include <sys/socket.h>
  16: #include <sys/time.h>
  17: #include <fcntl.h>
  18: #include <signal.h>
  19: #include "rgb.h"
  20: #include <netinet/in.h>
  21: #include <sys/un.h>
  22: #ifdef DNETCONN
  23: #include <netdnet/dn.h>
  24: #endif
  25: 
  26: extern int errno;
  27: extern int sys_nerr;
  28: extern char *sys_errlist[];
  29: extern CURSOR *cursor;
  30: extern short base_feep;
  31: extern WINDOW *rootwindow;
  32: 
  33: int HangUp();
  34: char *Xalloc(), *strcpy(), *strcat();
  35: PIXMAP *PixmapSave(), *MakePixmap();
  36: CURSOR *StoreCursor();
  37: BITMAP *StoreBitmap();
  38: 
  39: static char *devdisp;           /* The display device */
  40: static char *display;           /* The display number */
  41: static int devdesc;         /* The display file descriptor */
  42: DEVICE device;              /* The display info */
  43: static int Qmax;            /* device.queue->size - 1 */
  44: static int (*inputhandler)() = NULL;    /* input processor */
  45: static int (*blockhandler)() = NULL;    /* called before select() */
  46: static int (*wakeuphandler)() = NULL;   /* called after select() */
  47: 
  48: char *rgb_name = RGB_DB;    /* RGB database name */
  49: int havergb = 0;        /* have RGB database? */
  50: 
  51: static short _back[16] = {0x8888, 0x2222, 0x4444, 0x1111,
  52:               0x8888, 0x2222, 0x4444, 0x1111,
  53:               0x8888, 0x2222, 0x4444, 0x1111,
  54:               0x8888, 0x2222, 0x4444, 0x1111};
  55: 
  56: PIXMAP *roottile;
  57: 
  58: static short _pointer[16] = {0xf00f, 0x8811, 0x8421, 0x8241,
  59:                  0x4182, 0x2004, 0x1008, 0x0810,
  60:                  0x0810, 0x1008, 0x2004, 0x4182,
  61:                  0x8241, 0x8421, 0x8811, 0xf00f};
  62: 
  63: static short _ptrmask[16] = {0xf00f, 0xf81f, 0xfc3f, 0xfe7f,
  64:                  0x7ffe, 0x3ffc, 0x1ff8, 0x0ff0,
  65:                  0x0ff0, 0x1ff8, 0x3ffc, 0x7ffe,
  66:                  0xfe7f, 0xfc3f, 0xf81f, 0xf00f};
  67: 
  68: static short _ssmask[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  69: 
  70: CURSOR *rootcursor;     /* background cursor */
  71: static CURSOR *sscursor;    /* screen saver cursor */
  72: 
  73: static short default_click = 6;     /* KeyClick */
  74: static short default_repeat = 1;    /* AutoRepeat */
  75: static short default_lock = 1;      /* ShiftLock */
  76: static short default_feep = 3;      /* FeepControl */
  77: static short default_threshold = 2; /* MouseControl */
  78: static short default_acceleration = 4;
  79: static short default_savertime = 10;    /* ScreenSaver */
  80: static short default_savercycle = 60;
  81: static char *default_pix0 = NULL;   /* Background */
  82: static char *default_pix1 = NULL;   /* Foreground */
  83: static short default_mono = 0;      /* Force monochrome */
  84: static short default_blank = 0;     /* Blank video preferred */
  85: 
  86: static ColorDef basecolors[2] = {{BlackPixel, 0, 0, 0x8000},
  87:                  {WhitePixel, 0xff00, 0xff00, 0xff00}};
  88: static ColorDef randomcolors[2] = {{BlackPixel, 0, 0, 0},
  89:                    {WhitePixel, 0, 0, 0}};
  90: 
  91: static int socketOn[maxsocks];  /* 1: active, 0: inactive */
  92: int requestId[maxsocks];    /* Request count associated with the socket */
  93: static char *sockbuf[maxsocks]; /* Request buffers */
  94: char *bufptr[maxsocks];     /* Buffer pointers */
  95:                 /* Pointer to start of data in sockbuf */
  96: int bufcnt[maxsocks];       /* Buffer counts */
  97:                 /* Count of data bytes available in sockbuf */
  98: #define DEFBUFSIZE 4096     /* Default buffer size */
  99: #define MAXBUFSIZE (1<<17)  /* Maximum buffer size */
 100: static int bufsize[maxsocks];   /* Buffer sizes */
 101:                 /* Current size in bytes of sockbuf buffer */
 102: #ifdef DUALTCP
 103: int swapped[maxsocks];      /* 1: must byte swap on connection */
 104: #endif
 105: static int lastfdesc;       /* Maximum file descriptor */
 106: static int maxsock;     /* Highest socket in use + 1 */
 107: static int firstsock;       /* First possible socket */
 108: static int firstmask;       /* First possible socket mask */
 109: #ifdef DUALTCP
 110: static int swapmask;        /* Swap ports */
 111: #endif
 112: static int requestmask;     /* Listener mask */
 113: static int selmask[mskcnt]; /* Mask of open connections */
 114: int havemask[mskcnt];       /* Connections with buffered requests */
 115: int havestate;          /* <0: many, 0: none, >0: single */
 116: static int servergrabber;   /* Grabbing client */
 117: static int grabselmask[mskcnt]; /* Saved mask during GrabServer */
 118: static int grabhavemask[mskcnt];/* Saved mask during GrabServer */
 119: static int grabhavestate;   /* Saved state during GrabServer */
 120: static int devmask;     /* Event mask */
 121: int rr_counter;         /* Round robin counter */
 122: struct timeval waittime = {0, 0};
 123: struct timeval longtime = {0, 0};
 124: #define OUTTIME 10      /* 10 seconds */
 125: static struct timeval outtime = {OUTTIME, 0};
 126: static struct timeval notime = {0, 0};
 127: static unsigned errdelay = 15;
 128: short blank_video;
 129: 
 130: main(argc, argv)
 131:     int argc;
 132:     char **argv;
 133: {
 134:     register int i;
 135:     register char *arg;
 136: 
 137:     if (argc < 3)
 138:         Usage ();
 139:     devdisp = display = argv[1];
 140:     if (*display == '/')
 141:         display = "0";
 142:     argc--;     /* ignore tty name */
 143:     for (i = 2; i < argc; ) {
 144:         arg = argv[i];
 145:         i++;
 146:         if (strcmp (arg, "-a") == 0 && i < argc) {
 147:         default_acceleration = atoi (argv[i]);
 148:         i++;
 149:         if (default_acceleration == 0) Usage ();
 150:         } else if (strcmp (arg, "-c") == 0) {
 151:         default_click = 0;
 152:         } else if (strcmp (arg, "c") == 0 && i < argc) {
 153:         default_click = atoi (argv[i]);
 154:         i++;
 155:         if (default_click > 8) Usage ();
 156:         } else if (strcmp (arg, "-f") == 0 && i < argc) {
 157:         default_feep = atoi (argv[i]);
 158:         i++;
 159:         if (default_feep > 7) Usage ();
 160:         } else if (strcmp (arg, "-l") == 0) {
 161:         default_lock = 0;
 162:         } else if (strcmp (arg, "l") == 0) {
 163:         default_lock = 1;
 164:         } else if (strcmp (arg, "m") == 0) {
 165:         default_mono = 1;
 166:         } else if (strcmp (arg, "-p") == 0 && i < argc) {
 167:         default_savercycle = atoi (argv[i]);
 168:         if (default_savercycle == 0) Usage ();
 169:         i++;
 170:         } else if (strcmp (arg, "-r") == 0) {
 171:         default_repeat = 0;
 172:         } else if (strcmp (arg, "r") == 0) {
 173:         default_repeat = 1;
 174:         } else if (strcmp (arg, "-s") == 0 && i < argc) {
 175:         default_savertime = atoi (argv[i]);
 176:         if (default_savertime == 0) Usage ();
 177:         i++;
 178:         } else if (strcmp (arg, "-t") == 0 && i < argc) {
 179:         default_threshold = atoi (argv[i]);
 180:         i++;
 181:         } else if (strcmp (arg, "-v") == 0) {
 182:         default_blank = 1;
 183:         } else if (strcmp (arg, "v") == 0) {
 184:         default_blank = 0;
 185:         } else if (strcmp (arg, "-0") == 0 && i < argc) {
 186:         default_pix0 = argv[i];
 187:         i++;
 188:         } else if (strcmp (arg, "-1") == 0 && i < argc) {
 189:         default_pix1 = argv[i];
 190:         i++;
 191:         } else if (strcmp (arg, "-D") == 0 && i < argc) {
 192:         rgb_name = argv[i];
 193:         i++;
 194:         } else {
 195:         Usage ();
 196:         }
 197:     }
 198:     Initialize ();
 199:     Dispatcher ();
 200: }
 201: 
 202: Usage ()
 203: {
 204:     printf("usage:  X <display> [option ...] <tty>\n");
 205:     printf("options: -a #, c #, -c, -f #, -l, l, m, -p #, -r, r, -s #, -t #, v, -v\n");
 206:     printf("         -0 <color> -1 <color> -D <rgbdb>\n");
 207:     exit(1);
 208: }
 209: 
 210: /* Called from Dispatcher when there are no complete requests to process, or
 211:  * when multiple sockets have requests, or when there is input to be read.
 212:  */
 213: 
 214: Receive ()
 215: {
 216:     int mask[mskcnt];
 217:     register int i, maskval, rrmask;
 218:     register vsEventQueue *queue = device.queue;
 219:     register vsEvent *ev;
 220:     int mi, numread;
 221:     union {
 222:         struct sockaddr sa;
 223: #ifdef UNIXCONN
 224:         struct sockaddr_un un;
 225: #endif
 226: #ifdef TCPCONN
 227:         struct sockaddr_in in;
 228: #endif
 229: #ifdef DNETCONN
 230:         struct sockaddr_dn dn;
 231: #endif
 232:     } from;
 233:     int fromlen;
 234: 
 235:     while (1) {
 236: 
 237:         /* If there is input, deal with it */
 238: 
 239:         while (queue->head != queue->tail) {
 240:         ev = &queue->events[queue->head];
 241:         switch (ev->vse_type) {
 242:             case VSE_MMOTION:   /* The mouse moved */
 243:             Deal_with_movement ();
 244:             break;
 245:             case VSE_BUTTON:    /* A key/button moved */
 246:             ProcessInput (ev);
 247:             break;
 248:         }
 249:         if (queue->head == Qmax)
 250:             queue->head = 0;
 251:         else
 252:             queue->head++;
 253:         }
 254: 
 255:         /* If we already have data available, don't try to read more */
 256: 
 257:         if (havestate)
 258:         break;
 259: 
 260:         /* Wait for input or requests */
 261: 
 262:         if (blockhandler) (*blockhandler)();
 263:         copybits(selmask, mask);
 264:         i = select (maxsock, mask, (int *) NULL, (int *) NULL, &waittime);
 265:         if (wakeuphandler) (*wakeuphandler)();
 266:         if (i <= 0) {
 267:         /* A timeout or error occurred */
 268:         if (!i)
 269:             Screen_saver ();
 270:         else if (errno == EBADF)
 271:             Check_connections ();
 272:         continue;
 273:         }
 274: 
 275:         /* Check if only events */
 276: 
 277:         if (mask[0] & devmask) {
 278:         mask[0] &= ~devmask;
 279:         if (inputhandler) (*inputhandler)();
 280:         if (i == 1) continue;
 281:         }
 282: 
 283:         /* If request socket, deal with the new request */
 284: 
 285:         while (rrmask = (mask[0] & requestmask)) {
 286:         i = ffs (rrmask) - 1;
 287:         rrmask = 1 << i;
 288:         mask[0] &= ~rrmask;
 289:         if ((i = accept (i, (struct sockaddr *) NULL, (int *) NULL)) >= 0) {
 290:             fromlen = sizeof (from);
 291:             if (i >= lastfdesc ||
 292:             getpeername (i, &from.sa, &fromlen) ||
 293:             Invalid_host (&from.sa, fromlen)) {
 294:             close (i);
 295:             } else {
 296: #ifdef TCP_NODELAY
 297:             if (fromlen && (from.sa.sa_family == AF_INET)) {
 298:                 mi = 1;
 299:                 setsockopt (i, IPPROTO_TCP, TCP_NODELAY,
 300:                     &mi, sizeof (int));
 301:             }
 302: #endif
 303:             fcntl (i, F_SETFL, FNDELAY);
 304:             socketOn[i] = 1;
 305:             requestId[i] = 0;
 306:             if (servergrabber) {
 307:                 bitset(grabselmask, i);
 308:             } else {
 309:                 bitset(selmask, i);
 310:             }
 311:             bufptr[i] = sockbuf[i] = Xalloc (DEFBUFSIZE);
 312:             bufcnt[i] = 0;
 313:             bufsize[i] = DEFBUFSIZE;
 314:             if (i >= maxsock)
 315:                 maxsock = i + 1;
 316: #ifdef DUALTCP
 317:             if (rrmask & swapmask)
 318:                 swapped[i] = 1;
 319: #endif
 320:             }
 321:         }
 322:         }
 323: 
 324:         /* Read from all ready sockets */
 325: 
 326:         mi = 0;
 327:         i = firstsock;
 328:         rrmask = firstmask;
 329:         maskval = mask[0];
 330:         while (1) {
 331:         if (!maskval) {
 332:             if (mi == (mskcnt - 1))
 333:             break;
 334:             mi++;
 335:             i = mi << 5;
 336:             rrmask = 1;
 337:             maskval = mask[mi];
 338:             continue;
 339:         }
 340:         while (!(maskval & rrmask)) {
 341:             rrmask += rrmask;
 342:             i++;
 343:         }
 344:         maskval &= ~rrmask;
 345:         /* copy down any existing data */
 346:         if (bufcnt[i] && (bufptr[i] != sockbuf[i]))
 347:             bcopy (bufptr[i], sockbuf[i], bufcnt[i]);
 348: 
 349:         /* then read as much as we can */
 350:         bufptr[i] = sockbuf[i];
 351:         if ((numread = read (i, bufptr[i] + bufcnt[i],
 352:                      bufsize[i] - bufcnt[i])) <= 0)
 353:             Close_down (i);
 354:         /* see if we have enough for a request */
 355:         else if ((bufcnt[i] += numread) >= sizeof (XReq)) {
 356:             havemask[mi] |= rrmask;
 357:             if (havestate == 0)
 358:             havestate = i;
 359:             else if (havestate > 0)
 360:             havestate = -2;
 361:             else
 362:             havestate--;
 363:         }
 364:         rrmask += rrmask;
 365:         i++;
 366:         }
 367:     }
 368: 
 369:     if (havestate > 0) {
 370:         rr_counter = havestate;
 371:         return;
 372:     }
 373: 
 374:     /* Handle multiple requests on a round-robin basis */
 375: 
 376:     i = rr_counter + 1;
 377:     while (1) {
 378:         if (i >= maxsock)
 379:         i = firstsock;
 380:         rrmask = bitmask(i);
 381:         if (maskval = (maskword(havemask, i) & -rrmask))
 382:         break;
 383:         i += 32;
 384:         i &= ~31;
 385:     }
 386: 
 387:     while (!(maskval & rrmask)) {
 388:         rrmask += rrmask;
 389:         i++;
 390:     }
 391: 
 392:     rr_counter = i;
 393:     if (havestate == -1)
 394:         havestate = i;
 395: }
 396: 
 397: /* Write data to client.
 398:  * We might have to wait, if the client isn't keeping up with us.  We wait for
 399:  * a short time, then close the connection.  This isn't a wonderful solution,
 400:  * but it rarely seems to be a problem right now, and buffering output for
 401:  * asynchronous delivery sounds complicated and expensive.
 402:  */
 403: 
 404: Write (client, buf, total)
 405:     int client, total;
 406:     char *buf;
 407: {
 408:     int count = total;
 409:     register int n;
 410:     int mask[mskcnt];
 411: 
 412:     while (1) {
 413:         if ((n = write (client, buf, count)) == total)
 414:         return;
 415:         if (n > 0) {
 416:         buf += n;
 417:         total -= n;
 418:         if (total < count)
 419:             count = total;
 420:         } else if (errno == EMSGSIZE)
 421:         count >>= 1;
 422:         else if (errno != EWOULDBLOCK)
 423:         return;
 424:         if (blockhandler) (*blockhandler)();
 425:         singlebit(mask, client);
 426:         n = select (client + 1, (int *) NULL, mask, (int *) NULL, &outtime);
 427:         if (wakeuphandler) (*wakeuphandler)();
 428:         if (n != 1) {
 429:         close (client);
 430:         return;
 431:         }
 432:     }
 433: }
 434: 
 435: /* Read data from client.
 436:  * Returns NULL if the data isn't immediately available, and backs up the
 437:  * buffer structures to re-read the request.
 438:  */
 439: 
 440: caddr_t Read_segment (client, size)
 441:     register int client;
 442:     register int size;
 443: {
 444:     register int idx, mask;
 445:     char *ptr;
 446: 
 447:     if (bufcnt[client] >= size) {
 448:         ptr = bufptr[client];
 449:         bufptr[client] += size;
 450:         /* see if there is a request left */
 451:         if ((bufcnt[client] -= size) < sizeof (XReq)) {
 452:         idx = maskidx(client);
 453:         mask = bitmask(client);
 454:         if (havemask[idx] & mask) {
 455:             havemask[idx] &= ~mask;
 456:             if (havestate < 0)
 457:             havestate++;
 458:             else
 459:             havestate = 0;
 460:         }
 461:         }
 462:         return (ptr);
 463:     }
 464: 
 465:     /* back up to the request */
 466:     bufptr[client] -= sizeof (XReq);
 467:     bufcnt[client] += sizeof (XReq);
 468:     requestId[client]--;
 469: #ifdef DUALTCP
 470:     if (swapped[client])
 471:         Swap_request ((XReq *) bufptr[client]);
 472: #endif
 473:     /* but make it look like not enough is there */
 474:     idx = maskidx(client);
 475:     mask = bitmask(client);
 476:     if (havemask[idx] & mask) {
 477:         havemask[idx] &= ~mask;
 478:         if (havestate < 0)
 479:         havestate++;
 480:         else
 481:         havestate = 0;
 482:     }
 483:     if (size + sizeof (XReq) > bufsize[client]) {
 484:         /* must increase the buffer to accomodate what's coming */
 485:         if (size <= MAXBUFSIZE) {
 486:         ptr = Xalloc (bufsize[client] = size + sizeof (XReq));
 487:         bcopy (bufptr[client], ptr, bufcnt[client]);
 488:         free (sockbuf[client]);
 489:         sockbuf[client] = bufptr[client] = ptr;
 490:         } else
 491:         Close_down (client);
 492:     }
 493:     return (NULL);
 494: }
 495: 
 496: /* Give client sole access to server */
 497: 
 498: Grab_server (client)
 499:     register int client;
 500: {
 501:     register int idx, mask;
 502: 
 503:     if (servergrabber == 0) {
 504:         copybits(selmask, grabselmask);
 505:         clearbits(selmask);
 506:         selmask[0] = devmask | requestmask;
 507:         idx = maskidx(client);
 508:         mask = bitmask(client);
 509:         selmask[idx] |= mask;
 510:         copybits(havemask, grabhavemask);
 511:         clearbits(havemask);
 512:         grabhavestate = havestate;
 513:         if (grabhavemask[idx] & mask) {
 514:         grabhavemask[idx] &= ~mask;
 515:         havemask[idx] = mask;
 516:         havestate = client;
 517:         if (grabhavestate < 0)
 518:             grabhavestate++;
 519:         else
 520:             grabhavestate = 0;
 521:         } else
 522:         havestate = 0;
 523:         servergrabber = client;
 524:     }
 525: }
 526: 
 527: /* Restore global access to server */
 528: 
 529: Ungrab_server ()
 530: {
 531:     if (servergrabber) {
 532:         copybits(grabselmask, selmask);
 533:         if (havestate) {
 534:         bitset(grabhavemask, servergrabber);
 535:         if (grabhavestate == 0)
 536:             grabhavestate = servergrabber;
 537:         else if (grabhavestate > 0)
 538:             grabhavestate = -2;
 539:         else
 540:             grabhavestate--;
 541:         }
 542:         havestate = grabhavestate;
 543:         copybits(grabhavemask, havemask);
 544:         servergrabber = 0;
 545:     }
 546: }
 547: 
 548: /* Blank the screen when the server has been idle for a while */
 549: 
 550: Screen_saver ()
 551: {
 552:     int mask[mskcnt];
 553:     PIXMAP *save = NULL;
 554:     int video = -1;
 555:     struct timeval tv;
 556:     struct timezone tz;
 557:     int n;
 558: 
 559:     /* zap the cursor */
 560:     LoadCursor (sscursor);
 561:     /* make sure mouse motion wakes us up */
 562:     device.mbox->bottom = 0;
 563:     if (blank_video)
 564:         video = SetVideo (0);
 565:     if (!blank_video || video)
 566:         save = PixmapSave (0, 0, device.width, device.height);
 567:     if (!blank_video && save == NULL)
 568:         video = SetVideo (0);
 569:     do {
 570:         if (video) {
 571:         /* randomize the pattern */
 572:         gettimeofday (&tv, &tz);
 573:         if (device.entries > 2) {
 574:             randomcolors[0].red = tv.tv_sec & 0x4 ? -1 : 0;
 575:             randomcolors[0].green = tv.tv_sec & 0x2 ? -1 : 0;
 576:             randomcolors[0].blue = tv.tv_sec & 0x1 ? -1 : 0;
 577:             randomcolors[1].red = tv.tv_usec & 0x40000 ? -1 : 0;
 578:             randomcolors[1].green = tv.tv_usec & 0x20000 ? -1 : 0;
 579:             randomcolors[1].blue = tv.tv_usec & 0x10000 ? -1 : 0;
 580:             StoreColors (2, randomcolors);
 581:         }
 582:         TileFill (rootwindow->tile,
 583:               (int) (tv.tv_sec >> 4) & 0xf, (int) tv.tv_sec & 0xf,
 584:               (BITMAP *) NULL, 0, 0, device.width, device.height,
 585:               &rootwindow->clip, 1, GXcopy, -1);
 586:         }
 587:         if (blockhandler) (*blockhandler)();
 588:         copybits(selmask, mask);
 589:         n = select (maxsock, mask, (int *) NULL, (int *) NULL, &longtime);
 590:         if (wakeuphandler) (*wakeuphandler)();
 591:     } while (n == 0);
 592:     /* now restore the world */
 593:     if (video && device.entries > 2) {
 594:         Query_color (randomcolors[0].pixel, &randomcolors[0].red,
 595:              &randomcolors[0].green, &randomcolors[0].blue);
 596:         Query_color (randomcolors[1].pixel, &randomcolors[1].red,
 597:              &randomcolors[1].green, &randomcolors[1].blue);
 598:         StoreColors (2, randomcolors);
 599:     }
 600:     if (save) {
 601:         PixmapPut (save, 0, 0, device.width, device.height, 0, 0,
 602:                &rootwindow->clip, 1, GXcopy, -1);
 603:         FreePixmap (save);
 604:     } else if (video)
 605:         Draw_window (rootwindow, 1, 1);
 606:     else
 607:         SetVideo (1);
 608:     LoadCursor (cursor);
 609: }
 610: 
 611: /* Check the status of each client, and close our side of any goners. */
 612: 
 613: Check_connections ()
 614: {
 615:     register int i;
 616:     int mask[mskcnt];
 617: 
 618:     for (i = firstsock; i < maxsock; i++) {
 619:         if (!socketOn[i])
 620:         continue;
 621:         singlebit(mask, i);
 622:         if (select (i + 1, mask, (int *) NULL, (int *) NULL, &notime) < 0)
 623:         Close_down (i);
 624:     }
 625: }
 626: 
 627: /* Close down a client, freeing its resources. */
 628: 
 629: Close_down (i)
 630:     register int i;
 631: {
 632:     register int idx, mask;
 633: 
 634:     if (servergrabber)
 635:         Ungrab_server ();
 636:     idx = maskidx(i);
 637:     mask = bitmask(i);
 638:     selmask[idx] &= ~mask;
 639:     if (havemask[idx] & mask) {
 640:         havemask[idx] &= ~mask;
 641:         if (havestate < 0)
 642:         havestate++;
 643:         else
 644:         havestate = 0;
 645:     }
 646:     close (i);
 647:     socketOn[i] = 0;
 648:     if (i + 1 == maxsock) {
 649:         while ((maxsock > firstsock) && (!socketOn[maxsock - 1]))
 650:         --maxsock;
 651:     }
 652:     free (sockbuf[i]);
 653: #ifdef DUALTCP
 654:     swapped[i] = 0;
 655: #endif
 656:     Free_client_resources (i);
 657:     Deal_with_movement ();
 658:     /* if nobody is left, clean up after them */
 659:     if (maxsock == firstsock)
 660:         Restore_root ();
 661: }
 662: 
 663: /* This is where we create the background, etc. */
 664: 
 665: Initialize ()
 666: {
 667:     char fname[32];
 668:     int request;
 669: #ifdef TCPCONN
 670:     int whichbyte;
 671:     int tcpport1;
 672: #ifdef DUALTCP
 673:     int tcpport2;
 674: #endif
 675:     struct sockaddr_in mysock;
 676: #ifndef SO_DONTLINGER
 677:     static int linger[2] = { 0, 0 };
 678: #endif
 679: #endif
 680: #ifdef UNIXCONN
 681:     struct sockaddr_un unsock;
 682: #endif
 683: #ifdef DNETCONN
 684:     struct sockaddr_dn dnsock;
 685: #endif
 686:     int retry;
 687:     BITMAP *bit1, *bit2;
 688:     datum dbent;
 689:     RGB color;
 690: 
 691:     lastfdesc = getdtablesize() - 1;
 692:     if (lastfdesc > maxsocks)
 693:         lastfdesc = maxsocks;
 694:     /* hack test to decide where to log errors */
 695:     if (write (2, fname, 0)) {
 696:         strcpy (fname, "/usr/adm/X");
 697:         strcat (fname, display);
 698:         strcat (fname, "msgs");
 699:         freopen (fname, "w+", stderr);
 700:     }
 701:     if (getpgrp (0) == 0)
 702:         setpgrp (0, getpid ());
 703:     if (dbminit (rgb_name) == 0)
 704:         havergb = 1;
 705: 
 706:     requestmask = 0;
 707: #ifdef DUALTCP
 708:     swapmask = 0;
 709: #endif
 710: 
 711: #ifdef TCPCONN
 712:     tcpport1 = atoi (display);
 713:     whichbyte = 1;
 714:     if (*(char *) &whichbyte) {
 715: #ifdef DUALTCP
 716:         tcpport2 = tcpport1 + X_TCP_BI_PORT;
 717: #endif
 718:         tcpport1 += X_TCP_LI_PORT;
 719:     } else {
 720: #ifdef DUALTCP
 721:         tcpport2 = tcpport1 + X_TCP_LI_PORT;
 722: #endif
 723:         tcpport1 += X_TCP_BI_PORT;
 724:     }
 725: #endif
 726:     if ((devdesc = OpenDisplay (devdisp)) < 0)
 727:         Error ("Opening");
 728: 
 729:     signal (SIGPIPE, SIG_IGN);
 730: #ifdef TCPCONN
 731:     if ((request = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
 732:         Notice ("Creating TCP socket");
 733:     } else {
 734:         bzero ((char *)&mysock, sizeof (mysock));
 735:         mysock.sin_family = AF_INET;
 736:         mysock.sin_port = htons (tcpport1);
 737:         mysock.sin_addr.s_addr = htonl(INADDR_ANY);
 738:         retry = 20;
 739:         while (bind (request, (struct sockaddr *) &mysock,
 740:              sizeof (mysock))) {
 741:         if (--retry == 0)
 742:             Error ("Binding TCP socket");
 743:         sleep (10);
 744:         }
 745: #ifdef SO_DONTLINGER
 746:         if (setsockopt (request, SOL_SOCKET, SO_DONTLINGER, 0, 0))
 747: #else
 748:         if (setsockopt (request, SOL_SOCKET, SO_LINGER,
 749:                 linger, sizeof (linger)))
 750: #endif
 751:         Notice ("Setting TCP DONTLINGER");
 752:         if (listen (request, 5)) Error ("TCP Listening");
 753:         requestmask |= (1 << request);
 754:         Define_self (request);
 755:     }
 756: #ifdef DUALTCP
 757:     if ((request = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
 758:         Notice ("Creating dual TCP socket");
 759:     } else {
 760:         mysock.sin_port = htons (tcpport2);
 761:         retry = 20;
 762:         while (bind (request, (struct sockaddr *) &mysock,
 763:              sizeof (mysock))) {
 764:         if (--retry == 0)
 765:             Error ("Binding dual TCP socket");
 766:         sleep (10);
 767:         }
 768: #ifdef SO_DONTLINGER
 769:         if (setsockopt (request, SOL_SOCKET, SO_DONTLINGER, 0, 0))
 770: #else
 771:         if (setsockopt (request, SOL_SOCKET, SO_LINGER,
 772:                 linger, sizeof (linger)))
 773: #endif
 774:         Notice ("Setting dual TCP DONTLINGER");
 775:         if (listen (request, 5)) Error ("dual TCP Listening");
 776:         requestmask |= (1 << request);
 777:         swapmask |= (1 << request);
 778:         Define_self (request);
 779:     }
 780: #endif
 781: #endif
 782: #ifdef UNIXCONN
 783:     unsock.sun_family = AF_UNIX;
 784:     strcpy (unsock.sun_path, X_UNIX_PATH);
 785:     strcat (unsock.sun_path, display);
 786:     unlink (unsock.sun_path);
 787:     if ((request = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
 788:         Notice ("Creating Unix socket");
 789:     } else {
 790:         if (bind (request, (struct sockaddr *) &unsock,
 791:               strlen (unsock.sun_path) + 2))
 792:         Error ("Binding Unix socket");
 793:         if (listen (request, 5)) Error ("Unix Listening");
 794:         requestmask |= (1 << request);
 795:     }
 796: #endif
 797: #ifdef DNETCONN
 798:     if ((request = socket (AF_DECnet, SOCK_STREAM, 0)) < 0) {
 799:         Notice ("Creating DECnet socket");
 800:     } else {
 801:         bzero ((char *)&dnsock, sizeof (dnsock));
 802:         dnsock.sdn_family = AF_DECnet;
 803:         sprintf(dnsock.sdn_objname, "X%d", atoi (display));
 804:         dnsock.sdn_objnamel = strlen(dnsock.sdn_objname);
 805:         if (bind (request, (struct sockaddr *) &dnsock, sizeof (dnsock)))
 806:             Error ("Binding DECnet socket");
 807:         if (listen (request, 5)) Error ("DECnet Listening");
 808:         requestmask |= (1 << request);
 809:         Define_self (request);
 810:     }
 811: #endif
 812:     if (requestmask == 0) Error ("No Listeners");
 813:     signal (SIGHUP, SIG_IGN);
 814:     if (InitDisplay (&device)) Error ("Initializing");
 815:     signal (SIGHUP, HangUp);
 816:     Qmax = device.queue->size - 1;
 817:     devmask = 1 << devdesc;
 818:     selmask[0] = devmask | requestmask;
 819:     rr_counter = request;
 820:     havestate = 0;
 821:     firstsock = maxsock = request + 1;
 822:     firstmask = 1 << maxsock;
 823: 
 824:     if (default_mono && device.entries > 2)
 825:         device.entries = 2;
 826:     Init_colormap ();
 827:     if (device.entries > 2) {
 828:         if (default_pix0) {
 829:         if (*default_pix0 == '#')
 830:             Parse_color (default_pix0+1, &basecolors[0]);
 831:         else if TRUE(havergb) {
 832:             dbent.dptr = default_pix0;
 833:             dbent.dsize = strlen (default_pix0);
 834:             dbent = fetch (dbent);
 835:             if (dbent.dptr) {
 836:             bcopy(dbent.dptr, (caddr_t)&color, sizeof (RGB));
 837:             basecolors[0].red = color.red;
 838:             basecolors[0].green = color.green;
 839:             basecolors[0].blue = color.blue;
 840:             }
 841:         }
 842:         }
 843:         if (default_pix1) {
 844:         if (*default_pix1 == '#')
 845:             Parse_color (default_pix1+1, &basecolors[1]);
 846:         else if TRUE(havergb) {
 847:             dbent.dptr = default_pix1;
 848:             dbent.dsize = strlen (default_pix1);
 849:             dbent = fetch (dbent);
 850:             if (dbent.dptr) {
 851:             bcopy(dbent.dptr, (caddr_t)&color, sizeof (RGB));
 852:             basecolors[1].red = color.red;
 853:             basecolors[1].green = color.green;
 854:             basecolors[1].blue = color.blue;
 855:             }
 856:         }
 857:         }
 858:         Store_colors (2, basecolors);
 859:     }
 860:     bit1 = StoreBitmap (16, 16, (char *) _back);
 861:     roottile = MakePixmap (bit1, WhitePixel, BlackPixel);
 862:     if (--bit1->refcnt == 0)
 863:         FreeBitmap (bit1);
 864:     Create_root_window (device.height, device.width, roottile);
 865:     bit1 = StoreBitmap (16, 16, (char *) _pointer);
 866:     bit2 = StoreBitmap (16, 16, (char *) _ptrmask);
 867:     rootcursor = StoreCursor (GXcopy, bit1, WhitePixel, BlackPixel, bit2,
 868:                   7, 7);
 869:     if (--bit1->refcnt == 0)
 870:         FreeBitmap (bit1);
 871:     if (--bit2->refcnt == 0)
 872:         FreeBitmap (bit2);
 873:     bit1 = StoreBitmap (16, 16, (char *) _ssmask);
 874:     sscursor = StoreCursor (GXnoop, bit1, WhitePixel, BlackPixel, bit1,
 875:                 7, 7);
 876:     if (--bit1->refcnt == 0)
 877:         FreeBitmap (bit1);
 878:     Restore_root ();
 879:     errdelay = 0;
 880: }
 881: 
 882: /* Parse a color spec:  RGB, RRGGBB, RRRGGGBBB, RRRRGGGGBBBB */
 883: 
 884: Parse_color (spec, def)
 885:     register char *spec;
 886:     register ColorDef *def;
 887: {
 888:     register int n, i;
 889:     int r, g, b;
 890:     char c;
 891: 
 892:     n = strlen (spec);
 893:     if (n != 3 && n != 6 && n != 9 && n != 12)
 894:         return (-1);
 895:     n /= 3;
 896:     r = g = b = 0;
 897:     do {
 898:         r = g;
 899:         g = b;
 900:         b = 0;
 901:         for (i = n; --i >= 0; ) {
 902:         c = *spec++;
 903:         b <<= 4;
 904:         if (c >= '0' && c <= '9')
 905:             b |= c - '0';
 906:         else if (c >= 'A' && c <= 'F')
 907:             b |= c - ('A' - 10);
 908:         else if (c >= 'a' && c <= 'f')
 909:             b |= c - ('a' - 10);
 910:         else return (-1);
 911:         }
 912:     } while (*spec);
 913:     n <<= 2;
 914:     n = 16 - n;
 915:     def->red = r << n;
 916:     def->green = g << n;
 917:     def->blue = b << n;
 918:     return (0);
 919: }
 920: 
 921: /* Restore the world to original condition */
 922: 
 923: Restore_root ()
 924: {
 925:     Free_window_storage ();
 926:     Free_rectangle_storage ();
 927:     if (device.entries > 2)
 928:         Store_colors (2, basecolors);
 929:     Reset_cuts ();
 930:     waittime.tv_sec = default_savertime * 60;
 931:     longtime.tv_sec = default_savercycle * 60;
 932:     SetKeyClick (default_click);
 933:     SetAutoRepeat (default_repeat);
 934:     Set_shiftlock (default_lock);
 935:     base_feep = default_feep;
 936:     blank_video = default_blank;
 937:     rootwindow->mask = NoEvent;
 938:     rootwindow->client = 0;
 939:     rootwindow->tilemode = TileModeAbsolute;
 940:     rootwindow->clipmode = ClipModeDrawThru;
 941:     Change_background (rootwindow, roottile);
 942:     Map_root_window ();
 943:     Focus_keyboard (rootwindow);
 944:     Register_cursor (rootwindow, rootcursor);
 945:     Startup_mouse ();
 946:     SetMouseCharacteristics (default_threshold, default_acceleration);
 947:     Reset_hosts (display);
 948: }
 949: 
 950: /* Exists for ddX to call if it needs to simulate input queue */
 951: 
 952: Define_input_handler (func)
 953:     int (*func)();
 954: {
 955:     inputhandler = func;
 956: }
 957: 
 958: /* Exists for ddX to call if it needs computes before blocking */
 959: 
 960: Define_block_handler (func)
 961:     int (*func)();
 962: {
 963:     blockhandler = func;
 964: }
 965: 
 966: /* Exists for ddX to call if it needs computes after unblocking */
 967: 
 968: Define_wakeup_handler (func)
 969:     int (*func)();
 970: {
 971:     wakeuphandler = func;
 972: }
 973: 
 974: /* Force connections to close on SIGHUP from init */
 975: 
 976: HangUp ()
 977: {
 978:     int i;
 979: 
 980: #ifdef GPROF
 981:     chdir ("/tmp");
 982:     exit (0);
 983: #endif
 984:     for (i = firstsock; i < maxsock; i++) {
 985:         if (socketOn[i])
 986:         close (i);
 987:     }
 988:     if (DisplayDead ())
 989:         Error ("HangUp");
 990: }
 991: 
 992: /* log a server error */
 993: 
 994: Notice (where)
 995:     char *where;
 996: {
 997:     fprintf (stderr, "error: %s at %s\n",
 998:          (errno > 0 && errno < sys_nerr) ? sys_errlist[errno] : "?",
 999:          where);
1000:     fflush (stderr);
1001: }
1002: 
1003: /* log a fatal server error */
1004: 
1005: Error (where)
1006:     char *where;
1007: {
1008:     fprintf (stderr, "fatal ");
1009:     Notice (where);
1010:     if (errdelay)
1011:         sleep (errdelay);
1012:     exit (1);
1013: }
1014: 
1015: /* log a device error */
1016: 
1017: DeviceError (why)
1018:     char *why;
1019: {
1020:     fprintf (stderr, "device error: %s\n", why);
1021:     fflush (stderr);
1022: }

Defined functions

Check_connections defined in line 613; used 1 times
Close_down defined in line 629; used 3 times
Define_block_handler defined in line 960; never used
Define_input_handler defined in line 952; never used
Define_wakeup_handler defined in line 968; never used
DeviceError defined in line 1017; used 6 times
Error defined in line 1005; used 15 times
Grab_server defined in line 498; used 1 times
HangUp defined in line 976; used 2 times
Initialize defined in line 665; used 1 times
Notice defined in line 994; used 7 times
Parse_color defined in line 884; used 2 times
Read_segment defined in line 440; used 18 times
Receive defined in line 214; used 1 times
Restore_root defined in line 923; used 2 times
Screen_saver defined in line 550; used 1 times
Ungrab_server defined in line 529; used 2 times
Usage defined in line 202; used 7 times
main defined in line 130; never used

Defined variables

Qmax defined in line 43; used 2 times
_back defined in line 51; used 1 times
_pointer defined in line 58; used 1 times
_ptrmask defined in line 63; used 1 times
_ssmask defined in line 68; used 1 times
basecolors defined in line 86; used 10 times
blank_video defined in line 128; used 5 times
bufcnt defined in line 96; used 11 times
bufptr defined in line 94; used 13 times
bufsize defined in line 100; used 4 times
default_acceleration defined in line 78; used 3 times
default_blank defined in line 84; used 3 times
default_click defined in line 73; used 4 times
default_feep defined in line 76; used 3 times
default_lock defined in line 75; used 3 times
default_mono defined in line 83; used 2 times
default_pix0 defined in line 81; used 6 times
default_pix1 defined in line 82; used 6 times
default_repeat defined in line 74; used 3 times
default_savercycle defined in line 80; used 3 times
default_savertime defined in line 79; used 3 times
default_threshold defined in line 77; used 2 times
devdesc defined in line 41; used 2 times
devdisp defined in line 39; used 2 times
device defined in line 42; used 56 times
devmask defined in line 120; used 5 times
display defined in line 40; used 8 times
errdelay defined in line 127; used 3 times
firstmask defined in line 108; used 2 times
firstsock defined in line 107; used 7 times
grabhavemask defined in line 118; used 5 times
grabhavestate defined in line 119; used 10 times
grabselmask defined in line 117; used 3 times
havemask defined in line 114; used 13 times
havergb defined in line 49; used 4 times
havestate defined in line 115; used 29 times
lastfdesc defined in line 105; used 4 times
longtime defined in line 123; used 3 times
maxsock defined in line 106; used 14 times
notime defined in line 126; used 1 times
outtime defined in line 125; used 1 times
randomcolors defined in line 88; used 16 times
rcsid_main_c defined in line 8; never used
requestId defined in line 92; used 4 times
requestmask defined in line 112; used 9 times
rgb_name defined in line 48; used 2 times
rootcursor defined in line 70; used 3 times
roottile defined in line 56; used 4 times
rr_counter defined in line 121; used 6 times
selmask defined in line 113; used 10 times
servergrabber defined in line 116; used 8 times
sockbuf defined in line 93; used 7 times
socketOn defined in line 91; used 5 times
sscursor defined in line 71; used 2 times
swapmask defined in line 110; used 3 times
waittime defined in line 122; used 3 times

Defined macros

DEFBUFSIZE defined in line 98; used 2 times
MAXBUFSIZE defined in line 99; used 1 times
OUTTIME defined in line 124; used 1 times
Last modified: 1986-02-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4280
Valid CSS Valid XHTML 1.0 Strict