diff options
author | Simon Rettberg | 2018-10-16 10:08:48 +0200 |
---|---|---|
committer | Simon Rettberg | 2018-10-16 10:08:48 +0200 |
commit | d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 (patch) | |
tree | cbddf8e50f35a9c6e878a5bfe3c6d625d99e12ba /hacks/xsublim.c | |
download | xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.gz xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.xz xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.zip |
Original 5.40
Diffstat (limited to 'hacks/xsublim.c')
-rw-r--r-- | hacks/xsublim.c | 799 |
1 files changed, 799 insertions, 0 deletions
diff --git a/hacks/xsublim.c b/hacks/xsublim.c new file mode 100644 index 0000000..719de50 --- /dev/null +++ b/hacks/xsublim.c @@ -0,0 +1,799 @@ +/**************************************************************************** + * * + * xsublim -- Submit. Conform. Obey. * + * * + * Copyright (c) 1999 - 2000 Greg Knauss (greg@eod.com) * + * * + * Thanks to Jamie Zawinski, whose suggestions and advice made what was a * + * boring little program into a less boring (and a _lot_ less little) * + * program. * + * * + * Permission to use, copy, modify, distribute, and sell this software and * + * its documentation for any purpose is hereby granted without fee, provided * + * that the above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation. No representations are made about the suitability of this * + * software for any purpose. It is provided "as is" without express or * + * implied warranty. * + * * + * Stare into the subliminal for as long as you can... * + * * + *****************************************************************************/ + + +/* Warnings ******************************************************************* + + Please don't end this process with a SIGKILL. If it's got the X server + grabbed when you do, you'll never get it back and it won't be my fault. +*/ + + +/* Arguments ****************************************************************** + + -font font Font to use + -file filename New-line delimited phrase file + -program executable New-line delimited phrase-producing executable + -delayShow ms Microsecs for display of each word + -delayWord ms Microsecs for blank between words + -delayPhraseMin ms Microsecs for min blank between phrases + -delayPhraseMax ms Microsecs for max blank between phrases + -random Show phrases in random order (Default) + -no-random Show phrases in listed order + -screensaver Wait for an active screensaver (Default) + -no-screensaver Draw over active windows + -outline Draw a contrasting outline around words (Default) + -no-outline Draw words without an outline + -center Draw words in the center of the screen (Default) + -no-center Draw words randomly around the screen +*/ + + +/* Changelog ****************************************************************** + + 1.1.1 20000407 Added -program + 1.1.0 19991221 Added -file + 1.0.1 19990716 Assume that XGetImage()/XDestroyImage() don't leak, + which they apparently don't. I have no idea how I + convinced myself that they did. Huh. (greg@eod.com) + 1.0.0 19990716 Initial release +*/ + + +/* Defines *******************************************************************/ +#define XSUBLIM_NAME "XSublim" +#define XSUBLIM_TEXT_COUNT 1000 +#define XSUBLIM_TEXT_LENGTH 128 +#define XSUBLIM_TEXT_OUTLINE 1 +#define XSUBLIM_PROGRAM_SIZE 1024*10 +#define XSUBLIM_ARG_DELAYSHOW "delayShow" +#define XSUBLIM_ARG_DELAYWORD "delayWord" +#define XSUBLIM_ARG_DELAYPHRASEMIN "delayPhraseMin" +#define XSUBLIM_ARG_DELAYPHRASEMAX "delayPhraseMax" +#define XSUBLIM_ARG_RANDOM "random" +#define XSUBLIM_ARG_FILE "file" +#define XSUBLIM_ARG_PROGRAM "program" +#define XSUBLIM_ARG_SCREENSAVER "screensaver" +#define XSUBLIM_ARG_OUTLINE "outline" +#define XSUBLIM_ARG_CENTER "center" +#define XSUBLIM_ARG_FONT "font" +#define XSUBLIM_ARG_PHRASES "phrases" +#ifndef TRUE +#define FALSE 0 +#define TRUE 1 +#endif + + +/* Includes ******************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <sys/stat.h> +#include <X11/Intrinsic.h> +#include <X11/IntrinsicP.h> +#include <X11/CoreP.h> +#include <X11/Shell.h> +#include <X11/StringDefs.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xos.h> +#include <X11/Xproto.h> +#if defined(__sgi) +#include <X11/SGIScheme.h> +#endif + +#include "usleep.h" +#include "yarandom.h" +#include "resources.h" +#include "font-retry.h" +#include "vroot.h" + + +/* Globals *******************************************************************/ +char* progname; +char* progclass = XSUBLIM_NAME; + +# ifdef __GNUC__ + __extension__ /* don't warn about "string length is greater than the + length ISO C89 compilers are required to support" + in the following string constant... */ +# endif + +static char* defaults[] = +{ + ".background: #000000", + ".foreground: #FFFFFF", + "*" XSUBLIM_ARG_PHRASES ":" + "Submit.\\n" + "Conform.\\n" + "Obey.\\n" + "OBEY. OBEY. OBEY.\\n" + "Consume.\\n" + "Be silent.\\n" + "Fear.\\n" + "Waste.\\n" + "Money.\\n" + "Watch TV.\\n" + "Hate yourself.\\n" + "Buy needlessly.\\n" + "Despair quietly.\\n" + "God hates you.\\n" + "You are being watched.\\n" + "You will be punished.\\n" + "You serve no purpose.\\n" + "Your contributions are ignored.\\n" + "They are laughing at you.\\n" + "They lied to you.\\n" + "They read your mail.\\n" + "They know.\\n" + "Surrender.\\n" + "You will fail.\\n" + "Never question.\\n" + "You are a prisoner.\\n" + "You are helpless.\\n" + "You are diseased.\\n" + "Fear the unknown.\\n" + "Happiness follows obedience.\\n" + "Ignorance is strength.\\n" + "War is peace.\\n" + "Freedom is slavery.\\n" + "Abandon all hope.\\n" + "You will be assimilated.\\n" + "Resistance is futile.\\n" + "Resistance is useless.\\n" + "Life is pain.\\n" + "No escape.\\n" + "What's that smell?\\n" + "All praise the company.\\n" + "Fnord.\\n", + "*" XSUBLIM_ARG_FONT ": -*-utopia-*-r-*-*-*-600-*-*-p-*-*-*", + "*" XSUBLIM_ARG_DELAYSHOW ": 40000", + "*" XSUBLIM_ARG_DELAYWORD ": 100000", + "*" XSUBLIM_ARG_DELAYPHRASEMIN ": 5000000", + "*" XSUBLIM_ARG_DELAYPHRASEMAX ": 20000000", + "*" XSUBLIM_ARG_RANDOM ": true", + "*" XSUBLIM_ARG_SCREENSAVER ": true", + "*" XSUBLIM_ARG_OUTLINE": true", + "*" XSUBLIM_ARG_CENTER": true", + NULL +}; + +static XrmOptionDescRec options[] = +{ + {"-" XSUBLIM_ARG_FONT, "." XSUBLIM_ARG_FONT, + XrmoptionSepArg,0}, + {"-" XSUBLIM_ARG_DELAYSHOW, "." XSUBLIM_ARG_DELAYSHOW, + XrmoptionSepArg,0}, + {"-" XSUBLIM_ARG_DELAYWORD, "." XSUBLIM_ARG_DELAYWORD, + XrmoptionSepArg,0}, + {"-" XSUBLIM_ARG_DELAYPHRASEMIN,"." XSUBLIM_ARG_DELAYPHRASEMIN, + XrmoptionSepArg,0}, + {"-" XSUBLIM_ARG_DELAYPHRASEMAX,"." XSUBLIM_ARG_DELAYPHRASEMAX, + XrmoptionSepArg,0}, + {"-" XSUBLIM_ARG_RANDOM, "." XSUBLIM_ARG_RANDOM, + XrmoptionNoArg,"true"}, + {"-no-" XSUBLIM_ARG_RANDOM, "." XSUBLIM_ARG_RANDOM, + XrmoptionNoArg,"false"}, + {"-" XSUBLIM_ARG_FILE, "." XSUBLIM_ARG_FILE, + XrmoptionSepArg,0 }, +#if !defined(VMS) + {"-" XSUBLIM_ARG_PROGRAM, "." XSUBLIM_ARG_PROGRAM, + XrmoptionSepArg,0 }, +#endif + {"-" XSUBLIM_ARG_SCREENSAVER, "." XSUBLIM_ARG_SCREENSAVER, + XrmoptionNoArg,"true"}, + {"-no-" XSUBLIM_ARG_SCREENSAVER,"." XSUBLIM_ARG_SCREENSAVER, + XrmoptionNoArg,"false"}, + {"-" XSUBLIM_ARG_OUTLINE, "." XSUBLIM_ARG_OUTLINE, + XrmoptionNoArg,"true"}, + {"-no-" XSUBLIM_ARG_OUTLINE, "." XSUBLIM_ARG_OUTLINE, + XrmoptionNoArg,"false"}, + {"-" XSUBLIM_ARG_CENTER, "." XSUBLIM_ARG_CENTER, + XrmoptionNoArg,"true"}, + {"-no-" XSUBLIM_ARG_CENTER, "." XSUBLIM_ARG_CENTER, + XrmoptionNoArg,"false"}, + {NULL, NULL, + 0, 0 } +}; +static int Xsublim_Sig_Last; + + +/* Functions *****************************************************************/ + +/* Defer signals to protect the server grab ================================ */ +static void xsublim_Sig_Catch(int sig_Number) +{ + /* BSD needs this reset each time, and it shouldn't hurt anything + else */ + signal(sig_Number,xsublim_Sig_Catch); + Xsublim_Sig_Last = sig_Number; +} + +/* This was all basically swiped from driver/remote.c and util/vroot.h */ +static Window xsublim_Ss_GetWindow(Display* ss_Display) +{ + Screen *s = DefaultScreenOfDisplay (ss_Display); + Window root = XRootWindowOfScreen (s); + Window vroot = VirtualRootWindowOfScreen (s); + if (root == vroot) + return 0; + else + return vroot; +} + +/* Main ==================================================================== */ +static XErrorHandler Xsublim_Sh_Handler = NULL; +static int Xsublim_Sh_Status = 0; + +static int xsublim_Sh_Handler(Display* handle_Display, + XErrorEvent* handle_Error) +{ + if (handle_Error->error_code == BadMatch) + { + Xsublim_Sh_Status = BadMatch; + return 0; + } + if (Xsublim_Sh_Handler == NULL) + { + fprintf(stderr,"%s: ",progname); + abort(); + } + return (*Xsublim_Sh_Handler)(handle_Display,handle_Error); +} + + +int main(int argc,char* argv[]) +{ + XtAppContext app; + int sig_Number; + int sig_Signal[] = + { + SIGHUP, + SIGINT, + SIGQUIT, + SIGILL, + SIGTRAP, +#if defined(SIGIOT) + SIGIOT, +#endif + SIGABRT, +#if defined(SIGEMT) + SIGEMT, +#endif + SIGFPE, + SIGBUS, + SIGSEGV, +#if defined(SIGSYS) + SIGSYS, +#endif + SIGTERM, +#if defined(SIGXCPU) + SIGXCPU, +#endif +#if defined(SIGXFSZ) + SIGXFSZ, +#endif +#if defined(SIGDANGER) + SIGDANGER, +#endif + -1 + }; + Widget app_App; + Display* dpy; + Window win_Root; + XWindowAttributes attr_Win; + XGCValues gc_ValFore; + XGCValues gc_ValBack; + GC gc_GcFore; + GC gc_GcBack; + XFontStruct* font_Font; + char* font_List[] = + { + "-*-character-*-r-*-*-*-600-*-*-p-*-*-*", + "-*-helvetica-*-r-*-*-*-600-*-*-p-*-*-*", + "-*-lucida-*-r-*-*-*-600-*-*-p-*-*-*", + "-*-*-*-r-*-sans-*-600-*-*-p-*-*-*", + "-*-*-*-r-*-*-*-600-*-*-m-*-*-*", + "-*-helvetica-*-r-*-*-*-240-*-*-p-*-*-*", + "-*-lucida-*-r-*-*-*-240-*-*-p-*-*-*", + "-*-*-*-r-*-sans-*-240-*-*-p-*-*-*", + "-*-*-*-r-*-*-*-240-*-*-m-*-*-*", + "fixed", + NULL + }; + int font_Index; + int text_Length; + int text_X; + int text_Y; + int text_Width; + int text_Height; + char* text_List[XSUBLIM_TEXT_COUNT]; + int text_Used[XSUBLIM_TEXT_COUNT]; + char text_Text[XSUBLIM_TEXT_LENGTH+1]; + char* text_Phrase; + char* text_Word; + int text_Index; + int text_Item; + int text_Count; + struct + { + int outline_X; + int outline_Y; + } text_Outline[] = + { + { -1,-1 }, + { 1,-1 }, + { -1, 1 }, + { 1, 1 }, + { 0, 0 } + }; + int text_OutlineIndex; + XImage* image_Image = NULL; + int image_X = 0; + int image_Y = 0; + int image_Width = 0; + int image_Height = 0; + int arg_Count; + int arg_FlagCenter; + int arg_FlagOutline; + int arg_FlagScreensaver; + int arg_FlagRandom; + int arg_DelayShow; + int arg_DelayWord; + int arg_DelayPhraseMin; + int arg_DelayPhraseMax; + char* arg_Text; + char* arg_Source; + + /* Set-up ---------------------------------------------------------- */ + + /* Catch signals */ + Xsublim_Sig_Last = -1; + for (sig_Number = 0;sig_Signal[sig_Number] != -1;sig_Number++) + { + signal(sig_Number,xsublim_Sig_Catch); + } + + /* Randomize -- only need to do this here because this program + doesn't use the `screenhack.h' or `lockmore.h' APIs. */ +# undef ya_rand_init + ya_rand_init (0); + + /* Handle all the X nonsense */ +#if defined(__sgi) + SgiUseSchemes("none"); +#endif + for (arg_Count = 0;options[arg_Count].option != NULL;arg_Count++) + { + ; + } + app_App = XtAppInitialize(&app,progclass,options,arg_Count,&argc,argv, + defaults,0,0); + + /* jwz */ + if (argc > 1) + { + int x = 18; + int end = 78; + int i; + int count = (sizeof(options)/sizeof(*options))-1; + fprintf(stderr, "Unrecognised option: %s\n", argv[1]); + fprintf (stderr, "Options include: "); + for (i = 0; i < count; i++) + { + char *sw = options [i].option; + Bool argp = (options [i].argKind == XrmoptionSepArg); + int size = strlen (sw) + (argp ? 6 : 0) + 2; + if (x + size >= end) + { + fprintf (stderr, "\n\t\t "); + x = 18; + } + x += size; + fprintf (stderr, "%s", sw); + if (argp) fprintf (stderr, " <arg>"); + if (i != count-1) fprintf (stderr, ", "); + } + fprintf (stderr, ".\n"); + exit (-1); + } + + dpy = XtDisplay(app_App); + XtGetApplicationNameAndClass(dpy,&progname,&progclass); + win_Root = RootWindowOfScreen(XtScreen(app_App)); + XtDestroyWidget(app_App); + + /* Get the arguments */ + arg_FlagCenter = get_boolean_resource(dpy, XSUBLIM_ARG_CENTER,"Boolean"); + arg_FlagOutline = get_boolean_resource(dpy, XSUBLIM_ARG_OUTLINE,"Boolean"); + arg_FlagScreensaver = get_boolean_resource(dpy, XSUBLIM_ARG_SCREENSAVER, + "Boolean"); + arg_FlagRandom = get_boolean_resource(dpy, XSUBLIM_ARG_RANDOM,"Boolean"); + arg_DelayShow = get_integer_resource(dpy, XSUBLIM_ARG_DELAYSHOW,"Integer"); + arg_DelayWord = get_integer_resource(dpy, XSUBLIM_ARG_DELAYWORD,"Integer"); + arg_DelayPhraseMin = get_integer_resource(dpy, XSUBLIM_ARG_DELAYPHRASEMIN, + "Integer"); + arg_DelayPhraseMax = get_integer_resource(dpy, XSUBLIM_ARG_DELAYPHRASEMAX, + "Integer"); + if (arg_DelayPhraseMax < arg_DelayPhraseMin) + { + arg_DelayPhraseMax = arg_DelayPhraseMin; + } + + /* Get the phrases */ + text_Index = 0; + text_Item = 0; + text_Count = 0; + memset(text_Used,0,sizeof(text_Used)); + arg_Source = get_string_resource(dpy, XSUBLIM_ARG_FILE,"Filename"); + if (arg_Source != NULL) + { + FILE* file_Fs; + struct stat file_Stat; + + file_Fs = fopen(arg_Source,"rb"); + if (file_Fs == NULL) + { + fprintf(stderr,"%s: Could not open '%s'\n",progname, + arg_Source); + exit(-1); + } + if (fstat(fileno(file_Fs),&file_Stat) != 0) + { + fprintf(stderr,"%s: Could not stat '%s'\n",progname, + arg_Source); + exit(-1); + } + arg_Text = calloc(1,file_Stat.st_size+1); + if (arg_Text != NULL) + { + if (fread(arg_Text,file_Stat.st_size,1,file_Fs) != 1) + { + fprintf(stderr,"%s: Could not read '%s'\n", + progname,arg_Source); + exit(-1); + } + } + fclose(file_Fs); + } + else + { + arg_Source = get_string_resource(dpy, XSUBLIM_ARG_PROGRAM, + "Executable"); + if (arg_Source != NULL) + { + char* exe_Command = calloc(1,strlen(arg_Source)+10); + FILE* exe_Fs; + + if (exe_Command == NULL) + { + fprintf(stderr, + "%s: Could not allocate space for '%s'\n", + progname,arg_Source); + exit(-1); + } + sprintf(exe_Command,"( %s ) 2>&1",arg_Source); + + exe_Fs = popen(exe_Command,"r"); + if (exe_Fs == NULL) + { + fprintf(stderr,"%s: Could not run '%s'\n", + progname,arg_Source); + exit(-1); + } + arg_Text = calloc(1,XSUBLIM_PROGRAM_SIZE); + if (arg_Text != NULL) + { + if (fread(arg_Text,1,XSUBLIM_PROGRAM_SIZE, + exe_Fs) <= 0) + { + fprintf(stderr, + "%s: Could not read output of '%s'\n", + progname,arg_Source); + exit(-1); + } + if ( + strstr(arg_Text,": not found") || + strstr(arg_Text,": Not found") || + strstr(arg_Text,": command not found") || + strstr(arg_Text,": Command not found")) + { + fprintf(stderr, + "%s: Could not find '%s'\n", + progname,arg_Source); + exit(-1); + } + } + fclose(exe_Fs); + } + else + { + arg_Text = + get_string_resource(dpy, XSUBLIM_ARG_PHRASES,"Phrases"); + if (arg_Text != NULL) + { + arg_Text = strdup(arg_Text); + } + } + } + if (arg_Text != NULL) + { + while (((text_Phrase = strtok(arg_Text,"\n")) != NULL) && + (text_Count < XSUBLIM_TEXT_COUNT)) + { + arg_Text = NULL; + text_List[text_Count] = text_Phrase; + text_Count++; + } + text_List[text_Count] = NULL; + } + if (text_Count == 0) + { + fprintf(stderr,"%s: No text to display\n",progname); + exit(-1); + } + + /* Load the font */ + font_Font = load_font_retry(dpy, + get_string_resource(dpy, XSUBLIM_ARG_FONT,"Font")); + font_Index = 0; + while ((font_Font == NULL) && (font_List[font_Index] != NULL)) + { + font_Font = load_font_retry(dpy,font_List[font_Index]); + font_Index++; + } + if (font_Font == NULL) + { + fprintf(stderr,"%s: Couldn't load a font\n",progname); + exit(-1); + } + + /* Create the GCs */ + XGetWindowAttributes(dpy,win_Root,&attr_Win); + gc_ValFore.font = font_Font->fid; + gc_ValFore.foreground = get_pixel_resource(dpy, + attr_Win.colormap, + "foreground","Foreground"); + gc_ValFore.background = get_pixel_resource(dpy, + attr_Win.colormap, + "background","Background"); + gc_ValFore.subwindow_mode = IncludeInferiors; + gc_GcFore = XCreateGC(dpy,win_Root, + (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValFore); + gc_ValBack.font = font_Font->fid; + gc_ValBack.foreground = get_pixel_resource(dpy, + attr_Win.colormap, + "background","Background"); + gc_ValBack.background = get_pixel_resource(dpy, + attr_Win.colormap, + "foreground","Foreground"); + gc_ValBack.subwindow_mode = IncludeInferiors; + gc_GcBack = XCreateGC(dpy,win_Root, + (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValBack); + + /* Loop ------------------------------------------------------------ */ + while (Xsublim_Sig_Last == -1) + { + /* Once-per-phrase stuff ----------------------------------- */ + + /* If we're waiting for a screensaver... */ + if (arg_FlagScreensaver != FALSE) + { + /* Find the screensaver's window */ + win_Root = xsublim_Ss_GetWindow(dpy); + if (win_Root == 0) + { + usleep(30000000); + continue; + } + } + + /* Pick the next phrase */ + if (arg_FlagRandom != FALSE) + { + text_Item = random()%text_Count; + text_Index = 0; + } + while (text_Used[text_Item] != FALSE) + { + text_Index++; + text_Item++; + if (text_Index == text_Count) + { + text_Index = 0; + memset(text_Used,0,sizeof(text_Used)); + } + if (text_List[text_Item] == NULL) + { + text_Item = 0; + } + } + text_Used[text_Item] = TRUE; + strncpy(text_Text,text_List[text_Item], + XSUBLIM_TEXT_LENGTH); + text_Phrase = text_Text; + + /* Run through the phrase */ + while (((text_Word = strtok(text_Phrase," \t")) != NULL) && + (Xsublim_Sig_Last == -1)) + { + text_Phrase = NULL; + + /* Once-per-word stuff ----------------------------- */ + + /* Find the text's position */ + XGetWindowAttributes(dpy,win_Root,&attr_Win); + text_Length = strlen(text_Word); + text_Width = XTextWidth(font_Font,text_Word, + text_Length)+XSUBLIM_TEXT_OUTLINE*2; + text_Height = font_Font->ascent+font_Font->descent+1+ + XSUBLIM_TEXT_OUTLINE*2; + if (arg_FlagCenter == FALSE) + { + text_X = random()%(attr_Win.width-text_Width); + text_Y = random()%(attr_Win.height- + text_Height); + } + else + { + text_X = (attr_Win.width/2)-(text_Width/2); + text_Y = (attr_Win.height/2)-(text_Height/2); + } + + /* Find the image's position (and pad it out slightly, + otherwise bits of letter get left behind -- are + there boundry issues I don't know about?) */ + image_X = text_X-16; + image_Y = text_Y; + image_Width = text_Width+32; + image_Height = text_Height; + if (image_X < 0) + { + image_X = 0; + } + if (image_Y < 0) + { + image_Y = 0; + } + if (image_X+image_Width > attr_Win.width) + { + image_Width = attr_Win.width-image_X; + } + if (image_Y+image_Height > attr_Win.height) + { + image_Height = attr_Win.height-image_Y; + } + + /* Influence people for our own ends --------------- */ + + /* Grab the server -- we can't let anybody draw over + us */ + XSync(dpy,FALSE); + XGrabServer(dpy); + XSync(dpy,FALSE); + + /* Set up an error handler that ignores BadMatches -- + since the screensaver can take its window away at + any time, any call that uses it might choke */ + Xsublim_Sh_Status = 0; + Xsublim_Sh_Handler = + XSetErrorHandler(xsublim_Sh_Handler); + + /* Save the current background */ + image_Image = XGetImage(dpy,win_Root,image_X, + image_Y,image_Width,image_Height,~0L,ZPixmap); + + /* If we've successfully saved the background... */ + if (image_Image != NULL) + { + if (Xsublim_Sh_Status == 0) + { + /* Draw the outline */ + if (arg_FlagOutline != FALSE) + { + for (text_OutlineIndex = 0; + text_Outline[ + text_OutlineIndex].outline_X + != 0;text_OutlineIndex++) + { + /* Y'know, eight + character tabs and + descriptive variable + names become + annoying at some + point... */ + XDrawString( + dpy, + win_Root,gc_GcBack, + text_X+text_Outline[ + text_OutlineIndex]. + outline_X* + XSUBLIM_TEXT_OUTLINE, + text_Y+ + (font_Font->ascent)+ + text_Outline[ + text_OutlineIndex]. + outline_Y* + XSUBLIM_TEXT_OUTLINE, + text_Word, + text_Length); + } + } + + /* Draw the word */ + XDrawString(dpy,win_Root, + gc_GcFore,text_X, + text_Y+(font_Font->ascent),text_Word, + text_Length); + } + if (Xsublim_Sh_Status == 0) + { + /* Wait a bit */ + XSync(dpy,FALSE); + if (Xsublim_Sig_Last == -1) + { + usleep(arg_DelayShow); + } + + /* Restore the background */ + XPutImage(dpy,win_Root, + gc_GcFore,image_Image,0,0,image_X, + image_Y,image_Width,image_Height); + } + + /* Free the image */ + XDestroyImage(image_Image); + } + + /* Restore the error handler, ungrab the server */ + XSync(dpy,FALSE); + XSetErrorHandler(Xsublim_Sh_Handler); + XUngrabServer(dpy); + XSync(dpy,FALSE); + + /* Pause between words */ + if (Xsublim_Sig_Last == -1) + { + usleep(arg_DelayWord); + } + } + + /* Pause between phrases */ + if (Xsublim_Sig_Last == -1) + { + usleep(random()%(arg_DelayPhraseMax- + arg_DelayPhraseMin+1)+arg_DelayPhraseMin); + } + } + + /* Exit ------------------------------------------------------------ */ + for (sig_Number = 0;sig_Signal[sig_Number] != -1;sig_Number++) + { + signal(sig_Number,SIG_DFL); + } + kill(getpid(),Xsublim_Sig_Last); + + return 0; +} |