1 /* rotzoomer - creates a collage of rotated and scaled portions of the screen
2 * Copyright (C) 2001 Claudio Matsuoka <claudio@helllabs.org>
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
14 #include "screenhack.h"
15 #include <X11/Xutil.h>
17 #ifdef HAVE_XSHM_EXTENSION
20 static XShmSegmentInfo shm_info;
24 int w, h; /* rectangle width and height */
25 int inc1, inc2; /* rotation and zoom angle increments */
26 int dx, dy; /* translation increments */
27 int a1, a2; /* rotation and zoom angular variables */
28 int ox, oy; /* origin in the background copy */
29 int xx, yy; /* left-upper corner position (* 256) */
30 int x, y; /* left-upper corner position */
31 int ww, hh; /* valid area to place left-upper corner */
32 int n; /* number of iteractions */
36 static Display *display;
38 static Visual *visual;
39 static XImage *orig_map, *buffer_map;
40 static Colormap colormap;
42 static int width, height;
43 static struct zoom_area **zoom_box;
44 static int num_zoom = 2;
49 static void rotzoom (struct zoom_area *za)
51 int x, y, c, s, zoom, z;
52 int x2 = za->x + za->w - 1, y2 = za->y + za->h - 1;
55 z = 8100 * sin (M_PI * za->a2 / 8192);
58 c = zoom * cos (M_PI * za->a1 / 8192);
59 s = zoom * sin (M_PI * za->a1 / 8192);
60 for (y = za->y; y <= y2; y++) {
61 for (x = za->x; x <= x2; x++) {
62 ox = (x * c + y * s) >> 13;
63 oy = (-x * s + y * c) >> 13;
74 XPutPixel (buffer_map, x, y, XGetPixel (orig_map, ox, oy));
78 za->a1 += za->inc1; /* Rotation angle */
81 za->a2 += za->inc2; /* Zoom */
84 za->ox = ox; /* Save state for next iteration */
89 static void reset_zoom (struct zoom_area *za)
91 za->w = 50 + random() % 300;
92 za->h = 50 + random() % 300;
94 if (za->w > width / 3)
97 if (za->h > height / 3)
100 za->ww = width - za->w;
101 za->hh = height - za->h;
103 za->x = (random() % za->ww);
104 za->y = (random() % za->hh);
105 za->xx = za->x * 256;
106 za->yy = za->y * 256;
110 za->dx = ((2 * (random() & 1)) - 1) * (100 + random() % 300);
111 za->dy = ((2 * (random() & 1)) - 1) * (100 + random() % 300);
112 za->inc1 = ((2 * (random() & 1)) - 1) * (random () % 30);
113 za->inc2 = ((2 * (random() & 1)) - 1) * (random () % 30);
114 za->n = 50 + random() % 1000;
118 static struct zoom_area *create_zoom (void)
120 struct zoom_area *za;
122 za = malloc (sizeof (struct zoom_area));
129 static void update_position (struct zoom_area *za)
139 za->dx = 100 + random() % 100;
144 za->dy = 100 + random() % 100;
147 if (za->x > za->ww) {
149 za->dx = -(100 + random() % 100);
152 if (za->y > za->hh) {
154 za->dy = -(100 + random() % 100);
159 static void DisplayImage (int x, int y, int w, int h)
161 #ifdef HAVE_XSHM_EXTENSION
163 XShmPutImage (display, window, gc, buffer_map, x, y, x, y,
166 #endif /* HAVE_XSHM_EXTENSION */
167 XPutImage(display, window, gc, buffer_map, x, y, x, y, w, h);
171 static void hack_main (void)
175 for (i = 0; i < num_zoom; i++) {
177 update_position (zoom_box[i]);
179 if (zoom_box[i]->n) {
180 rotzoom (zoom_box[i]);
183 reset_zoom (zoom_box[i]);
187 for (i = 0; i < num_zoom; i++) {
188 DisplayImage(zoom_box[i]->x, zoom_box[i]->y,
189 zoom_box[i]->w, zoom_box[i]->h);
192 XSync(display,False);
193 screenhack_handle_events(display);
197 static void init_hack (void)
201 zoom_box = calloc (num_zoom, sizeof (struct zoom_area *));
202 for (i = 0; i < num_zoom; i++) {
203 zoom_box[i] = create_zoom ();
206 memcpy (buffer_map->data, orig_map->data,
207 height * buffer_map->bytes_per_line);
209 DisplayImage(0, 0, width, height);
210 XSync(display,False);
214 static void setup_X (Display * disp, Window win)
216 XWindowAttributes xwa;
221 XGetWindowAttributes (disp, win, &xwa);
225 colormap = xwa.colormap;
235 gcv.function = GXcopy;
236 gcv.subwindow_mode = IncludeInferiors;
237 gcflags = GCForeground | GCFunction;
238 if (use_subwindow_mode_p (xwa.screen, window)) /* see grabscreen.c */
239 gcflags |= GCSubwindowMode;
240 gc = XCreateGC (display, window, gcflags, &gcv);
241 grab_screen_image (xwa.screen, window);
243 orig_map = XGetImage (display, window, 0, 0, width, height, ~0L, ZPixmap);
246 fprintf(stderr, "XCreateGC failed\n");
252 #ifdef HAVE_XSHM_EXTENSION
254 buffer_map = create_xshm_image(display, xwa.visual, depth,
255 ZPixmap, 0, &shm_info, width, height);
258 fprintf(stderr, "create_xshm_image failed\n");
261 #endif /* HAVE_XSHM_EXTENSION */
264 buffer_map = XCreateImage(display, xwa.visual,
265 depth, ZPixmap, 0, 0, width, height, 8, 0);
266 buffer_map->data = (char *)calloc (buffer_map->height,
267 buffer_map->bytes_per_line);
273 char *progclass = "Rotzoomer";
276 #ifdef HAVE_XSHM_EXTENSION
286 XrmOptionDescRec options[] = {
287 #ifdef HAVE_XSHM_EXTENSION
288 { "-shm", ".useSHM", XrmoptionNoArg, "True" },
289 { "-no-shm", ".useSHM", XrmoptionNoArg, "False" },
291 { "-move", ".move", XrmoptionNoArg, "True"},
292 { "-no-move", ".move", XrmoptionNoArg, "False"},
293 { "-delay", ".delay", XrmoptionSepArg, 0},
294 { "-n", ".numboxes", XrmoptionSepArg, 0},
299 void screenhack(Display *disp, Window win)
301 #ifdef HAVE_XSHM_EXTENSION
302 use_shm = get_boolean_resource ("useSHM", "Boolean");
304 num_zoom = get_integer_resource("numboxes", "Integer");
305 move = get_boolean_resource("move", "Boolean");
306 delay = get_integer_resource("delay", "Integer");
312 /* Main drawing loop */