source: trunk/third/xscreensaver/hacks/moire2.c @ 15683

Revision 15683, 7.9 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15682, which included commits to RCS files with non-trunk default branches.
Line 
1/* xscreensaver, Copyright (c) 1997, 1998 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#include "screenhack.h"
13#include <X11/Xutil.h>
14
15#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
16# include "xdbe.h"
17#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
18
19static int ncolors;
20static XColor *colors = 0;
21static int fg_pixel, bg_pixel;
22static Pixmap p0 = 0, p1 = 0, p2 = 0, p3 = 0;
23static GC copy_gc = 0, erase_gc = 0, window_gc = 0;
24static int width, height, size;
25static int x1, x2, y1, y2, x3, y3;
26static int dx1, dx2, dx3, dy1, dy2, dy3;
27static int othickness, thickness;
28static Bool do_three;
29#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
30XdbeBackBuffer back_buf = 0;
31#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
32
33static void
34init_moire2 (Display *dpy, Window window)
35{
36  XWindowAttributes xgwa;
37  XGetWindowAttributes (dpy, window, &xgwa);
38
39  othickness = get_integer_resource("thickness", "Thickness");
40
41  if (mono_p)
42    ncolors = 2;
43  else
44    ncolors = get_integer_resource ("colors", "Colors");
45  if (ncolors < 2) ncolors = 2;
46  if (ncolors <= 2) mono_p = True;
47
48  if (mono_p)
49    colors = 0;
50  else
51    colors = (XColor *) malloc(sizeof(*colors) * (ncolors+1));
52
53  if (mono_p)
54    ;
55  else
56    make_smooth_colormap (dpy, xgwa.visual, xgwa.colormap, colors, &ncolors,
57                          True, 0, True);
58
59  bg_pixel = get_pixel_resource("background", "Background", dpy,
60                                xgwa.colormap);
61  fg_pixel = get_pixel_resource("foreground", "Foreground", dpy,
62                                xgwa.colormap);
63
64#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
65  back_buf = xdbe_get_backbuffer (dpy, window, XdbeUndefined);
66#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
67}
68
69
70static void
71reset_moire2 (Display *dpy, Window window)
72{
73  GC gc;
74  XWindowAttributes xgwa;
75  XGCValues gcv;
76  Bool xor;
77  XGetWindowAttributes (dpy, window, &xgwa);
78
79  do_three = (0 == (random() % 3));
80
81  width = xgwa.width;
82  height = xgwa.height;
83  size = width > height ? width : height;
84
85  if (p0) XFreePixmap(dpy, p0);
86  if (p1) XFreePixmap(dpy, p1);
87  if (p2) XFreePixmap(dpy, p2);
88  if (p3) XFreePixmap(dpy, p3);
89
90  p0 = XCreatePixmap(dpy, window, width, height, 1);
91  p1 = XCreatePixmap(dpy, window, width*2, height*2, 1);
92  p2 = XCreatePixmap(dpy, window, width*2, height*2, 1);
93  if (do_three)
94    p3 = XCreatePixmap(dpy, window, width*2, height*2, 1);
95  else
96    p3 = 0;
97
98  thickness = (othickness > 0 ? othickness : (1 + (random() % 4)));
99
100  gcv.foreground = 0;
101  gcv.line_width = (thickness == 1 ? 0 : thickness);
102  gc = XCreateGC (dpy, p1, GCForeground|GCLineWidth, &gcv);
103
104  XFillRectangle(dpy, p1, gc, 0, 0, width*2, height*2);
105  XFillRectangle(dpy, p2, gc, 0, 0, width*2, height*2);
106  if (do_three)
107    XFillRectangle(dpy, p3, gc, 0, 0, width*2, height*2);
108
109  XSetForeground(dpy, gc, 1);
110
111  xor = (do_three || (thickness == 1) || (random() & 1));
112
113  {
114    int i, ii, maxx, maxy;
115
116#define FROB(P) do { \
117    maxx = (size*4); \
118    maxy = (size*4); \
119    if (0 == (random() % 5)) { \
120        float f = 1.0 + frand(0.05); \
121        if (random() & 1) maxx *= f; \
122        else maxy *= f; \
123      } \
124    ii = (thickness + 1 + (xor ? 0 : 1) + (random() % (4 * thickness)));  \
125    for (i = 0; i < (size*2); i += ii)  \
126      XDrawArc(dpy, (P), gc, i-size, i-size, maxx-i-i, maxy-i-i, 0, 360*64); \
127    if (0 == (random() % 5)) \
128      { \
129        XSetFunction(dpy, gc, GXxor); \
130        XFillRectangle(dpy, (P), gc, 0, 0, width*2, height*2); \
131        XSetFunction(dpy, gc, GXcopy); \
132      } \
133    } while(0)
134
135    FROB(p1);
136    FROB(p2);
137    if (do_three)
138      FROB(p3);
139#undef FROB
140  }
141
142  XFreeGC(dpy, gc);
143
144  if (copy_gc) XFreeGC(dpy, copy_gc);
145  gcv.function = (xor ? GXxor : GXor);
146  gcv.foreground = 1;
147  gcv.background = 0;
148
149  copy_gc = XCreateGC (dpy, p0, GCFunction|GCForeground|GCBackground, &gcv);
150
151  gcv.foreground = 0;
152  if (erase_gc) XFreeGC(dpy, erase_gc);
153  erase_gc = XCreateGC (dpy, p0, GCForeground, &gcv);
154
155  gcv.foreground = fg_pixel;
156  gcv.background = bg_pixel;
157  if (window_gc) XFreeGC(dpy, window_gc);
158  window_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
159
160#define FROB(N,DN,MAX) \
161  N = (MAX/2) + (random() % MAX); \
162  DN = ((1 + (random() % (7*thickness))) * ((random() & 1) ? 1 : -1))
163
164  FROB(x1,dx1,width);
165  FROB(x2,dx2,width);
166  FROB(x3,dx3,width);
167  FROB(y1,dy1,height);
168  FROB(y2,dy2,height);
169  FROB(y3,dy3,height);
170#undef FROB
171}
172
173
174
175static void
176moire2 (Display *dpy, Window window)
177{
178#define FROB(N,DN,MAX) \
179  N += DN; \
180  if (N <= 0) N = 0, DN = -DN; \
181  else if (N >= MAX) N = MAX, DN = -DN; \
182  else if (0 == (random() % 100)) DN = -DN; \
183  else if (0 == (random() % 50)) \
184    DN += (DN <= -20 ? 1 : (DN >= 20 ? -1 : ((random() & 1) ? 1 : -1)))
185
186  FROB(x1,dx1,width);
187  FROB(x2,dx2,width);
188  FROB(x3,dx3,width);
189  FROB(y1,dy1,height);
190  FROB(y2,dy2,height);
191  FROB(y3,dy3,height);
192#undef FROB
193
194  XFillRectangle(dpy, p0, erase_gc, 0, 0, width, height);
195  XCopyArea(dpy, p1, p0, copy_gc, x1, y1, width, height, 0, 0);
196  XCopyArea(dpy, p2, p0, copy_gc, x2, y2, width, height, 0, 0);
197  if (do_three)
198    XCopyArea(dpy, p3, p0, copy_gc, x3, y3, width, height, 0, 0);
199
200#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
201  if (back_buf)
202    {
203      XdbeSwapInfo info[1];
204      info[0].swap_window = window;
205      info[0].swap_action = XdbeUndefined;
206      XCopyPlane (dpy, p0, back_buf, window_gc, 0, 0, width, height, 0, 0, 1L);
207      XdbeSwapBuffers (dpy, info, 1);
208    }
209  else
210#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
211    XCopyPlane (dpy, p0, window, window_gc, 0, 0, width, height, 0, 0, 1L);
212
213  XSync(dpy, False);
214
215#if 0
216  XCopyPlane(dpy, p1, window, window_gc, (width*2)/3, (height*2)/3,
217             width/2, height/2,
218             0, height/2, 1L);
219  XCopyPlane(dpy, p2, window, window_gc, (width*2)/3, (height*2)/3,
220             width/2, height/2,
221             width/2, height/2, 1L);
222#endif
223}
224
225
226
227
228char *progclass = "Moire2";
229
230char *defaults [] = {
231  ".background:         black",
232  ".foreground:         white",
233  "*delay:              50000",
234  "*thickness:          0",
235  "*colors:             150",
236  "*colorShift:         5",
237
238#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
239  /* Off by default, since it slows it down a lot, and the flicker isn't really
240     all that bad without it... Or rather, it flickers just as badly with it.
241     The XFree86 implementation of the XDBE extension totally blows!  There is
242     just *no* excuse for the "swap buffers" operation to flicker like it does.
243   */
244  "*useDBE:             False",
245#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
246
247  0
248};
249
250XrmOptionDescRec options [] = {
251  { "-delay",           ".delay",       XrmoptionSepArg, 0 },
252  { "-ncolors",         ".colors",      XrmoptionSepArg, 0 },
253  { "-thickness",       ".thickness",   XrmoptionSepArg, 0 },
254  { 0, 0, 0, 0 }
255};
256
257void
258screenhack (Display *dpy, Window window)
259{
260  int delay = get_integer_resource ("delay", "Integer");
261  int color_shift = get_integer_resource ("colorShift", "Integer");
262  int pix = 0;
263  Bool flip_a, flip_b;
264
265  if (color_shift <= 0) color_shift = 1;
266  init_moire2 (dpy, window);
267  while (1)
268    {
269      int iterations = 30 + (random() % 70) + (random() % 70);
270      reset_moire2 (dpy, window);
271
272      flip_a = mono_p ? False : (random() & 1);
273      flip_b = mono_p ? False : (random() & 1);
274
275      if (flip_b)
276        {
277          XSetForeground(dpy, window_gc, bg_pixel);
278          XSetBackground(dpy, window_gc, fg_pixel);
279        }
280      else
281        {
282          XSetForeground(dpy, window_gc, fg_pixel);
283          XSetBackground(dpy, window_gc, bg_pixel);
284        }
285
286      while (--iterations > 0)
287        {
288          int i;
289
290          if (!mono_p)
291            {
292              pix++;
293              pix = pix % ncolors;
294
295              if (flip_a)
296                XSetBackground(dpy, window_gc, colors[pix].pixel);
297              else
298                XSetForeground(dpy, window_gc, colors[pix].pixel);
299            }
300
301          for (i = 0; i < color_shift; i++)
302            {
303              moire2 (dpy, window);
304              screenhack_handle_events (dpy);
305              if (delay)
306                usleep(delay);
307            }
308        }
309    }
310}
Note: See TracBrowser for help on using the repository browser.