/* xscreensaver, Copyright (c) 2001-2018 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. */ /* This file contains code for drawing NTSC colorbars. A couple of things use this. */ #include "utils.h" #include "resources.h" #include "colorbars.h" #include "../hacks/ximage-loader.h" static const char * const colors[7][18] = { { "#CCCCCC", "#FFFF00", "#00FFFF", "#00FF00", /* tall bars */ "#FF00FF", "#FF0000", "#0000FF", "#000000", 0 }, { "#000000", "#0000FF", "#FF0000", "#FF00FF", /* short rev bars */ "#00FF00", "#00FFFF", "#FFFF00", "#CCCCCC", 0 }, { "#000000", 0 /* blank */ }, { "#FFFFFF", "#EEEEEE", "#DDDDDD", "#CCCCCC", /* gray ramp */ "#BBBBBB", "#AAAAAA", "#999999", "#888888", "#777777", "#666666", "#555555", "#444444", "#333333", "#222222", "#111111", "#000000" }, { "#000000", "#111111", "#222222", "#333333", /* gray rev ramp */ "#444444", "#555555", "#666666", "#777777", "#888888", "#999999", "#AAAAAA", "#BBBBBB", "#CCCCCC", "#DDDDDD", "#EEEEEE", "#FFFFFF" }, { "#000000", 0 /* blank */ }, { "#FF00FF", "#FF00FF", "#FF00FF", /* blacklevel row */ "#FFFFFF", "#FFFFFF", "#FFFFFF", "#0000AD", "#0000AD", "#0000AD", "#131313", "#131313", "#131313", "#000000", "#000000", "#262626", "#000000", "#000000", "#000000" } }; static const int heights[7] = { 63, 10, 1, 5, 5, 1, 15 }; /* percentages */ void draw_colorbars (Screen *screen, Visual *visual, Drawable drawable, Colormap cmap, int x, int y, int width, int height, Pixmap logo, Pixmap logo_mask) { Display *dpy = DisplayOfScreen (screen); int ypct = 0; int j; XGCValues gcv; GC gc = XCreateGC (dpy, drawable, 0, &gcv); if (width <= 0 || height <= 0) { Window root; int xx, yy; unsigned int bw, d; XGetGeometry (dpy, drawable, &root, &xx, &yy, (unsigned int *) &width, (unsigned int *) &height, &bw, &d); } for (j = 0; j < sizeof(colors) / sizeof(*colors); j++) { int i, h, ncols; int x1 = 0; int y2; for (ncols = 0; ncols < sizeof(*colors) / sizeof(**colors); ncols++) if (!colors[j][ncols]) break; ypct += heights[j]; y2 = height * ypct / 100; h = y2 - y; /* avoid roundoff fencepost */ for (i = 0; i < ncols; i++) { XColor xcolor; const char *color = colors[j][i]; int x2 = x + (width * (i+1) / ncols); int w = x2 - x1; /* avoid roundoff fencepost */ if (! XParseColor (dpy, cmap, color, &xcolor)) abort(); xcolor.flags = DoRed|DoGreen|DoBlue; if (!XAllocColor (dpy, cmap, &xcolor)) continue; XSetForeground (dpy, gc, xcolor.pixel); XFillRectangle (dpy, drawable, gc, x1, y, w, h); x1 = x2; } y = y2; } /* Add in the xscreensaver logo */ if (logo) { Window r; int x, y; unsigned int logo_width, logo_height, bw, d; int x1, y1, w, h; XGetGeometry (dpy, logo, &r, &x, &y, &logo_width, &logo_height, &bw, &d); w = width; h = height * heights[0] / 100; x1 = x + (w - (int) logo_width) / 2; y1 = y + (h - (int) logo_height) / 2; if (logo_mask) { XSetClipMask (dpy, gc, logo_mask); XSetClipOrigin (dpy, gc, x1, y1); } XCopyArea (dpy, logo, drawable, gc, 0, 0, logo_width, logo_height, x1, y1); } XFreeGC(dpy, gc); }