http://ftp.ksu.edu.tw/FTP/FreeBSD/distfiles/xscreensaver-4.20.tar.gz
[xscreensaver] / hacks / xlockmore.c
index 28828beb1e25439958dcd026bb421fb0f645630c..2ad0be4c0b21ff28ac89c34d126ff1695a77c900 100644 (file)
@@ -1,5 +1,6 @@
 /* xlockmore.c --- xscreensaver compatibility layer for xlockmore modules.
- * xscreensaver, Copyright (c) 1997, 1998, 2001 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 1997, 1998, 2001, 2002, 2004
+ *  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
 #include <sys/time.h>
 #include "screenhack.h"
 #include "xlockmoreI.h"
+#include <X11/Intrinsic.h>
 
 #define countof(x) (sizeof((x))/sizeof(*(x)))
 
 #define MAX_COLORS (1L<<13)
 
+extern XtAppContext app;
 extern ModeSpecOpt xlockmore_opts[];
 extern const char *app_defaults;
 
@@ -65,7 +68,7 @@ pre_merge_options (void)
   /* Add extra args, if they're mentioned in the defaults... */
   {
     char *args[] = { "-count", "-cycles", "-delay", "-ncolors",
-                    "-size", "-wireframe", "-use3d", "-useSHM",
+                    "-size", "-font", "-wireframe", "-use3d", "-useSHM",
                      "-showFPS" };
     for (j = 0; j < countof(args); j++)
       if (strstr(app_defaults, args[j]+1))
@@ -213,8 +216,12 @@ xlockmore_read_resources (void)
 
 static void
 xlockmore_handle_events (ModeInfo *mi, 
-                         void (*reshape) (ModeInfo *, int, int))
+                         void (*reshape) (ModeInfo *, int, int),
+                         Bool (*hook) (ModeInfo *, XEvent *))
 {
+  if (XtAppPending (app) & (XtIMTimer|XtIMAlternateInput))
+    XtAppProcessEvent (app, XtIMTimer|XtIMAlternateInput);
+
   while (XPending (mi->dpy))
     {
       XEvent event;
@@ -224,6 +231,9 @@ xlockmore_handle_events (ModeInfo *mi,
           XGetWindowAttributes (mi->dpy, mi->window, &mi->xgwa);
           reshape (mi, mi->xgwa.width, mi->xgwa.height);
         }
+      else if (hook && hook (mi, &event))
+        {
+        }
       else
         {
           screenhack_handle_event (mi->dpy, &event);
@@ -238,9 +248,11 @@ xlockmore_screenhack (Display *dpy, Window window,
                      Bool want_uniform_colors,
                      Bool want_smooth_colors,
                      Bool want_bright_colors,
+                      unsigned long event_mask,
                      void (*hack_init) (ModeInfo *),
                      void (*hack_draw) (ModeInfo *),
                      void (*hack_reshape) (ModeInfo *, int, int),
+                     Bool (*hack_handle_events) (ModeInfo *, XEvent *),
                      void (*hack_free) (ModeInfo *))
 {
   ModeInfo mi;
@@ -249,11 +261,22 @@ xlockmore_screenhack (Display *dpy, Window window,
   int i;
   time_t start, now;
   int orig_pause;
+  Bool root_p;
 
   memset(&mi, 0, sizeof(mi));
   mi.dpy = dpy;
   mi.window = window;
   XGetWindowAttributes (dpy, window, &mi.xgwa);
+  root_p = (window == RootWindowOfScreen (mi.xgwa.screen));
+
+  /* If this is the root window, don't allow ButtonPress to be selected.
+     Bad Things Happen. */
+  if (root_p)
+    event_mask &= (~(ButtonPressMask|ButtonReleaseMask));
+
+  /* If this hack wants additional events, select them. */
+  if (event_mask && ! (mi.xgwa.your_event_mask & event_mask))
+    XSelectInput (dpy, window, (mi.xgwa.your_event_mask | event_mask));
 
   color.flags = DoRed|DoGreen|DoBlue;
   color.red = color.green = color.blue = 0;
@@ -311,7 +334,6 @@ xlockmore_screenhack (Display *dpy, Window window,
        goto MONO;
       else
        {
-         int i;
          mi.pixels = (unsigned long *)
            calloc (mi.npixels, sizeof (*mi.pixels));
          for (i = 0; i < mi.npixels; i++)
@@ -343,7 +365,7 @@ xlockmore_screenhack (Display *dpy, Window window,
                                             mi.xgwa.colormap);
 
   mi.wireframe_p = get_boolean_resource ("wireframe", "Boolean");
-  mi.root_p = (window == RootWindowOfScreen (mi.xgwa.screen));
+  mi.root_p = root_p;
   mi.fps_p = get_boolean_resource ("showFPS", "Boolean");
 #ifdef HAVE_XSHM_EXTENSION
   mi.use_shm = get_boolean_resource ("useSHM", "Boolean");
@@ -355,6 +377,32 @@ xlockmore_screenhack (Display *dpy, Window window,
     mi.pause = 100000000;
   orig_pause = mi.pause;
 
+  /* If this hack uses fonts (meaning, mentioned "font" in DEFAULTS)
+     then load it. */
+  {
+    char *name = get_string_resource ("font", "Font");
+    if (name)
+      {
+        XFontStruct *f = XLoadQueryFont (dpy, name);
+        const char *def1 = "-*-times-bold-r-normal-*-180-*";
+        const char *def2 = "fixed";
+        if (!f)
+          {
+            fprintf (stderr, "%s: font %s does not exist, using %s\n",
+                     progname, name, def1);
+            f = XLoadQueryFont (dpy, def1);
+          }
+        if (!f)
+          {
+            fprintf (stderr, "%s: font %s does not exist, using %s\n",
+                     progname, def1, def2);
+            f = XLoadQueryFont (dpy, def2);
+          }
+        if (f) XSetFont (dpy, mi.gc, f->fid);
+        if (f) XFreeFont (dpy, f);
+      }
+  }
+
   xlockmore_read_resources ();
 
   XClearWindow (dpy, window);
@@ -366,7 +414,7 @@ xlockmore_screenhack (Display *dpy, Window window,
   do {
     hack_draw (&mi);
     XSync(dpy, False);
-    xlockmore_handle_events (&mi, hack_reshape);
+    xlockmore_handle_events (&mi, hack_reshape, hack_handle_events);
     if (mi.pause)
       usleep(mi.pause);
     mi.pause = orig_pause;