Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- File: COLORS.C
- Author: Joshua Marantz, Viewlogic Systems, Inc.
- Date: 5/19/88
- Env: Unix/X11
- This program demonstrates some basic raster drawing operations. It uses
- a simple 8-color scheme with a map that is arranged to yield intuitive
- effects when raster operations such as OR are used. This program should
- work correctly on a monochrome system, or any color system where it is
- possible to allocate 3 planes. The program draws three solid boxes in OR
- mode: one red, one green, one blue. They intersect in a manner such that
- all 7 colors should be visible. It then does several operations, waiting
- for a standard keyboard hit (using getchar ()) in between each one:
- 1. Redraws green box in GXandInverted. This should leave
- the red and blue boxes untouched on a color system.
- 2. Redraws green box in OR mode again.
- 3. Redraws red box in GXandInverted.
- 4. Redraws red box in OR mode.
- 5. Redraws blue box in GXandInverted.
- 6. Redraws blue box in OR mode. The window should now
- be just as it was when the boxes were initially drawn.
- 7. In XOR mode, draw a blue solid box over the whole window.
- 8. Redraw blue solid box, thus undoing effects of #7.
- 9-20. Repeat 7-8 for green,cyan,red,magenta,yellow,white.
- On a color system, the rectangles drawn using GXandInverted will erase the
- rectangle in the foreground color without trashing the rectangles drawn in
- the other two colors. This is because the pixel values are bitwise mutually
- exclusive.
- On a monochrome system, the rectangles drawn in GXandInverted mode will
- erase the corresponding rectangle on the screen, but it will also trash
- the other two. This is because all the rectangles were drawn in color 1,
- and thus are not bitwise mutually exclusive.
- Another problem with the monochrome system is that it is not
- straightforward to specify a black background and a white foreground.
- In the "initmono" procedure, the color map values are explicitly set
- to pixel values 0 and 1. In order for the OR-mode drawing to work
- correctly, the background must be 0, and the foreground non-zero. If
- BlackPixel is 1 and WhitePixel is 0, then we must use different raster
- operations to achieve the same effect.
- Thus we must set up a mapping for raster operations:
- Desired Operation Black==0 rasterop Black==1 rasterop
- DRAW GXor GXand
- ERASE GXandInverted GXorInverted
- HIGHLIGHT GXxor GXequiv
- */
- #include <stdio.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #define BLACK 0
- #define BLUE 1
- #define GREEN 2
- #define CYAN 3
- #define RED 4
- #define MAGENTA 5
- #define YELLOW 6
- #define WHITE 7
- #define FALSE 0
- #define TRUE 1
- static char *color_strings[] = {"black", "blue", "green", "cyan",
- "red", "magenta", "yellow", "white"};
- static int color_map[8];
- /* Set up the rectangles so they intersect in interesting ways. */
- XRectangle red = {10, 10, 300, 400};
- XRectangle green = {10, 250, 450, 100};
- XRectangle blue = {200, 300, 300, 250};
- XRectangle big = {0, 0, 500, 500};
- /* These arrays make it easier to do things to each primary color */
- static int primary_colors[] = {RED, GREEN, BLUE};
- static XRectangle *primary_rects[] = {&red, &green, &blue};
- /* Raster operation mapping */
- #define DRAW 0
- #define ERASE 1
- #define HIGHLIGHT 2
- /* Raster operations must be specified differently for mono */
- static unsigned long raster_map_normal[] = {GXor, GXandInverted, GXxor};
- static unsigned long raster_map_reverse[] = {GXand, GXorInverted, GXequiv};
- /* The default raster operations are OK if we can set the color map */
- static unsigned long *raster_map = raster_map_normal;
- /*
- This utility function maps a color number between 0 and 7 into
- an X pixel value, which can be used as an argument to
- XSetForeground or as the .pixel member of the XColor structure.
- */
- static unsigned int xlate_color(color_number, plane_mask, pixel)
- unsigned int color_number;
- unsigned int plane_mask[];
- unsigned int pixel[];
- {
- return (((color_number & 0x1) ? plane_mask[0] : 0) |
- ((color_number & 0x2) ? plane_mask[1] : 0) |
- ((color_number & 0x4) ? plane_mask[2] : 0) |
- pixel[0]);
- }
- /* Allocate colors in an X color map and set them up. */
- unsigned int initcolor(dpy, scrn)
- Display *dpy;
- int scrn;
- {
- Colormap map;
- int status;
- unsigned int plane_mask[3], pixel[1];
- int i;
- XColor colors[8];
- map = DefaultColormap (dpy, scrn);
- status = XAllocColorCells (dpy, map, FALSE,
- plane_mask, 3, pixel, 1);
- printf ("status = %d\n", status);
- XInstallColormap (dpy, map);
- /* Initialize the X color structure and store it in the map. */
- for (i = 0; i < 8; i++) {
- XParseColor (dpy, map, color_strings[i], &colors[i]);
- colors[i].pixel = color_map[i] = xlate_color (i, plane_mask, pixel);
- colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- XStoreColors (dpy, map, colors, 8);
- return (plane_mask[0] | plane_mask[1] | plane_mask[2]);
- }
- /*
- Set up the mapping of color numbers into monochrome values.
- Change the raster operations to the logically opposite functions
- if black is pixel #1.
- */
- static unsigned int initmono(dpy, scrn)
- Display *dpy;
- int scrn;
- {
- int i;
- color_map[BLACK] = BlackPixel (dpy, scrn);
- for (i = 1; i < 8; i++)
- color_map[i] = WhitePixel (dpy, scrn);
- /* If the background color is not color 0, then change raster maps */
- if (color_map[BLACK] != 0)
- raster_map = raster_map_reverse;
- return (AllPlanes);
- }
- /*
- Draw a rectangle in the specified color and raster operation. This
- routine is inefficient because it flushes after each graphics call,
- but it is useful for debugging and demos.
- */
- static void drawrect(dpy, win, gc, r, color, rasterop)
- Display *dpy;
- Window win;
- GC gc;
- XRectangle *r;
- unsigned int color, rasterop;
- {
- XSetForeground (dpy, gc, color_map[color]);
- XSetFunction (dpy, gc, raster_map[rasterop]);
- XFillRectangle (dpy, win, gc, r -> x, r -> y, r -> width, r -> height);
- XFlush (dpy);
- }
- /*
- Main procedure: initialize X display, set up monochrome or color
- mapping, create a window, wait for it to be mapped, draw rectangles
- in various forms, and exit.
- */
- int main() {
- Display *dpy;
- Window win;
- int scrn;
- GC gc;
- unsigned int plane_mask;
- XGCValues v;
- XEvent e;
- int i;
- /* Connect to the display and init the color map */
- if ((dpy = XOpenDisplay (NULL)) == NULL) {
- fprintf (stderr, "Could not connect to default X display.\n");
- exit (1);
- }
- scrn = DefaultScreen (dpy);
- if (DisplayPlanes (dpy, scrn) >= 3)
- plane_mask = initcolor (dpy, scrn);
- else
- plane_mask = initmono (dpy, scrn);
- /* Create and map the window. */
- win = XCreateSimpleWindow (dpy, DefaultRootWindow (dpy),
- 100, 100, 500, 500,
- 1, /* Border width */
- color_map[WHITE],
- color_map[BLACK]);
- XMapWindow (dpy, win);
- XSetWindowColormap (dpy, win, DefaultColormap (dpy, scrn));
- /* Set up the graphics context for the plane mask and fill style */
- v.plane_mask = plane_mask;
- v.fill_style = FillSolid;
- gc = XCreateGC (dpy, win, GCPlaneMask | GCFillStyle, &v);
- /* Wait for the window to be mapped. */
- XSelectInput (dpy, win, ExposureMask);
- XNextEvent (dpy, &e);
- /* Draw the initial filled rectangles. */
- for (i = 0; i < 3; i++)
- drawrect (dpy, win, gc, primary_rects[i], primary_colors[i], DRAW);
- /* 1-6: For each primary color, erase its box and redraw it. */
- for (i = 0; i < 3; i++) {
- getchar ();
- drawrect (dpy, win, gc, primary_rects[i], primary_colors[i], ERASE);
- getchar ();
- drawrect (dpy, win, gc, primary_rects[i], primary_colors[i], DRAW);
- }
- /* 7-20: For each of the colors, XOR a big box over the window twice. */
- for (i = 0; i < 8; i++) {
- getchar ();
- drawrect (dpy, win, gc, &big, i, HIGHLIGHT);
- getchar ();
- drawrect (dpy, win, gc, &big, i, HIGHLIGHT);
- }
- getchar ();
- }
Add Comment
Please, Sign In to add comment