ftp://ftp.krokus.ru/pub/OpenBSD/distfiles/xscreensaver-5.01.tar.gz
[xscreensaver] / hacks / flag.c
index 1c2c5054ed12096558eadc2181f5cfa80f8e39fe..c74e921de4698e9ac3d9b07055bde42b24e016cd 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- Mode: C; tab-width: 4 -*-
  * flag --- a waving flag
  */
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)flag.c       4.02 97/04/01 xlockmore";
 #endif
 
@@ -24,36 +24,36 @@ static const char sccsid[] = "@(#)flag.c    4.02 97/04/01 xlockmore";
  * other special, indirect and consequential damages.
  *
  * Revision History: 
- * 13-May-97: jwz@netscape.com: turned into a standalone program.
+ * 22-Jan-98: jwz: made the flag wigglier; added xpm support.
+ *            (I tried to do this by re-porting from xlockmore, but the
+ *            current xlockmore version is completely inscrutable.)
+ * 13-May-97: jwz@jwz.org: turned into a standalone program.
  *                       Made it able to animate arbitrary (runtime) text or bitmaps.
  * 01-May-96: written.
  */
 
+#ifdef HAVE_COCOA
+# define DEF_FONT "Monaco 15"
+#else
+# define DEF_FONT "fixed"
+#endif
+
 #ifdef STANDALONE
-# define PROGCLASS                                     "Flag"
-# define HACK_INIT                                     init_flag
-# define HACK_DRAW                                     draw_flag
-# define flag_opts                                     xlockmore_opts
-# define DEFAULTS      "*delay:                50000   \n"                     \
-                                       "*cycles:               1000    \n"                     \
-                                       "*size:                 -7      \n"                     \
-                                       "*ncolors:              200     \n"
+# define DEFAULTS      "*delay:                50000   \n"             \
+                                       "*cycles:               1000    \n"             \
+                                       "*size:                 -7      \n"             \
+                                       "*ncolors:              200     \n"             \
+                                       "*bitmap:                               \n"             \
+                                       "*font:         " DEF_FONT      "\n"    \
+                                       "*text:                                 \n"
 # define BRIGHT_COLORS
 # define UNIFORM_COLORS
-# define DEF_FONT                                      "-*-helvetica-bold-r-*-240-*"
-# define DEF_BITMAP                                    ""
-# define DEF_TEXT                                      ""
+# define reshape_flag 0
+# define flag_handle_event 0
 # include "xlockmore.h"                                /* from the xscreensaver distribution */
 
-#ifdef HAVE_XMU
-# ifndef VMS
-#  include <X11/Xmu/Drawing.h>
-# else  /* VMS */
-#  include <Xmu/Drawing.h>
-# endif /* VMS */
-#endif /* HAVE_XMU */
-
-#include "bob.xbm"
+#include "xpm-pixmap.h"
+#include "images/bob.xbm"
 
 #else  /* !STANDALONE */
 # include "xlock.h"                                    /* from the xlockmore distribution */
@@ -61,19 +61,26 @@ static const char sccsid[] = "@(#)flag.c    4.02 97/04/01 xlockmore";
 #endif /* !STANDALONE */
 
 
-#if defined(VMS) && !defined(HAVE_UNAME) && (__VMS_VER >= 70000000)
-# define HAVE_UNAME 1
-#endif
-
 #ifdef HAVE_UNAME
 # include <sys/utsname.h>
 #endif /* HAVE_UNAME */
 
-ModeSpecOpt flag_opts = {
-  0, NULL, 0, NULL, NULL };
+#ifdef STANDALONE
+static XrmOptionDescRec opts[] =
+{
+  { "-bitmap", ".flag.bitmap", XrmoptionSepArg, 0 },
+  { "-text",   ".flag.text",   XrmoptionSepArg, 0 }
+};
 
-#include <string.h>
-#include <X11/Xutil.h>
+#endif /* STANDALONE */
+
+ENTRYPOINT ModeSpecOpt flag_opts = {
+#ifdef STANDALONE
+  2, opts, 0, NULL, NULL
+#else  /* !STANDALONE */
+  0, NULL, 0, NULL, NULL
+#endif /* STANDALONE */
+};
 
 #define MINSIZE 1
 #define MAXSCALE 8
@@ -96,6 +103,7 @@ typedef struct {
        int         timer;
        int         initialized;
        int         stab[ANGLES];
+    Bool               dbufp;
        Pixmap      cache;
        int         width, height;
        int         pointsize;
@@ -119,8 +127,18 @@ initSintab(ModeInfo * mi)
        flagstruct *fp = &flags[MI_SCREEN(mi)];
        int         i;
 
+  /*-
+   * change the periodicity of the sin formula : the maximum of the
+   * periocity seem to be 16 ( 2^4 ), after the drawing isn't good looking
+   */
+       int         periodicity = random_num(4);
+       int         puissance = 1;
+
+       /* for (i=0;i<periodicity;i++) puissance*=2; */
+       puissance <<= periodicity;
        for (i = 0; i < ANGLES; i++)
-               fp->stab[i] = (int) (SINF(i * 4 * M_PI / ANGLES) * fp->samp) + fp->sofs;
+               fp->stab[i] = (int) (SINF(i * puissance * M_PI / ANGLES) * fp->samp) +
+                       fp->sofs;
 }
 
 static void
