/*
- * fliptext, Copyright (c) 2005 Jamie Zawinski <jwz@jwz.org>
+ * fliptext, Copyright (c) 2005-2007 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
* implied warranty.
*/
-#include <X11/Intrinsic.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
-extern XtAppContext app;
+#include <ctype.h>
+#include <sys/stat.h>
-#define PROGCLASS "FlipText"
-#define HACK_INIT init_fliptext
-#define HACK_DRAW draw_fliptext
-#define HACK_RESHAPE reshape_fliptext
-#define fliptext_opts xlockmore_opts
+#ifndef HAVE_COCOA
+# include <X11/Intrinsic.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_UNAME
+# include <sys/utsname.h>
+#endif /* HAVE_UNAME */
-#define DEF_PROGRAM "xscreensaver-text --cols 0" /* don't wrap */
-#define DEF_LINES "8"
-#define DEF_FONT_SIZE "20"
-#define DEF_COLUMNS "80"
-#define DEF_ALIGN "random"
-#define DEF_COLOR "#00CCFF"
-#define DEF_SPEED "1.0"
/* Utopia 800 needs 64 512x512 textures (4096x4096 bitmap).
Utopia 720 needs 16 512x512 textures (2048x2048 bitmap).
Times 240 needs 1 512x512 texture.
*/
#define DEF_FONT "-*-utopia-bold-r-normal-*-*-720-*-*-*-*-iso8859-1"
-
-#define TAB_WIDTH 8
-
-#define FONT_WEIGHT 14
-#define KEEP_ASPECT
+#define DEF_COLOR "#00CCFF"
#define DEFAULTS "*delay: 10000 \n" \
"*showFPS: False \n" \
"*font: " DEF_FONT "\n" \
".foreground: " DEF_COLOR "\n" \
+# define refresh_fliptext 0
+# define fliptext_handle_event 0
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
#define BELLRAND(n) ((frand((n)) + frand((n)) + frand((n))) / 3)
#include "xlockmore.h"
+#include "texfont.h"
#ifdef USE_GL /* whole file */
-#include <ctype.h>
-#include <GL/glu.h>
-#include <sys/stat.h>
-#include "texfont.h"
+/* Should be in <GL/glext.h> */
+# ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
+# define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+# endif
+# ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
+# define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+# endif
-#ifdef HAVE_UNAME
-# include <sys/utsname.h>
-#endif /* HAVE_UNAME */
+
+#define DEF_PROGRAM "xscreensaver-text --cols 0" /* don't wrap */
+#define DEF_LINES "8"
+#define DEF_FONT_SIZE "20"
+#define DEF_COLUMNS "80"
+#define DEF_ALIGN "random"
+#define DEF_SPEED "1.0"
+#define TAB_WIDTH 8
+
+#define FONT_WEIGHT 14
+#define KEEP_ASPECT
typedef enum { NEW, HESITATE, IN, LINGER, OUT, DEAD } line_state;
typedef enum { SCROLL_BOTTOM, SCROLL_TOP, SPIN } line_anim_type;
typedef struct {
+ Display *dpy;
GLXContext *glx_context;
texture_font_data *texfont;
FILE *pipe;
XtInputId pipe_id;
+ XtIntervalId pipe_timer;
Time subproc_relaunch_delay;
char *buf;
{"-columns", ".columns", XrmoptionSepArg, 0 },
{"-speed", ".speed", XrmoptionSepArg, 0 },
/*{"-font", ".font", XrmoptionSepArg, 0 },*/
+ {"-alignment", ".alignment", XrmoptionSepArg, 0 },
{"-left", ".alignment", XrmoptionNoArg, "Left" },
{"-right", ".alignment", XrmoptionNoArg, "Right" },
{"-center", ".alignment", XrmoptionNoArg, "Center" },
{&speed, "speed", "Speed", DEF_SPEED, t_Float},
};
-ModeSpecOpt fliptext_opts = {countof(opts), opts, countof(vars), vars, NULL};
+ENTRYPOINT ModeSpecOpt fliptext_opts = {countof(opts), opts, countof(vars), vars, NULL};
static void
launch_text_generator (fliptext_configuration *sc)
{
- char *oprogram = get_string_resource ("program", "Program");
+ XtAppContext app = XtDisplayToApplicationContext (sc->dpy);
+ char *oprogram = get_string_resource (sc->dpy, "program", "Program");
char *program = (char *) malloc (strlen (oprogram) + 10);
strcpy (program, "( ");
strcat (program, oprogram);
relaunch_generator_timer (XtPointer closure, XtIntervalId *id)
{
fliptext_configuration *sc = (fliptext_configuration *) closure;
+ if (!sc->pipe_timer) abort();
+ sc->pipe_timer = 0;
launch_text_generator (sc);
}
static void
drain_input (fliptext_configuration *sc)
{
+ XtAppContext app = XtDisplayToApplicationContext (sc->dpy);
if (sc->buf_tail < sc->buf_size - 2)
{
int target = sc->buf_size - sc->buf_tail - 2;
sc->buf[sc->buf_tail] = 0;
/* Set up a timer to re-launch the subproc in a bit. */
- XtAppAddTimeOut (app, sc->subproc_relaunch_delay,
- relaunch_generator_timer,
- (XtPointer) sc);
+ sc->pipe_timer = XtAppAddTimeOut (app, sc->subproc_relaunch_delay,
+ relaunch_generator_timer,
+ (XtPointer) sc);
}
}
}
ln->width = sc->font_scale * texture_string_width (sc->texfont, s, 0);
ln->height = sc->font_scale * sc->line_height;
+ memcpy (ln->color, sc->color, sizeof(ln->color));
+
sc->nlines++;
if (sc->lines_size <= sc->nlines)
{
static void
tick_line (fliptext_configuration *sc, line *line)
{
- int stagger = 60; /* frames of delay between line spin-outs */
+ int stagger = 30; /* frames of delay between line spin-outs */
int slide = 600; /* frames in a slide in/out */
int linger = 0; /* frames to pause with no motion */
- double i;
+ double i, ii;
if (line->state >= DEAD) abort();
if (++line->step >= line->steps)
if (linger == 0 && line->state == LINGER)
line->state++;
+ if (sc->anim_type != SPIN)
+ stagger *= 2;
+
switch (line->state)
{
case HESITATE: /* entering state HESITATE */
break;
case IN:
- memset (line->color, 0, sizeof (line->color));
+ line->color[3] = 0;
switch (sc->anim_type)
{
case SCROLL_BOTTOM: /* entering state BOTTOM IN */
break;
case OUT:
- memcpy (sc->color, line->color, sizeof(line->color));
switch (sc->anim_type)
{
case SCROLL_BOTTOM: /* entering state BOTTOM OUT */
break;
case LINGER:
- memcpy (sc->color, line->color, sizeof(line->color));
line->from = line->to;
line->steps = linger;
break;
case IN:
case OUT:
i = (double) line->step / line->steps;
- if (line->state == IN) i = 1-i;
- i = i * i;
- if (line->state == IN) i = 1-i;
-
- line->color[0] = sc->color[0] * (line->state == IN ? i : 1-i);
- line->color[1] = sc->color[1] * (line->state == IN ? i : 1-i);
- line->color[2] = sc->color[2] * (line->state == IN ? i : 1-i);
- line->color[3] = sc->color[3] * (line->state == IN ? i : 1-i);
-
- line->current.x = line->from.x + (i * (line->to.x - line->from.x));
- line->current.y = line->from.y + (i * (line->to.y - line->from.y));
- line->current.z = line->from.z + (i * (line->to.z - line->from.z));
- line->cth = line->fth + (i * (line->tth - line->fth));
+
+ /* Move along the path exponentially, slow side towards the middle. */
+ if (line->state == OUT)
+ ii = i * i;
+ else
+ ii = 1 - ((1-i) * (1-i));
+
+ line->current.x = line->from.x + (ii * (line->to.x - line->from.x));
+ line->current.y = line->from.y + (ii * (line->to.y - line->from.y));
+ line->current.z = line->from.z + (ii * (line->to.z - line->from.z));
+ line->cth = line->fth + (ii * (line->tth - line->fth));
+
+ if (line->state == OUT) ii = 1-ii;
+ line->color[3] = sc->color[3] * ii;
break;
case HESITATE:
sc->rotation.y = 5 - BELLRAND(10);
sc->rotation.z = 5 - BELLRAND(10);
- switch (random() % 7)
+ switch (random() % 8)
{
case 0: sc->anim_type = SCROLL_TOP; break;
case 1: sc->anim_type = SCROLL_BOTTOM; break;
maxy -= maxh/2;
sc->mid.x = minx + frand (maxx - minx);
- sc->mid.y = miny + frand (maxy - miny);
+ if (sc->anim_type == SPIN)
+ sc->mid.y = miny + BELLRAND (maxy - miny);
+ else
+ sc->mid.y = miny + frand (maxy - miny);
sc->in.x = BELLRAND(sc->right_margin * 2) - sc->right_margin;
sc->out.x = BELLRAND(sc->right_margin * 2) - sc->right_margin;
/* Window management, etc
*/
-void
+ENTRYPOINT void
reshape_fliptext (ModeInfo *mi, int width, int height)
{
fliptext_configuration *sc = &scs[MI_SCREEN(mi)];
}
-void
+ENTRYPOINT void
init_fliptext (ModeInfo *mi)
{
int wire = MI_IS_WIREFRAME(mi);
}
sc = &scs[MI_SCREEN(mi)];
+ sc->dpy = MI_DISPLAY(mi);
if ((sc->glx_context = init_GL(mi)) != NULL) {
reshape_fliptext (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
}
- program = get_string_resource ("program", "Program");
+ program = get_string_resource (mi->dpy, "program", "Program");
{
int cw, lh;
glEnable (GL_ALPHA_TEST);
glEnable (GL_TEXTURE_2D);
-# ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
/* "Anistropic filtering helps for quadrilateral-angled textures.
A sharper image is accomplished by interpolating and filtering
multiple samples from one or more mipmaps to better approximate
very distorted textures. This is the next level of filtering
after trilinear filtering." */
- glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16);
- clear_gl_error();
-# endif
+ if (strstr ((char *) glGetString(GL_EXTENSIONS),
+ "GL_EXT_texture_filter_anisotropic"))
+ {
+ GLfloat anisotropic = 0.0;
+ glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic);
+ if (anisotropic >= 1.0)
+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ anisotropic);
+ }
}
/* The default font is (by fiat) "18 points".
if (min_lines < 1) min_lines = 1;
parse_color (mi, "foreground",
- get_string_resource("foreground", "Foreground"),
+ get_string_resource(mi->dpy, "foreground", "Foreground"),
sc->color);
sc->top_margin = (sc->char_width * 100);
}
-void
+ENTRYPOINT void
draw_fliptext (ModeInfo *mi)
{
fliptext_configuration *sc = &scs[MI_SCREEN(mi)];
+/* XtAppContext app = XtDisplayToApplicationContext (sc->dpy);*/
Display *dpy = MI_DISPLAY(mi);
Window window = MI_WINDOW(mi);
int i;
if (!sc->glx_context)
return;
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sc->glx_context));
+
+#if 0
if (XtAppPending (app) & (XtIMTimer|XtIMAlternateInput))
XtAppProcessEvent (app, XtIMTimer|XtIMAlternateInput);
+#endif
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glXSwapBuffers(dpy, window);
}
+ENTRYPOINT void
+release_fliptext (ModeInfo *mi)
+{
+ if (scs) {
+ int screen;
+ for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
+ fliptext_configuration *sc = &scs[screen];
+ if (sc->pipe_id)
+ XtRemoveInput (sc->pipe_id);
+ if (sc->pipe)
+ pclose (sc->pipe);
+ if (sc->pipe_timer)
+ XtRemoveTimeOut (sc->pipe_timer);
+
+ /* #### there's more to free here */
+ }
+ free (scs);
+ scs = 0;
+ }
+ FreeAllGL(mi);
+}
+
+XSCREENSAVER_MODULE ("FlipText", fliptext)
+
#endif /* USE_GL */