|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 11986 (0x2ed2)
Types: TextFile
Names: »xface.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/others/image/xface.c«
/* xface.c - face agent for X windows */
#ifndef lint
static char *rcsid = "$Header: /f/osi/others/image/RCS/xface.c,v 7.0 89/11/23 22:00:03 mrose Rel $";
#endif
/*
* $Header: /f/osi/others/image/RCS/xface.c,v 7.0 89/11/23 22:00:03 mrose Rel $
*
*
* $Log: xface.c,v $
* Revision 7.0 89/11/23 22:00:03 mrose
* Release 6.0
*
*/
/*
* NOTICE
*
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
* this agreement.
*
*/
#include <errno.h>
#include <stdio.h>
#include "imagesbr.h"
#include "internet.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
/* \f
DATA */
static int sd = NOTOK;
int debug = 0;
int errsw = 0;
static int portsw = 0;
static int ppidsw = 0;
static int sleepsw = 30;
static char *myname = "xface";
static int eventfd = NOTOK;
static int (*eventfx)() = NULL;
static int (*alarmfx)() = NULL;
static char *display = NULL;
static char *geometry = NULL;
static Display *DISP;
static int SCRN;
static struct type_IMAGE_Image *myim = NULL;
typedef struct _frame {
short x, y;
unsigned int width, height;
unsigned int bdrwidth;
unsigned long border;
unsigned long background;
} Frame;
static int mapped;
static int parent;
static Window mywindow = 0;
static Frame myframe;
static unsigned long backpix, bdrpix;
static GC forepix, highpix;
int ALRMser (), XWINser ();
extern int errno;
char *getenv ();
/* \f
MAIN */
/* ARGSUSED */
main (argc, argv, envp)
int argc;
char **argv,
**envp;
{
char buffer[BUFSIZ],
*vec[NVEC + 1];
arginit (argv);
if (portsw > 0)
startsocket (portsw);
if (ppidsw > 0)
envinit ();
if (errsw)
errsw = NOTOK;
for (;;) {
if ((portsw > 0 ? readsocket (buffer) : getline (buffer)) == NOTOK)
break;
if (str2vec (buffer, vec) != 2)
continue;
fetch_face (vec[0], vec[1]);
if (debug)
(void) fflush (stderr);
}
exit (0);
}
/* \f
*/
static fetch_face (host, user)
char *host,
*user;
{
if ((myim = fetch_image (user, host)) == NULL && recording)
LLOG (pgm_log, LLOG_NOTICE,
("no image for \"%s\" \"%s\"", user, host));
if (mywindow != NULL || myim)
display_X ();
}
/* \f
*/
static int getline (buffer)
char *buffer;
{
register int i;
register char *cp,
*ep;
static int sticky = 0;
if (sticky) {
sticky = 0;
return NOTOK;
}
printf ("%s> ", myname);
(void) fflush (stdout);
for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) {
if (i == EOF) {
printf ("\n");
if (cp != buffer) {
sticky++;
break;
}
return NOTOK;
}
if (cp < ep)
*cp++ = i;
}
*cp = NULL;
return OK;
}
/* \f
ARGINIT */
static arginit (vec)
char **vec;
{
int n;
register char *ap,
*cp;
if (myname = rindex (*vec, '/'))
myname++;
if (myname == NULL || *myname == NULL)
myname = *vec;
isodetailor (myname, 1);
init_aka (myname, 0, NULLCP);
if ((ap = getenv ("FACEPROC"))
&& (cp = index (ap, ' '))
&& sscanf (++cp, "%d", &n) == 1
&& n >= 1)
portsw = n;
for (vec++; ap = *vec; vec++)
if (*ap == '-')
switch (*++ap) {
case 'd':
debug++;
break;
case 'e':
errsw++;
break;
case 'p':
if ((ap = *++vec) == NULL
|| sscanf (ap, "%d", &portsw) != 1
|| portsw < 1)
adios (NULLCP, "usage: %s -p port", myname);
break;
case 'r':
recording++;
break;
case 's':
if ((ap = *++vec) == NULL
|| sscanf (ap, "%d", &sleepsw) != 1
|| sleepsw < 1)
adios (NULLCP, "usage: %s -s seconds", myname);
break;
case 'u':
ppidsw = getppid ();
break;
default:
adios (NULLCP, "unknown switch -%s", ap);
}
else
if (*ap == '=')
geometry = ap;
else
if ((cp = rindex (ap, ':')) && sscanf (++cp, "%d", &n) == 1)
display = ap;
else
adios (NULLCP, "usage: %s [switches] host:display",
myname);
if (debug)
ll_dbinit (pgm_log, myname);
else
ll_hdinit (pgm_log, myname);
if ((DISP = XOpenDisplay (display)) == NULL)
adios (NULLCP, "unable to open display \"%s\"",
XDisplayName (display));
SCRN = DefaultScreen (DISP);
}
/* \f
*/
static envinit ()
{
int i,
pid;
if (debug)
return;
for (i = 0; (pid = fork ()) == NOTOK && i < 5; i++)
sleep (5);
switch (pid) {
case NOTOK:
case OK:
break;
default:
exit (0);
}
ll_hdinit (pgm_log, myname);
}
/* \f
*/
static display_X ()
{
if (mywindow == NULL) {
int bwidth;
char *opt,
def[BUFSIZ];
XSizeHints hints;
XSetWindowAttributes xswattrs;
unsigned long xswattrs_mask;
forepix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L,
(XGCValues *) NULL);
highpix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L,
(XGCValues *) NULL);
XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1,
forepix);
XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1,
highpix);
if ((opt = XGetDefault (DISP, myname, "ReverseVideo"))
&& strcmp (opt, "on") == 0) {
XSetForeground(DISP, forepix, WhitePixel(DISP, SCRN));
XSetForeground(DISP, highpix, WhitePixel(DISP, SCRN));
backpix = BlackPixel(DISP, SCRN);
bdrpix = WhitePixel(DISP, SCRN);
XSetFunction(DISP, forepix, GXcopyInverted);
XSetFunction(DISP, highpix, GXand);
}
else {
XSetForeground(DISP, forepix, BlackPixel(DISP, SCRN));
XSetForeground(DISP, highpix, BlackPixel(DISP, SCRN));
backpix = WhitePixel(DISP, SCRN);
bdrpix = BlackPixel(DISP, SCRN);
XSetFunction(DISP, forepix, GXcopy);
XSetFunction(DISP, highpix, GXor);
}
XSetBackground (DISP, forepix, backpix);
XSetBackground (DISP, highpix, backpix);
if (opt = XGetDefault (DISP, myname, "BorderWidth"))
bwidth = atoi (opt);
else
bwidth = 2;
myframe.bdrwidth = bwidth;
myframe.height = myim -> height;
if (myframe.height + bwidth * 2 > DisplayHeight (DISP, SCRN))
myframe.height = DisplayHeight (DISP, SCRN) - bwidth * 2;
myframe.width = myim -> width;
if (myframe.width + bwidth * 2 > DisplayWidth (DISP, SCRN))
myframe.width = DisplayWidth (DISP, SCRN) - bwidth * 2;
myframe.x = DisplayWidth (DISP, SCRN) - (myframe.width + bwidth * 2);
myframe.y = 0;
(void) sprintf (def, "=%dx%d+%d+%d", myframe.width, myframe.height,
myframe.x, myframe.y);
if (debug)
fprintf (stderr, "def: %s, myframe: =%dx%d+%d+%d/%d\n", def,
myframe.width, myframe.height, myframe.x, myframe.y,
myframe.bdrwidth);
hints.width = myim -> width;
hints.height = myim -> height;
hints.x = hints.y = 0;
hints.flags = PSize | PPosition;
xswattrs.border_pixel = bdrpix;
xswattrs.background_pixel = backpix;
xswattrs_mask = CWBackPixel | CWBorderPixel;
mywindow = XCreateWindow (DISP, RootWindow (DISP, SCRN),
myframe.x, myframe.y,
myframe.width, myframe.height,
myframe.bdrwidth,
0, InputOutput, (Visual *) CopyFromParent,
xswattrs_mask, &xswattrs);
XSetStandardProperties (DISP, mywindow, myname, "Face Agent", None,
(char **) 0, 0, &hints);
XSelectInput (DISP, mywindow, ExposureMask | StructureNotifyMask);
XMapWindow (DISP, mywindow);
mapped = parent = 0;
}
else
Redisplay ();
eventfd = ConnectionNumber (DISP);
eventfx = XWINser;
alarmfx = ALRMser;
XWINser (0);
}
/* \f
*/
static Redisplay ()
{
int sx,
sy,
dx,
dy;
unsigned int h,
w;
XImage *image;
if (myim == NULL) {
XClearWindow (DISP, mywindow);
return;
}
sx = max (myim -> width - (int) myframe.width, 0) / 2;
sy = max (myim -> height - (int) myframe.height, 0) / 2;
dx = max ((int) myframe.width - myim -> width, 0) / 2;
dy = max ((int) myframe.height - myim -> height, 0) / 2;
w = min (myframe.width, myim -> width);
h = min (myframe.height, myim -> height);
if (debug) {
fprintf (stderr, "im: %dx%d frame:%dx%d\n",
myim -> width, myim -> height, myframe.width, myframe.height);
fprintf (stderr, "sx=%d sy=%d dx=%d dy=%d w=%d h=%d\n",
sx, sy, dx, dy, w, h);
}
image = XCreateImage (DISP, DefaultVisual (DISP, SCRN), 1, XYBitmap, 0,
myim -> data -> qb_forw -> qb_data,
(unsigned int) myim -> width,
(unsigned int) myim -> height, 8, 0);
if (image == NULL)
adios (NULLCP, "XCreateImage failed");
image -> byte_order = image -> bitmap_bit_order = LSBFirst;
XClearWindow (DISP, mywindow);
XPutImage (DISP, mywindow, forepix, image, sx, sy, dx, dy, w, h);
XDestroyImage (image);
}
/* \f
*/
static int ALRMser ()
{
if (mywindow && mapped) {
if (parent)
XClearWindow (DISP, mywindow);
else
XUnmapWindow (DISP, mywindow);
}
if (myim)
myim = NULL;
}
/* \f
*/
/* ARGSUSED */
static int XWINser (io)
int io;
{
int ww,
wh;
XEvent xevent;
register XEvent *xe = &xevent;
while (XPending (DISP)) {
XNextEvent (DISP, xe);
switch (xe -> type) {
case Expose:
if (debug)
fprintf (stderr, "Expose %d\n",
((XExposeEvent *) xe) -> count);
if (myim) {
if (((XExposeEvent *) xe) -> count > 0)
break;
mapped = 1;
Redisplay ();
}
else {
unmap: ;
if (parent)
XClearWindow (DISP, mywindow);
else
XUnmapWindow (DISP, mywindow);
}
break;
case MapNotify:
if (debug)
fprintf (stderr, "MapNotify (0x%x)\n",
myim);
if (myim) {
mapped = 1;
Redisplay ();
}
else
goto unmap;
break;
case ConfigureNotify:
if (debug)
fprintf (stderr, "ConfigureNotify %dx%d\n",
((XConfigureEvent *) xe) -> height,
((XConfigureEvent *) xe) -> width);
if ((wh = ((XConfigureEvent *) xe) -> height) > 0
&& (ww = ((XConfigureEvent *) xe) -> width) > 0)
myframe.height = wh, myframe.width = ww;
break;
case UnmapNotify:
if (debug)
fprintf (stderr, "UnmapNotify\n");
mapped = 0;
break;
case ReparentNotify:
if (debug)
fprintf (stderr, "ReparentNotify\n");
parent = 1;
break;
default:
if (debug)
fprintf (stderr, "Event %d\n", xe -> type);
break;
}
}
}
/* \f
SOCKET */
int startsocket (portno)
int portno;
{
struct sockaddr_in in_socket;
register struct sockaddr_in *isock = &in_socket;
isock -> sin_family = AF_INET;
isock -> sin_port = htons ((u_short) portno);
isock -> sin_addr.s_addr = INADDR_ANY;
if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == NOTOK)
adios ("socket", "unable to create");
if (bind (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK)
adios ("socket", "unable to bind");
}
/* \f
*/
int readsocket (buffer)
char *buffer;
{
int cc;
for (;;) {
int i,
nfds;
fd_set imask;
struct sockaddr_in in_socket;
struct sockaddr_in *isock = &in_socket;
FD_ZERO (&imask);
nfds = sd + 1;
FD_SET (sd, &imask);
if (eventfd != NOTOK) {
(*eventfx) (0);
if (eventfd >= nfds)
nfds = eventfd + 1;
FD_SET (eventfd, &imask);
}
if (xselect (nfds, &imask, NULLFD, NULLFD, sleepsw) <= 0) {
if (errno == EINTR)
continue;
if (ppidsw > 0 && kill (ppidsw, 0) == NOTOK) {
(void) close (sd);
return NOTOK;
}
if (alarmfx)
(*alarmfx) ();
continue;
}
if (ppidsw > 0 && kill (ppidsw, 0) == NOTOK) {
(void) close (sd);
return NOTOK;
}
if (eventfd != NOTOK && FD_ISSET (eventfd, &imask))
(*eventfx) (1);
if (!FD_ISSET (sd, &imask))
continue;
i = sizeof *isock;
if ((cc = recvfrom (sd, buffer, BUFSIZ, 0, (struct sockaddr *) isock,
&i)) == NOTOK) {
if (errno == EINTR)
continue;
adios ("failed", "recvfrom socket");
}
break;
}
buffer[cc] = NULL;
return OK;
}