@@ -136,13 +154,23 @@ affiche(ModeInfo * mi)
                                fp->stab[(fp->sidx + x + y) % ANGLES];
                        yp = (int) (fp->size * (float) y) +
                                fp->stab[(fp->sidx + 4 * x + y + y) % ANGLES];
-                       if (XGetPixel(fp->image, x, y))
+
+                       if (fp->image->depth > 1)
+                         XSetForeground(display, MI_GC(mi),
+                                                        XGetPixel(fp->image, x, y));
+                       else if (XGetPixel(fp->image, x, y))
                                XSetForeground(display, MI_GC(mi), MI_WIN_BLACK_PIXEL(mi));
                        else if (MI_NPIXELS(mi) <= 2)
                                XSetForeground(display, MI_GC(mi), MI_WIN_WHITE_PIXEL(mi));
                        else
                                XSetForeground(display, MI_GC(mi),
                                               MI_PIXEL(mi, (y + x + fp->sidx + fp->startcolor) % MI_NPIXELS(mi)));
+
+            if (fp->cache == MI_WINDOW(mi)) {  /* not double-buffering */
+              xp += fp->x_flag;
+              yp += fp->y_flag;
+            }
+
                        if (fp->pointsize <= 1)
                                XDrawPoint(display, fp->cache, MI_GC(mi), xp, yp);
                        else if (fp->pointsize < 6)
@@ -161,8 +189,12 @@ make_flag_bits(ModeInfo *mi)
 {
   Display *dpy = MI_DISPLAY(mi);
   flagstruct *fp = &flags[MI_SCREEN(mi)];
-  char *bitmap_name = get_string_resource ("bitmap", "Bitmap");
-  char *text = get_string_resource ("text", "Text");
+  char *bitmap_name = get_string_resource (dpy, "bitmap", "Bitmap");
+  char *text = get_string_resource (dpy, "text", "Text");
+
+#ifdef HAVE_COCOA
+  bitmap_name = 0;  /* #### always use default */
+#endif
 
   /* If neither a bitmap nor text are specified, randomly select either
         the builtin bitmap or builtin text. */
@@ -184,34 +216,23 @@ make_flag_bits(ModeInfo *mi)
          *bitmap_name &&
          !!strcmp(bitmap_name, "(default)"))
        {
-#ifdef HAVE_XMU
-         int width, height, xh, yh;
-         Pixmap bitmap =
-               XmuLocateBitmapFile (DefaultScreenOfDisplay (dpy),
-                                                        bitmap_name, 0, 0, &width, &height, &xh, &yh);
-         if (!bitmap)
+         Pixmap bitmap = 0;
+      int width = 0;
+      int height = 0;
+
+      bitmap = xpm_file_to_pixmap (dpy, MI_WINDOW (mi), bitmap_name,
+                                   &width, &height, 0);
+         if (bitmap)
                {
-                 fprintf(stderr, "%s: unable to load bitmap file %s\n",
-                                 progname, bitmap_name);
-                 exit (1);
+                 fp->image = XGetImage(dpy, bitmap, 0, 0, width, height, ~0L,
+                                                               ZPixmap);
+                 XFreePixmap(dpy, bitmap);
                }
-         fp->image = XGetImage(dpy, bitmap, 0, 0, width, height,
-                                                       1L, XYPixmap);
-         XFreePixmap(dpy, bitmap);
-
-#else  /* !XMU */
-      fprintf (stderr,
-                          "%s: your vendor doesn't ship the standard Xmu library.\n",
-                          progname);
-      fprintf (stderr, "\tWe can't load XBM files without it.\n");
-      exit (1);
-#endif /* !XMU */
-
        }
   else if (text && *text)
        {
          char *text2;
-         char *fn = get_string_resource ("font", "Font");
+         char *fn = get_string_resource (dpy, "font", "Font");
          char *def_fn = "fixed";
          char *line, *token;
          int width, height;
@@ -240,9 +261,15 @@ make_flag_bits(ModeInfo *mi)
                                *s = 0;
                          text = (char *) malloc(strlen(uts.nodename) +
                                                                         strlen(uts.sysname) +
+                                                                        strlen(uts.version) +
                                                                         strlen(uts.release) + 10);
+# ifdef _AIX
+                         sprintf(text, "%s\n%s %s.%s",
+                                         uts.nodename, uts.sysname, uts.version, uts.release);
+# else  /* !_AIX */
                          sprintf(text, "%s\n%s %s",
                                          uts.nodename, uts.sysname, uts.release);
+# endif /* !_AIX */
                        }
 #else  /* !HAVE_UNAME */
 # ifdef VMS
