source: trunk/third/xscreensaver/hacks/truchet.c @ 12203

Revision 12203, 13.3 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12202, which included commits to RCS files with non-trunk default branches.
Line 
1/* truchet --- curved and straight tilings
2 * Copyright (c) 1998 Adrian Likins <adrian@gimp.org>
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/* This screensaver draws two varieties of truchet patterns, a curved one and
14   a straight one. There are lots and lots of command line options to play
15   with.
16
17   If your running remotely or on a slow machine or slow xserver, some of the
18   settings will be way too much. The default settings should be okay though.
19
20   This screensaver doesnt use anything bizarre or special at all, just a few
21   standard xlib calls.
22
23   A few suggested commandline combos..All these were tested on a k6-200
24   running XFree86 3.3 on a ark2000, so your mileage may vary...
25
26      truchet -delay 200 -no-curves
27      truchet -delay 500 -no-curves -square -no-erase
28      truchet -delay 500 -no-erase -square -erase-count 5
29      truchet -scroll
30      truchet -scroll -no-erase -anim-step-size 9
31      truchet -delay 200 -no-angles -min-width 36 -max-width 36
32      truchet -delay 200 -no-curves -min-width 12 -max-width 12
33      truchet -delay 200 -no-curves -min-width 36 -max-width 36 -no-erase
34      truchet -delay 100 -min-width 256 -max-width 512 -no-erase \
35              -min-linewidth 96 -root
36      truchet -min-width 64 -max-width 128 -no-erase -max-linewidth 4 \
37              -root -no-angles
38      truchet -min-width 64 -max-width 128 -no-erase -max-linewidth 4 \
39              -root -no-curves -delay 25
40 */
41
42#include "screenhack.h"
43
44#define MAXRATIO 2
45
46
47char *progclass="Truchet";
48
49char *defaults [] = {
50  "*minWidth:                 40",
51  "*minHeight:                40",
52  "*max-Width:                150",
53  "*max-Height:               150",
54  "*maxLineWidth:             25",
55  "*minLineWidth:             2",
56  "*erase:                    True",
57  "*eraseCount:               25",       
58  "*square:                   True",
59  "*delay:                    1000",
60  "*curves:                   True",
61  "*angles:                   True",
62  "*angles-and-curves:        True",
63  "*scroll:                   False",
64  "*scroll-overlap:           400",
65  "*anim-delay:               100",
66  "*anim-step-size:           3",
67  "*randomize:                false",
68   0
69};
70
71/* options passed to this program */
72XrmOptionDescRec options [] = {
73  { "-min-width",      ".minWidth",       XrmoptionSepArg, 0 },
74  { "-max-height",     ".max-Height",      XrmoptionSepArg, 0 },
75  { "-max-width",      ".max-Width",       XrmoptionSepArg, 0 },
76  { "-min-height",     ".minHeight",      XrmoptionSepArg, 0 },
77  { "-max-linewidth",  ".maxLineWidth",   XrmoptionSepArg, 0 },
78  { "-min-linewidth",  ".minLineWidth",   XrmoptionSepArg, 0 },
79  { "-erase",          ".erase",          XrmoptionNoArg, "True" },
80  { "-no-erase",       ".erase",          XrmoptionNoArg, "False" },
81  { "-erase-count",    ".eraseCount",     XrmoptionSepArg, 0 },
82  { "-square",         ".square",         XrmoptionNoArg, "True" },
83  { "-not-square",     ".square",         XrmoptionNoArg, "False" },
84  { "-curves",         ".curves",         XrmoptionNoArg, "True" },
85  { "-angles",         ".angles",         XrmoptionNoArg,  "True" },
86  { "-no-angles",      ".angles",         XrmoptionNoArg,  "False" },
87  { "-no-curves",      ".curves",         XrmoptionNoArg, "False" },
88  { "-delay",          ".delay",          XrmoptionSepArg, 0 },
89  { "-scroll",         ".scroll",         XrmoptionNoArg, "True" },
90  { "-scroll-overlap", ".scroll-overlap", XrmoptionSepArg, 0 },
91  { "-anim-delay",     ".anim-delay",     XrmoptionSepArg, 0 },
92  { "-anim-step-size",  ".anim-step-size", XrmoptionSepArg, 0 },
93  { "-randomize",       ".randomize",     XrmoptionNoArg, "True" },
94  { 0, 0, 0, 0 }
95};
96
97static GC agc, bgc;
98static int linewidth;
99static int width, height;
100static XWindowAttributes xgwa;
101static Pixmap frame;
102static int overlap;
103
104static void draw_truchet(Display *disp, Window win);
105static void draw_angles(Display *disp, Window win);
106static void scroll_area(Display *disp, Window win, int delay, int step_size);
107
108static void draw_angles(Display *disp, Window win)
109{
110  int countX;
111  int countY;
112
113  countX=0;
114  countY=0;
115 
116  while((xgwa.height+overlap) > countY*height)
117        {
118          while((xgwa.width+overlap) > countX*width)
119            {
120              if(random()%2)
121              {
122                /* block1 */
123                XDrawLine(disp,frame,agc,
124                          (countX*width)+(width/2),
125                          (countY*height),
126                          (countX*width)+(width),
127                          (countY*height)+(height/2));
128                XDrawLine(disp,frame,agc,
129                          (countX*width),
130                          (countY*height)+(height/2),
131                          (countX*width)+(width/2),
132                          (countY*height)+(height));
133              }
134            else
135              {
136                /* block 2 */
137                XDrawLine(disp,frame,agc,
138                          (countX*width)+(width/2),
139                          (countY*height),
140                          (countX*width),
141                          (countY*height)+(height/2));
142                XDrawLine(disp,frame,agc,
143                          (countX*width)+(width),
144                          (countY*height)+(height/2),
145                          (countX*width)+(width/2),
146                          (countY*height)+(height));
147              }
148              countX++;
149            }
150          countY++;
151          countX=0;
152        }
153
154  countX=0;
155  countY=0;
156}
157 
158
159static void draw_truchet(Display *disp, Window win)
160{
161  int countX;
162  int countY;
163
164
165  countX=0;
166  countY=0;
167
168
169  while(xgwa.height+overlap > countY*height)
170        {
171          while(xgwa.width+overlap > countX*width)
172            {
173              if(random()%2)
174              {
175                /* block1 */
176                XDrawArc(disp, frame, agc,
177                         ((countX*width)-(width/2)),
178                         ((countY*height)-(height/2)),
179                         width,
180                         height,
181                         0, -5760);
182                XDrawArc(disp,frame, agc,
183                         ((countX*width)+(width/2)),
184                         ((countY*height)+(height/2)),
185                         width,
186                         height,
187                         11520,
188                         -5760);
189              }
190            else
191              {
192                /* block 2 */
193                XDrawArc(disp,frame,agc,
194                         ((countX*width)+(width/2)),
195                         ((countY*height)-(height/2)),
196                         width,
197                         height,
198                         17280,
199                         -5760);
200                XDrawArc(disp,frame,agc,
201                         ((countX*width)-(width/2)),
202                         ((countY*height)+(height/2)),
203                         width,
204                         height,
205                         0,
206                         5760);
207              }
208              countX++;
209            }
210          countY++;
211          countX=0;
212        }
213   countX=0;
214   countY=0;
215}
216/* this is the function called for your screensaver */
217void screenhack(Display *disp, Window win)
218{
219  XGCValues gcv;
220  int countX;
221  int countY;
222  int maxlinewidth;
223  int minlinewidth;
224  int minwidth;
225  int minheight;
226  int max_height;
227  int max_width;
228  int delay;
229  int count;
230  int anim_delay;
231  int anim_step_size;
232
233
234  Colormap cmap;
235  XColor fgc;
236  Bool curves;
237  Bool square;
238  Bool angles;
239  Bool erase;
240  Bool eraseCount;
241  Bool scroll;
242 
243
244  maxlinewidth = get_integer_resource ("maxLineWidth", "Integer");
245  minlinewidth = get_integer_resource ("minLineWidth", "Integer");
246  minwidth = get_integer_resource ("minWidth", "Integer");
247  minheight = get_integer_resource ("minHeight", "Integer");
248  max_width = get_integer_resource ("max-Width", "Integer");
249  max_height = get_integer_resource ("max-Height", "Integer" );
250  delay = get_integer_resource ("delay", "Integer");
251  eraseCount = get_integer_resource ("eraseCount", "Integer");
252  square = get_boolean_resource ("square", "Boolean");
253  curves = get_boolean_resource ("curves", "Boolean");
254  angles = get_boolean_resource ("angles", "Boolean");
255  erase = get_boolean_resource ("erase", "Boolean");
256  scroll = get_boolean_resource ("scroll", "Boolean");
257  overlap = get_integer_resource ("scroll-overlap", "Integer");
258  anim_delay = get_integer_resource ("anim-delay", "Integer");
259  anim_step_size = get_integer_resource ("anim-step-size", "Integer");
260
261  if (get_boolean_resource("randomize", "Randomize"))
262    {
263      int i = (random() % 12);
264      switch(i) {
265      case 0:
266        break;
267      case 1:
268        curves = False;
269        break;
270      case 2:
271        curves = False;
272        square = True;
273        erase = False;
274        break;
275      case 3:
276        square = True;
277        erase = False;
278        eraseCount = 5;
279        break;
280      case 4:
281        scroll = True;
282        break;
283      case 5:
284        scroll = True;
285        erase = False;
286        anim_step_size = 9;
287        break;
288      case 6:
289        angles = False;
290        minwidth = max_width = 36;
291        break;
292      case 7:
293        curves = False;
294        minwidth = max_width = 12;
295        break;
296      case 8:
297        curves = False;
298        erase = False;
299        minwidth = max_width = 36;
300        break;
301      case 9:
302        erase = False;
303        minwidth = 256;
304        max_width = 512;
305        minlinewidth = 96;
306        break;
307      case 10:
308        angles = False;
309        minwidth = 64;
310        max_width = 128;
311        maxlinewidth = 4;
312        break;
313      case 11:
314        curves = False;
315        minwidth = 64;
316        max_width = 128;
317        maxlinewidth = 4;
318        break;
319      default:
320        abort();
321        break;
322      }
323    }
324
325  XGetWindowAttributes (disp, win, &xgwa);
326  gcv.foreground = BlackPixel(disp,0);
327  gcv.background = WhitePixel(disp,0);
328  gcv.line_width = 25;
329  cmap = xgwa.colormap;
330
331  gcv.foreground = get_pixel_resource("background", "Background",
332                                      disp, xgwa.colormap);
333
334  bgc = XCreateGC (disp, win, GCForeground, &gcv);
335  agc = XCreateGC(disp, win, GCForeground, &gcv);
336
337  XFillRectangle(disp, win, bgc, 0, 0, xgwa.width, xgwa.height);
338
339 
340  width=60;
341  height=60;
342  linewidth=1;
343  countX=0;
344  countY=0;
345  count=0;
346  XSetForeground(disp, agc, gcv.background);
347 
348 
349  frame = XCreatePixmap(disp,win, xgwa.width+overlap, xgwa.height+overlap, xgwa.depth);
350 
351
352  while(1)
353    {
354      if (!mono_p)
355        {
356        /* XXX there are probably bugs with this. */
357        /* could be...I just borrowed this code from munch */
358
359        fgc.red = random() % 65535;
360        fgc.green = random() % 65535;
361        fgc.blue = random() % 65535;
362       
363        if (XAllocColor(disp, cmap, &fgc))
364          {
365            XSetForeground(disp, agc, fgc.pixel);
366          }
367        else
368          {
369            /* use white if all else fails  */
370            XSetForeground(disp,agc, gcv.background);
371          }
372      }
373
374     
375     
376
377      /* generate a random line width */
378      linewidth=(random()% maxlinewidth);
379
380      /* check for lower bound */
381      if(linewidth < minlinewidth)
382        linewidth = minlinewidth;
383
384      /* try to get an odd linewidth as it seem to work a little better */
385      if(linewidth%2)
386        linewidth++;
387
388      /* grab a random height and width */
389      width=(random()%max_width);
390      height=(random()%max_height);
391
392      /* make sure we dont get a 0 height or width */
393      if(width == 0 || height == 0)
394        {
395          height=max_height;
396          width=max_width;
397        }
398
399
400      /* check for min height and width */
401      if(height < minheight)
402        {
403          height=minheight;
404        }
405      if(width < minwidth)
406        {
407          width=minwidth;
408        }
409
410      /* if tiles need to be square, fix it... */
411      if(square)
412        height=width;
413
414      /* check for sane aspect ratios */
415      if((width/height) > MAXRATIO)
416        height=width;
417      if((height/width) > MAXRATIO)
418        width=height;
419     
420      /* to avoid linewidths of zero */
421      if(linewidth == 0 || linewidth < minlinewidth)
422        linewidth = minlinewidth;
423
424      /* try to keep from getting line widths that would be too big */
425      if(linewidth > 0 && linewidth >= (height/5))
426        linewidth = height/5;
427 
428      XSetLineAttributes(disp, agc, linewidth, LineSolid, CapRound, JoinRound);
429
430      if(erase || (count >= eraseCount))
431        {
432          /*  XClearWindow(disp,win); */
433          XFillRectangle(disp, frame, bgc, 0, 0, xgwa.width+overlap, xgwa.height+overlap);
434          count=0;
435        }
436           
437      if(!scroll)
438        overlap=0;
439           
440      /* do the fun stuff...*/
441      if(curves && angles)
442        {
443          if(random()%2)
444            draw_truchet(disp,win);
445          else
446            draw_angles(disp,win);
447        }
448      else if(curves && !angles)
449        draw_truchet(disp,win);
450      else if(!curves && angles)
451        draw_angles(disp,win);
452
453   
454      XCopyArea(disp,frame,win,agc,0,0,xgwa.width,xgwa.height,0,0);
455      if(scroll)
456        {
457          scroll_area(disp,win,anim_delay,anim_step_size);
458          delay = 0;
459        }
460      else
461        XSync(disp, False);
462     
463      screenhack_handle_events (disp);
464
465      /* the delay to try to minimize seizures */
466      usleep((delay*1000));
467      count++;
468     
469    }
470
471}
472
473static void scroll_area(Display *disp, Window win, int delay, int step_size)
474{
475
476  int scrollcount_x;
477  int scrollcount_y;
478  int offset;
479  int scroll;
480  /* note local delay overirdes static delay cause... */
481
482
483  scrollcount_x=0;
484  scrollcount_y=0;
485
486  offset=overlap/2;
487  scroll=overlap/4;
488 
489      /* if anyone knows a good way to generate a more random scrolling motion... */
490  while(scrollcount_x <= scroll)
491    {
492      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
493      XSync(disp, False);
494      scrollcount_x=scrollcount_x+step_size;
495      scrollcount_y=scrollcount_y+step_size;
496      usleep(1000*delay);
497    }
498  while(scrollcount_x >= 0)
499    {
500      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
501      XSync(disp, False);
502      scrollcount_y=scrollcount_y+step_size;
503      scrollcount_x=scrollcount_x-step_size;
504      usleep(1000*delay);
505    }
506  while(scrollcount_y >= scroll)
507    {
508      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
509      XSync(disp, False);
510      scrollcount_x=scrollcount_x-step_size;
511      scrollcount_y=scrollcount_y-step_size;
512      usleep(1000*delay);
513    }
514  while(scrollcount_y > 0)
515    {
516      XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
517      XSync(disp, False);
518      scrollcount_y=scrollcount_y-step_size;
519      scrollcount_x=scrollcount_x+step_size;
520      usleep(1000*delay);
521    }
522 
523  XSync(disp, False);
524  scrollcount_x=0;
525  scrollcount_y=0;
526 
527}
Note: See TracBrowser for help on using the repository browser.