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, ¬ime) < 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: }