* other special, indirect and consequential damages.
*
* Revision History:
+ * 10-Jun-06: j.grahl@ucl.ac.uk: tweaked functions for parameter of Julia set
* 28-May-97: jwz@jwz.org: added interactive frobbing with the mouse.
* 10-May-97: jwz@jwz.org: turned into a standalone program.
* 02-Dec-95: snagged boilerplate from hop.c
*/
#ifdef STANDALONE
-# define PROGCLASS "Julia"
-# define HACK_INIT init_julia
-# define HACK_DRAW draw_julia
-# define julia_opts xlockmore_opts
-# define DEFAULTS "*count: 1000 \n" \
- "*cycles: 20 \n" \
- "*delay: 10000 \n" \
- "*ncolors: 200 \n"
+# define DEFAULTS "*count: 1000 \n" \
+ "*cycles: 20 \n" \
+ "*delay: 10000 \n" \
+ "*ncolors: 200 \n" \
+ "*fpsSolid: true \n" \
+ "*ignoreRotation: True \n" \
+
# define UNIFORM_COLORS
+# define release_julia 0
+# define reshape_julia 0
# include "xlockmore.h" /* in xscreensaver distribution */
#else /* !STANDALONE */
# include "xlock.h" /* in xlockmore distribution */
#endif /* !STANDALONE */
-static Bool track_p;
-
#define DEF_MOUSE "False"
-static XrmOptionDescRec opts[] =
-{
- {"-mouse", ".julia.mouse", XrmoptionNoArg, (caddr_t) "on"},
- {"+mouse", ".julia.mouse", XrmoptionNoArg, (caddr_t) "off"},
-};
-static argtype vars[] =
-{
- {&track_p, "mouse", "Mouse", DEF_MOUSE, t_Bool},
-};
-static OptionStruct desc[] =
-{
- {"-/+mouse", "turn on/off mouse tracking"},
-};
-
-ModeSpecOpt julia_opts = { 2, opts, 1, vars, desc };
+ENTRYPOINT ModeSpecOpt julia_opts = { 0, };
#define numpoints ((0x2<<jp->depth)-1)
int nbuffers;
int redrawing, redrawpos;
Pixmap pixmap;
+#ifndef HAVE_JWXYZ
Cursor cursor;
+#endif
GC stippledGC;
XPoint **pointBuffer; /* pointer for XDrawPoints */
+ Bool button_down_p;
+ int mouse_x, mouse_y;
} juliastruct;
static void
incr(ModeInfo * mi, juliastruct * jp)
{
- int cx, cy;
-
- if (track_p)
+ if (jp->button_down_p)
{
- Window r, c;
- int rx, ry;
- unsigned int m;
- XQueryPointer(MI_DISPLAY(mi), MI_WINDOW(mi),
- &r, &c, &rx, &ry, &cx, &cy, &m);
- if (cx <= 0 || cy <= 0 ||
- cx >= MI_WIN_WIDTH(mi) || cy >= MI_WIN_HEIGHT(mi))
- goto NOTRACK;
- }
-
- if (track_p)
- {
- jp->cr = ((double) (cx + 2 - jp->centerx)) * 2 / jp->centerx;
- jp->ci = ((double) (cy + 2 - jp->centery)) * 2 / jp->centery;
+ jp->cr = ((double) (jp->mouse_x + 2 - jp->centerx)) * 2 / jp->centerx;
+ jp->ci = ((double) (jp->mouse_y + 2 - jp->centery)) * 2 / jp->centery;
}
else
{
- NOTRACK:
+#if 0
jp->cr = 1.5 * (sin(M_PI * (jp->inc / 300.0)) *
sin(jp->inc * M_PI / 200.0));
jp->ci = 1.5 * (cos(M_PI * (jp->inc / 300.0)) *
jp->cr += 0.5 * cos(M_PI * jp->inc / 400.0);
jp->ci += 0.5 * sin(M_PI * jp->inc / 400.0);
+#else
+ jp->cr = 1.5 * (sin(M_PI * (jp->inc / 290.0)) *
+ sin(jp->inc * M_PI / 210.0));
+ jp->ci = 1.5 * (cos(M_PI * (jp->inc / 310.0)) *
+ cos(jp->inc * M_PI / 190.0));
+
+ jp->cr += 0.5 * cos(M_PI * jp->inc / 395.0);
+ jp->ci += 0.5 * sin(M_PI * jp->inc / 410.0);
+#endif
}
}
-void
+ENTRYPOINT void
init_julia(ModeInfo * mi)
{
Display *display = MI_DISPLAY(mi);
XGCValues gcv;
int i;
- if (julias == NULL) {
- if ((julias = (juliastruct *) calloc(MI_NUM_SCREENS(mi),
- sizeof (juliastruct))) == NULL)
- return;
- }
+ MI_INIT (mi, julias);
jp = &julias[MI_SCREEN(mi)];
jp->centerx = MI_WIN_WIDTH(mi) / 2;
jp->depth = 10;
- if (track_p && !jp->cursor)
+#ifndef HAVE_JWXYZ
+ if (jp->button_down_p && !jp->cursor && !jp->cursor)
{
Pixmap bit;
XColor black;
0, 0);
XFreePixmap (display, bit);
}
+#endif /* HAVE_JWXYZ */
if (jp->pixmap != None &&
jp->circsize != (MIN(jp->centerx, jp->centery) / 60) * 2 + 1) {
if (jp->pixmap == None) {
GC fg_gc = None, bg_gc = None;
- jp->circsize = (MIN(jp->centerx, jp->centery) / 96) * 2 + 1;
+ jp->circsize = MAX(8, (MIN(jp->centerx, jp->centery) / 96) * 2 + 1);
jp->pixmap = XCreatePixmap(display, window, jp->circsize, jp->circsize, 1);
gcv.foreground = 1;
fg_gc = XCreateGC(display, jp->pixmap, GCForeground, &gcv);
XFreeGC(display, bg_gc);
}
+#ifndef HAVE_JWXYZ
if (MI_WIN_IS_INROOT(mi))
;
else if (jp->circsize > 0)
XDefineCursor (display, window, jp->cursor);
else
XUndefineCursor (display, window);
+#endif /* HAVE_JWXYZ */
if (!jp->stippledGC) {
gcv.foreground = MI_WIN_BLACK_PIXEL(mi);
}
+ENTRYPOINT Bool
+julia_handle_event (ModeInfo *mi, XEvent *event)
+{
+ juliastruct *jp = &julias[MI_SCREEN(mi)];
+
+ if (event->xany.type == ButtonPress &&
+ event->xbutton.button == Button1)
+ {
+ jp->button_down_p = True;
+ jp->mouse_x = event->xbutton.x;
+ jp->mouse_y = event->xbutton.y;
+ return True;
+ }
+ else if (event->xany.type == ButtonRelease &&
+ event->xbutton.button == Button1)
+ {
+ jp->button_down_p = False;
+ return True;
+ }
+ else if (event->xany.type == MotionNotify && jp->button_down_p)
+ {
+ jp->mouse_x = event->xmotion.x;
+ jp->mouse_y = event->xmotion.y;
+ return True;
+ }
+
+ return False;
+}
+
+
+
/* hack: moved here by jwz. */
#define ERASE_IMAGE(d,w,g,x,y,xl,yl,xs,ys) \
if (yl<y) \
XFillRectangle(d,w,g,xl,yl,xs,ys)
-void
-draw_julia(ModeInfo * mi)
+ENTRYPOINT void
+draw_julia (ModeInfo * mi)
{
Display *display = MI_DISPLAY(mi);
Window window = MI_WINDOW(mi);
new_circle.x = (int) (jp->centerx * jp->cr / 2) + jp->centerx - 2;
new_circle.y = (int) (jp->centery * jp->ci / 2) + jp->centery - 2;
XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi));
- ERASE_IMAGE(display, window, gc, new_circle.x, new_circle.y,
- old_circle.x, old_circle.y, jp->circsize, jp->circsize);
+ XFillArc(display, window, gc,
+ old_circle.x-jp->circsize/2-2,
+ old_circle.y-jp->circsize/2-2,
+ jp->circsize+4, jp->circsize+4,
+ 0, 360*64);
/* draw a circle at the c-parameter so you can see it's effect on the
structure of the julia set */
- XSetTSOrigin(display, jp->stippledGC, new_circle.x, new_circle.y);
XSetForeground(display, jp->stippledGC, MI_WIN_WHITE_PIXEL(mi));
+#ifndef HAVE_JWXYZ
+ XSetTSOrigin(display, jp->stippledGC, new_circle.x, new_circle.y);
XSetStipple(display, jp->stippledGC, jp->pixmap);
XSetFillStyle(display, jp->stippledGC, FillOpaqueStippled);
- XFillRectangle(display, window, jp->stippledGC, new_circle.x, new_circle.y,
- jp->circsize, jp->circsize);
- XFlush(display);
+#endif /* HAVE_JWXYZ */
+ XDrawArc(display, window, jp->stippledGC,
+ new_circle.x-jp->circsize/2,
+ new_circle.y-jp->circsize/2,
+ jp->circsize, jp->circsize,
+ 0, 360*64);
+
if (jp->erase == 1) {
XDrawPoints(display, window, gc,
jp->pointBuffer[jp->buffer], numpoints, CoordModeOrigin);
}
}
-void
-release_julia(ModeInfo * mi)
+ENTRYPOINT void
+free_julia (ModeInfo * mi)
{
- if (julias != NULL) {
- int screen;
-
- for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
- Display *display = MI_DISPLAY(mi);
- juliastruct *jp = &julias[screen];
- int buffer;
-
- if (jp->pointBuffer) {
- for (buffer = 0; buffer < jp->nbuffers; buffer++)
- if (jp->pointBuffer[buffer])
- (void) free((void *) jp->pointBuffer[buffer]);
- (void) free((void *) jp->pointBuffer);
- }
- if (jp->stippledGC != None)
- XFreeGC(display, jp->stippledGC);
- if (jp->pixmap != None)
- XFreePixmap(display, jp->pixmap);
- if (jp->cursor)
- XFreeCursor (display, jp->cursor);
- }
- (void) free((void *) julias);
- julias = NULL;
+ Display *display = MI_DISPLAY(mi);
+ juliastruct *jp = &julias[MI_SCREEN(mi)];
+ int buffer;
+
+ if (jp->pointBuffer) {
+ for (buffer = 0; buffer < jp->nbuffers; buffer++)
+ if (jp->pointBuffer[buffer])
+ (void) free((void *) jp->pointBuffer[buffer]);
+ (void) free((void *) jp->pointBuffer);
}
+ if (jp->stippledGC != None)
+ XFreeGC(display, jp->stippledGC);
+ if (jp->pixmap != None)
+ XFreePixmap(display, jp->pixmap);
+#ifndef HAVE_JWXYZ
+ if (jp->cursor)
+ XFreeCursor (display, jp->cursor);
+#endif
}
-void
-refresh_julia(ModeInfo * mi)
+#ifndef STANDALONE
+ENTRYPOINT void
+refresh_julia (ModeInfo * mi)
{
juliastruct *jp = &julias[MI_SCREEN(mi)];
jp->redrawing = 1;
jp->redrawpos = 0;
}
+#endif
+
+XSCREENSAVER_MODULE ("Julia", julia)