X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fxmatrix.c;h=decddaa7bd7c8aaaf64b376452775dbd762d6ada;hb=78add6e627ee5f10e1fa6f3852602ea5066eee5a;hp=60fe09dd2b9c487dedf355b3ceaaab5a50231ac8;hpb=c1b9b55ad8d59dc05ef55e316aebf5863e7dfa56;p=xscreensaver diff --git a/hacks/xmatrix.c b/hacks/xmatrix.c index 60fe09dd..decddaa7 100644 --- a/hacks/xmatrix.c +++ b/hacks/xmatrix.c @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 1999, 2001 Jamie Zawinski +/* xscreensaver, Copyright (c) 1999-2018 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 @@ -43,7 +43,7 @@ * And keep in mind that this program emulates the * behavior of the computer screens that were visible * in the movies -- not the behavior of the effects in - * the title sequences. + * the title sequences. "GLMatrix" does that. * * ========================================================== * @@ -54,44 +54,19 @@ #endif #include "screenhack.h" -#include "xpm-pixmap.h" +#include "textclient.h" +#include "ximage-loader.h" #include #include -#ifdef HAVE_COCOA -# define HAVE_XPM -#else -# define DO_XBM /* only do mono bitmaps under real X11 */ -#endif - -#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) -# include "images/matrix1.xpm" -# include "images/matrix2.xpm" -# include "images/matrix1b.xpm" -# include "images/matrix2b.xpm" -#endif - -#ifdef DO_XBM -# include "images/matrix1.xbm" -# include "images/matrix2.xbm" -# include "images/matrix1b.xbm" -# include "images/matrix2b.xbm" -#endif /* DO_XBM */ - -#ifndef HAVE_COCOA -# include +#ifndef HAVE_JWXYZ # include #endif -#ifdef HAVE_FORKPTY -# include -# ifdef HAVE_PTY_H -# include -# endif -# ifdef HAVE_UTIL_H -# include -# endif -#endif /* HAVE_FORKPTY */ +#include "images/gen/matrix1_png.h" +#include "images/gen/matrix2_png.h" +#include "images/gen/matrix1b_png.h" +#include "images/gen/matrix2b_png.h" #define CHAR_COLS 16 #define CHAR_ROWS 13 @@ -201,13 +176,8 @@ typedef struct { m_mode mode; m_mode def_mode; /* Mode to return to after trace etc. */ - pid_t pid; - FILE *pipe; - XtInputId pipe_id; - Bool input_available_p; - Time subproc_relaunch_delay; + text_data *tc; char buf [BUF_SIZE*2+1]; /* ring buffer */ - Bool do_fill_buff; int buf_done; int buf_pos; @@ -249,39 +219,25 @@ typedef struct { static void load_images_1 (Display *dpy, m_state *state, int which) { -#if defined(HAVE_GDK_PIXBUF) || defined(HAVE_XPM) - if (!get_boolean_resource (dpy, "mono", "Boolean") && - state->xgwa.depth > 1) + const unsigned char *png = 0; + unsigned long size = 0; + if (which == 1) { - char **bits = - (which == 1 ? (state->small_p ? matrix1b_xpm : matrix1_xpm) : - (state->small_p ? matrix2b_xpm : matrix2_xpm)); - - state->images[which] = - xpm_data_to_pixmap (state->dpy, state->window, bits, - &state->image_width, &state->image_height, 0); + if (state->small_p) + png = matrix1b_png, size = sizeof(matrix1b_png); + else + png = matrix1_png, size = sizeof(matrix1_png); } else -#endif /* !HAVE_XPM && !HAVE_GDK_PIXBUF */ { -#ifdef DO_XBM - unsigned long fg, bg; - state->image_width = (state->small_p ? matrix1b_width :matrix1_width); - state->image_height = (state->small_p ? matrix1b_height:matrix1_height); - fg = get_pixel_resource(state->dpy, state->xgwa.colormap, - "foreground", "Foreground"); - bg = get_pixel_resource(state->dpy, state->xgwa.colormap, - "background", "Background"); - state->images[which] = - XCreatePixmapFromBitmapData (state->dpy, state->window, (char *) - (which == 1 ? (state->small_p ? matrix1b_bits :matrix1_bits) : - (state->small_p ? matrix2b_bits :matrix2_bits)), - state->image_width, state->image_height, - bg, fg, state->xgwa.depth); -#else /* !DO_XBM */ - abort(); -#endif /* !DO_XBM */ + if (state->small_p) + png = matrix2b_png, size = sizeof(matrix2b_png); + else + png = matrix2_png, size = sizeof(matrix2_png); } + state->images[which] = + image_data_to_pixmap (state->dpy, state->window, png, size, + &state->image_width, &state->image_height, 0); } @@ -331,52 +287,13 @@ flip_images (m_state *state, Bool flipped_p) } } -static void -subproc_cb (XtPointer closure, int *source, XtInputId *id) -{ - m_state *state = (m_state *) closure; - state->input_available_p = True; -} - -static void -launch_text_generator (m_state *state) -{ - XtAppContext app = XtDisplayToApplicationContext (state->dpy); - char *oprogram = get_string_resource (state->dpy, "program", "Program"); - char *program = (char *) malloc (strlen (oprogram) + 10); - strcpy (program, "( "); - strcat (program, oprogram); - strcat (program, " ) 2>&1"); - - if ((state->pipe = popen (program, "r"))) - { - state->pipe_id = - XtAppAddInput (app, fileno (state->pipe), - (XtPointer) (XtInputReadMask | XtInputExceptMask), - subproc_cb, (XtPointer) state); - } - else - { - perror (program); - } -} - - -static void -relaunch_generator_timer (XtPointer closure, XtIntervalId *id) -{ - m_state *state = (m_state *) closure; - launch_text_generator (state); -} /* When the subprocess has generated some output, this reads as much as it can into s->buf at s->buf_tail. */ - static void fill_input (m_state *s) { - XtAppContext app = XtDisplayToApplicationContext (s->dpy); int n = 0; int loadBytes; if(s->buf_done > s->buf_pos){ @@ -385,15 +302,18 @@ fill_input (m_state *s) else{ loadBytes = ((BUF_SIZE - s->buf_pos) + s->buf_done) - 1; } - if (! s->pipe) return; - if (! s->input_available_p) return; - s->input_available_p = False; - - if (loadBytes > 0){ - n = read (fileno (s->pipe), - (void *) (s->buf+s->buf_pos), - loadBytes); - } + + if (!s->tc) + return; + + if (loadBytes > 0) + { + int c = textclient_getc (s->tc); + n = (c > 0 ? 1 : -1); + s->buf [s->buf_pos] = (char) c; + } + + if (n > 0) { s->do_fill_buff = False; @@ -410,20 +330,10 @@ fill_input (m_state *s) /* Couldn't read anything from the buffer */ /* Assume EOF has been reached, so start again */ s->do_fill_buff = True; - XtRemoveInput (s->pipe_id); - s->pipe_id = 0; - pclose (s->pipe); - s->pipe = 0; - - /* Set up a timer to re-launch the subproc in a bit. */ - XtAppAddTimeOut (app, s->subproc_relaunch_delay, - relaunch_generator_timer, - (XtPointer) s); } } - static void cursor_on_timer (XtPointer closure, XtIntervalId *id); static void cursor_off_timer (XtPointer closure, XtIntervalId *id); @@ -502,6 +412,19 @@ init_spinners (m_state *state) } +static void +clear_spinners (m_state *state) +{ + int i; + for (i = 0; i < state->grid_width * state->grid_height; i++) + if (state->cells[i].spinner) + { + state->cells[i].spinner = 0; + state->cells[i].changed = 1; + } +} + + static void set_mode (m_state *, m_mode); @@ -509,25 +432,22 @@ static void init_trace (m_state *state) { char *s = get_string_resource (state->dpy, "tracePhone", "TracePhone"); - char *s2, *s3; - int i; + const char *s2; + signed char *s3; if (!s) goto FAIL; state->tracing = (signed char *) malloc (strlen (s) + 1); - s3 = (char *) state->tracing; + s3 = state->tracing; for (s2 = s; *s2; s2++) if (*s2 >= '0' && *s2 <= '9') - *s3++ = *s2; + *s3++ = -*s2; *s3 = 0; - if (s3 == (char *) state->tracing) + if (s3 == state->tracing) goto FAIL; - for (i = 0; i < strlen((char *) state->tracing); i++) - state->tracing[i] = -state->tracing[i]; - state->glyph_map = decimal_encoding; state->nglyphs = countof(decimal_encoding); @@ -563,12 +483,7 @@ init_drain (m_state *state) } /* Turn off all the spinners, else they never go away. */ - for (i = 0; i < state->grid_width * state->grid_height; i++) - if (state->cells[i].spinner) - { - state->cells[i].spinner = 0; - state->cells[i].changed = 1; - } + clear_spinners (state); } static Bool @@ -807,7 +722,7 @@ xmatrix_init (Display *dpy, Window window) set_mode (state, ASCII); state->def_mode = ASCII; state->use_pipe_p = True; - launch_text_generator (state); + state->tc = textclient_open (dpy); } else if (!mode || !*mode || !strcasecmp(mode, "matrix")) set_mode (state, MATRIX); @@ -1176,6 +1091,7 @@ hack_text (m_state *state) { case TRACE_TEXT_A: case TRACE_TEXT_B: + clear_spinners (state); if (state->mode == TRACE_TEXT_A) { if (state->grid_width >= 52) @@ -1250,6 +1166,7 @@ hack_text (m_state *state) case KNOCK: { + clear_spinners (state); state->typing = ("\001Wake up, Neo...\n" "\001The Matrix has you...\n" "\001Follow the white rabbit.\n" @@ -1275,6 +1192,7 @@ hack_text (m_state *state) lot like Cisco IOS to me. (IOS is a descendant of VMS.) */ + clear_spinners (state); state->typing = # ifdef __GNUC__ __extension__ /* don't warn about "string length is greater than @@ -1384,6 +1302,33 @@ hack_text (m_state *state) state->typing_delay = state->typing_char_delay; if (state->typing_cursor_p) set_cursor (state, True); + +# ifdef USE_IPHONE + /* Stupid iPhone X bezel. + #### This is the worst of all possible ways to do this! But how else? + */ + if (state->xgwa.width == 2436 || state->xgwa.height == 2436) + switch (state->mode) + { + case TRACE_TEXT_A: + case TRACE_TEXT_B: + case KNOCK: + case NMAP: + { + int off = 5 * (state->small_p ? 2 : 1); + if (state->xgwa.width > state->xgwa.height) + { + state->typing_left_margin += off; + state->cursor_x += off; + } + else + { + state->cursor_y += off; + } + } + default: break; + } +# endif } else { @@ -1394,7 +1339,7 @@ hack_text (m_state *state) AGAIN: c = ((unsigned char *) state->typing)[0]; - c1 = ((unsigned char *) state->typing)[1]; + c1 = c ? ((unsigned char *) state->typing)[1] : 0; state->typing_delay = (!c || c1 == '\n' ? state->typing_line_delay @@ -1564,7 +1509,7 @@ hack_matrix (m_state *state) if (state->mode == TRACE_A || state->mode == TRACE_B) bottom_feeder_p = True; - if (state->insert_top_p && state->insert_bottom_p) + else if (state->insert_top_p && state->insert_bottom_p) bottom_feeder_p = (random() & 1); else bottom_feeder_p = state->insert_bottom_p; @@ -1757,6 +1702,13 @@ xmatrix_reshape (Display *dpy, Window window, void *closure, free (state->feeders); state->feeders = nfeeders; } + if (state->tc) + textclient_reshape (state->tc, + state->xgwa.width, + state->xgwa.height, + state->grid_width - 2, + state->grid_height - 1, + 0); } static Bool @@ -1826,10 +1778,16 @@ xmatrix_event (Display *dpy, Window window, void *closure, XEvent *event) return True; default: - return False; + break; } } + if (screenhack_event_helper (dpy, window, event)) + { + set_mode (state, DRAIN_MATRIX); + return True; + } + return False; } @@ -1837,7 +1795,8 @@ static void xmatrix_free (Display *dpy, Window window, void *closure) { m_state *state = (m_state *) closure; - + if (state->tc) + textclient_close (state->tc); if (state->cursor_timer) XtRemoveTimeOut (state->cursor_timer); @@ -1849,6 +1808,7 @@ xmatrix_free (Display *dpy, Window window, void *closure) static const char *xmatrix_defaults [] = { ".background: black", ".foreground: #00AA00", + ".lowrez: true", /* Small font is unreadable at 5120x2880 */ "*fpsSolid: true", "*matrixFont: large", "*delay: 10000", @@ -1860,8 +1820,9 @@ static const char *xmatrix_defaults [] = { "*trace: True", "*knockKnock: True", "*usePipe: False", - "*program: xscreensaver-text", - "*geometry: 800x600", + "*usePty: False", + "*program: xscreensaver-text --latin1", + "*geometry: 960x720", 0 };