summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrws <empty>1994-04-19 09:29:46 +0000
committerrws <empty>1994-04-19 09:29:46 +0000
commit51b4d5c7ee0eb53e68aaa6c9286db320d4f52ecf (patch)
tree43065fec30da666208b12bd41ed3a71be84587c3
parent0fa5a4b3b3cc82afd3bd3fbf6cb9759a8a3d1b47 (diff)
Initial revisionR6prelim
-rw-r--r--xc/unsupported/doc/papers/tutorials/visuals/xsd.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/xc/unsupported/doc/papers/tutorials/visuals/xsd.c b/xc/unsupported/doc/papers/tutorials/visuals/xsd.c
new file mode 100644
index 000000000..20af7116c
--- /dev/null
+++ b/xc/unsupported/doc/papers/tutorials/visuals/xsd.c
@@ -0,0 +1,215 @@
+#include <X11/Xlib.h>
+#include <stdio.h>
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+Display *dpy; /* X server we're talking to */
+int dumpw, dumph; /* Size of the "specified rectangle" */
+
+/*
+ * There will be one of these for each Colormap we find
+ */
+struct cmp {
+ struct cmp *next; /* Link in chain */
+ Colormap cmap; /* The Colormap ID */
+ unsigned long allocated, used;/* Size & usage of inUse */
+ XColor *inUse; /* Array of in-use colors */
+};
+struct cmp *inUse; /* The list of Colormaps we found */
+int numColor = 0; /* Upper bound on number of distinct RGB values */
+
+/*
+ * There will be one of these for each pixel in the rectangle
+ */
+struct pxl {
+ struct cmp *pCmap; /* The colormap for this pixel */
+ unsigned long pixel; /* The pixel value at this pixel */
+};
+struct pxl *Map; /* The map representing the rectangle */
+#define FindPixel(x,y) ((Map+((y)*dumpw))+(x))
+
+/*
+ * Find (and create if necessary) a struct cmp for this Colormap
+ */
+struct cmp *
+FindColormap(cmap)
+ Colormap cmap;
+{
+ register struct cmp *pCmap;
+
+ /* If we've seen this Colormap before, return its struct cmp */
+ for (pCmap = inUse; pCmap; pCmap = pCmap->next)
+ if (cmap == pCmap->cmap)
+ return (pCmap);
+ /* First time, so create a new struct cmp, link it and return it */
+ pCmap = (struct cmp *) calloc(sizeof (struct cmp), 1);
+ pCmap->next = inUse;
+ pCmap->cmap = cmap;
+ inUse = pCmap;
+ return (pCmap);
+}
+
+/*
+ * Record this pixel value as being in use in its Colormap
+ */
+void
+RegisterPixel(pixel, pCmap)
+ unsigned long pixel;
+ struct cmp *pCmap;
+{
+ register unsigned long i = pCmap->used;
+
+ /* If the pixel value is already known, do nothing */
+ while (i)
+ if (pixel == pCmap->inUse[--i].pixel)
+ return;
+ /* This is the first time we've seen this pixel value */
+ if (pCmap->used >= pCmap->allocated) {
+ /* Need to expand or create the inUse array */
+ pCmap->allocated = (pCmap->allocated * 2) + 10;
+ pCmap->inUse = (XColor *)(pCmap->inUse ?
+ realloc(pCmap->inUse,
+ pCmap->allocated * sizeof (XColor)) :
+ malloc(pCmap->allocated * sizeof (XColor)));
+ }
+ /* Now we have space to store the XColor, use QueryColor to get RGB */
+ pCmap->inUse[pCmap->used].pixel = pixel;
+ XQueryColor(dpy, pCmap->cmap, &pCmap->inUse[pCmap->used]);
+ numColor++;
+ pCmap->used++;
+}
+
+/*
+ * This gets called once for each window we find as we walk down the tree
+ */
+DoWindow(w, xo, yo, x, y, wi, hi)
+ Window w;
+ int xo, yo; /* Parent's origin in root space */
+ int x, y; /* Top-left of rectangle in root space */
+ int wi, hi; /* Size of rectangle */
+{
+ XWindowAttributes xwa; /* Place to return the window's attributes */
+ XImage *xim; /* Image to store window's pixels */
+ int width, height, x1, y1, xi, yi;
+ Window root, parent, *children;
+ int nchild, n;
+ struct cmp *pCmap;
+
+ /* Get the attributes of this window, and locate its struct cmp */
+ if (!XGetWindowAttributes(dpy, w, &xwa) || xwa.map_state != IsViewable)
+ return;
+ pCmap = FindColormap(xwa.colormap);
+ /* Compute top-left of image in root space */
+ x1 = max(x, xwa.x+xo);
+ y1 = max(y, xwa.y+yo);
+ width = min(x+wi, xwa.x + xwa.width + 2*xwa.border_width + xo) - x1;
+ height = min(y+hi, xwa.y + xwa.height + 2*xwa.border_width + yo) - y1;
+ if (width <= 0 || height <= 0)
+ return;
+ /* Use GetImage to get the pixel values for the rectangle */
+ if (!(xim = XGetImage(dpy, w, x1-xwa.border_width-xwa.x-xo,
+ y1-xwa.border_width-xwa.y-yo, width, height,
+ (~0), ZPixmap)))
+ return;
+ /* For each pixel in the returned image */
+ for (yi = 0; yi < height; yi++)
+ for (xi = 0; xi < width; xi++) {
+ register struct pxl *pPxl = FindPixel(xi+x1, yi+y1);
+
+ /* Label the pixel in the map with this window's Colormap */
+ pPxl->pCmap = pCmap;
+ /* And with its pixel value */
+ pPxl->pixel = XGetPixel(xim, xi, yi);
+ RegisterPixel(pPxl->pixel, pCmap);
+ }
+ /* Free the space for the image */
+ XDestroyImage(xim);
+ /* Find the children of this window, in back-to-front order */
+ if (XQueryTree(dpy, w, &root, &parent, &children, &nchild)) {
+ for (n = 0; n < nchild; n++) {
+ /* Process each of the child windows recursively */
+ DoWindow(children[n], xo + xwa.x + xwa.border_width,
+ yo + xwa.y + xwa.border_width, x1, y1, width, height);
+ }
+ /* Free the list of children */
+ if (nchild > 0)
+ XFree(children);
+ }
+ return;
+}
+
+/*
+ * Return the XColor structure for the pixel at [x,y] in the map
+ */
+XColor *
+FindColor(x, y)
+ int x, y;
+{
+ struct pxl *pPxl = FindPixel(x, y); /* Find the struct pxl */
+ struct cmp *pCmp = pPxl->pCmap; /* And the struct cmp */
+ int i;
+
+ /* Scan the in-use array for this colormap for the pixel value */
+ for (i = 0; i < pCmp->used; i++)
+ if (pPxl->pixel == pCmp->inUse[i].pixel)
+ return (&(pCmp->inUse[i]));
+ return (NULL);
+}
+
+/*
+ * Write the representation of the rectangle to stdout
+ */
+DoOutput(x, y, w, h)
+ int x, y, w, h;
+{
+ int xi, yi;
+
+ /* Write the width, height, and number of colors */
+ fwrite(&w, sizeof (int), 1, stdout);
+ fwrite(&h, sizeof (int), 1, stdout);
+ fwrite(&numColor, sizeof (int), 1, stdout);
+ /* For each pixel in the image */
+ for (yi = 0; yi < h; yi++)
+ for (xi = 0; xi < w; xi++) {
+ XColor *color = FindColor(x + xi, y + yi);
+
+ /* Write the R, G & B values for this pixel */
+ fwrite(&(color->red), sizeof (unsigned short), 1, stdout);
+ fwrite(&(color->green), sizeof (unsigned short), 1, stdout);
+ fwrite(&(color->blue), sizeof (unsigned short), 1, stdout);
+ }
+}
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int scrn;
+
+ /* Try to connect to the server */
+ if ((dpy = XOpenDisplay(NULL)) == (Display *) 0) {
+ fprintf(stderr, "Can't open display\n");
+ exit(1);
+ }
+ /* Dump the specified part of the default screen */
+ scrn = DefaultScreen(dpy);
+ if (argc > 1)
+ dumpw = atoi(argv[1]);
+ else
+ dumpw = DisplayWidth(dpy, scrn);
+ if (argc > 2)
+ dumph = atoi(argv[2]);
+ else
+ dumph = DisplayHeight(dpy, scrn);
+ /* Create the map with one struct pxl per pixel */
+ Map = (struct pxl *) calloc(sizeof (struct pxl), dumpw * dumph);
+ /* Grab the server so things don't change under our feet */
+ XGrabServer(dpy);
+ /* Recursively build the map */
+ DoWindow(RootWindow(dpy, scrn), 0, 0, 0, 0, dumpw, dumph);
+ /* Finished reading things from the server - let it go */
+ XUngrabServer(dpy);
+ /* Write the RGB representation of the rectangle to stdout */
+ DoOutput(0, 0, dumpw, dumph);
+ exit(0);
+}