Received: by ATHENA-PO-2.MIT.EDU (5.45/4.7) id AA03090; Fri, 11 Aug 89 11:56:14 EDT
Received: by ATHENA.MIT.EDU (5.45/4.7) id AA23130; Fri, 11 Aug 89 11:56:29 EDT
Received: from RELAY.CS.NET by expo.lcs.mit.edu; Fri, 11 Aug 89 11:54:23 EDT
Received: from tektronix.tek.com by RELAY.CS.NET id aa03335; 11 Aug 89 11:53 EDT
Received: by tektronix.TEK.COM (5.51/7.1)
	id AA03363; Fri, 11 Aug 89 08:54:54 PDT
Received: by tekirl.labs.tek.com (5.51/7.1)
	id AA28570; Fri, 11 Aug 89 08:51:02 PDT
Received: by tekcrl.LABS.TEK.COM (5.51/6.24)
	id AA17405; Fri, 11 Aug 89 08:53:09 PDT
Message-Id: <8908111553.AA17405@tekcrl.LABS.TEK.COM>
To: Chris Walters <walters%community-chest.mitre.org@gateway.mitre.org>
Cc: xvideo@expo.lcs.mit.edu
Subject: Re: Sample code for Parallax server?
In-Reply-To: Your message of Thu, 10 Aug 89 10:34:59 -0400.
	     <8908101435.AA05199@community-chest.mitre.org>
Date: 11 Aug 89 08:53:06 PDT (Fri)
From: Todd Brunhoff <toddb%tekcrl.labs.tek.com@relay.cs.net>

Enclosed is an exceptionally stupid program for displaying video on
a parallax using the old parallax extension mechanism. (R3).  You
might want to get galatea from Dan Applebaum at MIT (he mentioned it
on this mailing list about a week ago).

Todd
-------------------------
/* $Header: xhw0.c,v 1.2 87/11/18 08:27:04 toddb Exp $ */
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#define LIVE    "Live Video"
#define STILL   "Still Video"
#define BORDER  1
#define FONT    "pellucidaserif12b"

/*
 * This structure forms the WM_HINTS property of the window,
 * letting the window manager know how to handle this window.
 * See Section 9.1 of the Xlib manual.
 */
XWMHints        xwmh = {
    (InputHint|StateHint),      /* flags */
    False,                      /* input */
    NormalState,                /* initial_state */
    0,                          /* icon pixmap */
    0,                          /* icon window */
    0, 0,                       /* icon location */
    0,                          /* icon mask */
    0,                          /* Window group */
};

