source: trunk/third/xscreensaver/hacks/zoom.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/*
2 *  Copyright (C) 2000 James Macnicol
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation.  No representations are made about the suitability of this
9 * software for any purpose.  It is provided "as is" without express or
10 * implied warranty.
11 */
12
13#include <math.h>
14#include "screenhack.h"
15#include <X11/Xutil.h>
16#include <sys/time.h>
17
18#ifndef MIN
19#define MIN(a, b) (((a) < (b))?(a):(b))
20#endif
21
22#ifndef MAX
23#define MAX(a, b) (((a) > (b))?(a):(b))
24#endif
25
26#define MINX 0.0
27#define MINY 0.0
28/* This should be *way* slower than the spotlight hack was */
29#define X_PERIOD 45000.0
30#define Y_PERIOD 36000.0
31
32static int sizex, sizey;
33
34static int delay;
35static int pixwidth, pixheight, pixspacex, pixspacey, lensoffsetx, lensoffsety;
36static Bool lenses;
37
38static GC window_gc;
39
40static XImage *orig_map;
41static Pixmap pm;
42
43static int tlx, tly, s;
44
45static long currentTimeInMs(void)
46{
47  struct timeval curTime;
48#ifdef GETTIMEOFDAY_TWO_ARGS
49  struct timezone tz = {0,0};
50  gettimeofday(&curTime, &tz);
51#else
52  gettimeofday(&curTime);
53#endif
54  return curTime.tv_sec*1000 + curTime.tv_usec/1000.0;
55}
56
57static void init_hack(Display *dpy, Window window)
58{
59  XGCValues gcv;
60  XWindowAttributes xgwa;
61  Colormap cmap;
62  unsigned long fg, bg;
63  long gcflags;
64  int nblocksx, nblocksy;
65
66  XGetWindowAttributes(dpy, window, &xgwa);
67  sizex = xgwa.width;
68  sizey = xgwa.height;
69  cmap = xgwa.colormap;
70  fg = get_pixel_resource("foreground", "Foreground", dpy, cmap);
71  bg = get_pixel_resource("background", "Background", dpy, cmap);
72
73  delay = get_integer_resource("delay", "Integer");
74  if (delay < 1)
75    delay = 1;
76  pixwidth = get_integer_resource("pixwidth", "Integer");
77  if (pixwidth < 1)
78    pixwidth = 1;
79  pixheight = get_integer_resource("pixheight", "Integer");
80  if (pixheight < 1)
81    pixheight = 1;
82  pixspacex = get_integer_resource("pixspacex", "Integer");
83  if (pixspacex < 0)
84    pixspacex = 0;
85  pixspacey = get_integer_resource("pixspacey", "Integer");
86  if (pixspacey < 0)
87    pixspacey = 0;
88  lenses = get_boolean_resource("lenses", "Boolean");
89  lensoffsetx = get_integer_resource("lensoffsetx", "Integer");
90  lensoffsetx = MAX(0, MIN(pixwidth, lensoffsetx));
91  lensoffsety = get_integer_resource("lensoffsety", "Integer");
92  lensoffsety = MAX(0, MIN(pixwidth, lensoffsety));
93
94  gcv.function = GXcopy;
95  gcv.subwindow_mode = IncludeInferiors;
96  gcflags = GCForeground|GCFunction;
97  gcv.foreground = bg;
98  if (!lenses && use_subwindow_mode_p(xgwa.screen, window))       /* see grabscreen.c */
99    gcflags |= GCSubwindowMode;
100  window_gc = XCreateGC(dpy, window, gcflags, &gcv);
101
102
103  orig_map = NULL;
104  pm = XCreatePixmap(dpy, window, sizex, sizey, xgwa.depth);
105  load_random_image (xgwa.screen, window, pm, NULL);
106
107  if (!lenses) {
108    orig_map = XGetImage(dpy, pm, 0, 0, sizex, sizey, ~0L, ZPixmap);
109    XFreePixmap(dpy, pm);
110    pm = 0;
111  }
112
113  /* We might have needed this to grab the image, but if we leave this set
114     to GCSubwindowMode, then we'll *draw* right over subwindows too. */
115  XSetSubwindowMode (dpy, window_gc, ClipByChildren);
116
117
118  XFillRectangle(dpy, window, window_gc, 0, 0, sizex, sizey);
119  XSetWindowBackground(dpy, window, bg);
120
121  nblocksx = (int)ceil((double)sizex / (double)(pixwidth + pixspacex));
122  nblocksy = (int)ceil((double)sizey / (double)(pixheight + pixspacey));
123  if (lenses)
124    s = MAX((nblocksx - 1) * lensoffsetx + pixwidth,
125            (nblocksy - 1) * lensoffsety + pixheight) * 2;
126  else
127    s = MAX(nblocksx, nblocksy) * 2;
128}
129
130static void onestep(Display *dpy, Window window)
131{
132  unsigned x, y, i, j;
133
134  long now;
135
136#define nrnd(x) (random() % (x))
137
138  now = currentTimeInMs();
139
140  /* find new x,y */
141  tlx = ((1. + sin(((float)now) / X_PERIOD * 2. * M_PI))/2.0)
142    * (sizex - s/2) /* -s/4 */ + MINX;
143  tly = ((1. + sin(((float)now) / Y_PERIOD * 2. * M_PI))/2.0)
144    * (sizey - s/2) /* -s/4 */ + MINY;
145
146  if (lenses) {
147    for (x = i = 0; x < sizex; x += (pixwidth + pixspacex), ++i)
148      for (y = j = 0; y < sizey; y += (pixheight + pixspacey), ++j) {
149        XCopyArea(dpy, pm /* src */, window /* dest */, window_gc,
150                  tlx + i * lensoffsetx /* src_x */,
151                  tly + j * lensoffsety /* src_y */,
152                  pixwidth, pixheight,
153                  x /* dest_x */, y /* dest_y */);
154      }
155  } else {
156    for (x = i = 0; x < sizex; x += (pixwidth + pixspacex), ++i)
157      for (y = j = 0; y < sizey; y += (pixheight + pixspacey), ++j) {
158        XSetForeground(dpy, window_gc, XGetPixel(orig_map, tlx+i, tly+j));
159        XFillRectangle(dpy, window, window_gc,
160                       i * (pixwidth + pixspacex),
161                       j * (pixheight + pixspacey), pixwidth, pixheight);
162      }
163  }
164}
165
166char *progclass = "Zoom";
167
168char *defaults[] = {
169  "*dontClearRoot: True",
170#ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */
171  "*visualID: Best",
172#endif
173  "*lenses:      false",
174  "*delay:       10000",
175  "*pixwidth:    10",
176  "*pixheight:   10",
177  "*pixspacex:   2",
178  "*pixspacey:   2",
179  "*lensoffsetx: 5",
180  "*lensoffsety: 5",
181  0
182};
183
184XrmOptionDescRec options[] = {
185  { "-lenses", ".lenses", XrmoptionNoArg, "true" },
186  { "-delay", ".delay", XrmoptionSepArg, 0 },
187  { "-pixwidth", ".pixwidth", XrmoptionSepArg, 0 },
188  { "-pixheight", ".pixheight", XrmoptionSepArg, 0 },
189  { "-pixspacex", ".pixspacex", XrmoptionSepArg, 0 },
190  { "-pixspacey", ".pixspacey", XrmoptionSepArg, 0 },
191  { "-lensoffsetx", ".lensoffsetx", XrmoptionSepArg, 0 },
192  { "-lensoffsety", ".lensoffsety", XrmoptionSepArg, 0 },
193  { 0, 0, 0, 0 }
194};
195
196void screenhack(Display *dpy, Window window)
197{
198  init_hack(dpy, window);
199  while (1) {
200    onestep(dpy, window);
201    XSync(dpy, False);
202    if (delay)
203      usleep(delay);
204    screenhack_handle_events(dpy);
205  }
206}
Note: See TracBrowser for help on using the repository browser.