b5e87abe3a88b91b041ae0c7b9d3f41facfdeef8
[xscreensaver] / utils / colorbars.c
1 /* xscreensaver, Copyright (c) 2001-2018 Jamie Zawinski <jwz@jwz.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 /* This file contains code for drawing NTSC colorbars.
13    A couple of things use this.
14  */
15
16 #include "utils.h"
17 #include "resources.h"
18 #include "colorbars.h"
19 #include "../hacks/ximage-loader.h"
20
21 static const char * const colors[7][18] = {
22   { "#CCCCCC", "#FFFF00", "#00FFFF", "#00FF00",         /* tall bars */
23     "#FF00FF", "#FF0000", "#0000FF", "#000000",
24     0
25   }, {
26     "#000000", "#0000FF", "#FF0000", "#FF00FF",         /* short rev bars */
27     "#00FF00", "#00FFFF", "#FFFF00", "#CCCCCC",
28     0
29   }, {
30     "#000000", 0                                        /* blank */
31   }, {
32     "#FFFFFF", "#EEEEEE", "#DDDDDD", "#CCCCCC",         /* gray ramp */
33     "#BBBBBB", "#AAAAAA", "#999999", "#888888",
34     "#777777", "#666666", "#555555", "#444444",
35     "#333333", "#222222", "#111111", "#000000"
36   }, {
37     "#000000", "#111111", "#222222", "#333333",         /* gray rev ramp */
38     "#444444", "#555555", "#666666", "#777777",
39     "#888888", "#999999", "#AAAAAA", "#BBBBBB",
40     "#CCCCCC", "#DDDDDD", "#EEEEEE", "#FFFFFF"
41   }, {
42     "#000000", 0                                        /* blank */
43   }, {
44     "#FF00FF", "#FF00FF", "#FF00FF",                    /* blacklevel row */
45     "#FFFFFF", "#FFFFFF", "#FFFFFF",
46     "#0000AD", "#0000AD", "#0000AD",
47     "#131313", "#131313", "#131313",
48     "#000000", "#000000", "#262626",
49     "#000000", "#000000", "#000000"
50   }
51 };
52
53 static const int heights[7] = { 63, 10, 1, 5, 5, 1, 15 };   /* percentages */
54
55
56 void
57 draw_colorbars (Screen *screen, Visual *visual,
58                 Drawable drawable, Colormap cmap,
59                 int x, int y, int width, int height,
60                 Pixmap logo, Pixmap logo_mask)
61 {
62   Display *dpy = DisplayOfScreen (screen);
63   int oy = y;
64   int ypct = 0;
65   int j;
66   XGCValues gcv;
67   GC gc = XCreateGC (dpy, drawable, 0, &gcv);
68
69   if (width <= 0 || height <= 0)
70     {
71       Window root;
72       int xx, yy;
73       unsigned int bw, d;
74       XGetGeometry (dpy, drawable,
75                     &root, &xx, &yy,
76                     (unsigned int *) &width,
77                     (unsigned int *) &height,
78                     &bw, &d);
79     }
80
81   for (j = 0; j < sizeof(colors) / sizeof(*colors); j++)
82     {
83       int i, h, ncols;
84       int x1 = 0;
85       int y2;
86       for (ncols = 0; ncols < sizeof(*colors) / sizeof(**colors); ncols++)
87         if (!colors[j][ncols]) break;
88       ypct += heights[j];
89       y2 = height * ypct / 100;
90       h = y2 - y; /* avoid roundoff fencepost */
91       for (i = 0; i < ncols; i++)
92         {
93           XColor xcolor;
94           const char *color = colors[j][i];
95           int x2 = x + (width * (i+1) / ncols);
96           int w = x2 - x1; /* avoid roundoff fencepost */
97           if (! XParseColor (dpy, cmap, color, &xcolor))
98             abort();
99           xcolor.flags = DoRed|DoGreen|DoBlue;
100           if (!XAllocColor (dpy, cmap, &xcolor))
101             continue;
102           XSetForeground (dpy, gc, xcolor.pixel);
103           XFillRectangle (dpy, drawable, gc, x1, y, w, h);
104           x1 = x2;
105         }
106       y = y2;
107     }
108
109   y = oy;
110
111   /* Add in the xscreensaver logo */
112   if (logo)
113     {
114       Window r;
115       int x, y;
116       unsigned int logo_width, logo_height, bw, d;
117       int x1, y1, w, h;
118       XGetGeometry (dpy, logo, &r, &x, &y, &logo_width, &logo_height, &bw, &d);
119       w = width;
120       h = height * heights[0] / 100;
121       x1 = x + (w - (int) logo_width) / 2;
122       y1 = y + (h - (int) logo_height) / 2;
123       if (logo_mask)
124         {
125           XSetClipMask (dpy, gc, logo_mask);
126           XSetClipOrigin (dpy, gc, x1, y1);
127         }
128       XCopyArea (dpy, logo, drawable, gc, 0, 0,
129                  logo_width, logo_height, x1, y1);
130     }
131
132   XFreeGC(dpy, gc);
133 }