X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=utils%2Ftextclient.c;fp=utils%2Ftextclient.c;h=fe409287db6fbc0d015087505e9150b1937fa312;hp=f0d7fe898d65f82877ad862db9aeba4b7c4c0d2d;hb=d6b0217f2417bd19187f0ebc389d6c5c2233b11c;hpb=aa75c7476aeaa84cf3abc192b376a8b03c325213 diff --git a/utils/textclient.c b/utils/textclient.c index f0d7fe89..fe409287 100644 --- a/utils/textclient.c +++ b/utils/textclient.c @@ -104,6 +104,19 @@ subproc_cb (XtPointer closure, int *source, XtInputId *id) (c >= '0' && c <= '9') || \ c == '.' || c == '_' || c == '-' || c == '+' || c == '/')) +#ifdef HAVE_COCOA +static char * +escape_str (char *s, const char *src) +{ + while (*src) { + char c = *src++; + if (BACKSLASH(c)) *s++ = '\\'; + *s++ = c; + } + return s; +} +#endif + static void launch_text_generator (text_data *d) { @@ -112,17 +125,17 @@ launch_text_generator (text_data *d) const char *oprogram = d->program; char *s; + size_t oprogram_size = strlen(oprogram); + size_t len; + # ifdef HAVE_COCOA /* /bin/sh on OS X 10.10 wipes out the PATH. */ const char *path = getenv("PATH"); - char *cmd = s = malloc ((strlen(oprogram) + strlen(path)) * 2 + 100); + size_t cmd_capacity = (oprogram_size + strlen(path)) * 2 + 100; + char *cmd = s = malloc (cmd_capacity); strcpy (s, "export PATH="); s += strlen (s); - while (*path) { - char c = *path++; - if (BACKSLASH(c)) *s++ = '\\'; - *s++ = c; - } + s = escape_str (s, path); strcpy (s, "; "); s += strlen (s); # else @@ -139,20 +152,82 @@ launch_text_generator (text_data *d) "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")) + len = 17; /* strlen("xscreensaver-text") */ + if (oprogram_size >= len && + !memcmp (oprogram, "xscreensaver-text", len) && + (oprogram[len] == ' ' || !oprogram[len])) { - if (d->char_w) + /* strstr is sloppy here. Technically, we should be parsing the command + line to identify flags and their arguments. This will blow up if one + of those pesky end users could set .textLiteral to "--cols". + */ + if (d->char_w && !strstr (oprogram, "--cols ")) sprintf (s, " --cols %d", d->char_w); - if (d->max_lines) + if (d->max_lines && !strstr (oprogram, "--lines ")) sprintf (s, " --lines %d", d->max_lines); s += strlen(s); + +# ifdef HAVE_COCOA + /* Also special-case "xscreensaver-text" to specify the text content on + the command line. defaults(1) on macOS doesn't know about the default + screenhack resources that don't make it into the + ~/Library/Preferences/ByHost/org.jwz.xscreensaver.*.plist. + */ + + char *text_mode_flag = " --date"; + char *value_res = NULL; + char *text_mode = get_string_resource (d->dpy, "textMode", "String"); + + if (text_mode) + { + if (!strcmp (text_mode, "1") || !strcmp (text_mode, "literal")) + { + text_mode_flag = " --text"; + value_res = "textLiteral"; + } + else if (!strcmp (text_mode, "2") || !strcmp (text_mode, "file")) + { + text_mode_flag = " --file"; + value_res = "textFile"; + } + else if (!strcmp (text_mode, "3") || !strcmp (text_mode, "url")) + { + text_mode_flag = " --url"; + value_res = "textURL"; + } + else if (!strcmp (text_mode, "4") || !strcmp (text_mode, "program")) + { + text_mode_flag = " --program"; + value_res = "textProgram"; + } + + free (text_mode); + } + + strcpy (s, text_mode_flag); + s += strlen (s); + + if (value_res) + { + size_t old_s = s - cmd; + char *value = get_string_resource (d->dpy, value_res, ""); + if (!value) + value = strdup(""); + cmd = realloc(cmd, cmd_capacity + strlen(value) * 2); + s = cmd + old_s; + *s = ' '; + ++s; + s = escape_str(s, value); + free(value); + } +# endif /* HAVE_COCOA */ } strcpy (s, " ) 2>&1"); # ifdef DEBUG - fprintf (stderr, "%s: textclient: launch %s: %s\n", cmd, - (d->pty_p ? "pty" : "pipe"), program); + fprintf (stderr, "%s: textclient: launch %s: %s\n", progname, + (d->pty_p ? "pty" : "pipe"), cmd); # endif #ifdef HAVE_FORKPTY @@ -167,6 +242,15 @@ launch_text_generator (text_data *d) ws.ws_ypixel = d->pix_h; d->pipe = 0; + +# ifdef HAVE_COCOA + if (getenv ("MallocScribble")) + /* This is here to stop me from wasting my time trying to answer + this question the next time I forget about it. */ + fprintf (stderr, "%s: WARNING: forkpty hates 'Enable Guard Malloc'\n", + progname); +# endif + if ((d->pid = forkpty(&fd, NULL, NULL, &ws)) < 0) { /* Unable to fork */ @@ -184,6 +268,15 @@ launch_text_generator (text_data *d) av[i++] = "-c"; av[i++] = cmd; av[i] = 0; +# ifdef DEBUG + { + int j; + fprintf (stderr, "%s: textclient: execvp:", progname); + for (j = 0; j < i; j++) + fprintf (stderr, " %s", av[j]); + fprintf (stderr, "\n"); + } +# endif execvp (av[0], av); sprintf (buf, "%.100s: %.100s", progname, oprogram); perror (buf); @@ -327,6 +420,9 @@ textclient_reshape (text_data *d, ws.ws_ypixel = pix_h; ioctl (fileno (d->pipe), TIOCSWINSZ, &ws); kill (d->pid, SIGWINCH); +# ifdef DEBUG + fprintf (stderr, "%s: textclient: SIGWINCH\n", progname); +# endif } # endif /* HAVE_FORKPTY && TIOCSWINSZ */ @@ -337,6 +433,9 @@ textclient_reshape (text_data *d, */ if (!strcmp (d->program, "xscreensaver-text")) { +# ifdef DEBUG + fprintf (stderr, "%s: textclient: reshape relaunch\n", progname); +# endif close_pipe (d); d->input_available_p = False; start_timer (d); @@ -387,6 +486,10 @@ textclient_open (Display *dpy) { d->pty_p = 1; d->program = strdup (getenv ("SHELL")); +# ifdef DEBUG + fprintf (stderr, "%s: textclient: standalone: %s\n", + progname, d->program); +# endif } } # endif