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

Revision 15683, 5.8 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/*
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  grab_screen_image(xgwa.screen, window);
103
104  /* We might have needed this to grab the image, but if we leave this set
105     to GCSubwindowMode, then we'll *draw* right over subwindows too. */
106  XSetSubwindowMode (dpy, window_gc, ClipByChildren);
107
108  if (lenses) {
109    orig_map = NULL;
110    pm = XCreatePixmap(dpy, window, sizex, sizey, xgwa.depth);
111    XCopyArea(dpy, window, pm, window_gc, 0, 0, sizex, sizey, 0, 0);
112  } else {
113    orig_map = XGetImage(dpy, window, 0, 0, sizex, sizey, ~0L, ZPixmap);
114    pm = 0;
115  }
116
117  XFillRectangle(dpy, window, window_gc, 0, 0, sizex, sizey);
118  XSetWindowBackground(dpy, window, bg);
119
120  nblocksx = (int)ceil((double)sizex / (double)(pixwidth + pixspacex));
121  nblocksy = (int)ceil((double)sizey / (double)(pixheight + pixspacey));
122  if (lenses)
123    s = MAX((nblocksx - 1) * lensoffsetx + pixwidth,
124            (nblocksy - 1) * lensoffsety + pixheight) * 2;
125  else
126    s = MAX(nblocksx, nblocksy) * 2;
127}
128
129static void onestep(Display *dpy, Window window)
130{
131  unsigned x, y, i, j;
132
133  long now;
134
135#define nrnd(x) (random() % (x))
136
137  now = currentTimeInMs();
138
139  /* find new x,y */
140  tlx = ((1. + sin(((float)now) / X_PERIOD * 2. * M_PI))/2.0)
141    * (sizex - s/2) /* -s/4 */ + MINX;
142  tly = ((1. + sin(((float)now) / Y_PERIOD * 2. * M_PI))/2.0)
143    * (sizey - s/2) /* -s/4 */ + MINY;
144
145  if (lenses) {
146    for (x = i = 0; x < sizex; x += (pixwidth + pixspacex), ++i)
147      for (y = j = 0; y < sizey; y += (pixheight + pixspacey), ++j) {
148        XCopyArea(dpy, pm /* src */, window /* dest */, window_gc,
149                  tlx + i * lensoffsetx /* src_x */,
150                  tly + j * lensoffsety /* src_y */,
151                  pixwidth, pixheight,
152                  x /* dest_x */, y /* dest_y */);
153      }
154  } else {
155    for (x = i = 0; x < sizex; x += (pixwidth + pixspacex), ++i)
156      for (y = j = 0; y < sizey; y += (pixheight + pixspacey), ++j) {
157        XSetForeground(dpy, window_gc, XGetPixel(orig_map, tlx+i, tly+j));
158        XFillRectangle(dpy, window, window_gc,
159                       i * (pixwidth + pixspacex),
160                       j * (pixheight + pixspacey), pixwidth, pixheight);
161      }
162  }
163}
164
165char *progclass = "Zoom";
166
167char *defaults[] = {
168  "*dontClearRoot: True",
169#ifdef __sgi /* really, HAVE_READ_DISPLAY_EXTENSION */
170  "*visualID: Best",
171#endif
172  "*lenses:      false",
173  "*delay:       10000",
174  "*pixwidth:    10",
175  "*pixheight:   10",
176  "*pixspacex:   2",
177  "*pixspacey:   2",
178  "*lensoffsetx: 5",
179  "*lensoffsety: 5",
180  0
181};
182
183XrmOptionDescRec options[] = {
184  { "-lenses", ".lenses", XrmoptionNoArg, "true" },
185  { "-delay", ".delay", XrmoptionSepArg, 0 },
186  { "-pixwidth", ".pixwidth", XrmoptionSepArg, 0 },
187  { "-pixheight", ".pixheight", XrmoptionSepArg, 0 },
188  { "-pixspacex", ".pixspacex", XrmoptionSepArg, 0 },
189  { "-pixspacey", ".pixspacex", XrmoptionSepArg, 0 },
190  { "-lensoffsetx", ".lensoffsetx", XrmoptionSepArg, 0 },
191  { "-lensoffsety", ".lensoffsety", XrmoptionSepArg, 0 },
192  { 0, 0, 0, 0 }
193};
194
195void screenhack(Display *dpy, Window window)
196{
197  init_hack(dpy, window);
198  while (1) {
199    onestep(dpy, window);
200    XSync(dpy, False);
201    if (delay)
202      usleep(delay);
203    screenhack_handle_events(dpy);
204  }
205}
Note: See TracBrowser for help on using the repository browser.