summaryrefslogtreecommitdiff
path: root/app/xlockmore/modes/munch.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 11:09:41 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 11:09:41 +0000
commit95c2d1cbda23a41cdf6e63520c7f0b825e63dd5b (patch)
tree06d3ffa4312e568c4157f69fe1bddaddec9bc497 /app/xlockmore/modes/munch.c
parent3928433848e2d6a9356f3d438a14b32a4f87f660 (diff)
Importing xlockmore 5.22
Diffstat (limited to 'app/xlockmore/modes/munch.c')
-rw-r--r--app/xlockmore/modes/munch.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/app/xlockmore/modes/munch.c b/app/xlockmore/modes/munch.c
new file mode 100644
index 000000000..687deac65
--- /dev/null
+++ b/app/xlockmore/modes/munch.c
@@ -0,0 +1,268 @@
+/* -*- Mode: C; tab-width: 4 -*- */
+/* munch --- munching squares */
+
+#if !defined( lint ) && !defined( SABER )
+static const char sccsid[] = "@(#)munch.c 5.00 2000/11/01 xlockmore";
+
+#endif
+
+/*-
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * Tim Showalter <tjs@andrew.cmu.edu>
+ *
+ * Copyright 1997, Tim Showalter
+ * Permission is granted to copy, modify, and use this as long
+ * as this notice remains intact. No warranties are expressed or implied.
+ * CMU Sucks.
+ *
+ * Some code stolen from / This is meant to work with
+ * xscreensaver, Copyright (c) 1992, 1995, 1996
+ * Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * Revision History:
+ * 01-Nov-2000: Allocation checks
+ */
+
+/*-
+ * Munching Squares is this simplistic, silly screen hack (according to
+ * HAKMEM, discovered by Jackson Wright in 1962) where you take Y = X XOR T
+ * and graph it over and over. According to HAKMEM, it takes 5 instructions
+ * of PDP-1 assembly. This is a little more complicated than that, mostly X's
+ * fault, but it does some other random things.
+ * http://www.inwap.com/pdp10/hbaker/hakmem/hacks.html#item146
+ */
+
+#ifdef STANDALONE
+#define MODE_munch
+#define PROGCLASS "Munch"
+#define HACK_INIT init_munch
+#define HACK_DRAW draw_munch
+#define munch_opts xlockmore_opts
+#define DEFAULTS "*delay: 5000 \n" \
+ "*cycles: 7 \n"
+#include "xlockmore.h" /* from the xscreensaver distribution */
+#else /* !STANDALONE */
+#include "xlock.h" /* from the xlockmore distribution */
+#endif /* !STANDALONE */
+
+#ifdef MODE_munch
+
+ModeSpecOpt munch_opts =
+{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
+
+#ifdef USE_MODULES
+ModStruct munch_description =
+{"munch", "init_munch", "draw_munch", "release_munch",
+ "init_munch", "init_munch", (char *) NULL, &munch_opts,
+ 5000, 1, 7, 1, 64, 1.0, "",
+ "Shows munching squares", 0, NULL};
+
+#endif
+
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+/* flags for random things. Must be < log2(random's maximum), incidentially. */
+#define SHIFT_KX (0x01)
+#define SHIFT_KT (0x02)
+#define SHIFT_KY (0x04)
+#define GRAV (0x08)
+
+typedef struct {
+ int width, height;
+ int logminwidth;
+ int logmaxwidth;
+ GC gc;
+ int thiswidth;
+ int t;
+ int atX, atY;
+ int kX, kT, kY;
+ int grav;
+} munchstruct;
+
+static munchstruct *munches = (munchstruct *) NULL;
+
+static void
+munchBit(ModeInfo * mi, int width, /* pixels */
+ int atX, int atY, /* pixels */
+ int kX, int kT, int kY, /* pixels */
+ int grav /* 0 or not */ )
+{
+ munchstruct *mp = &munches[MI_SCREEN(mi)];
+
+ int x, y;
+ int drawX, drawY;
+
+#if 0
+ (void) fprintf(stderr, "Doing width %d at %d %d shift %d %d %d grav %d\n",
+ width, atX, atY, kX, kT, kY, grav);
+#endif
+
+ for (x = 0; x < width; x++) {
+ /* figure out the next point */
+ y = ((x ^ ((mp->t + kT) % width)) + kY) % width;
+
+ drawX = ((x + kX) % width) + atX;
+ drawY = (grav ? y + atY : atY + width - 1 - y);
+
+ /* used to be bugs where it would draw partially offscreen.
+ while that might be a pretty feature, I didn't want it to do
+ that yet. if these trigger, please let me know.
+ */
+#ifdef DEBUG
+ assert(drawX >= 0 && drawX < MI_WIDTH(mi));
+ assert(drawY >= 0 && drawY < MI_HEIGHT(mi));
+#endif
+
+ XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), mp->gc, drawX, drawY);
+ /* XXX may want to change this to XDrawPoints,
+ but it's fast enough without it for the moment. */
+
+ }
+}
+
+/*
+ * dumb way to get # of digits in number. Probably faster than actually
+ * doing a log and a division, maybe.
+ */
+static int
+dumb_log_2(int k)
+{
+ int r = -1;
+
+ while (k > 0) {
+ k >>= 1;
+ r++;
+ }
+ return r;
+}
+
+void
+init_munch(ModeInfo * mi)
+{
+ Display *display = MI_DISPLAY(mi);
+ munchstruct *mp;
+
+ if (munches == NULL) {
+ if ((munches = (munchstruct *) calloc(MI_NUM_SCREENS(mi),
+ sizeof (munchstruct))) == NULL)
+ return;
+ }
+ mp = &munches[MI_SCREEN(mi)];
+
+ if (mp->gc == None) {
+ if ((mp->gc = XCreateGC(display, MI_WINDOW(mi),
+ (unsigned long) 0, (XGCValues *) NULL)) == None)
+ return;
+ }
+ mp->width = MI_WIDTH(mi);
+ mp->height = MI_HEIGHT(mi);
+
+ /* We need a square; limit on screen size? */
+ /* we want a power of 2 for the width or the munch doesn't fill up. */
+ mp->logmaxwidth = (int)
+ dumb_log_2((mp->height < mp->width) ? mp->height : mp->width);
+
+ XSetFunction(display, mp->gc, GXxor);
+
+ mp->logminwidth = MI_CYCLES(mi);
+ if (mp->logminwidth < 2 || MI_IS_ICONIC(mi))
+ mp->logminwidth = 2;
+
+ if (mp->logmaxwidth < mp->logminwidth)
+ mp->logmaxwidth = mp->logminwidth;
+
+ mp->t = 0;
+
+ MI_CLEARWINDOW(mi);
+}
+
+void
+draw_munch(ModeInfo * mi)
+{
+ munchstruct *mp;
+
+ if (munches == NULL)
+ return;
+ mp = &munches[MI_SCREEN(mi)];
+ if (mp->gc == None)
+ return;
+
+ MI_IS_DRAWN(mi) = True;
+ if (!mp->t) { /* New one */
+ int randflags = (int) LRAND();
+
+ /* choose size -- power of two */
+ mp->thiswidth = (int) (1 << (mp->logminwidth +
+ (LRAND() % (1 + mp->logmaxwidth - mp->logminwidth))));
+
+ if (MI_NPIXELS(mi) > 2)
+ XSetForeground(MI_DISPLAY(mi), mp->gc,
+ MI_PIXEL(mi, NRAND(MI_NPIXELS(mi))));
+ else /* Xor'red so WHITE may not be appropriate */
+ XSetForeground(MI_DISPLAY(mi), mp->gc, 1);
+
+ mp->atX = (int) (LRAND() %
+ ((mp->width <= mp->thiswidth) ? 1 : mp->width - mp->thiswidth));
+ mp->atY = (int) (LRAND() %
+ ((mp->height <= mp->thiswidth) ? 1 : mp->height - mp->thiswidth));
+
+ /* wrap-around by these values; no need to %
+ as we end up doing that later anyway */
+ mp->kX = (int) ((randflags & SHIFT_KX) ? LRAND() % mp->thiswidth : 0);
+ mp->kT = (int) ((randflags & SHIFT_KT) ? LRAND() % mp->thiswidth : 0);
+ mp->kY = (int) ((randflags & SHIFT_KY) ? LRAND() % mp->thiswidth : 0);
+
+ /* set the gravity of the munch, or rather,
+ which direction we draw stuff in. */
+ mp->grav = randflags & GRAV;
+ }
+ /* Finally draw this munching square. */
+ munchBit(mi,
+ mp->thiswidth, /* Width, in pixels */
+ /* draw at this location */
+ mp->atX, mp->atY, mp->kX, mp->kT, mp->kY, mp->grav);
+
+ mp->t++;
+ if (mp->t == mp->thiswidth)
+ mp->t = 0;
+}
+
+void
+release_munch(ModeInfo * mi)
+{
+ if (munches != NULL) {
+ int screen;
+
+ for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
+ munchstruct *mp = &munches[screen];
+
+ if (mp->gc != None)
+ XFreeGC(MI_DISPLAY(mi), mp->gc);
+ }
+ free(munches);
+ munches = (munchstruct *) NULL;
+ }
+}
+
+#endif /* MODE_munch */