-/* menger, Copyright (c) 2001, 2002 Jamie Zawinski <jwz@jwz.org>
+/* menger, Copyright (c) 2001-2014 Jamie Zawinski <jwz@jwz.org>
* Copyright (c) 2002 Aurelien Jacobs <aurel@gnuage.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* just draw them as spots on the surface! It would look the same.
*/
-#include <X11/Intrinsic.h>
-
-extern XtAppContext app;
-
-#define PROGCLASS "Menger"
-#define HACK_INIT init_sponge
-#define HACK_DRAW draw_sponge
-#define HACK_RESHAPE reshape_sponge
-#define HACK_HANDLE_EVENT sponge_handle_event
-#define EVENT_MASK PointerMotionMask
-#define sws_opts xlockmore_opts
-
-#define DEF_SPIN "True"
-#define DEF_WANDER "True"
-#define DEF_SPEED "150"
-#define DEF_MAX_DEPTH "3"
-#define DEF_OPTIMIZE "True"
-
#define DEFAULTS "*delay: 30000 \n" \
"*showFPS: False \n" \
"*wireframe: False \n" \
- "*maxDepth: " DEF_MAX_DEPTH "\n" \
- "*speed:" DEF_SPEED "\n" \
- "*optimize:" DEF_OPTIMIZE "\n" \
- "*spin: " DEF_SPIN "\n" \
- "*wander: " DEF_WANDER "\n" \
+ "*suppressRotationAnimation: True\n" \
+# define refresh_sponge 0
+# define release_sponge 0
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
#ifdef USE_GL /* whole file */
-#include <GL/glu.h>
-
+#define DEF_SPIN "True"
+#define DEF_WANDER "True"
+#define DEF_SPEED "150"
+#define DEF_MAX_DEPTH "3"
typedef struct {
GLXContext *glx_context;
int ccolor1;
int ccolor2;
+ int draw_tick;
+
} sponge_configuration;
static sponge_configuration *sps = NULL;
static Bool do_spin;
static Bool do_wander;
static int speed;
-static Bool do_optimize;
static int max_depth;
static XrmOptionDescRec opts[] = {
- { "-spin", ".spin", XrmoptionNoArg, "True" },
- { "+spin", ".spin", XrmoptionNoArg, "False" },
- { "-wander", ".wander", XrmoptionNoArg, "True" },
- { "+wander", ".wander", XrmoptionNoArg, "False" },
- { "-speed", ".speed", XrmoptionSepArg, 0 },
- { "-optimize", ".optimize", XrmoptionNoArg, "True" },
- { "+optimize", ".optimize", XrmoptionNoArg, "False" },
- {"-depth", ".maxDepth", XrmoptionSepArg, (caddr_t) 0 },
+ { "-wander", ".wander", XrmoptionNoArg, "True" },
+ { "+wander", ".wander", XrmoptionNoArg, "False" },
+ { "-spin", ".spin", XrmoptionSepArg, 0 },
+ { "-speed", ".speed", XrmoptionSepArg, 0 },
+ { "-depth", ".maxDepth", XrmoptionSepArg, 0 },
};
static argtype vars[] = {
{&do_spin, "spin", "Spin", DEF_SPIN, t_Bool},
{&do_wander, "wander", "Wander", DEF_WANDER, t_Bool},
{&speed, "speed", "Speed", DEF_SPEED, t_Int},
- {&do_optimize, "optimize", "Optimize", DEF_OPTIMIZE, t_Bool},
{&max_depth, "maxDepth", "MaxDepth", DEF_MAX_DEPTH, t_Int},
};
-ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL};
+ENTRYPOINT ModeSpecOpt sponge_opts = {countof(opts), opts, countof(vars), vars, NULL};
/* Window management, etc
*/
-void
+ENTRYPOINT void
reshape_sponge (ModeInfo *mi, int width, int height)
{
GLfloat h = (GLfloat) height / (GLfloat) width;
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
+# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
+ {
+ int o = (int) current_device_rotation();
+ if (o != 0 && o != 180 && o != -180)
+ glScalef (1/h, 1/h, 1/h);
+ }
+# endif
+
glClear(GL_COLOR_BUFFER_BIT);
}
}
static int
-menger_recurs (int level, float x0, float x1, float y0, float y1,
- float z0, float z1, int faces, Bool wireframe, int orig)
+menger_recurs_1 (int level, float x0, float x1, float y0, float y1,
+ float z0, float z1, int faces, Bool wireframe,
+ int orig, int forig)
{
float xi, yi, zi;
int f, x, y, z;
- static int forig;
int n = 0;
if (orig)
{
- forig = faces;
if (wireframe)
n += cube (x0, x1, y0, y1, z0, z1,
faces & (X0 | X1 | Y0 | Y1), wireframe);
if (forig & Z1 && z == 0 && (x == 1 || y == 1))
f |= Z1;
- n += menger_recurs (level-1,
- x0+x*xi, x0+(x+1)*xi,
- y0+y*yi, y0+(y+1)*yi,
- z0+z*zi, z0+(z+1)*zi, f, wireframe, 0);
+ n += menger_recurs_1 (level-1,
+ x0+x*xi, x0+(x+1)*xi,
+ y0+y*yi, y0+(y+1)*yi,
+ z0+z*zi, z0+(z+1)*zi, f, wireframe, 0,
+ forig);
}
else if (wireframe && (x != 1 || y != 1 || z != 1))
n += cube (x0+x*xi, x0+(x+1)*xi,
return n;
}
+static int
+menger_recurs (int level, float x0, float x1, float y0, float y1,
+ float z0, float z1, int faces, Bool wireframe,
+ int orig)
+{
+ return menger_recurs_1 (level, x0, x1, y0, y1, z0, z1, faces,
+ wireframe, orig, faces);
+}
+
+
static void
build_sponge (sponge_configuration *sp, Bool wireframe, int level)
{
}
-Bool
+ENTRYPOINT Bool
sponge_handle_event (ModeInfo *mi, XEvent *event)
{
sponge_configuration *sp = &sps[MI_SCREEN(mi)];
- if (event->xany.type == ButtonPress &&
- event->xbutton.button & Button1)
- {
- sp->button_down_p = True;
- gltrackball_start (sp->trackball,
- event->xbutton.x, event->xbutton.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
- return True;
- }
- else if (event->xany.type == ButtonRelease &&
- event->xbutton.button & Button1)
+ if (gltrackball_event_handler (event, sp->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &sp->button_down_p))
+ return True;
+ else if (event->xany.type == KeyPress)
{
- sp->button_down_p = False;
- return True;
+ KeySym keysym;
+ char c = 0;
+ XLookupString (&event->xkey, &c, 1, &keysym, 0);
+ if (c == '+' || c == '=' ||
+ keysym == XK_Up || keysym == XK_Right || keysym == XK_Next)
+ {
+ sp->draw_tick = speed;
+ sp->current_depth += (sp->current_depth > 0 ? 1 : -1);
+ sp->current_depth--;
+ return True;
+ }
+ else if (c == '-' || c == '_' ||
+ keysym == XK_Down || keysym == XK_Left || keysym == XK_Prior)
+ {
+ sp->draw_tick = speed;
+ sp->current_depth -= (sp->current_depth > 0 ? 1 : -1);
+ sp->current_depth--;
+ return True;
+ }
+ else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
+ goto DEF;
}
- else if (event->xany.type == MotionNotify &&
- sp->button_down_p)
+ else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
{
- gltrackball_track (sp->trackball,
- event->xmotion.x, event->xmotion.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
+ DEF:
+ sp->draw_tick = speed;
return True;
}
-void
+ENTRYPOINT void
init_sponge (ModeInfo *mi)
{
sponge_configuration *sp;
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
-
- sp = &sps[MI_SCREEN(mi)];
}
sp = &sps[MI_SCREEN(mi)];
if (!wire)
{
- static GLfloat pos0[4] = {-1.0, -1.0, 1.0, 0.1};
- static GLfloat pos1[4] = { 1.0, -0.2, 0.2, 0.1};
- static GLfloat dif0[4] = {1.0, 1.0, 1.0, 1.0};
- static GLfloat dif1[4] = {1.0, 1.0, 1.0, 1.0};
+ static const GLfloat pos0[4] = {-1.0, -1.0, 1.0, 0.1};
+ static const GLfloat pos1[4] = { 1.0, -0.2, 0.2, 0.1};
+ static const GLfloat dif0[4] = {1.0, 1.0, 1.0, 1.0};
+ static const GLfloat dif1[4] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, pos0);
glLightfv(GL_LIGHT1, GL_POSITION, pos1);
1.0,
do_wander ? wander_speed : 0,
True);
- sp->trackball = gltrackball_init ();
+ sp->trackball = gltrackball_init (True);
}
sp->ncolors = 128;
sp->sponge_list0 = glGenLists (1);
sp->sponge_list1 = glGenLists (1);
sp->sponge_list2 = glGenLists (1);
+
+ sp->draw_tick = 9999999;
}
-void
+ENTRYPOINT void
draw_sponge (ModeInfo *mi)
{
sponge_configuration *sp = &sps[MI_SCREEN(mi)];
Display *dpy = MI_DISPLAY(mi);
Window window = MI_WINDOW(mi);
- static GLfloat color0[4] = {0.0, 0.0, 0.0, 1.0};
- static GLfloat color1[4] = {0.0, 0.0, 0.0, 1.0};
- static GLfloat color2[4] = {0.0, 0.0, 0.0, 1.0};
-
- static int tick = 99999;
+ GLfloat color0[4] = {0.0, 0.0, 0.0, 1.0};
+ GLfloat color1[4] = {0.0, 0.0, 0.0, 1.0};
+ GLfloat color2[4] = {0.0, 0.0, 0.0, 1.0};
if (!sp->glx_context)
return;
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sp->glx_context));
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
if (sp->ccolor1 >= sp->ncolors) sp->ccolor1 = 0;
if (sp->ccolor2 >= sp->ncolors) sp->ccolor2 = 0;
- if (tick++ >= speed)
+ if (sp->draw_tick++ >= speed)
{
- tick = 0;
+ sp->draw_tick = 0;
if (sp->current_depth >= max_depth)
sp->current_depth = -max_depth;
sp->current_depth++;
? -sp->current_depth : sp->current_depth));
mi->polygon_count = sp->squares_fp; /* for FPS display */
+ mi->recursion_depth = (sp->current_depth < 0
+ ? -sp->current_depth : sp->current_depth);
}
glScalef (2.0, 2.0, 2.0);
glXSwapBuffers(dpy, window);
}
+XSCREENSAVER_MODULE_2 ("Menger", menger, sponge)
+
#endif /* USE_GL */