main(argc,argv)
    int argc;
    char **argv;
{
    Display    *dpy;            /* X server connection */
    Window      win;            /* Window ID */
    GC          gc;             /* GC to draw with */
    XFontStruct *fontstruct;    /* Font descriptor */
    unsigned long fth;          /* Font size parameters */
    unsigned long fg, bg, bd;   /* Pixel values */
    unsigned long bw;           /* Border width */
    XGCValues   gcv;            /* Struct for creating GC */
    XEvent      event;          /* Event received */
    XSizeHints  xsh;            /* Size hints for window manager */
    char       *geomSpec;       /* Window geometry string */
    XWindowAttributes xwa;      /* Temporary Window Attribute struct */
    XSetWindowAttributes xswa;  /* Temporary Window Attribute struct */

    /*
     * Open the display using the $DISPLAY environment variable to locate
     * the X server.  See Section 2.1.
     */
    if ((dpy = XOpenDisplay(NULL)) == NULL) {
        fprintf(stderr, "%s: can't open %s\n", argv[0], XDisplayName(NULL));
        exit(1);
    }

    /*
     * Load the font to use.  See Sections 10.2 & 6.5.1
     */
    if ((fontstruct = XLoadQueryFont(dpy, FONT)) == NULL) {
        fprintf(stderr, "%s: display %s doesn't know font %s\n",
                argv[0], DisplayString(dpy), FONT);
        exit(1);
    }
    fth = fontstruct->max_bounds.ascent + fontstruct->max_bounds.descent;

    /*
     * Select colors for the border,  the window background,  and the
     * foreground.
     */
    bd = WhitePixel(dpy, DefaultScreen(dpy));
    bg = BlackPixel(dpy, DefaultScreen(dpy));
    fg = WhitePixel(dpy, DefaultScreen(dpy));

    /*
     * Set the border width of the window
     */
    bw = BORDER;

    /*
     * Deal with providing the window with an initial position & size.
     * Fill out the XSizeHints struct to inform the window manager. See
     * Sections 9.1.6 & 10.3.
     */
    xsh.flags = (PPosition | PSize | PMinSize | PResizeInc);
    xsh.height = 480 + bw * 2;
    xsh.width = 640 + bw * 2;
    xsh.min_width = 64;
    xsh.min_height = 48;
    xsh.width_inc = 64;
    xsh.height_inc = 48;
    xsh.x = (DisplayWidth(dpy, DefaultScreen(dpy)) - xsh.width) / 2;
    xsh.x = (DisplayWidth(dpy, DefaultScreen(dpy)) - xsh.width) / 2;
    xsh.y = (DisplayHeight(dpy, DefaultScreen(dpy)) - xsh.height) / 2;

    /*
     * Create the Window with the information in the XSizeHints, the
     * border width,  and the border & background pixels. See Section 3.3.
     */
    win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
                              xsh.x, xsh.y, xsh.width, xsh.height,
                              bw, bd, bg);

    /*
     * Set the standard properties for the window managers. See Section
     * 9.1.
     */
    XSetStandardProperties(dpy, win, LIVE, LIVE, None, argv, argc, &xsh);
    XSetWMHints(dpy, win, &xwmh);

    /*
     * Ensure that the window's colormap field points to the default
     * colormap,  so that the window manager knows the correct colormap to
     * use for the window.  See Section 3.2.9. Also,  set the window's Bit
     * Gravity to reduce Expose events.
     */
    xswa.colormap = DefaultColormap(dpy, DefaultScreen(dpy));
    xswa.bit_gravity = CenterGravity;
    XChangeWindowAttributes(dpy, win, (CWColormap | CWBitGravity), &xswa);

    /*
     * Create the GC for writing the text.  See Section 5.3.
     */
    gcv.font = fontstruct->fid;
    gcv.foreground = fg;
    gcv.background = bg;
    gc = XCreateGC(dpy, win, (GCFont | GCForeground | GCBackground), &gcv);
    XSync(dpy, 0);

    XPlxVideoSet(dpy, win, gc);
    XSync(dpy, 0);

    /*
     * Specify the event types we're interested in - only Exposures.  See
     * Sections 8.5 & 8.4.5.1
     */
    XSelectInput(dpy, win, ExposureMask | StructureNotifyMask);

    /*
     * Map the window to make it visible.  See Section 3.5.
     */
    XMapWindow(dpy, win);

    /*
     * Loop forever,  examining each event.
     */
    while (1) {
        /*
         * Get the next event
         */
        XNextEvent(dpy, &event);

        /*
         * On the last of each group of Expose events,  repaint the entire
         * window.  See Section 8.4.5.1.
         */
        if (event.type == Expose && event.xexpose.count == 0) {
            int         x, y;

            /*
             * Remove any other pending Expose events from the queue to
             * avoid multiple repaints. See Section 8.7.
             */
            while (XCheckTypedEvent(dpy, Expose, &event));

            /*
             * Find out how big the window is now,  so that we can center
             * the text in it.
             */
            if (XGetWindowAttributes(dpy, win, &xwa) == 0)
                break;
            printf("x,y,w,h=%d,%d,%d,%d\n",
                xwa.x, xwa.y, xwa.width, xwa.height);

            XSync(dpy, 0);
            xwa.width -= xwa.border_width;
            xwa.height -= xwa.border_width;
            if (xwa.width == 640 && xwa.height == 480) {
                XSetStandardProperties(dpy, win, LIVE, LIVE, None,
                                        argv, argc, &xsh);
                XPlxVideoLive(dpy, win, gc,
                              0, 0,             /* vx, vy */
                              0, 0,             /* x, y */
                              640, 480);        /* w, h */
            } else {
                XSetStandardProperties(dpy, win, STILL, STILL, None,
                                        argv, argc, &xsh);
                XPlxVideoScale(dpy, win, gc,
                              0, 0,             /* vx, vy */
                              640, 480,         /* vw, vh */
                              0, 0,             /* x, y */
                              xwa.width, xwa.height);
            }
            XSync(dpy, 0);

#ifdef notdef
            /*
             * Fill the window with the background color,  and then paint
             * the centered string.
             */
            XClearWindow(dpy, win);
            XDrawString(dpy, win, gc, x, y, STRING, strlen(STRING));
#endif
        } else {
                /* printf("evtype=%d\n", event.type); */
        }
    }

    exit(1);
}
