1 /* truchet --- curved and straight tilings
2 * Copyright (c) 1998 Adrian Likins <adrian@gimp.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
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
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.
20 This screensaver doesnt use anything bizarre or special at all, just a few
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...
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
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 \
38 truchet -min-width 64 -max-width 128 -no-erase -max-linewidth 4 \
39 -root -no-curves -delay 25
42 #include "screenhack.h"
47 char *progclass="Truchet";
62 "*angles-and-curves: True",
64 "*scroll-overlap: 400",
71 /* options passed to this program */
72 XrmOptionDescRec 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" },
99 static int width, height;
100 static XWindowAttributes xgwa;
104 static void draw_truchet(Display *disp, Window win);
105 static void draw_angles(Display *disp, Window win);
106 static void scroll_area(Display *disp, Window win, int delay, int step_size);
108 static void draw_angles(Display *disp, Window win)
116 while((xgwa.height+overlap) > countY*height)
118 while((xgwa.width+overlap) > countX*width)
123 XDrawLine(disp,frame,agc,
124 (countX*width)+(width/2),
126 (countX*width)+(width),
127 (countY*height)+(height/2));
128 XDrawLine(disp,frame,agc,
130 (countY*height)+(height/2),
131 (countX*width)+(width/2),
132 (countY*height)+(height));
137 XDrawLine(disp,frame,agc,
138 (countX*width)+(width/2),
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));
159 static void draw_truchet(Display *disp, Window win)
169 while(xgwa.height+overlap > countY*height)
171 while(xgwa.width+overlap > countX*width)
176 XDrawArc(disp, frame, agc,
177 ((countX*width)-(width/2)),
178 ((countY*height)-(height/2)),
182 XDrawArc(disp,frame, agc,
183 ((countX*width)+(width/2)),
184 ((countY*height)+(height/2)),
193 XDrawArc(disp,frame,agc,
194 ((countX*width)+(width/2)),
195 ((countY*height)-(height/2)),
200 XDrawArc(disp,frame,agc,
201 ((countX*width)-(width/2)),
202 ((countY*height)+(height/2)),
216 /* this is the function called for your screensaver */
217 void screenhack(Display *disp, Window win)
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");
261 if (get_boolean_resource("randomize", "Randomize"))
263 int i = (random() % 12);
290 minwidth = max_width = 36;
294 minwidth = max_width = 12;
299 minwidth = max_width = 36;
325 XGetWindowAttributes (disp, win, &xgwa);
326 gcv.foreground = BlackPixel(disp,0);
327 gcv.background = WhitePixel(disp,0);
329 cmap = xgwa.colormap;
331 gcv.foreground = get_pixel_resource("background", "Background",
332 disp, xgwa.colormap);
334 bgc = XCreateGC (disp, win, GCForeground, &gcv);
335 agc = XCreateGC(disp, win, GCForeground, &gcv);
337 XFillRectangle(disp, win, bgc, 0, 0, xgwa.width, xgwa.height);
346 XSetForeground(disp, agc, gcv.background);
349 frame = XCreatePixmap(disp,win, xgwa.width+overlap, xgwa.height+overlap, xgwa.depth);
356 /* XXX there are probably bugs with this. */
357 /* could be...I just borrowed this code from munch */
359 fgc.red = random() % 65535;
360 fgc.green = random() % 65535;
361 fgc.blue = random() % 65535;
363 if (XAllocColor(disp, cmap, &fgc))
365 XSetForeground(disp, agc, fgc.pixel);
369 /* use white if all else fails */
370 XSetForeground(disp,agc, gcv.background);
377 /* generate a random line width */
378 linewidth=(random()% maxlinewidth);
380 /* check for lower bound */
381 if(linewidth < minlinewidth)
382 linewidth = minlinewidth;
384 /* try to get an odd linewidth as it seem to work a little better */
388 /* grab a random height and width */
389 width=(random()%max_width);
390 height=(random()%max_height);
392 /* make sure we dont get a 0 height or width */
393 if(width == 0 || height == 0)
400 /* check for min height and width */
401 if(height < minheight)
410 /* if tiles need to be square, fix it... */
414 /* check for sane aspect ratios */
415 if((width/height) > MAXRATIO)
417 if((height/width) > MAXRATIO)
420 /* to avoid linewidths of zero */
421 if(linewidth == 0 || linewidth < minlinewidth)
422 linewidth = minlinewidth;
424 /* try to keep from getting line widths that would be too big */
425 if(linewidth > 0 && linewidth >= (height/5))
426 linewidth = height/5;
428 XSetLineAttributes(disp, agc, linewidth, LineSolid, CapRound, JoinRound);
430 if(erase || (count >= eraseCount))
432 /* XClearWindow(disp,win); */
433 XFillRectangle(disp, frame, bgc, 0, 0, xgwa.width+overlap, xgwa.height+overlap);
440 /* do the fun stuff...*/
444 draw_truchet(disp,win);
446 draw_angles(disp,win);
448 else if(curves && !angles)
449 draw_truchet(disp,win);
450 else if(!curves && angles)
451 draw_angles(disp,win);
454 XCopyArea(disp,frame,win,agc,0,0,xgwa.width,xgwa.height,0,0);
457 scroll_area(disp,win,anim_delay,anim_step_size);
463 screenhack_handle_events (disp);
465 /* the delay to try to minimize seizures */
466 usleep((delay*1000));
473 static void scroll_area(Display *disp, Window win, int delay, int step_size)
480 /* note local delay overirdes static delay cause... */
489 /* if anyone knows a good way to generate a more random scrolling motion... */
490 while(scrollcount_x <= scroll)
492 XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
494 scrollcount_x=scrollcount_x+step_size;
495 scrollcount_y=scrollcount_y+step_size;
498 while(scrollcount_x >= 0)
500 XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
502 scrollcount_y=scrollcount_y+step_size;
503 scrollcount_x=scrollcount_x-step_size;
506 while(scrollcount_y >= scroll)
508 XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
510 scrollcount_x=scrollcount_x-step_size;
511 scrollcount_y=scrollcount_y-step_size;
514 while(scrollcount_y > 0)
516 XCopyArea(disp, frame, win, agc,scrollcount_x+offset,scrollcount_y+offset, xgwa.width, xgwa.height, 0,0);
518 scrollcount_y=scrollcount_y-step_size;
519 scrollcount_x=scrollcount_x+step_size;