|
|
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.