X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Ffliptext.c;h=d35706cb2a5ad0325c22c865f9341f72f2271c43;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hp=58241a686e5517d015ef8194ab9a5db1b61fbefa;hpb=c1b9b55ad8d59dc05ef55e316aebf5863e7dfa56;p=xscreensaver diff --git a/hacks/glx/fliptext.c b/hacks/glx/fliptext.c index 58241a68..d35706cb 100644 --- a/hacks/glx/fliptext.c +++ b/hacks/glx/fliptext.c @@ -1,5 +1,5 @@ /* - * fliptext, Copyright (c) 2005-2007 Jamie Zawinski + * fliptext, Copyright (c) 2005-2015 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -14,39 +14,20 @@ # include "config.h" #endif /* HAVE_CONFIG_H */ -#include -#include - -#ifndef HAVE_COCOA -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_UNAME -# include -#endif /* HAVE_UNAME */ - - -/* Utopia 800 needs 64 512x512 textures (4096x4096 bitmap). - Utopia 720 needs 16 512x512 textures (2048x2048 bitmap). - Utopia 480 needs 16 512x512 textures (2048x2048 bitmap). - Utopia 400 needs 4 512x512 textures (1024x1024 bitmap). - Utopia 180 needs 1 512x512 texture. - Times 240 needs 1 512x512 texture. - */ -#define DEF_FONT "-*-utopia-bold-r-normal-*-*-720-*-*-*-*-iso8859-1" +#define DEF_FONT "-*-utopia-bold-r-normal-*-*-720-*-*-*-*-*-*" #define DEF_COLOR "#00CCFF" #define DEFAULTS "*delay: 10000 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" \ + "*usePty: False \n" \ + "*texFontCacheSize: 60 \n" \ "*font: " DEF_FONT "\n" \ ".foreground: " DEF_COLOR "\n" \ + "*program: xscreensaver-text --cols 0" /* don't wrap */ # define refresh_fliptext 0 +# define release_fliptext 0 # define fliptext_handle_event 0 #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -56,6 +37,7 @@ #include "xlockmore.h" #include "texfont.h" +#include "textclient.h" #ifdef USE_GL /* whole file */ @@ -68,7 +50,6 @@ # endif -#define DEF_PROGRAM "xscreensaver-text --cols 0" /* don't wrap */ #define DEF_LINES "8" #define DEF_FONT_SIZE "20" #define DEF_COLUMNS "80" @@ -105,11 +86,9 @@ typedef struct { GLXContext *glx_context; texture_font_data *texfont; + text_data *tc; - FILE *pipe; - XtInputId pipe_id; - XtIntervalId pipe_timer; - Time subproc_relaunch_delay; + int alignment; char *buf; int buf_size; @@ -138,16 +117,14 @@ typedef struct { static fliptext_configuration *scs = NULL; -static char *program; static int max_lines, min_lines; static float font_size; static int target_columns; static char *alignment_str; -static int alignment, alignment_random_p; +static int alignment_random_p; static GLfloat speed; static XrmOptionDescRec opts[] = { - {"-program", ".program", XrmoptionSepArg, 0 }, {"-lines", ".lines", XrmoptionSepArg, 0 }, {"-size", ".fontSize", XrmoptionSepArg, 0 }, {"-columns", ".columns", XrmoptionSepArg, 0 }, @@ -160,7 +137,6 @@ static XrmOptionDescRec opts[] = { }; static argtype vars[] = { - {&program, "program", "Program", DEF_PROGRAM, t_String}, {&max_lines, "lines", "Integer", DEF_LINES, t_Int}, {&font_size, "fontSize", "Float", DEF_FONT_SIZE, t_Float}, {&target_columns, "columns", "Integer", DEF_COLUMNS, t_Int}, @@ -233,113 +209,15 @@ strip (char *s, Bool leading, Bool trailing) } - -/* Subprocess. - (This bit mostly cribbed from phosphor.c) - */ - -static void drain_input (fliptext_configuration *sc); - -static void -subproc_cb (XtPointer closure, int *source, XtInputId *id) -{ - fliptext_configuration *sc = (fliptext_configuration *) closure; - drain_input (sc); -} - - -static void -launch_text_generator (fliptext_configuration *sc) -{ - 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); - strcat (program, " ) 2>&1"); - - if ((sc->pipe = popen (program, "r"))) - { - sc->pipe_id = - XtAppAddInput (app, fileno (sc->pipe), - (XtPointer) (XtInputReadMask | XtInputExceptMask), - subproc_cb, (XtPointer) sc); - } - else - { - perror (program); - } -} - - -static void -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); -} - - -/* When the subprocess has generated some output, this reads as much as it - can into sc->buf at sc->buf_tail. - */ -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; - int n = (sc->pipe - ? read (fileno (sc->pipe), - (void *) (sc->buf + sc->buf_tail), - target) - : 0); - if (n > 0) - { - sc->buf_tail += n; - sc->buf[sc->buf_tail] = 0; - } - else - { - if (sc->pipe) - { - XtRemoveInput (sc->pipe_id); - sc->pipe_id = 0; - pclose (sc->pipe); - sc->pipe = 0; - } - - /* If the process didn't print a terminating newline, add one. */ - if (sc->buf_tail > 1 && - sc->buf[sc->buf_tail-1] != '\n') - { - sc->buf[sc->buf_tail++] = '\n'; - sc->buf[sc->buf_tail] = 0; - } - - /* Then add one more, just for giggles. */ - sc->buf[sc->buf_tail++] = '\n'; - sc->buf[sc->buf_tail] = 0; - - /* Set up a timer to re-launch the subproc in a bit. */ - sc->pipe_timer = XtAppAddTimeOut (app, sc->subproc_relaunch_delay, - relaunch_generator_timer, - (XtPointer) sc); - } - } -} - - static int char_width (fliptext_configuration *sc, char c) { + XCharStruct e; char s[2]; s[0] = c; s[1] = 0; - return texture_string_width (sc->texfont, s, 0); + texture_string_metrics (sc->texfont, s, &e, 0, 0); + return e.width; } @@ -354,8 +232,23 @@ get_one_line (fliptext_configuration *sc) int wrap_pix = sc->font_wrap_pixels; int col = 0; int col_pix = 0; - char *s = sc->buf; + int target = sc->buf_size - sc->buf_tail - 2; + + /* Fill as much as we can into sc->buf, but stop at newline. + */ + while (target > 0) + { + int c = textclient_getc (sc->tc); + if (c <= 0) + break; + sc->buf[sc->buf_tail++] = (char) c; + sc->buf[sc->buf_tail] = 0; + target--; + if (c == '\r' || c == '\n') + break; + } + while (!result) { int cw; @@ -401,8 +294,8 @@ get_one_line (fliptext_configuration *sc) { char *t = result; char *ut = untabify (t); - strip (ut, (alignment == 0), 1); /* if centering, strip - leading whitespace too */ + strip (ut, (sc->alignment == 0), 1); /* if centering, strip + leading whitespace too */ result = ut; free (t); } @@ -461,6 +354,7 @@ blank_p (const char *s) static line * make_line (fliptext_configuration *sc, Bool skip_blanks_p) { + XCharStruct e; line *ln; char *s; @@ -477,7 +371,8 @@ make_line (fliptext_configuration *sc, Bool skip_blanks_p) ln = (line *) calloc (1, sizeof(*ln)); ln->text = s; ln->state = NEW; - ln->width = sc->font_scale * texture_string_width (sc->texfont, s, 0); + texture_string_metrics (sc->texfont, s, &e, 0, 0); + ln->width = sc->font_scale * e.width; ln->height = sc->font_scale * sc->line_height; memcpy (ln->color, sc->color, sizeof(ln->color)); @@ -536,9 +431,9 @@ draw_line (ModeInfo *mi, line *line) glRotatef (line->cth, 0, 1, 0); - if (alignment == 1) + if (sc->alignment == 1) glTranslatef (-line->width, 0, 0); - else if (alignment == 0) + else if (sc->alignment == 0) glTranslatef (-line->width/2, 0, 0); glScalef (sc->font_scale, sc->font_scale, sc->font_scale); @@ -557,8 +452,11 @@ draw_line (ModeInfo *mi, line *line) glColor3f (0.4, 0.4, 0.4); while (*s) { + XCharStruct e; *c = *s++; - w = texture_string_width (sc->texfont, c, &h); + texture_string_metrics (sc->texfont, c, &e, 0, 0); + w = e.width; + h = e.ascent + e.descent; glBegin (GL_LINE_LOOP); glVertex3f (0, 0, 0); glVertex3f (w, 0, 0); @@ -789,11 +687,11 @@ reset_lines (ModeInfo *mi) maxh = maxy - miny; if (alignment_random_p) - alignment = (random() % 3) - 1; + sc->alignment = (random() % 3) - 1; - if (alignment == -1) maxx -= maxw; - else if (alignment == 1) minx += maxw; - else minx += maxw/2, maxx -= maxw/2; + if (sc->alignment == -1) maxx -= maxw; + else if (sc->alignment == 1) minx += maxw; + else minx += maxw/2, maxx -= maxw/2; miny += maxh/2; maxy -= maxh/2; @@ -890,6 +788,9 @@ reshape_fliptext (ModeInfo *mi, int width, int height) } +static void free_fliptext (ModeInfo *mi); + + ENTRYPOINT void init_fliptext (ModeInfo *mi) { @@ -897,32 +798,26 @@ init_fliptext (ModeInfo *mi) fliptext_configuration *sc; - if (!scs) { - scs = (fliptext_configuration *) - calloc (MI_NUM_SCREENS(mi), sizeof (fliptext_configuration)); - if (!scs) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - - sc = &scs[MI_SCREEN(mi)]; - sc->lines = (line **) calloc (max_lines+1, sizeof(char *)); - } + MI_INIT(mi, scs, free_fliptext); sc = &scs[MI_SCREEN(mi)]; + sc->lines = (line **) calloc (max_lines+1, sizeof(char *)); + sc->dpy = MI_DISPLAY(mi); if ((sc->glx_context = init_GL(mi)) != NULL) { reshape_fliptext (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */ } - program = get_string_resource (mi->dpy, "program", "Program"); - { - int cw, lh; + XCharStruct e; + int cw, lh, ascent, descent; sc->texfont = load_texture_font (MI_DISPLAY(mi), "font"); check_gl_error ("loading font"); - cw = texture_string_width (sc->texfont, "n", &lh); + texture_string_metrics (sc->texfont, "n", &e, &ascent, &descent); + cw = e.width; + lh = ascent + descent; sc->char_width = cw; sc->line_height = lh; } @@ -972,19 +867,17 @@ init_fliptext (ModeInfo *mi) sc->buf_size = target_columns * max_lines; sc->buf = (char *) calloc (1, sc->buf_size); - sc->subproc_relaunch_delay = 2 * 1000; /* 2 seconds */ - alignment_random_p = False; if (!alignment_str || !*alignment_str || !strcasecmp(alignment_str, "left")) - alignment = -1; + sc->alignment = -1; else if (!strcasecmp(alignment_str, "center") || !strcasecmp(alignment_str, "middle")) - alignment = 0; + sc->alignment = 0; else if (!strcasecmp(alignment_str, "right")) - alignment = 1; + sc->alignment = 1; else if (!strcasecmp(alignment_str, "random")) - alignment = -1, alignment_random_p = True; + sc->alignment = -1, alignment_random_p = True; else { @@ -994,7 +887,7 @@ init_fliptext (ModeInfo *mi) exit (1); } - launch_text_generator (sc); + sc->tc = textclient_open (sc->dpy); if (max_lines < 1) max_lines = 1; min_lines = max_lines * 0.66; @@ -1035,6 +928,7 @@ draw_fliptext (ModeInfo *mi) mi->polygon_count = 0; glPushMatrix(); + glRotatef(current_device_rotation(), 0, 0, 1); { GLfloat s = 3.0 / (sc->top_margin - sc->bottom_margin); glScalef(s, s, s); @@ -1088,26 +982,15 @@ draw_fliptext (ModeInfo *mi) glXSwapBuffers(dpy, window); } -ENTRYPOINT void -release_fliptext (ModeInfo *mi) +static void +free_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); + fliptext_configuration *sc = &scs[MI_SCREEN(mi)]; + if (sc->tc) + textclient_close (sc->tc); + free(sc->lines); + + /* #### there's more to free here */ } XSCREENSAVER_MODULE ("FlipText", fliptext)