~ubuntu-branches/debian/sid/xscreensaver/sid

« back to all changes in this revision

Viewing changes to hacks/rocks.c

  • Committer: Bazaar Package Importer
  • Author(s): Jose Luis Rivas, Tormod Volden, Jose Luis Rivas
  • Date: 2008-07-15 14:48:48 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20080715144848-c6c6mhyxij0dk2p7
Tags: 5.05-3
[ Tormod Volden ]
* debian/patches/10_jwz-xscreensaver-randr-patch-3.patch:
  from upstream, addresses issues with xrandr/xinerama
  (Closes: #482385, #428797, #471920, #453708, #473681, #479715, #480231)
* fixed typo "screen < real_nscreens" in driver/lock:1527 from above patch
* drop 61_DualHead-nVidia_bug471920.patch (obsolete)
* drop 67_XineRama-mode_bug473681.patch (obsolete)
* fix m6502.o typo in hacks/Makefile.in
* refresh 53_XScreenSaver.ad.in.patch
* refresh (disabled) 60_add-ant-hack.patch

[ Jose Luis Rivas ]
* add xscreensaver-demo desktop file, thanks to Daniel Dickinson
  (Closes: #480592)
* update package descriptions (thanks jwz)
* fix categories in xscreensaver.menu
* change build-deps from xlibmesa-gl-dev to libgl1-mesa-dev,
  xutils to xutils-dev, x-dev to x11proto-core-dev.
* bump Standards-Version to 3.8.0
* add Vcs fields and Homepage to debian/control
* Flurry is not installed until the bug get fixed (Closes: #484112)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998
 
1
/* xscreensaver, Copyright (c) 1992, 1995, 1996, 1997, 1998, 2006
2
2
 *  Jamie Zawinski <jwz@jwz.org>
3
3
 *
4
4
 * Permission to use, copy, modify, distribute, and sell this software and its
41
41
   higher resolution or compute power.
42
42
 */
43
43
 
44
 
static double sins [SIN_RESOLUTION];
45
 
static double coss [SIN_RESOLUTION];
46
 
static double depths [(MAX_DEPTH + 1) * DEPTH_SCALE];
47
 
 
48
 
static Display *dpy;
49
 
static Window window;
50
 
static int width, height, midx, midy;
51
 
static int dep_x, dep_y;
52
 
static int ncolors;
53
 
static XColor *colors;
54
 
static float max_dep;
55
 
static GC erase_gc;
56
 
static GC *draw_gcs;
57
 
static Bool rotate_p;
58
 
static Bool move_p;
59
 
static int speed;
60
 
static Bool threed;
61
 
static GC threed_left_gc, threed_right_gc;
62
 
static double threed_delta;
 
44
struct state {
 
45
  Display *dpy;
 
46
  Window window;
 
47
 
 
48
  double sins [SIN_RESOLUTION];
 
49
  double coss [SIN_RESOLUTION];
 
50
  double depths [(MAX_DEPTH + 1) * DEPTH_SCALE];
 
51
 
 
52
  int width, height, midx, midy;
 
53
  int dep_x, dep_y;
 
54
  int ncolors;
 
55
  XColor *colors;
 
56
  float max_dep;
 
57
  GC erase_gc;
 
58
  GC *draw_gcs;
 
59
  Bool rotate_p;
 
60
  Bool move_p;
 
61
  int speed;
 
62
  Bool threed;
 
63
  GC threed_left_gc, threed_right_gc;
 
64
  double threed_delta;
 
65
 
 
66
  struct rock *rocks;
 
67
  int nrocks;
 
68
  Pixmap pixmaps [MAX_SIZE];
 
69
  int delay;
 
70
 
 
71
  int move_current_dep[2];
 
72
  int move_speed[2];
 
73
  short move_direction[2];
 
74
  int move_limit[2];
 
75
 
 
76
  int current_delta;    /* observer Z rotation */
 
77
  int  new_delta;
 
78
  int  dchange_tick;
 
79
};
 
80
 
 
81
 
63
82
 
64
83
#define GETZDIFF(z) \
65
 
        (threed_delta * 40.0 * \
 
84
        (st->threed_delta * 40.0 * \
66
85
         (1.0 - ((MAX_DEPTH * DEPTH_SCALE / 2) / \
67
86
                 ((z) + 20.0 * DEPTH_SCALE))))
68
87
 
76
95
  int color;
77
96
};
78
97
 
79
 
static struct rock *rocks;
80
 
static int nrocks;
81
 
static Pixmap pixmaps [MAX_SIZE];
82
 
static int delay;
83
 
 
84
 
static void rock_compute (struct rock *);
85
 
static void rock_draw (struct rock *, Bool draw_p);
 
98
static void rock_compute (struct state *, struct rock *);
 
99
static void rock_draw (struct state *, struct rock *, Bool draw_p);
86
100
 
87
101
static void
88
 
rock_reset (struct rock *rock)
 
102
rock_reset (struct state *st, struct rock *rock)
89
103
{
90
104
  rock->real_size = MAX_SIZE;
91
105
  rock->r = (SIN_RESOLUTION * 0.7) + (random () % (30 * SIN_RESOLUTION));
92
106
  rock->theta = random () % SIN_RESOLUTION;
93
107
  rock->depth = MAX_DEPTH * DEPTH_SCALE;
94
 
  rock->color = random() % ncolors;
95
 
  rock_compute (rock);
96
 
  rock_draw (rock, True);
 
108
  rock->color = random() % st->ncolors;
 
109
  rock_compute (st, rock);
 
110
  rock_draw (st, rock, True);
97
111
}
98
112
 
99
113
static void
100
 
rock_tick (struct rock *rock, int d)
 
114
rock_tick (struct state *st, struct rock *rock, int d)
101
115
{
102
116
  if (rock->depth > 0)
103
117
    {
104
 
      rock_draw (rock, False);
105
 
      rock->depth -= speed;
106
 
      if (rotate_p)
 
118
      rock_draw (st, rock, False);
 
119
      rock->depth -= st->speed;
 
120
      if (st->rotate_p)
107
121
        {
108
122
          rock->theta = (rock->theta + d) % SIN_RESOLUTION;
109
123
        }
113
127
        rock->depth = 0;
114
128
      else
115
129
        {
116
 
          rock_compute (rock);
117
 
          rock_draw (rock, True);
 
130
          rock_compute (st, rock);
 
131
          rock_draw (st, rock, True);
118
132
        }
119
133
    }
120
134
  else if ((random () % 40) == 0)
121
 
    rock_reset (rock);
 
135
    rock_reset (st, rock);
122
136
}
123
137
 
124
138
static void
125
 
rock_compute (struct rock *rock)
 
139
rock_compute (struct state *st, struct rock *rock)
126
140
{
127
 
  double factor = depths [rock->depth];
 
141
  double factor = st->depths [rock->depth];
128
142
  double rsize = rock->real_size * factor;
129
143
 
130
144
  rock->size = (int) (rsize + 0.5);
131
145
  rock->diff = (int) GETZDIFF(rock->depth);
132
 
  rock->x = midx + (coss [rock->theta] * rock->r * factor);
133
 
  rock->y = midy + (sins [rock->theta] * rock->r * factor);
 
146
  rock->x = st->midx + (st->coss [rock->theta] * rock->r * factor);
 
147
  rock->y = st->midy + (st->sins [rock->theta] * rock->r * factor);
134
148
 
135
 
  if (move_p)
 
149
  if (st->move_p)
136
150
    {
137
151
      double move_factor = (((double) MOVE_STYLE) -
138
152
                            (((double) rock->depth) /
139
153
                             (((double) (MAX_DEPTH + 1)) *
140
154
                              ((double) DEPTH_SCALE))));
141
155
      /* move_factor is 0 when the rock is close, 1 when far */
142
 
      rock->x += (((double) dep_x) * move_factor);
143
 
      rock->y += (((double) dep_y) * move_factor);
 
156
      rock->x += (((double) st->dep_x) * move_factor);
 
157
      rock->y += (((double) st->dep_y) * move_factor);
144
158
    }
145
159
}
146
160
 
147
161
static void
148
 
rock_draw (rock, draw_p)
149
 
     struct rock *rock;
150
 
     Bool draw_p;
 
162
rock_draw (struct state *st, struct rock *rock, Bool draw_p)
151
163
{
152
164
  GC gc = (draw_p 
153
 
           ? (threed ? erase_gc : draw_gcs[rock->color])
154
 
           : erase_gc);
 
165
           ? (st->threed ? st->erase_gc : st->draw_gcs[rock->color])
 
166
           : st->erase_gc);
155
167
 
156
 
  if (rock->x <= 0 || rock->y <= 0 || rock->x >= width || rock->y >= height)
 
168
  if (rock->x <= 0 || rock->y <= 0 || rock->x >= st->width || rock->y >= st->height)
157
169
    {
158
170
      /* this means that if a rock were to go off the screen at 12:00, but
159
171
         would have been visible at 3:00, it won't come back once the observer
160
172
         rotates around so that the rock would have been visible again.
161
173
         Oh well.
162
174
       */
163
 
      if (!move_p)
 
175
      if (!st->move_p)
164
176
        rock->depth = 0;
165
177
      return;
166
178
    }
167
179
  if (rock->size <= 1)
168
180
    {
169
 
      if (threed)
 
181
      if (st->threed)
170
182
        {
171
 
          if (draw_p) gc = threed_left_gc;
172
 
          XDrawPoint (dpy, window, gc, rock->x - rock->diff, rock->y);
173
 
          if (draw_p) gc = threed_right_gc;
174
 
          XDrawPoint (dpy, window, gc, rock->x + rock->diff, rock->y);
 
183
          if (draw_p) gc = st->threed_left_gc;
 
184
          XDrawPoint (st->dpy, st->window, gc, rock->x - rock->diff, rock->y);
 
185
          if (draw_p) gc = st->threed_right_gc;
 
186
          XDrawPoint (st->dpy, st->window, gc, rock->x + rock->diff, rock->y);
175
187
        }
176
188
      else
177
189
        {
178
 
          XDrawPoint (dpy, window, gc, rock->x, rock->y);
 
190
          XDrawPoint (st->dpy, st->window, gc, rock->x, rock->y);
179
191
        }
180
192
    }
181
193
  else if (rock->size <= MIN_SIZE || !draw_p)
182
194
    {
183
 
      if (threed)
 
195
      if (st->threed)
184
196
        {
185
 
          if (draw_p) gc = threed_left_gc;
186
 
          XFillRectangle(dpy, window, gc,
 
197
          if (draw_p) gc = st->threed_left_gc;
 
198
          XFillRectangle(st->dpy, st->window, gc,
187
199
                         rock->x - rock->size / 2 - rock->diff,
188
200
                         rock->y - rock->size / 2,
189
201
                         rock->size, rock->size);
190
 
          if (draw_p) gc = threed_right_gc;
191
 
          XFillRectangle(dpy, window, gc,
 
202
          if (draw_p) gc = st->threed_right_gc;
 
203
          XFillRectangle(st->dpy, st->window, gc,
192
204
                         rock->x - rock->size / 2 + rock->diff,
193
205
                         rock->y - rock->size / 2,
194
206
                         rock->size, rock->size);
195
207
        }
196
208
      else
197
209
        {
198
 
          XFillRectangle (dpy, window, gc,
 
210
          XFillRectangle (st->dpy, st->window, gc,
199
211
                          rock->x - rock->size/2, rock->y - rock->size/2,
200
212
                          rock->size, rock->size);
201
213
        }
202
214
    }
203
215
  else if (rock->size < MAX_SIZE)
204
216
    {
205
 
      if (threed)
 
217
      if (st->threed)
206
218
        {
207
 
          gc = threed_left_gc;
208
 
          XCopyPlane(dpy, pixmaps[rock->size], window, gc,
 
219
          gc = st->threed_left_gc;
 
220
          XCopyPlane(st->dpy, st->pixmaps[rock->size], st->window, gc,
209
221
                     0, 0, rock->size, rock->size,
210
222
                     rock->x - rock->size / 2 - rock->diff,
211
223
                     rock->y - rock->size / 2, 1L);
212
 
          gc = threed_right_gc;
213
 
          XCopyPlane(dpy, pixmaps[rock->size], window, gc,
 
224
          gc = st->threed_right_gc;
 
225
          XCopyPlane(st->dpy, st->pixmaps[rock->size], st->window, gc,
214
226
                     0, 0, rock->size, rock->size,
215
227
                     rock->x - rock->size / 2 + rock->diff,
216
228
                     rock->y - rock->size / 2, 1L);
217
229
        }
218
230
      else
219
231
        {
220
 
          XCopyPlane (dpy, pixmaps [rock->size], window, gc,
 
232
          XCopyPlane (st->dpy, st->pixmaps [rock->size], st->window, gc,
221
233
                      0, 0, rock->size, rock->size,
222
234
                      rock->x - rock->size/2, rock->y - rock->size/2,
223
235
                      1L);
227
239
 
228
240
 
229
241
static void
230
 
init_pixmaps (Display *dpy, Window window)
 
242
init_pixmaps (struct state *st)
231
243
{
232
244
  int i;
233
245
  XGCValues gcv;
234
246
  GC fg_gc = 0, bg_gc = 0;
235
 
  pixmaps [0] = pixmaps [1] = 0;
 
247
  st->pixmaps [0] = st->pixmaps [1] = 0;
236
248
  for (i = MIN_DEPTH; i < MAX_SIZE; i++)
237
249
    {
238
250
      int w = (1+(i/32))<<5; /* server might be faster if word-aligned */
239
251
      int h = i;
240
 
      Pixmap p = XCreatePixmap (dpy, window, w, h, 1);
 
252
      Pixmap p = XCreatePixmap (st->dpy, st->window, w, h, 1);
241
253
      XPoint points [7];
242
 
      pixmaps [i] = p;
 
254
      st->pixmaps [i] = p;
243
255
      if (! p)
244
256
        {
245
257
          fprintf (stderr, "%s: couldn't allocate pixmaps", progname);
248
260
      if (! fg_gc)
249
261
        {       /* must use drawable of pixmap, not window (fmh) */
250
262
          gcv.foreground = 1;
251
 
          fg_gc = XCreateGC (dpy, p, GCForeground, &gcv);
 
263
          fg_gc = XCreateGC (st->dpy, p, GCForeground, &gcv);
252
264
          gcv.foreground = 0;
253
 
          bg_gc = XCreateGC (dpy, p, GCForeground, &gcv);
 
265
          bg_gc = XCreateGC (st->dpy, p, GCForeground, &gcv);
254
266
        }
255
 
      XFillRectangle (dpy, p, bg_gc, 0, 0, w, h);
 
267
      XFillRectangle (st->dpy, p, bg_gc, 0, 0, w, h);
256
268
      points [0].x = i * 0.15; points [0].y = i * 0.85;
257
269
      points [1].x = i * 0.00; points [1].y = i * 0.20;
258
270
      points [2].x = i * 0.30; points [2].y = i * 0.00;
260
272
      points [4].x = i * 0.90; points [4].y = i * 0.10;
261
273
      points [5].x = i * 1.00; points [5].y = i * 0.55;
262
274
      points [6].x = i * 0.45; points [6].y = i * 1.00;
263
 
      XFillPolygon (dpy, p, fg_gc, points, 7, Nonconvex, CoordModeOrigin);
 
275
      XFillPolygon (st->dpy, p, fg_gc, points, 7, Nonconvex, CoordModeOrigin);
264
276
    }
265
 
  XFreeGC (dpy, fg_gc);
266
 
  XFreeGC (dpy, bg_gc);
 
277
  XFreeGC (st->dpy, fg_gc);
 
278
  XFreeGC (st->dpy, bg_gc);
267
279
}
268
280
 
269
281
 
270
282
static int
271
 
compute_move(int axe)                           /* 0 for x, 1 for y */
 
283
compute_move(struct state *st, int axe)                 /* 0 for x, 1 for y */
272
284
{
273
 
  static int current_dep[2] = {0, 0};
274
 
  static int speed[2] = {0, 0};
275
 
  static short direction[2] = {0, 0};
276
 
  static int limit[2] = {0, 0};
277
285
  int change = 0;
278
286
 
279
 
  limit[0] = midx;
280
 
  limit[1] = midy;
281
 
 
282
 
  current_dep[axe] += speed[axe];       /* We adjust the displacement */
283
 
 
284
 
  if (current_dep[axe] > (int) (limit[axe] * max_dep))
 
287
  st->move_limit[0] = st->midx;
 
288
  st->move_limit[1] = st->midy;
 
289
 
 
290
  st->move_current_dep[axe] += st->move_speed[axe];     /* We adjust the displacement */
 
291
 
 
292
  if (st->move_current_dep[axe] > (int) (st->move_limit[axe] * st->max_dep))
285
293
    {
286
 
      if (current_dep[axe] > limit[axe])
287
 
        current_dep[axe] = limit[axe];
288
 
      direction[axe] = -1;
 
294
      if (st->move_current_dep[axe] > st->move_limit[axe])
 
295
        st->move_current_dep[axe] = st->move_limit[axe];
 
296
      st->move_direction[axe] = -1;
289
297
    }                   /* This is when we reach the upper screen limit */
290
 
  if (current_dep[axe] < (int) (-limit[axe] * max_dep))
 
298
  if (st->move_current_dep[axe] < (int) (-st->move_limit[axe] * st->max_dep))
291
299
    {
292
 
      if (current_dep[axe] < -limit[axe])
293
 
        current_dep[axe] = -limit[axe];
294
 
      direction[axe] = 1;
 
300
      if (st->move_current_dep[axe] < -st->move_limit[axe])
 
301
        st->move_current_dep[axe] = -st->move_limit[axe];
 
302
      st->move_direction[axe] = 1;
295
303
    }                   /* This is when we reach the lower screen limit */
296
 
  if (direction[axe] == 1)      /* We adjust the speed */
297
 
    speed[axe] += 1;
298
 
  else if (direction[axe] == -1)
299
 
    speed[axe] -= 1;
300
 
 
301
 
  if (speed[axe] > MAX_DEP_SPEED)
302
 
    speed[axe] = MAX_DEP_SPEED;
303
 
  else if (speed[axe] < -MAX_DEP_SPEED)
304
 
    speed[axe] = -MAX_DEP_SPEED;
305
 
 
306
 
  if (move_p && !(random() % DIRECTION_CHANGE_RATE))
 
304
  if (st->move_direction[axe] == 1)     /* We adjust the speed */
 
305
    st->move_speed[axe] += 1;
 
306
  else if (st->move_direction[axe] == -1)
 
307
    st->move_speed[axe] -= 1;
 
308
 
 
309
  if (st->move_speed[axe] > MAX_DEP_SPEED)
 
310
    st->move_speed[axe] = MAX_DEP_SPEED;
 
311
  else if (st->move_speed[axe] < -MAX_DEP_SPEED)
 
312
    st->move_speed[axe] = -MAX_DEP_SPEED;
 
313
 
 
314
  if (st->move_p && !(random() % DIRECTION_CHANGE_RATE))
307
315
    {
308
316
      /* We change direction */
309
317
      change = random() & 1;
310
318
      if (change != 1)
311
319
        {
312
 
          if (direction[axe] == 0)
313
 
            direction[axe] = change - 1;        /* 0 becomes either 1 or -1 */
 
320
          if (st->move_direction[axe] == 0)
 
321
            st->move_direction[axe] = change - 1;       /* 0 becomes either 1 or -1 */
314
322
          else
315
 
            direction[axe] = 0;                 /* -1 or 1 become 0 */
 
323
            st->move_direction[axe] = 0;                        /* -1 or 1 become 0 */
316
324
        }
317
325
    }
318
 
  return (current_dep[axe]);
 
326
  return (st->move_current_dep[axe]);
319
327
}
320
328
 
321
329
static void
322
 
tick_rocks (int d)
 
330
tick_rocks (struct state *st, int d)
323
331
{
324
332
  int i;
325
333
 
326
 
  if (move_p)
 
334
  if (st->move_p)
327
335
    {
328
 
      dep_x = compute_move(0);
329
 
      dep_y = compute_move(1);
 
336
      st->dep_x = compute_move(st, 0);
 
337
      st->dep_y = compute_move(st, 1);
330
338
    }
331
339
 
332
 
  for (i = 0; i < nrocks; i++)
333
 
    rock_tick (&rocks [i], d);
 
340
  for (i = 0; i < st->nrocks; i++)
 
341
    rock_tick (st, &st->rocks [i], d);
334
342
}
335
343
 
336
344
 
337
 
static void
338
 
rocks_once (void)
 
345
static unsigned long
 
346
rocks_draw (Display *dpy, Window window, void *closure)
339
347
{
340
 
  static int current_delta = 0; /* observer Z rotation */
341
 
  static int window_tick = 50;
342
 
        static int  new_delta = 0;
343
 
        static int  dchange_tick = 0;
344
 
 
345
 
  if (window_tick++ == 50)
346
 
    {
347
 
      XWindowAttributes xgwa;
348
 
      XGetWindowAttributes (dpy, window, &xgwa);
349
 
      window_tick = 0;
350
 
      width = xgwa.width;
351
 
      height = xgwa.height;
352
 
      midx = width/2;
353
 
      midy = height/2;
354
 
    }
355
 
 
356
 
  if (current_delta != new_delta)
357
 
    {
358
 
      if (dchange_tick++ == 5)
 
348
  struct state *st = (struct state *) closure;
 
349
  if (st->current_delta != st->new_delta)
 
350
    {
 
351
      if (st->dchange_tick++ == 5)
359
352
        {
360
 
          dchange_tick = 0;
361
 
          if (current_delta < new_delta)
362
 
            current_delta++;
 
353
          st->dchange_tick = 0;
 
354
          if (st->current_delta < st->new_delta)
 
355
            st->current_delta++;
363
356
          else
364
 
            current_delta--;
 
357
            st->current_delta--;
365
358
        }
366
359
    }
367
360
  else
368
361
    {
369
362
      if (! (random() % 50))
370
363
        {
371
 
          new_delta = ((random() % 11) - 5);
 
364
          st->new_delta = ((random() % 11) - 5);
372
365
          if (! (random() % 10))
373
 
            new_delta *= 5;
 
366
            st->new_delta *= 5;
374
367
        }
375
368
    }
376
 
  tick_rocks (current_delta);
 
369
  tick_rocks (st, st->current_delta);
 
370
 
 
371
  return st->delay;
377
372
}
378
373
 
379
 
static void
380
 
init_rocks (Display *d, Window w)
 
374
static void *
 
375
rocks_init (Display *d, Window w)
381
376
{
 
377
  struct state *st = (struct state *) calloc (1, sizeof(*st));
382
378
  int i;
383
379
  XGCValues gcv;
384
380
  Colormap cmap;
385
381
  XWindowAttributes xgwa;
386
382
  unsigned int bg;
387
 
  dpy = d;
388
 
  window = w;
389
 
  XGetWindowAttributes (dpy, window, &xgwa);
 
383
  st->dpy = d;
 
384
  st->window = w;
 
385
  XGetWindowAttributes (st->dpy, st->window, &xgwa);
 
386
 
 
387
  st->width = xgwa.width;
 
388
  st->height = xgwa.height;
 
389
  st->midx = st->width/2;
 
390
  st->midy = st->height/2;
 
391
 
390
392
  cmap = xgwa.colormap;
391
 
  delay = get_integer_resource ("delay", "Integer");
392
 
  if (delay < 0) delay = 0;
393
 
  speed = get_integer_resource ("speed", "Integer");
394
 
  if (speed < 1) speed = 1;
395
 
  if (speed > 100) speed = 100;
396
 
  rotate_p = get_boolean_resource ("rotate", "Boolean");
397
 
  move_p = get_boolean_resource ("move", "Boolean");
 
393
  st->delay = get_integer_resource (st->dpy, "delay", "Integer");
 
394
  if (st->delay < 0) st->delay = 0;
 
395
  st->speed = get_integer_resource (st->dpy, "speed", "Integer");
 
396
  if (st->speed < 1) st->speed = 1;
 
397
  if (st->speed > 100) st->speed = 100;
 
398
  st->rotate_p = get_boolean_resource (st->dpy, "rotate", "Boolean");
 
399
  st->move_p = get_boolean_resource (st->dpy, "move", "Boolean");
398
400
  if (mono_p)
399
 
    ncolors = 2;
 
401
    st->ncolors = 2;
400
402
  else
401
 
    ncolors = get_integer_resource ("colors", "Colors");
 
403
    st->ncolors = get_integer_resource (st->dpy, "colors", "Colors");
402
404
 
403
 
  if (ncolors < 2)
 
405
  if (st->ncolors < 2)
404
406
    {
405
 
      ncolors = 2;
 
407
      st->ncolors = 2;
406
408
      mono_p = True;
407
409
  }
408
410
 
409
 
  colors = (XColor *) malloc(ncolors * sizeof(*colors));
410
 
  draw_gcs = (GC *) malloc(ncolors * sizeof(*draw_gcs));
411
 
 
412
 
  bg = get_pixel_resource ("background", "Background", dpy, cmap);
413
 
  colors[0].pixel = bg;
414
 
  colors[0].flags = DoRed|DoGreen|DoBlue;
415
 
  XQueryColor(dpy, cmap, &colors[0]);
416
 
 
417
 
  ncolors--;
418
 
  make_random_colormap(dpy, xgwa.visual, cmap, colors+1, &ncolors, True,
 
411
  st->colors = (XColor *) malloc(st->ncolors * sizeof(*st->colors));
 
412
  st->draw_gcs = (GC *) malloc(st->ncolors * sizeof(*st->draw_gcs));
 
413
 
 
414
  bg = get_pixel_resource (st->dpy, cmap, "background", "Background");
 
415
  st->colors[0].pixel = bg;
 
416
  st->colors[0].flags = DoRed|DoGreen|DoBlue;
 
417
  XQueryColor(st->dpy, cmap, &st->colors[0]);
 
418
 
 
419
  st->ncolors--;
 
420
  make_random_colormap(st->dpy, xgwa.visual, cmap, st->colors+1, &st->ncolors, True,
419
421
                       True, 0, True);
420
 
  ncolors++;
 
422
  st->ncolors++;
421
423
 
422
 
  if (ncolors < 2)
 
424
  if (st->ncolors < 2)
423
425
    {
424
 
      ncolors = 2;
 
426
      st->ncolors = 2;
425
427
      mono_p = True;
426
428
  }
427
429
 
428
430
  if (mono_p)
429
431
    {
430
 
      unsigned int fg = get_pixel_resource("foreground", "Foreground",
431
 
                                           dpy, cmap);
432
 
      colors[1].pixel = fg;
433
 
      colors[1].flags = DoRed|DoGreen|DoBlue;
434
 
      XQueryColor(dpy, cmap, &colors[1]);
 
432
      unsigned int fg = get_pixel_resource(st->dpy, cmap, "foreground", "Foreground");
 
433
      st->colors[1].pixel = fg;
 
434
      st->colors[1].flags = DoRed|DoGreen|DoBlue;
 
435
      XQueryColor(st->dpy, cmap, &st->colors[1]);
435
436
      gcv.foreground = fg;
436
437
      gcv.background = bg;
437
 
      draw_gcs[0] = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
438
 
      draw_gcs[1] = draw_gcs[0];
 
438
      st->draw_gcs[0] = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
 
439
      st->draw_gcs[1] = st->draw_gcs[0];
439
440
    }
440
441
  else
441
 
    for( i = 0; i < ncolors; i++ )
 
442
    for( i = 0; i < st->ncolors; i++ )
442
443
      {
443
 
        gcv.foreground = colors[i].pixel;
 
444
        gcv.foreground = st->colors[i].pixel;
444
445
        gcv.background = bg;
445
 
        draw_gcs[i] = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
 
446
        st->draw_gcs[i] = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
446
447
      }
447
448
 
448
449
  gcv.foreground = bg;
449
 
  erase_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
 
450
  st->erase_gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
450
451
 
451
 
  max_dep = (move_p ? MAX_DEP : 0);
 
452
  st->max_dep = (st->move_p ? MAX_DEP : 0);
452
453
 
453
454
  for (i = 0; i < SIN_RESOLUTION; i++)
454
455
    {
455
 
      sins [i] = sin ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
456
 
      coss [i] = cos ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
 
456
      st->sins [i] = sin ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
 
457
      st->coss [i] = cos ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
457
458
    }
458
459
  /* we actually only need i/speed of these, but wtf */
459
 
  for (i = 1; i < (sizeof (depths) / sizeof (depths[0])); i++)
460
 
    depths [i] = atan (((double) 0.5) / (((double) i) / DEPTH_SCALE));
461
 
  depths [0] = M_PI/2; /* avoid division by 0 */
 
460
  for (i = 1; i < (sizeof (st->depths) / sizeof (st->depths[0])); i++)
 
461
    st->depths [i] = atan (((double) 0.5) / (((double) i) / DEPTH_SCALE));
 
462
  st->depths [0] = M_PI/2; /* avoid division by 0 */
462
463
 
463
 
  threed = get_boolean_resource("use3d", "Boolean");
464
 
  if (threed)
 
464
  st->threed = get_boolean_resource(st->dpy, "use3d", "Boolean");
 
465
  if (st->threed)
465
466
    {
466
467
      gcv.background = bg;
467
 
      gcv.foreground = get_pixel_resource ("left3d", "Foreground", dpy, cmap);
468
 
      threed_left_gc = XCreateGC (dpy, window, GCForeground|GCBackground,&gcv);
469
 
      gcv.foreground = get_pixel_resource ("right3d", "Foreground", dpy, cmap);
470
 
      threed_right_gc = XCreateGC (dpy, window,GCForeground|GCBackground,&gcv);
471
 
      threed_delta = get_float_resource("delta3d", "Integer");
 
468
      gcv.foreground = get_pixel_resource (st->dpy, cmap, "left3d", "Foreground");
 
469
      st->threed_left_gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground,&gcv);
 
470
      gcv.foreground = get_pixel_resource (st->dpy, cmap, "right3d", "Foreground");
 
471
      st->threed_right_gc = XCreateGC (st->dpy, st->window,GCForeground|GCBackground,&gcv);
 
472
      st->threed_delta = get_float_resource(st->dpy, "delta3d", "Integer");
472
473
    }
473
474
 
474
475
  /* don't want any exposure events from XCopyPlane */
475
 
  for( i = 0; i < ncolors; i++)
476
 
    XSetGraphicsExposures (dpy, draw_gcs[i], False);
477
 
  XSetGraphicsExposures (dpy, erase_gc, False);
478
 
 
479
 
  nrocks = get_integer_resource ("count", "Count");
480
 
  if (nrocks < 1) nrocks = 1;
481
 
  rocks = (struct rock *) calloc (nrocks, sizeof (struct rock));
482
 
  init_pixmaps (dpy, window);
483
 
  XClearWindow (dpy, window);
484
 
}
485
 
 
 
476
  for( i = 0; i < st->ncolors; i++)
 
477
    XSetGraphicsExposures (st->dpy, st->draw_gcs[i], False);
 
478
  XSetGraphicsExposures (st->dpy, st->erase_gc, False);
 
479
 
 
480
  st->nrocks = get_integer_resource (st->dpy, "count", "Count");
 
481
  if (st->nrocks < 1) st->nrocks = 1;
 
482
  st->rocks = (struct rock *) calloc (st->nrocks, sizeof (struct rock));
 
483
  init_pixmaps (st);
 
484
  XClearWindow (st->dpy, st->window);
 
485
  return st;
 
486
}
 
487
 
 
488
static void
 
489
rocks_reshape (Display *dpy, Window window, void *closure, 
 
490
                 unsigned int w, unsigned int h)
 
491
{
 
492
  struct state *st = (struct state *) closure;
 
493
  st->width = w;
 
494
  st->height = h;
 
495
  st->midx = st->width/2;
 
496
  st->midy = st->height/2;
 
497
}
 
498
 
 
499
static Bool
 
500
rocks_event (Display *dpy, Window window, void *closure, XEvent *event)
 
501
{
 
502
  return False;
 
503
}
 
504
 
 
505
static void
 
506
rocks_free (Display *dpy, Window window, void *closure)
 
507
{
 
508
}
486
509
 
487
510
 
488
 
char *progclass = "Rocks";
489
511
 
490
 
char *defaults [] = {
 
512
static const char *rocks_defaults [] = {
491
513
  ".background: Black",
492
514
  ".foreground: #E9967A",
493
515
  "*colors:     5",
503
525
  0
504
526
};
505
527
 
506
 
XrmOptionDescRec options [] = {
 
528
static XrmOptionDescRec rocks_options [] = {
507
529
  { "-count",           ".count",       XrmoptionSepArg, 0 },
508
530
  { "-rotate",          ".rotate",      XrmoptionNoArg,  "true" },
509
 
  { "-norotate",        ".rotate",      XrmoptionNoArg,  "false" },
 
531
  { "-no-rotate",        ".rotate",      XrmoptionNoArg,  "false" },
510
532
  { "-move",            ".move",        XrmoptionNoArg,  "true" },
511
 
  { "-nomove",          ".move",        XrmoptionNoArg,  "false" },
 
533
  { "-no-move",          ".move",        XrmoptionNoArg,  "false" },
512
534
  { "-delay",           ".delay",       XrmoptionSepArg, 0 },
513
535
  { "-speed",           ".speed",       XrmoptionSepArg, 0 },
514
536
  {"-3d",               ".use3d",       XrmoptionNoArg, "True"},
520
542
  { 0, 0, 0, 0 }
521
543
};
522
544
 
523
 
void
524
 
screenhack (Display *dpy, Window window)
525
 
{
526
 
  init_rocks (dpy, window);
527
 
  while (1)
528
 
    {
529
 
      rocks_once ();
530
 
      XSync (dpy, False);
531
 
      screenhack_handle_events (dpy);
532
 
      if (delay) usleep (delay);
533
 
    }
534
 
}
 
545
XSCREENSAVER_MODULE ("Rocks", rocks)