-/* xscreensaver, Copyright (c) 1999-2005 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1999-2011 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
* Pty and vt100 emulation by Fredrik Tolf <fredrik@dolda2000.com>
*/
-#include "screenhack.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/Intrinsic.h>
+#ifndef HAVE_COCOA
+# define XK_MISCELLANY
+# include <X11/keysymdef.h>
+# include <X11/Xatom.h>
+# include <X11/Intrinsic.h>
+#endif
-#define XK_MISCELLANY
-#include <X11/keysymdef.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# include <fcntl.h> /* for O_RDWR */
+#endif
#ifdef HAVE_FORKPTY
# include <sys/ioctl.h>
# endif
#endif /* HAVE_FORKPTY */
-extern XtAppContext app;
+#include "screenhack.h"
#define FUZZY_BORDER
#define NPAR 16
+#define BUILTIN_FONT
+
+#ifdef BUILTIN_FONT
+# include "images/6x10font.xbm"
+#endif /* BUILTIN_FONT */
+
typedef struct {
unsigned char name;
int width, height;
Window window;
XWindowAttributes xgwa;
XFontStruct *font;
+ const char *program;
int grid_width, grid_height;
int char_width, char_height;
int saved_x, saved_y;
int cursor_x, cursor_y;
XtIntervalId cursor_timer;
+ XtIntervalId pipe_timer;
Time cursor_blink;
FILE *pipe;
XComposeStatus compose;
Bool meta_sends_esc_p;
Bool swap_bs_del_p;
+ int delay;
+
+ char last_c;
+ int bk;
+
+ Bool meta_done_once;
+ unsigned int meta_mask;
} p_state;
that box (the "charcell" box) then we're going to lose it. Alas.
*/
-static p_state *
-init_phosphor (Display *dpy, Window window)
+
+static void clear (p_state *);
+static void set_cursor (p_state *, Bool on);
+
+static void *
+phosphor_init (Display *dpy, Window window)
{
int i;
unsigned long flags;
p_state *state = (p_state *) calloc (sizeof(*state), 1);
- char *fontname = get_string_resource ("font", "Font");
+ char *fontname = get_string_resource (dpy, "font", "Font");
XFontStruct *font;
state->dpy = dpy;
state->window = window;
XGetWindowAttributes (dpy, window, &state->xgwa);
- XSelectInput (dpy, window, state->xgwa.your_event_mask | ExposureMask);
-
- state->meta_sends_esc_p = get_boolean_resource ("metaSendsESC", "Boolean");
- state->swap_bs_del_p = get_boolean_resource ("swapBSDEL", "Boolean");
+/* XSelectInput (dpy, window, state->xgwa.your_event_mask | ExposureMask);*/
- state->font = XLoadQueryFont (dpy, fontname);
+ state->delay = get_integer_resource (dpy, "delay", "Integer");
+ state->meta_sends_esc_p = get_boolean_resource (dpy, "metaSendsESC", "Boolean");
+ state->swap_bs_del_p = get_boolean_resource (dpy, "swapBSDEL", "Boolean");
- if (!state->font)
+ if (!strcasecmp (fontname, "builtin") ||
+ !strcasecmp (fontname, "(builtin)"))
{
- fprintf(stderr, "couldn't load font \"%s\"\n", fontname);
+#ifndef BUILTIN_FONT
+ fprintf (stderr, "%s: no builtin font\n", progname);
state->font = XLoadQueryFont (dpy, "fixed");
+#endif /* !BUILTIN_FONT */
}
- if (!state->font)
+ else
{
- fprintf(stderr, "couldn't load font \"fixed\"");
- exit(1);
+ state->font = XLoadQueryFont (dpy, fontname);
+
+ if (!state->font)
+ {
+ fprintf(stderr, "couldn't load font \"%s\"\n", fontname);
+ state->font = XLoadQueryFont (dpy, "fixed");
+ }
+ if (!state->font)
+ {
+ fprintf(stderr, "couldn't load font \"fixed\"");
+ exit(1);
+ }
}
font = state->font;
- state->scale = get_integer_resource ("scale", "Integer");
- state->ticks = STATE_MAX + get_integer_resource ("ticks", "Integer");
+ state->scale = get_integer_resource (dpy, "scale", "Integer");
+ state->ticks = STATE_MAX + get_integer_resource (dpy, "ticks", "Integer");
state->escstate = 0;
{
- char *s = get_string_resource ("mode", "Integer");
+ char *s = get_string_resource (dpy, "mode", "Integer");
state->mode = 0;
if (!s || !*s || !strcasecmp (s, "pipe"))
state->mode = 0;
printf ("font: %s\n", XGetAtomName(dpy, font->properties[i].card32));
#endif /* 0 */
- state->cursor_blink = get_integer_resource ("cursor", "Time");
+ state->cursor_blink = get_integer_resource (dpy, "cursor", "Time");
state->subproc_relaunch_delay =
- (1000 * get_integer_resource ("relaunch", "Time"));
+ (1000 * get_integer_resource (dpy, "relaunch", "Time"));
+
+# ifdef BUILTIN_FONT
+ if (! font)
+ {
+ state->char_width = (font6x10_width / 256) - 1;
+ state->char_height = font6x10_height;
+ }
+ else
+# endif /* BUILTIN_FONT */
+ {
+ state->char_width = font->max_bounds.width;
+ state->char_height = font->max_bounds.ascent + font->max_bounds.descent;
+ }
+
+ state->program = get_string_resource (dpy, "program", "Program");
+
+
+ /* Kludge for MacOS standalone mode: see OSX/SaverRunner.m. */
+ {
+ const char *s = getenv ("XSCREENSAVER_STANDALONE");
+ if (s && *s && strcmp(s, "0"))
+ {
+ state->mode = 1;
+ state->program = getenv ("SHELL");
+ }
+ }
- state->char_width = font->max_bounds.width;
- state->char_height = font->max_bounds.ascent + font->max_bounds.descent;
state->grid_width = state->xgwa.width / (state->char_width * state->scale);
state->grid_height = state->xgwa.height /(state->char_height * state->scale);
int h1, h2;
double s1, s2, v1, v2;
- unsigned long fg = get_pixel_resource ("foreground", "Foreground",
- state->dpy, state->xgwa.colormap);
- unsigned long bg = get_pixel_resource ("background", "Background",
- state->dpy, state->xgwa.colormap);
- unsigned long flare = get_pixel_resource ("flareForeground", "Foreground",
- state->dpy,state->xgwa.colormap);
- unsigned long fade = get_pixel_resource ("fadeForeground", "Foreground",
- state->dpy,state->xgwa.colormap);
+ unsigned long fg = get_pixel_resource (state->dpy, state->xgwa.colormap,
+ "foreground", "Foreground");
+ unsigned long bg = get_pixel_resource (state->dpy, state->xgwa.colormap,
+ "background", "Background");
+ unsigned long flare = get_pixel_resource (state->dpy,state->xgwa.colormap,
+ "flareForeground", "Foreground");
+ unsigned long fade = get_pixel_resource (state->dpy,state->xgwa.colormap,
+ "fadeForeground", "Foreground");
XColor start, end;
/* Now, GCs all around.
*/
- state->gcv.font = font->fid;
+ state->gcv.font = (font ? font->fid : 0);
state->gcv.cap_style = CapRound;
#ifdef FUZZY_BORDER
state->gcv.line_width = (int) (((long) state->scale) * 1.3);
capture_font_bits (state);
+ set_cursor (state, True);
+
launch_text_generator (state);
+/* clear (state);*/
return state;
}
/* Re-query the window size and update the internal character grid if changed.
*/
-static void
+static Bool
resize_grid (p_state *state)
{
int ow = state->grid_width;
if (ow == state->grid_width &&
oh == state->grid_height)
- return;
+ return False;
state->cells = (p_cell *) calloc (sizeof(p_cell),
state->grid_width * state->grid_height);
state->cursor_y = state->grid_height-1;
free (ocells);
+ return True;
}
capture_font_bits (p_state *state)
{
XFontStruct *font = state->font;
- int safe_width = font->max_bounds.rbearing - font->min_bounds.lbearing;
- int height = state->char_height;
+ int safe_width, height;
unsigned char string[257];
int i;
- Pixmap p = XCreatePixmap (state->dpy, state->window,
- (safe_width * 256), height, 1);
+ Pixmap p;
+
+# ifdef BUILTIN_FONT
+ Pixmap p2 = 0;
+
+ if (!font)
+ {
+ safe_width = state->char_width + 1;
+ height = state->char_height;
+ p2 = XCreatePixmapFromBitmapData (state->dpy, state->window,
+ (char *) font6x10_bits,
+ font6x10_width,
+ font6x10_height,
+ 1, 0, 1);
+ }
+ else
+# endif /* BUILTIN_FONT */
+ {
+ safe_width = font->max_bounds.rbearing - font->min_bounds.lbearing;
+ height = state->char_height;
+ }
+
+ p = XCreatePixmap (state->dpy, state->window,
+ (safe_width * 256), height, 1);
for (i = 0; i < 256; i++)
string[i] = (unsigned char) i;
state->gcv.foreground = 1;
state->gc1 = XCreateGC (state->dpy, p,
- (GCFont | GCForeground | GCBackground |
+ ((font ? GCFont : 0) |
+ GCForeground | GCBackground |
GCCapStyle | GCLineWidth),
&state->gcv);
+#ifdef HAVE_COCOA
+ jwxyz_XSetAntiAliasing (state->dpy, state->gc0, False);
+ jwxyz_XSetAntiAliasing (state->dpy, state->gc1, False);
+#endif
+
#ifdef FUZZY_BORDER
{
state->gcv.line_width = (int) (((long) state->scale) * 0.8);
if (state->gcv.line_width < 1)
state->gcv.line_width = 1;
state->gc2 = XCreateGC (state->dpy, p,
- (GCFont | GCForeground | GCBackground |
+ ((font ? GCFont : 0) |
+ GCForeground | GCBackground |
GCCapStyle | GCLineWidth),
&state->gcv);
}
XFillRectangle (state->dpy, p, state->gc0, 0, 0, (safe_width * 256), height);
- for (i = 0; i < 256; i++)
+# ifdef BUILTIN_FONT
+ if (p2)
+ {
+ XCopyPlane (state->dpy, p2, p, state->gc1,
+ 0, 0, font6x10_width, font6x10_height,
+ 0, 0, 1);
+ XFreePixmap (state->dpy, p2);
+ }
+ else
+# endif /* BUILTIN_FONT */
{
- if (string[i] < font->min_char_or_byte2 ||
- string[i] > font->max_char_or_byte2)
- continue;
- XDrawString (state->dpy, p, state->gc1,
- i * safe_width, font->ascent,
- (char *) (string + i), 1);
+ for (i = 0; i < 256; i++)
+ {
+ if (string[i] < font->min_char_or_byte2 ||
+ string[i] > font->max_char_or_byte2)
+ continue;
+ XDrawString (state->dpy, p, state->gc1,
+ i * safe_width, font->ascent,
+ (char *) (string + i), 1);
+ }
}
/* Draw the cursor. */
XFillRectangle (state->dpy, p, state->gc1,
(CURSOR_INDEX * safe_width), 1,
- (font->per_char
- ? font->per_char['n'-font->min_char_or_byte2].width
- : font->max_bounds.width),
- font->ascent - 1);
+ (font
+ ? (font->per_char
+ ? font->per_char['n'-font->min_char_or_byte2].width
+ : font->max_bounds.width)
+ : state->char_width),
+ (font
+ ? font->ascent - 1
+ : state->char_height));
-#if 0
- XCopyPlane (state->dpy, p, state->window, state->gcs[FLARE],
- 0, 0, (safe_width * 256), height, 0, 0, 1L);
- XSync(state->dpy, False);
-#endif
-
- XSync (state->dpy, False);
state->font_bits = XGetImage (state->dpy, p, 0, 0,
(safe_width * 256), height, ~0L, XYPixmap);
XFreePixmap (state->dpy, p);
int x1, y;
XFontStruct *font = state->font;
- int safe_width = font->max_bounds.rbearing - font->min_bounds.lbearing;
+ int safe_width = (font
+ ? font->max_bounds.rbearing - font->min_bounds.lbearing
+ : state->char_width + 1);
int width = state->scale * state->char_width;
int height = state->scale * state->char_height;
- if (c < font->min_char_or_byte2 ||
- c > font->max_char_or_byte2)
+ if (font && (c < font->min_char_or_byte2 ||
+ c > font->max_char_or_byte2))
goto DONE;
gc = state->gc1;
cursor_off_timer (XtPointer closure, XtIntervalId *id)
{
p_state *state = (p_state *) closure;
+ XtAppContext app = XtDisplayToApplicationContext (state->dpy);
set_cursor_1 (state, False);
state->cursor_timer = XtAppAddTimeOut (app, state->cursor_blink,
cursor_on_timer, closure);
cursor_on_timer (XtPointer closure, XtIntervalId *id)
{
p_state *state = (p_state *) closure;
+ XtAppContext app = XtDisplayToApplicationContext (state->dpy);
set_cursor_1 (state, True);
state->cursor_timer = XtAppAddTimeOut (app, 2 * state->cursor_blink,
cursor_off_timer, closure);
static void
print_char (p_state *state, int c)
{
- static char last_c = 0;
- static int bk;
-
p_cell *cell = &state->cells[state->grid_width * state->cursor_y
+ state->cursor_x];
int i, start, end;
case 10: /* LF */
case 11: /* VT */
case 12: /* FF */
- if(last_c == 13)
+ if(state->last_c == 13)
{
cell->state = NORMAL;
- cell->p_char = state->chars[bk];
+ cell->p_char = state->chars[state->bk];
cell->changed = True;
}
if (state->cursor_y < state->grid_height - 1)
state->cursor_x = 0;
cell = &state->cells[state->grid_width * state->cursor_y];
if((cell->p_char == NULL) || (cell->p_char->name == CURSOR_INDEX))
- bk = ' ';
+ state->bk = ' ';
else
- bk = cell->p_char->name;
+ state->bk = cell->p_char->name;
break;
case 14: /* SO */
case 15: /* SI */
if (c == '\r' || c == '\n') /* handle CR, LF, or CRLF as "new line". */
{
- if (c == '\n' && last_c == '\r')
+ if (c == '\n' && state->last_c == '\r')
; /* CRLF -- do nothing */
else
{
set_cursor (state, True);
}
- last_c = c;
+ state->last_c = c;
}
}
-static void
-run_phosphor (p_state *state)
+static unsigned long
+phosphor_draw (Display *dpy, Window window, void *closure)
{
+ p_state *state = (p_state *) closure;
update_display (state, True);
decay (state);
drain_input (state);
+ return state->delay;
}
\f
static void
launch_text_generator (p_state *state)
{
+ XtAppContext app = XtDisplayToApplicationContext (state->dpy);
char buf[255];
- char *oprogram = get_string_resource ("program", "Program");
+ const char *oprogram = state->program;
char *program = (char *) malloc (strlen (oprogram) + 50);
- /* oprogram contains a "%d" where the current number of columns goes
- */
strcpy (program, "( ");
- sprintf (program + strlen(program), oprogram, state->grid_width);
+ strcat (program, oprogram);
+
+ /* Kludge! Special-case "xscreensaver-text" to tell it how wide
+ the screen is. We used to do this by just always feeding
+ `program' through sprintf() and setting the default value to
+ "xscreensaver-text --cols %d", but that makes things blow up
+ if someone ever uses a --program that includes a % anywhere.
+ */
+ if (!strcmp (oprogram, "xscreensaver-text"))
+ sprintf (program + strlen(program), " --cols %d", state->grid_width-1);
+
strcat (program, " ) 2>&1");
#ifdef HAVE_FORKPTY
{
/* don't mess up controlling terminal if someone dumbly does
"-pipe -program tcsh". */
- fclose (stdin);
+ static int protected_stdin_p = 0;
+ if (! protected_stdin_p) {
+ fclose (stdin);
+ open ("/dev/null", O_RDWR); /* re-allocate fd 0 */
+ protected_stdin_p = 1;
+ }
if ((state->pipe = popen (program, "r")))
{
relaunch_generator_timer (XtPointer closure, XtIntervalId *id)
{
p_state *state = (p_state *) closure;
+ /* if (!state->pipe_timer) abort(); */
+ state->pipe_timer = 0;
launch_text_generator (state);
}
static void
drain_input (p_state *state)
{
- if (state->input_available_p)
+ XtAppContext app = XtDisplayToApplicationContext (state->dpy);
+ if (state->input_available_p && state->pipe)
{
unsigned char s[2];
int n = read (fileno (state->pipe), (void *) s, 1);
+
if (n == 1)
{
print_char (state, s[0]);
{
waitpid(state->pid, NULL, 0);
fclose (state->pipe);
+ state->pid = 0;
}
else
{
}
state->pipe = 0;
- if (state->cursor_x != 0) /* break line if unbroken */
- print_char (state, '\n'); /* blank line */
+ if (state->cursor_x != 0) { /* break line if unbroken */
+ print_char (state, '\r');
+ print_char (state, '\n');
+ }
+ print_char (state, '\r'); /* blank line */
print_char (state, '\n');
/* Set up a timer to re-launch the subproc in a bit. */
- XtAppAddTimeOut (app, state->subproc_relaunch_delay,
- relaunch_generator_timer,
- (XtPointer) state);
+ state->pipe_timer =
+ XtAppAddTimeOut (app, state->subproc_relaunch_delay,
+ relaunch_generator_timer,
+ (XtPointer) state);
}
state->input_available_p = False;
do_icccm_meta_key_stupidity (Display *dpy)
{
unsigned int modbits = 0;
+# ifndef HAVE_COCOA
int i, j, k;
XModifierKeymap *modmap = XGetModifierMapping (dpy);
for (i = 3; i < 8; i++)
XFree (syms);
}
XFreeModifiermap (modmap);
+# endif /* HAVE_COCOA */
return modbits;
}
/* Returns a mask of the bit or bits of a KeyPress event that mean "meta".
*/
static unsigned int
-meta_modifier (Display *dpy)
+meta_modifier (p_state *state)
{
- static Bool done_once = False;
- static unsigned int mask = 0;
- if (!done_once)
+ if (!state->meta_done_once)
{
/* Really, we are supposed to recompute this if a KeymapNotify
event comes in, but fuck it. */
- done_once = True;
- mask = do_icccm_meta_key_stupidity (dpy);
+ state->meta_done_once = True;
+ state->meta_mask = do_icccm_meta_key_stupidity (state->dpy);
}
- return mask;
+ return state->meta_mask;
}
static void
-handle_events (p_state *state)
+phosphor_reshape (Display *dpy, Window window, void *closure,
+ unsigned int w, unsigned int h)
{
- XSync (state->dpy, False);
- while (XPending (state->dpy))
- {
- XEvent event;
- XNextEvent (state->dpy, &event);
+ p_state *state = (p_state *) closure;
+ Bool changed_p = resize_grid (state);
- if (event.xany.type == ConfigureNotify)
- {
- resize_grid (state);
+ if (! changed_p) return;
# if defined(HAVE_FORKPTY) && defined(TIOCSWINSZ)
- if (state->pid)
- {
- /* Tell the sub-process that the screen size has changed. */
- struct winsize ws;
- ws.ws_row = state->grid_height - 1;
- ws.ws_col = state->grid_width - 2;
- ws.ws_xpixel = state->xgwa.width;
- ws.ws_ypixel = state->xgwa.height;
- ioctl (fileno (state->pipe), TIOCSWINSZ, &ws);
- kill (state->pid, SIGWINCH);
- }
+ if (state->pid && state->pipe)
+ {
+ /* Tell the sub-process that the screen size has changed. */
+ struct winsize ws;
+ ws.ws_row = state->grid_height - 1;
+ ws.ws_col = state->grid_width - 2;
+ ws.ws_xpixel = state->xgwa.width;
+ ws.ws_ypixel = state->xgwa.height;
+ ioctl (fileno (state->pipe), TIOCSWINSZ, &ws);
+ kill (state->pid, SIGWINCH);
+ }
# endif /* HAVE_FORKPTY && TIOCSWINSZ */
- }
- else if (event.xany.type == Expose)
- {
- update_display (state, False);
- }
- else if (event.xany.type == KeyPress)
+
+
+ /* If we're running xscreensaver-text, then kill and restart it any
+ time the window is resized so that it gets an updated --cols arg
+ right away. But if we're running something else, leave it alone.
+ */
+ if (!strcmp (state->program, "xscreensaver-text"))
+ {
+ if (state->pid)
+ kill (state->pid, SIGTERM);
+ if (state->pipe)
+ pclose (state->pipe);
+ state->input_available_p = False;
+ relaunch_generator_timer (state, 0);
+ }
+}
+
+
+static Bool
+phosphor_event (Display *dpy, Window window, void *closure, XEvent *event)
+{
+ p_state *state = (p_state *) closure;
+
+ if (event->xany.type == Expose)
+ update_display (state, False);
+ else if (event->xany.type == KeyPress)
+ {
+ KeySym keysym;
+ unsigned char c = 0;
+ XLookupString (&event->xkey, (char *) &c, 1, &keysym,
+ &state->compose);
+ if (c != 0 && state->pipe)
{
- KeySym keysym;
- unsigned char c = 0;
- XLookupString (&event.xkey, (char *) &c, 1, &keysym,
- &state->compose);
- if (c != 0 && state->pipe)
+ if (!state->swap_bs_del_p) ;
+ else if (c == 127) c = 8;
+ else if (c == 8) c = 127;
+
+ /* If meta was held down, send ESC, or turn on the high bit. */
+ if (event->xkey.state & meta_modifier (state))
{
- if (!state->swap_bs_del_p) ;
- else if (c == 127) c = 8;
- else if (c == 8) c = 127;
-
- /* If meta was held down, send ESC, or turn on the high bit. */
- if (event.xkey.state & meta_modifier (state->dpy))
- {
- if (state->meta_sends_esc_p)
- fputc ('\033', state->pipe);
- else
- c |= 0x80;
- }
-
- fputc (c, state->pipe);
- fflush (state->pipe);
- event.xany.type = 0; /* don't interpret this event defaultly. */
+ if (state->meta_sends_esc_p)
+ fputc ('\033', state->pipe);
+ else
+ c |= 0x80;
}
- }
- screenhack_handle_event (state->dpy, &event);
+ fputc (c, state->pipe);
+ fflush (state->pipe);
+ event->xany.type = 0; /* don't interpret this event defaultly. */
+ }
+ return True;
}
- if (XtAppPending (app) & (XtIMTimer|XtIMAlternateInput))
- XtAppProcessEvent (app, XtIMTimer|XtIMAlternateInput);
+ return False;
+}
+
+static void
+phosphor_free (Display *dpy, Window window, void *closure)
+{
+ p_state *state = (p_state *) closure;
+
+ if (state->pipe_id)
+ XtRemoveInput (state->pipe_id);
+ if (state->pipe)
+ pclose (state->pipe);
+ if (state->cursor_timer)
+ XtRemoveTimeOut (state->cursor_timer);
+ if (state->pipe_timer)
+ XtRemoveTimeOut (state->pipe_timer);
+
+ /* #### there's more to free here */
+
+ free (state);
}
-\f
-char *progclass = "Phosphor";
-char *defaults [] = {
+static const char *phosphor_defaults [] = {
".background: Black",
- ".foreground: Green",
- "*fadeForeground: DarkGreen",
- "*flareForeground: White",
+ ".foreground: #00FF00",
+ "*fpsSolid: true",
+ "*fadeForeground: #006400",
+ "*flareForeground: #FFFFFF",
+#if defined(BUILTIN_FONT)
+ "*font: (builtin)",
+#elif defined(HAVE_COCOA)
+ "*font: Monaco 15",
+#else
"*font: fixed",
+#endif
"*scale: 6",
"*ticks: 20",
"*delay: 50000",
"*cursor: 333",
- "*program: xscreensaver-text --cols %d",
+ "*program: xscreensaver-text",
"*relaunch: 5",
"*metaSendsESC: True",
"*swapBSDEL: True",
0
};
-XrmOptionDescRec options [] = {
+static XrmOptionDescRec phosphor_options [] = {
{ "-font", ".font", XrmoptionSepArg, 0 },
{ "-scale", ".scale", XrmoptionSepArg, 0 },
{ "-ticks", ".ticks", XrmoptionSepArg, 0 },
};
-void
-screenhack (Display *dpy, Window window)
-{
- int delay = get_integer_resource ("delay", "Integer");
- p_state *state = init_phosphor (dpy, window);
-
- clear (state);
-
- while (1)
- {
- run_phosphor (state);
- XSync (dpy, False);
- handle_events (state);
- if (delay) usleep (delay);
- }
-}
+XSCREENSAVER_MODULE ("Phosphor", phosphor)