source: trunk/third/xscreensaver/hacks/popsquares.c @ 20148

Revision 20148, 5.7 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/* Copyright (c) 2003 Levi Burton <donburton@sbcglobal.net>
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#include "screenhack.h"
13#include "colors.h"
14
15#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
16# include "xdbe.h"
17#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
18
19typedef struct _square {
20  int x, y, w, h;
21  int color;
22} square;
23
24void
25randomize_square_colors(square *squares, int nsquares, int ncolors)
26{
27  int i;
28  square *s = squares;
29  for (i = 0; i < nsquares; i++)
30    s[i].color = random() % ncolors;
31}
32
33
34char *progclass = "popsquares";
35
36char *defaults [] = {
37  ".background: blue",
38  ".foreground: blue4",
39  "*delay: 25000",
40  "*subdivision:  5",
41  "*border: 1",
42  "*ncolors: 128",
43  "*twitch: False",
44  "*doubleBuffer: False",
45#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
46  "*useDBE: True",
47  "*useDBEClear: True",
48#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
49  0
50};
51
52XrmOptionDescRec options [] = {
53  { "-fg", ".foreground", XrmoptionSepArg, 0},
54  { "-bg", ".background", XrmoptionSepArg, 0},
55  { "-delay",     ".delay", XrmoptionSepArg, 0 },
56  { "-subdivision", ".subdivision", XrmoptionSepArg, 0 },
57  { "-border", ".border", XrmoptionSepArg, 0},
58  { "-ncolors",   ".ncolors", XrmoptionSepArg, 0 },
59  { "-twitch",    ".twitch", XrmoptionNoArg, "True" },
60  { "-no-twitch", ".twitch", XrmoptionNoArg, "False" },
61  { "-db",        ".doubleBuffer", XrmoptionNoArg, "True" },
62  { "-no-db",     ".doubleBuffer", XrmoptionNoArg, "False" },
63  { 0, 0, 0, 0 }
64};
65
66void
67screenhack (Display *dpy, Window window)
68{
69  int delay = get_integer_resource ("delay", "Integer");
70  int subdivision = get_integer_resource("subdivision", "Integer");
71  int border = get_integer_resource("border", "Integer");
72  int ncolors = get_integer_resource("ncolors", "Integer");
73  Bool twitch = get_boolean_resource("twitch", "Boolean");
74  Bool dbuf = get_boolean_resource("doubleBuffer", "Boolean");
75  int x, y;
76  int sw, sh, gw, gh, nsquares = 0;
77  double s1, v1, s2, v2 = 0;
78  int h1, h2 = 0;
79  /* Not sure how to use DBEClear */
80  /* Bool dbeclear_p = get_boolean_resource("useDBEClear", "Boolean"); */
81  XColor *colors = 0;
82  XColor fg, bg;
83  XGCValues gcv;
84  GC gc;
85  square *squares;
86  XWindowAttributes xgwa;
87  Pixmap b=0, ba=0, bb=0;
88#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
89  XdbeBackBuffer backb = 0;
90#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
91 
92  XGetWindowAttributes (dpy, window, &xgwa);
93
94  fg.pixel = get_pixel_resource ("foreground", "Foreground", dpy, xgwa.colormap);
95  bg.pixel = get_pixel_resource ("background", "Background", dpy, xgwa.colormap);
96
97  XQueryColor (dpy, xgwa.colormap, &fg);
98  XQueryColor (dpy, xgwa.colormap, &bg);
99
100  sw = xgwa.width / subdivision;
101  sh = xgwa.height / subdivision;
102  gw = xgwa.width / sw;
103  gh = xgwa.height / sh;
104  nsquares = gw * gh;
105
106  gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
107
108  colors = (XColor *) calloc (ncolors, sizeof(XColor));
109  squares = (square *) calloc (nsquares, sizeof(square));
110
111  rgb_to_hsv (fg.red, fg.green, fg.blue, &h1, &s1, &v1);
112  rgb_to_hsv (bg.red, bg.green, bg.blue, &h2, &s2, &v2);
113  make_color_ramp (dpy, xgwa.colormap,
114                   h1, s1, v1,
115                   h2, s2, v2,
116                   colors, &ncolors,  /* would this be considered a value-result argument? */
117                   True, True, False);
118  if (ncolors < 2)
119    {
120      fprintf (stderr, "%s: insufficient colors!\n", progname);
121      exit (1);
122    }
123
124  for (y = 0; y < gh; y++)
125    for (x = 0; x < gw; x++)
126      {
127        square *s = (square *) &squares[gw * y + x];
128        s->w = sw;
129        s->h = sh;
130        s->x = x * sw;
131        s->y = y * sh;
132      }
133
134  randomize_square_colors(squares, nsquares, ncolors);
135
136  if (dbuf)
137    {
138#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
139      b = xdbe_get_backbuffer (dpy, window, XdbeUndefined);
140      backb = b;
141#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
142      if (!b)                     
143        {
144          ba = XCreatePixmap (dpy, window, xgwa.width, xgwa.height, xgwa.depth);
145          bb = XCreatePixmap (dpy, window, xgwa.width, xgwa.height, xgwa.depth);
146          b = ba;
147        }
148    }
149  else
150    {
151      b = window;
152    }
153
154  while (1)
155    {
156      for (y = 0; y < gh; y++)
157        for (x = 0; x < gw; x++)
158          {
159            square *s = (square *) &squares[gw * y + x];
160            XSetForeground (dpy, gc, colors[s->color].pixel);
161            XFillRectangle (dpy, b, gc, s->x, s->y,
162                            border ? s->w - border : s->w,
163                            border ? s->h - border : s->h);
164            s->color++;
165            if (s->color == ncolors)
166              {
167                if (twitch && ((random() % 4) == 0))
168                  randomize_square_colors (squares, nsquares, ncolors);
169                else
170                  s->color = random() % ncolors;
171              }
172          }
173#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
174      if (backb)
175        {
176          XdbeSwapInfo info[1];
177          info[0].swap_window = window;
178          info[0].swap_action = XdbeUndefined;
179          XdbeSwapBuffers (dpy, info, 1);
180        }
181      else
182#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
183        if (dbuf)
184          {
185            XCopyArea (dpy, b, window, gc, 0, 0,
186                       xgwa.width, xgwa.height, 0, 0);
187            b = (b == ba ? bb : ba);
188          }
189
190      XSync (dpy, False);
191      screenhack_handle_events (dpy);
192      if (delay)
193        usleep (delay);
194    }
195}
Note: See TracBrowser for help on using the repository browser.