|
|
1.1 ! root 1: /* xface.c - face agent for X windows */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/others/image/RCS/xface.c,v 7.0 89/11/23 22:00:03 mrose Rel $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/others/image/RCS/xface.c,v 7.0 89/11/23 22:00:03 mrose Rel $ ! 9: * ! 10: * ! 11: * $Log: xface.c,v $ ! 12: * Revision 7.0 89/11/23 22:00:03 mrose ! 13: * Release 6.0 ! 14: * ! 15: */ ! 16: ! 17: /* ! 18: * NOTICE ! 19: * ! 20: * Acquisition, use, and distribution of this module and related ! 21: * materials are subject to the restrictions of a license agreement. ! 22: * Consult the Preface in the User's Manual for the full terms of ! 23: * this agreement. ! 24: * ! 25: */ ! 26: ! 27: ! 28: #include <errno.h> ! 29: #include <stdio.h> ! 30: #include "imagesbr.h" ! 31: #include "internet.h" ! 32: #include <X11/Xlib.h> ! 33: #include <X11/Xutil.h> ! 34: ! 35: /* DATA */ ! 36: ! 37: static int sd = NOTOK; ! 38: int debug = 0; ! 39: int errsw = 0; ! 40: static int portsw = 0; ! 41: static int ppidsw = 0; ! 42: static int sleepsw = 30; ! 43: ! 44: static char *myname = "xface"; ! 45: ! 46: static int eventfd = NOTOK; ! 47: static int (*eventfx)() = NULL; ! 48: ! 49: static int (*alarmfx)() = NULL; ! 50: ! 51: ! 52: static char *display = NULL; ! 53: static char *geometry = NULL; ! 54: ! 55: ! 56: static Display *DISP; ! 57: static int SCRN; ! 58: ! 59: static struct type_IMAGE_Image *myim = NULL; ! 60: ! 61: ! 62: typedef struct _frame { ! 63: short x, y; ! 64: unsigned int width, height; ! 65: unsigned int bdrwidth; ! 66: unsigned long border; ! 67: unsigned long background; ! 68: } Frame; ! 69: ! 70: ! 71: static int mapped; ! 72: static int parent; ! 73: ! 74: static Window mywindow = 0; ! 75: static Frame myframe; ! 76: ! 77: ! 78: static unsigned long backpix, bdrpix; ! 79: static GC forepix, highpix; ! 80: ! 81: int ALRMser (), XWINser (); ! 82: ! 83: ! 84: extern int errno; ! 85: ! 86: char *getenv (); ! 87: ! 88: /* MAIN */ ! 89: ! 90: /* ARGSUSED */ ! 91: ! 92: main (argc, argv, envp) ! 93: int argc; ! 94: char **argv, ! 95: **envp; ! 96: { ! 97: char buffer[BUFSIZ], ! 98: *vec[NVEC + 1]; ! 99: ! 100: arginit (argv); ! 101: ! 102: if (portsw > 0) ! 103: startsocket (portsw); ! 104: ! 105: if (ppidsw > 0) ! 106: envinit (); ! 107: ! 108: if (errsw) ! 109: errsw = NOTOK; ! 110: ! 111: for (;;) { ! 112: if ((portsw > 0 ? readsocket (buffer) : getline (buffer)) == NOTOK) ! 113: break; ! 114: ! 115: if (str2vec (buffer, vec) != 2) ! 116: continue; ! 117: ! 118: fetch_face (vec[0], vec[1]); ! 119: ! 120: if (debug) ! 121: (void) fflush (stderr); ! 122: } ! 123: ! 124: exit (0); ! 125: } ! 126: ! 127: /* */ ! 128: ! 129: static fetch_face (host, user) ! 130: char *host, ! 131: *user; ! 132: { ! 133: if ((myim = fetch_image (user, host)) == NULL && recording) ! 134: LLOG (pgm_log, LLOG_NOTICE, ! 135: ("no image for \"%s\" \"%s\"", user, host)); ! 136: ! 137: if (mywindow != NULL || myim) ! 138: display_X (); ! 139: } ! 140: ! 141: /* */ ! 142: ! 143: static int getline (buffer) ! 144: char *buffer; ! 145: { ! 146: register int i; ! 147: register char *cp, ! 148: *ep; ! 149: static int sticky = 0; ! 150: ! 151: if (sticky) { ! 152: sticky = 0; ! 153: return NOTOK; ! 154: } ! 155: ! 156: printf ("%s> ", myname); ! 157: (void) fflush (stdout); ! 158: ! 159: for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) { ! 160: if (i == EOF) { ! 161: printf ("\n"); ! 162: if (cp != buffer) { ! 163: sticky++; ! 164: break; ! 165: } ! 166: ! 167: return NOTOK; ! 168: } ! 169: ! 170: if (cp < ep) ! 171: *cp++ = i; ! 172: } ! 173: *cp = NULL; ! 174: ! 175: return OK; ! 176: } ! 177: ! 178: /* ARGINIT */ ! 179: ! 180: static arginit (vec) ! 181: char **vec; ! 182: { ! 183: int n; ! 184: register char *ap, ! 185: *cp; ! 186: ! 187: if (myname = rindex (*vec, '/')) ! 188: myname++; ! 189: if (myname == NULL || *myname == NULL) ! 190: myname = *vec; ! 191: ! 192: isodetailor (myname, 1); ! 193: init_aka (myname, 0, NULLCP); ! 194: ! 195: if ((ap = getenv ("FACEPROC")) ! 196: && (cp = index (ap, ' ')) ! 197: && sscanf (++cp, "%d", &n) == 1 ! 198: && n >= 1) ! 199: portsw = n; ! 200: ! 201: for (vec++; ap = *vec; vec++) ! 202: if (*ap == '-') ! 203: switch (*++ap) { ! 204: case 'd': ! 205: debug++; ! 206: break; ! 207: ! 208: case 'e': ! 209: errsw++; ! 210: break; ! 211: ! 212: case 'p': ! 213: if ((ap = *++vec) == NULL ! 214: || sscanf (ap, "%d", &portsw) != 1 ! 215: || portsw < 1) ! 216: adios (NULLCP, "usage: %s -p port", myname); ! 217: break; ! 218: ! 219: case 'r': ! 220: recording++; ! 221: break; ! 222: ! 223: case 's': ! 224: if ((ap = *++vec) == NULL ! 225: || sscanf (ap, "%d", &sleepsw) != 1 ! 226: || sleepsw < 1) ! 227: adios (NULLCP, "usage: %s -s seconds", myname); ! 228: break; ! 229: ! 230: case 'u': ! 231: ppidsw = getppid (); ! 232: break; ! 233: ! 234: default: ! 235: adios (NULLCP, "unknown switch -%s", ap); ! 236: } ! 237: else ! 238: if (*ap == '=') ! 239: geometry = ap; ! 240: else ! 241: if ((cp = rindex (ap, ':')) && sscanf (++cp, "%d", &n) == 1) ! 242: display = ap; ! 243: else ! 244: adios (NULLCP, "usage: %s [switches] host:display", ! 245: myname); ! 246: ! 247: if (debug) ! 248: ll_dbinit (pgm_log, myname); ! 249: else ! 250: ll_hdinit (pgm_log, myname); ! 251: ! 252: if ((DISP = XOpenDisplay (display)) == NULL) ! 253: adios (NULLCP, "unable to open display \"%s\"", ! 254: XDisplayName (display)); ! 255: SCRN = DefaultScreen (DISP); ! 256: } ! 257: ! 258: /* */ ! 259: ! 260: static envinit () ! 261: { ! 262: int i, ! 263: pid; ! 264: ! 265: if (debug) ! 266: return; ! 267: ! 268: for (i = 0; (pid = fork ()) == NOTOK && i < 5; i++) ! 269: sleep (5); ! 270: switch (pid) { ! 271: case NOTOK: ! 272: case OK: ! 273: break; ! 274: ! 275: default: ! 276: exit (0); ! 277: } ! 278: ! 279: ll_hdinit (pgm_log, myname); ! 280: } ! 281: ! 282: /* */ ! 283: ! 284: static display_X () ! 285: { ! 286: if (mywindow == NULL) { ! 287: int bwidth; ! 288: char *opt, ! 289: def[BUFSIZ]; ! 290: XSizeHints hints; ! 291: XSetWindowAttributes xswattrs; ! 292: unsigned long xswattrs_mask; ! 293: ! 294: forepix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, ! 295: (XGCValues *) NULL); ! 296: highpix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, ! 297: (XGCValues *) NULL); ! 298: XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, ! 299: forepix); ! 300: XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, ! 301: highpix); ! 302: if ((opt = XGetDefault (DISP, myname, "ReverseVideo")) ! 303: && strcmp (opt, "on") == 0) { ! 304: XSetForeground(DISP, forepix, WhitePixel(DISP, SCRN)); ! 305: XSetForeground(DISP, highpix, WhitePixel(DISP, SCRN)); ! 306: backpix = BlackPixel(DISP, SCRN); ! 307: bdrpix = WhitePixel(DISP, SCRN); ! 308: XSetFunction(DISP, forepix, GXcopyInverted); ! 309: XSetFunction(DISP, highpix, GXand); ! 310: } ! 311: else { ! 312: XSetForeground(DISP, forepix, BlackPixel(DISP, SCRN)); ! 313: XSetForeground(DISP, highpix, BlackPixel(DISP, SCRN)); ! 314: backpix = WhitePixel(DISP, SCRN); ! 315: bdrpix = BlackPixel(DISP, SCRN); ! 316: XSetFunction(DISP, forepix, GXcopy); ! 317: XSetFunction(DISP, highpix, GXor); ! 318: } ! 319: ! 320: XSetBackground (DISP, forepix, backpix); ! 321: XSetBackground (DISP, highpix, backpix); ! 322: ! 323: if (opt = XGetDefault (DISP, myname, "BorderWidth")) ! 324: bwidth = atoi (opt); ! 325: else ! 326: bwidth = 2; ! 327: ! 328: myframe.bdrwidth = bwidth; ! 329: myframe.height = myim -> height; ! 330: if (myframe.height + bwidth * 2 > DisplayHeight (DISP, SCRN)) ! 331: myframe.height = DisplayHeight (DISP, SCRN) - bwidth * 2; ! 332: myframe.width = myim -> width; ! 333: if (myframe.width + bwidth * 2 > DisplayWidth (DISP, SCRN)) ! 334: myframe.width = DisplayWidth (DISP, SCRN) - bwidth * 2; ! 335: myframe.x = DisplayWidth (DISP, SCRN) - (myframe.width + bwidth * 2); ! 336: myframe.y = 0; ! 337: (void) sprintf (def, "=%dx%d+%d+%d", myframe.width, myframe.height, ! 338: myframe.x, myframe.y); ! 339: ! 340: if (debug) ! 341: fprintf (stderr, "def: %s, myframe: =%dx%d+%d+%d/%d\n", def, ! 342: myframe.width, myframe.height, myframe.x, myframe.y, ! 343: myframe.bdrwidth); ! 344: ! 345: hints.width = myim -> width; ! 346: hints.height = myim -> height; ! 347: hints.x = hints.y = 0; ! 348: hints.flags = PSize | PPosition; ! 349: ! 350: xswattrs.border_pixel = bdrpix; ! 351: xswattrs.background_pixel = backpix; ! 352: xswattrs_mask = CWBackPixel | CWBorderPixel; ! 353: ! 354: mywindow = XCreateWindow (DISP, RootWindow (DISP, SCRN), ! 355: myframe.x, myframe.y, ! 356: myframe.width, myframe.height, ! 357: myframe.bdrwidth, ! 358: 0, InputOutput, (Visual *) CopyFromParent, ! 359: xswattrs_mask, &xswattrs); ! 360: ! 361: XSetStandardProperties (DISP, mywindow, myname, "Face Agent", None, ! 362: (char **) 0, 0, &hints); ! 363: ! 364: XSelectInput (DISP, mywindow, ExposureMask | StructureNotifyMask); ! 365: ! 366: XMapWindow (DISP, mywindow); ! 367: mapped = parent = 0; ! 368: } ! 369: else ! 370: Redisplay (); ! 371: ! 372: eventfd = ConnectionNumber (DISP); ! 373: eventfx = XWINser; ! 374: alarmfx = ALRMser; ! 375: ! 376: XWINser (0); ! 377: } ! 378: ! 379: /* */ ! 380: ! 381: static Redisplay () ! 382: { ! 383: int sx, ! 384: sy, ! 385: dx, ! 386: dy; ! 387: unsigned int h, ! 388: w; ! 389: XImage *image; ! 390: ! 391: if (myim == NULL) { ! 392: XClearWindow (DISP, mywindow); ! 393: return; ! 394: } ! 395: ! 396: sx = max (myim -> width - (int) myframe.width, 0) / 2; ! 397: sy = max (myim -> height - (int) myframe.height, 0) / 2; ! 398: dx = max ((int) myframe.width - myim -> width, 0) / 2; ! 399: dy = max ((int) myframe.height - myim -> height, 0) / 2; ! 400: w = min (myframe.width, myim -> width); ! 401: h = min (myframe.height, myim -> height); ! 402: ! 403: if (debug) { ! 404: fprintf (stderr, "im: %dx%d frame:%dx%d\n", ! 405: myim -> width, myim -> height, myframe.width, myframe.height); ! 406: fprintf (stderr, "sx=%d sy=%d dx=%d dy=%d w=%d h=%d\n", ! 407: sx, sy, dx, dy, w, h); ! 408: } ! 409: ! 410: image = XCreateImage (DISP, DefaultVisual (DISP, SCRN), 1, XYBitmap, 0, ! 411: myim -> data -> qb_forw -> qb_data, ! 412: (unsigned int) myim -> width, ! 413: (unsigned int) myim -> height, 8, 0); ! 414: if (image == NULL) ! 415: adios (NULLCP, "XCreateImage failed"); ! 416: image -> byte_order = image -> bitmap_bit_order = LSBFirst; ! 417: XClearWindow (DISP, mywindow); ! 418: XPutImage (DISP, mywindow, forepix, image, sx, sy, dx, dy, w, h); ! 419: ! 420: XDestroyImage (image); ! 421: } ! 422: ! 423: /* */ ! 424: ! 425: static int ALRMser () ! 426: { ! 427: if (mywindow && mapped) { ! 428: if (parent) ! 429: XClearWindow (DISP, mywindow); ! 430: else ! 431: XUnmapWindow (DISP, mywindow); ! 432: } ! 433: ! 434: if (myim) ! 435: myim = NULL; ! 436: } ! 437: ! 438: /* */ ! 439: ! 440: /* ARGSUSED */ ! 441: ! 442: static int XWINser (io) ! 443: int io; ! 444: { ! 445: int ww, ! 446: wh; ! 447: XEvent xevent; ! 448: register XEvent *xe = &xevent; ! 449: ! 450: while (XPending (DISP)) { ! 451: XNextEvent (DISP, xe); ! 452: ! 453: switch (xe -> type) { ! 454: case Expose: ! 455: if (debug) ! 456: fprintf (stderr, "Expose %d\n", ! 457: ((XExposeEvent *) xe) -> count); ! 458: if (myim) { ! 459: if (((XExposeEvent *) xe) -> count > 0) ! 460: break; ! 461: mapped = 1; ! 462: Redisplay (); ! 463: } ! 464: else { ! 465: unmap: ; ! 466: if (parent) ! 467: XClearWindow (DISP, mywindow); ! 468: else ! 469: XUnmapWindow (DISP, mywindow); ! 470: } ! 471: break; ! 472: ! 473: case MapNotify: ! 474: if (debug) ! 475: fprintf (stderr, "MapNotify (0x%x)\n", ! 476: myim); ! 477: if (myim) { ! 478: mapped = 1; ! 479: Redisplay (); ! 480: } ! 481: else ! 482: goto unmap; ! 483: break; ! 484: ! 485: case ConfigureNotify: ! 486: if (debug) ! 487: fprintf (stderr, "ConfigureNotify %dx%d\n", ! 488: ((XConfigureEvent *) xe) -> height, ! 489: ((XConfigureEvent *) xe) -> width); ! 490: if ((wh = ((XConfigureEvent *) xe) -> height) > 0 ! 491: && (ww = ((XConfigureEvent *) xe) -> width) > 0) ! 492: myframe.height = wh, myframe.width = ww; ! 493: break; ! 494: ! 495: case UnmapNotify: ! 496: if (debug) ! 497: fprintf (stderr, "UnmapNotify\n"); ! 498: mapped = 0; ! 499: break; ! 500: ! 501: case ReparentNotify: ! 502: if (debug) ! 503: fprintf (stderr, "ReparentNotify\n"); ! 504: parent = 1; ! 505: break; ! 506: ! 507: default: ! 508: if (debug) ! 509: fprintf (stderr, "Event %d\n", xe -> type); ! 510: break; ! 511: } ! 512: } ! 513: } ! 514: ! 515: /* SOCKET */ ! 516: ! 517: int startsocket (portno) ! 518: int portno; ! 519: { ! 520: struct sockaddr_in in_socket; ! 521: register struct sockaddr_in *isock = &in_socket; ! 522: ! 523: isock -> sin_family = AF_INET; ! 524: isock -> sin_port = htons ((u_short) portno); ! 525: isock -> sin_addr.s_addr = INADDR_ANY; ! 526: ! 527: if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == NOTOK) ! 528: adios ("socket", "unable to create"); ! 529: ! 530: if (bind (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK) ! 531: adios ("socket", "unable to bind"); ! 532: } ! 533: ! 534: /* */ ! 535: ! 536: int readsocket (buffer) ! 537: char *buffer; ! 538: { ! 539: int cc; ! 540: ! 541: for (;;) { ! 542: int i, ! 543: nfds; ! 544: fd_set imask; ! 545: struct sockaddr_in in_socket; ! 546: struct sockaddr_in *isock = &in_socket; ! 547: ! 548: FD_ZERO (&imask); ! 549: ! 550: nfds = sd + 1; ! 551: FD_SET (sd, &imask); ! 552: if (eventfd != NOTOK) { ! 553: (*eventfx) (0); ! 554: ! 555: if (eventfd >= nfds) ! 556: nfds = eventfd + 1; ! 557: FD_SET (eventfd, &imask); ! 558: } ! 559: ! 560: if (xselect (nfds, &imask, NULLFD, NULLFD, sleepsw) <= 0) { ! 561: if (errno == EINTR) ! 562: continue; ! 563: ! 564: if (ppidsw > 0 && kill (ppidsw, 0) == NOTOK) { ! 565: (void) close (sd); ! 566: return NOTOK; ! 567: } ! 568: ! 569: if (alarmfx) ! 570: (*alarmfx) (); ! 571: ! 572: continue; ! 573: } ! 574: ! 575: if (ppidsw > 0 && kill (ppidsw, 0) == NOTOK) { ! 576: (void) close (sd); ! 577: return NOTOK; ! 578: } ! 579: ! 580: if (eventfd != NOTOK && FD_ISSET (eventfd, &imask)) ! 581: (*eventfx) (1); ! 582: ! 583: if (!FD_ISSET (sd, &imask)) ! 584: continue; ! 585: ! 586: i = sizeof *isock; ! 587: if ((cc = recvfrom (sd, buffer, BUFSIZ, 0, (struct sockaddr *) isock, ! 588: &i)) == NOTOK) { ! 589: if (errno == EINTR) ! 590: continue; ! 591: adios ("failed", "recvfrom socket"); ! 592: } ! 593: ! 594: break; ! 595: } ! 596: ! 597: buffer[cc] = NULL; ! 598: ! 599: return OK; ! 600: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.