@@ -326,8 +353,10 @@ make_flag_bits(ModeInfo *mi)
        }
   else
        {
+      char *bits = (char *) malloc (sizeof(bob_bits));
+      memcpy (bits, bob_bits, sizeof(bob_bits));
          fp->image = XCreateImage (dpy, MI_VISUAL(mi), 1, XYBitmap, 0,
-                                                               (char *) bob_bits, bob_width, bob_height,
+                                                               bits, bob_width, bob_height,
                                                                8, 0);
          fp->image->byte_order = LSBFirst;
          fp->image->bitmap_bit_order = LSBFirst;
@@ -363,7 +392,7 @@ make_flag_bits(ModeInfo *mi)
 #endif /* !STANDALONE */
 
 
-void
+ENTRYPOINT void
 init_flag(ModeInfo * mi)
 {
        Display    *display = MI_DISPLAY(mi);
@@ -396,9 +425,17 @@ init_flag(ModeInfo * mi)
        fp->sidx = fp->x_flag = fp->y_flag = 0;
 
        if (!fp->initialized) {
+      fp->dbufp = True;
+# ifdef HAVE_COCOA             /* Don't second-guess Quartz's double-buffering */
+      fp->dbufp = False;
+#endif
                fp->initialized = True;
-               if (!(fp->cache = XCreatePixmap(display, MI_WINDOW(mi),
-               MAXW(fp), MAXH(fp), MI_WIN_DEPTH(mi))))
+               if (!fp->dbufp)
+          fp->cache = MI_WINDOW(mi);  /* not double-buffering */
+        else
+          if (!(fp->cache = XCreatePixmap(display, MI_WINDOW(mi),
+                                          MAXW(fp), MAXH(fp),
+                                          MI_WIN_DEPTH(mi))))
 #ifdef STANDALONE
                  exit(-1);
 #else   /* !STANDALONE */
@@ -429,41 +466,47 @@ init_flag(ModeInfo * mi)
        XClearWindow(display, MI_WINDOW(mi));
 }
 
-void
+ENTRYPOINT void release_flag(ModeInfo * mi);
+
+
+ENTRYPOINT void
 draw_flag(ModeInfo * mi)
 {
        Display    *display = MI_DISPLAY(mi);
        Window      window = MI_WINDOW(mi);
        flagstruct *fp = &flags[MI_SCREEN(mi)];
 
-       if (fp->width <= MAXW(fp) || fp->height <= MAXH(fp)) {
+    if (fp->cache == window) {  /* not double-buffering */
+      XClearWindow (display, window);
+    } else if (fp->width <= MAXW(fp) || fp->height <= MAXH(fp)) {
                fp->size = MININITSIZE;
                /* fp->pointsize = MINPOINTSIZE; */
-               XCopyArea(display, fp->cache, window, MI_GC(mi),
-                         0, 0, MINW(fp), MINH(fp), fp->x_flag, fp->y_flag);
+        XCopyArea(display, fp->cache, window, MI_GC(mi),
+                  0, 0, MINW(fp), MINH(fp), fp->x_flag, fp->y_flag);
        } else {
                if ((fp->size + fp->inctaille) > MAXSCALE)
                        fp->inctaille = -fp->inctaille;
                if ((fp->size + fp->inctaille) < MINSCALE)
                        fp->inctaille = -fp->inctaille;
                fp->size += fp->inctaille;
-               XCopyArea(display, fp->cache, window, MI_GC(mi),
-                         0, 0, MAXW(fp), MAXH(fp), fp->x_flag, fp->y_flag);
+        XCopyArea(display, fp->cache, window, MI_GC(mi),
+                  0, 0, MAXW(fp), MAXH(fp), fp->x_flag, fp->y_flag);
        }
        XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi));
        XFillRectangle(display, fp->cache, MI_GC(mi),
                       0, 0, MAXW(fp), MAXH(fp));
-       XFlush(display);
        affiche(mi);
        fp->sidx += 2;
        fp->sidx %= (ANGLES * MI_NPIXELS(mi));
-       XFlush(display);
        fp->timer++;
        if ((MI_CYCLES(mi) > 0) && (fp->timer >= MI_CYCLES(mi)))
+      {
+        release_flag(mi);
                init_flag(mi);
+      }
 }
 
-void
+ENTRYPOINT void
 release_flag(ModeInfo * mi)
 {
        if (flags != NULL) {
@@ -471,7 +514,7 @@ release_flag(ModeInfo * mi)
 
                for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
                  {
-                       if (flags[screen].cache)
+                       if (flags[screen].cache && flags[screen].dbufp)
                                XFreePixmap(MI_DISPLAY(mi), flags[screen].cache);
                        if (flags[screen].image)
                          XDestroyImage(flags[screen].image);
@@ -481,8 +524,10 @@ release_flag(ModeInfo * mi)
        }
 }
 
-void
+ENTRYPOINT void
 refresh_flag(ModeInfo * mi)
 {
        /* Do nothing, it will refresh by itself */
 }
+
+XSCREENSAVER_MODULE ("Flag", flag)