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

Revision 20148, 6.2 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/* xscreensaver, Copyright (c) 1997, 1998, 2001 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 * Concept snarfed from Michael D. Bayne in
12 * http://www.go2net.com/internet/deep/1997/04/16/body.html
13 */
14
15#include "screenhack.h"
16#include <X11/Xutil.h>
17#include <stdio.h>
18
19#ifdef HAVE_XSHM_EXTENSION
20# include "xshm.h"
21static Bool use_shm;
22static XShmSegmentInfo shm_info;
23#endif /* HAVE_XSHM_EXTENSION */
24
25static int offset = 0;
26static XColor *colors = 0;
27static int ncolors = 0;
28static GC gc = 0;
29static unsigned long fg_pixel = 0;
30static unsigned long bg_pixel = 0;
31
32static void
33init_moire (Display *dpy, Window window)
34{
35  int oncolors;
36  int i;
37  int fgh, bgh;
38  double fgs, fgv, bgs, bgv;
39  XWindowAttributes xgwa;
40  XColor fgc, bgc;
41  XGCValues gcv;
42  XGetWindowAttributes (dpy, window, &xgwa);
43
44  offset = get_integer_resource ("offset", "Integer");
45  if (offset < 2) offset = 2;
46
47#ifdef HAVE_XSHM_EXTENSION
48  use_shm = get_boolean_resource("useSHM", "Boolean");
49#endif /*  HAVE_XSHM_EXTENSION */
50
51 MONO:
52  if (colors)
53    {
54      for (i = 0; i < ncolors; i++)
55        XFreeColors (dpy, xgwa.colormap, &colors[i].pixel, 1, 0);
56      free(colors);
57      colors = 0;
58    }
59
60  if (mono_p)
61    {
62      fg_pixel = WhitePixelOfScreen (DefaultScreenOfDisplay(dpy));
63      bg_pixel = BlackPixelOfScreen (DefaultScreenOfDisplay(dpy));
64    }
65  else
66    {
67      fg_pixel = get_pixel_resource ("foreground", "Foreground", dpy,
68                                     xgwa.colormap);
69      bg_pixel = get_pixel_resource ("background", "Background", dpy,
70                                     xgwa.colormap);
71    }
72
73  if (mono_p)
74    {
75      offset *= 20;   /* compensate for lack of shading */
76      gcv.foreground = fg_pixel;
77    }
78  else
79    {
80      ncolors = get_integer_resource ("ncolors", "Integer");
81      if (ncolors < 2) ncolors = 2;
82      oncolors = ncolors;
83
84      fgc.flags = bgc.flags = DoRed|DoGreen|DoBlue;
85      if (get_boolean_resource("random","Boolean"))
86        {
87          fgc.red   = random() & 0xFFFF;
88          fgc.green = random() & 0xFFFF;
89          fgc.blue  = random() & 0xFFFF;
90          bgc.red   = random() & 0xFFFF;
91          bgc.green = random() & 0xFFFF;
92          bgc.blue  = random() & 0xFFFF;
93        }
94      else
95        {
96          fgc.pixel = fg_pixel;
97          bgc.pixel = bg_pixel;
98          XQueryColor (dpy, xgwa.colormap, &fgc);
99          XQueryColor (dpy, xgwa.colormap, &bgc);
100        }
101      rgb_to_hsv (fgc.red, fgc.green, fgc.blue, &fgh, &fgs, &fgv);
102      rgb_to_hsv (bgc.red, bgc.green, bgc.blue, &bgh, &bgs, &bgv);
103
104      colors = (XColor *) malloc (sizeof (XColor) * (ncolors+2));
105      memset(colors, 0, (sizeof (XColor) * (ncolors+2)));
106      make_color_ramp (dpy, xgwa.colormap,
107                       fgh, fgs, fgv, bgh, bgs, bgv,
108                       colors, &ncolors,
109                       True, True, False);
110      if (ncolors != oncolors)
111        fprintf(stderr, "%s: got %d of %d requested colors.\n",
112                progname, ncolors, oncolors);
113
114      if (ncolors <= 2)
115        {
116          mono_p = True;
117          goto MONO;
118        }
119
120      gcv.foreground = colors[0].pixel;
121    }
122  gc = XCreateGC (dpy, window, GCForeground, &gcv);
123}
124
125
126static void
127moire (Display *dpy, Window window, int offset, XColor *colors, int ncolors)
128{
129  long x, y, xo, yo;
130  int factor = (random() % offset) + 1;
131  XGCValues gcv;
132  XWindowAttributes xgwa;
133  XImage *image;
134  int depth;
135  XGetWindowAttributes (dpy, window, &xgwa);
136
137  xo = (random() % xgwa.width)  - xgwa.width/2;
138  yo = (random() % xgwa.height) - xgwa.height/2;
139
140  depth = visual_depth(DefaultScreenOfDisplay(dpy), xgwa.visual);
141
142  image = 0;
143# ifdef HAVE_XSHM_EXTENSION
144  if (use_shm)
145    {
146      image = create_xshm_image(dpy, xgwa.visual, depth, ZPixmap, 0,
147                                &shm_info, xgwa.width, 1);
148      if (!image)
149        use_shm = False;
150    }
151# endif /* HAVE_XSHM_EXTENSION */
152
153  if (!image)
154    {
155      image = XCreateImage (dpy, xgwa.visual,
156                            depth, ZPixmap, 0,      /* depth, format, offset */
157                            0, xgwa.width, 1, 8, 0); /* data, w, h, pad, bpl */
158      image->data = (char *) calloc(image->height, image->bytes_per_line);
159    }
160
161  for (y = 0; y < xgwa.height; y++)
162    {
163      for (x = 0; x < xgwa.width; x++)
164        {
165          double xx = x + xo;
166          double yy = y + yo;
167          double i = ((xx * xx) + (yy * yy)) / (double) factor;
168          if (mono_p)
169            gcv.foreground = ((((long) i) & 1) ? fg_pixel : bg_pixel);
170          else
171            gcv.foreground = colors[((long) i) % ncolors].pixel;
172          XPutPixel (image, x, 0, gcv.foreground);
173        }
174
175# ifdef HAVE_XSHM_EXTENSION
176      if (use_shm)
177        XShmPutImage(dpy, window, gc, image, 0, 0, 0, y, xgwa.width, 1, False);
178      else
179# endif /*  HAVE_XSHM_EXTENSION */
180        XPutImage (dpy, window, gc, image, 0, 0, 0, y, xgwa.width, 1);
181
182      XSync(dpy, False);
183    }
184
185# ifdef HAVE_XSHM_EXTENSION
186  if (!use_shm)
187# endif /*  HAVE_XSHM_EXTENSION */
188    if (image->data)
189      {
190        free(image->data);
191        image->data = 0;
192      }
193
194# ifdef HAVE_XSHM_EXTENSION
195  if (use_shm)
196    destroy_xshm_image (dpy, image, &shm_info);
197  else
198# endif /*  HAVE_XSHM_EXTENSION */
199    XDestroyImage (image);
200}
201
202
203char *progclass = "Moire";
204
205char *defaults [] = {
206  ".background:         blue",
207  ".foreground:         red",
208  "*random:             true",
209  "*delay:              5",
210  "*ncolors:            64",
211  "*offset:             50",
212#ifdef HAVE_XSHM_EXTENSION
213  "*useSHM:           True",
214#endif /*  HAVE_XSHM_EXTENSION */
215  0
216};
217
218XrmOptionDescRec options [] = {
219  { "-random",          ".random",      XrmoptionNoArg, "True" },
220  { "-no-random",       ".random",      XrmoptionNoArg, "False" },
221  { "-delay",           ".delay",       XrmoptionSepArg, 0 },
222  { "-ncolors",         ".ncolors",     XrmoptionSepArg, 0 },
223  { "-offset",          ".offset",      XrmoptionSepArg, 0 },
224#ifdef HAVE_XSHM_EXTENSION
225  { "-shm",             ".useSHM",      XrmoptionNoArg, "True" },
226  { "-no-shm",          ".useSHM",      XrmoptionNoArg, "False" },
227#endif /*  HAVE_XSHM_EXTENSION */
228  { 0, 0, 0, 0 }
229};
230
231void
232screenhack (Display *dpy, Window window)
233{
234  int delay = get_integer_resource ("delay", "Integer");
235  while (1)
236    {
237      init_moire (dpy, window);
238      moire (dpy, window, offset, colors, ncolors);
239      XSync (dpy, False);
240      screenhack_handle_events (dpy);
241      if (delay)
242        sleep(delay);
243    }
244}
Note: See TracBrowser for help on using the repository browser.