1 /* fuzzyflakes, Copyright (c) 2004
2 * Barry Dmytro <badcherry@mailc.net>
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 #define PI 3.14159265359
17 typedef struct _flake_var
27 { /* Struct containing the atrributes to our flakes */
32 unsigned long BordColor;
33 unsigned long ForeColor;
34 unsigned long BackColor;
39 FlakeVariable *** Flakes; /* a dynamic array containing positions of all the flakes */
41 unsigned long GCFlags;
45 XWindowAttributes XGWA;
54 InitFuzzyFlakes (Display *dpy, Window window)
57 XWindowAttributes xgwa;
60 XGetWindowAttributes (dpy, window, &xgwa);
63 Flake.DB.b = Flake.DB.ba = Flake.DB.bb = 0;
64 Flake.DB.dbuf = get_boolean_resource ("doubleBuffer", "Boolean");
69 Flake.DB.ba = XCreatePixmap (dpy, window, xgwa.width, xgwa.height,xgwa.depth);
70 Flake.DB.bb = XCreatePixmap (dpy, window, xgwa.width, xgwa.height,xgwa.depth);
71 Flake.DB.b = Flake.DB.ba;
79 Flake.DisplayVar = dpy;
80 Flake.WindowVar = window;
81 Flake.Arms = get_integer_resource ("arms", "Integer");
82 Flake.Thickness = get_integer_resource ("thickness", "Integer");
83 Flake.BorderThickness = get_integer_resource ("bthickness", "Integer");
84 Flake.Radius = get_integer_resource ("radius", "Integer");
85 Flake.BordColor = get_pixel_resource ("border","Border",dpy,cmap);
86 Flake.ForeColor = get_pixel_resource ("foreground","Foreground",dpy,cmap);
87 Flake.BackColor = get_pixel_resource ("background","Background",dpy,cmap);
88 Flake.Density = get_integer_resource ("density", "Integer");
89 Flake.Layers = get_integer_resource ("layers", "Integer");
90 Flake.FallingSpeed = get_integer_resource ("fallingspeed", "Integer");
91 Flake.Delay = get_integer_resource ("delay", "Integer");
93 if (Flake.Delay < 0) Flake.Delay = 0;
95 Flake.GCValues.foreground = get_pixel_resource("foreground","Foreground", dpy, cmap);
96 Flake.GCValues.background = get_pixel_resource("background","Background", dpy, cmap);
97 Flake.GCValues.line_width = Flake.Thickness;
98 Flake.GCValues.line_style = LineSolid;
99 Flake.GCValues.cap_style = CapProjecting;
100 Flake.GCValues.join_style = JoinMiter;
101 Flake.GCFlags |= (GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle);
103 Flake.GCVar = XCreateGC (Flake.DisplayVar, Flake.WindowVar, Flake.GCFlags, &Flake.GCValues);
105 Flake.Density = Flake.XGWA.width/200*Flake.Density;
106 Flake.Flakes = malloc(sizeof(FlakeVariable**)*Flake.Layers);
107 for(i=1;i<=Flake.Layers;i++)
109 Flake.Flakes[i-1] = malloc(sizeof(FlakeVariable*)*Flake.Density);
110 for(j=0;j<Flake.Density;j++)
112 Flake.Flakes[i-1][j] = malloc(sizeof(FlakeVariable));
113 Flake.Flakes[i-1][j]->XPos = random()%Flake.XGWA.width;
114 Flake.Flakes[i-1][j]->YPos = random()%Flake.XGWA.height;
115 Flake.Flakes[i-1][j]->Angle = random()%360*(PI/180);
116 Flake.Flakes[i-1][j]->Ticks = random()%360;
117 Flake.Flakes[i-1][j]->XOffset = random()%Flake.XGWA.height;
123 FuzzyFlakesMove(void)
126 for(i=1;i<=Flake.Layers;i++)
128 for(j=0;j<Flake.Density;j++)
130 FlakeVariable * FlakeVar;
131 FlakeVar = Flake.Flakes[i-1][j];
133 FlakeVar->YPos = FlakeVar->YPos + ((double)Flake.FallingSpeed)/10/i;
134 FlakeVar->TrueX = (sin(FlakeVar->XOffset + FlakeVar->Ticks*(PI/180)*((double)Flake.FallingSpeed/10)))*10 + FlakeVar->XPos;
135 FlakeVar->Angle = FlakeVar->Angle + 0.005*((double)Flake.FallingSpeed/10);
136 if(FlakeVar->YPos - Flake.Radius > Flake.XGWA.height)
139 FlakeVar->YPos = 0 - Flake.Radius;
146 FuzzyFlakesDrawFlake(int XPos, int YPos, double AngleOffset, int Layer)
149 double x,y,Angle,Radius;
151 /* calculate the shrink factor debending on which layer we are drawing atm */
152 Radius = (double)(Flake.Radius - Layer * 5);
154 /* draw the flake one arm at a time */
155 for(i=1;i<=Flake.Arms;i++)
158 Diameter = (Flake.BorderThickness*2 + Flake.Thickness)/Layer;
159 /* compute the angle of this arm of the flake */
160 Angle = ((2*PI)/Flake.Arms)*i + AngleOffset;
161 /* calculate the x and y dispositions for this arm */
162 y=(int)(sin(Angle)*Radius);
163 x=(int)(cos(Angle)*Radius);
164 /* draw the base for the arm */
165 Flake.GCValues.line_width = Diameter;
166 XFreeGC(Flake.DisplayVar,Flake.GCVar);
167 Flake.GCVar = XCreateGC (Flake.DisplayVar, Flake.DB.b, Flake.GCFlags, &Flake.GCValues);
168 XSetForeground(Flake.DisplayVar,Flake.GCVar,Flake.BordColor);
169 XDrawLine(Flake.DisplayVar, Flake.DB.b, Flake.GCVar, XPos,YPos,XPos+x,YPos+y);
172 /* draw the flake one arm at a time */
173 for(i=1;i<=Flake.Arms;i++)
175 /* compute the angle of this arm of the flake */
176 Angle = ((2*PI)/Flake.Arms)*i + AngleOffset;
177 /* calculate the x and y dispositions for this arm */
178 y=(int)(sin(Angle)*Radius);
179 x=(int)(cos(Angle)*Radius);
180 /* draw the inside of the arm */
181 Flake.GCValues.line_width = Flake.Thickness/Layer;
182 XFreeGC(Flake.DisplayVar,Flake.GCVar);
183 Flake.GCVar = XCreateGC (Flake.DisplayVar, Flake.DB.b, Flake.GCFlags, &Flake.GCValues);
184 XSetForeground(Flake.DisplayVar,Flake.GCVar,Flake.ForeColor);
185 XDrawLine(Flake.DisplayVar, Flake.DB.b, Flake.GCVar, XPos,YPos,XPos+x,YPos+y);
190 FuzzyFlakes (Display *dpy, Window window)
196 XSetForeground(Flake.DisplayVar,Flake.GCVar,Flake.BackColor);
197 XFillRectangle(Flake.DisplayVar,Flake.DB.b,Flake.GCVar,0,0,Flake.XGWA.width,Flake.XGWA.height);
199 for(i=Flake.Layers;i>=1;i--)
201 for(j=0;j<Flake.Density;j++)
203 FuzzyFlakesDrawFlake(
204 Flake.Flakes[i-1][j]->TrueX,
205 Flake.Flakes[i-1][j]->YPos,
206 Flake.Flakes[i-1][j]->Angle,i);
213 char *progclass = "FuzzyFlakes";
215 char *defaults [] = {
216 ".background: pale green",
227 "*doubleBuffer: True",
231 XrmOptionDescRec options [] = {
232 { "-arms", ".arms", XrmoptionSepArg, 0 },
233 { "-thickness", ".thickness", XrmoptionSepArg, 0 },
234 { "-bthickness", ".bthickness", XrmoptionSepArg, 0 },
235 { "-radius", ".radius", XrmoptionSepArg, 0 },
236 { "-layers", ".layers", XrmoptionSepArg, 0 },
237 { "-density", ".density", XrmoptionSepArg, 0 },
238 { "-speed", ".fallingspeed",XrmoptionSepArg, 0 },
239 { "-delay", ".delay", XrmoptionSepArg, 0 },
240 { "-db", ".doubleBuffer", XrmoptionNoArg, "True" },
241 { "-no-db", ".doubleBuffer", XrmoptionNoArg, "False" },
246 screenhack (Display *dpy, Window window)
248 InitFuzzyFlakes (dpy, window);
251 FuzzyFlakes (dpy, Flake.DB.b);
254 XCopyArea (Flake.DisplayVar, Flake.DB.b, Flake.WindowVar, Flake.GCVar, 0, 0,
255 Flake.XGWA.width, Flake.XGWA.height, 0, 0);
256 Flake.DB.b = (Flake.DB.b == Flake.DB.ba ? Flake.DB.bb : Flake.DB.ba);
258 screenhack_handle_events (dpy);
260 if (Flake.Delay) usleep (Flake.Delay);