source: trunk/third/xscreensaver/hacks/xsublim.c @ 20148

Revision 20148, 22.5 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/****************************************************************************
2 *                                                                           *
3 * xsublim -- Submit.  Conform.  Obey.                                       *
4 *                                                                           *
5 * Copyright (c) 1999 - 2000 Greg Knauss (greg@eod.com)                      *
6 *                                                                           *
7 * Thanks to Jamie Zawinski, whose suggestions and advice made what was a    *
8 * boring little program into a less boring (and a _lot_ less little)        *
9 * program.                                                                  *
10 *                                                                           *
11 * Permission to use, copy, modify, distribute, and sell this software and   *
12 * its documentation for any purpose is hereby granted without fee, provided *
13 * that the above copyright notice appear in all copies and that both that   *
14 * copyright notice and this permission notice appear in supporting          *
15 * documentation.  No representations are made about the suitability of this *
16 * software for any purpose.  It is provided "as is" without express or      *
17 * implied warranty.                                                         *
18 *                                                                           *
19 * Stare into the subliminal for as long as you can...                       *
20 *                                                                           *
21 *****************************************************************************/
22
23
24/* Warnings *******************************************************************
25
26        Please don't end this process with a SIGKILL.  If it's got the X server
27        grabbed when you do, you'll never get it back and it won't be my fault.
28*/
29
30
31/* Arguments ******************************************************************
32
33        -font font           Font to use
34        -file filename       New-line delimited phrase file
35        -program executable  New-line delimited phrase-producing executable
36        -delayShow ms        Microsecs for display of each word
37        -delayWord ms        Microsecs for blank between words
38        -delayPhraseMin ms   Microsecs for min blank between phrases
39        -delayPhraseMax ms   Microsecs for max blank between phrases
40        -random              Show phrases in random order (Default)
41        -no-random           Show phrases in listed order
42        -screensaver         Wait for an active screensaver (Default)
43        -no-screensaver      Draw over active windows       
44        -outline             Draw a contrasting outline around words (Default)
45        -no-outline          Draw words without an outline
46        -center              Draw words in the center of the screen (Default)
47        -no-center           Draw words randomly around the screen
48*/
49
50
51/* Changelog ******************************************************************
52
53        1.1.1  20000407  Added -program
54        1.1.0  19991221  Added -file
55        1.0.1  19990716  Assume that XGetImage()/XDestroyImage() don't leak,
56                          which they apparently don't.  I have no idea how I
57                          convinced myself that they did.  Huh.  (greg@eod.com)
58        1.0.0  19990716  Initial release
59*/
60
61
62/* Defines *******************************************************************/
63#define XSUBLIM_NAME               "XSublim"
64#define XSUBLIM_TEXT_COUNT         1000
65#define XSUBLIM_TEXT_LENGTH        128
66#define XSUBLIM_TEXT_OUTLINE       1
67#define XSUBLIM_PROGRAM_SIZE       1024*10
68#define XSUBLIM_ARG_DELAYSHOW      "delayShow"
69#define XSUBLIM_ARG_DELAYWORD      "delayWord"
70#define XSUBLIM_ARG_DELAYPHRASEMIN "delayPhraseMin"
71#define XSUBLIM_ARG_DELAYPHRASEMAX "delayPhraseMax"
72#define XSUBLIM_ARG_RANDOM         "random"
73#define XSUBLIM_ARG_FILE           "file"
74#define XSUBLIM_ARG_PROGRAM        "program"
75#define XSUBLIM_ARG_SCREENSAVER    "screensaver"
76#define XSUBLIM_ARG_OUTLINE        "outline"
77#define XSUBLIM_ARG_CENTER         "center"
78#define XSUBLIM_ARG_FONT           "font"
79#define XSUBLIM_ARG_PHRASES        "phrases"
80#ifndef TRUE
81#define FALSE 0
82#define TRUE  1
83#endif
84
85
86/* Includes ******************************************************************/
87#include <stdio.h>
88#include <stdlib.h>
89#include <string.h>
90#include <signal.h>
91#include <sys/stat.h>
92#include <X11/Intrinsic.h>
93#include <X11/IntrinsicP.h>
94#include <X11/CoreP.h>
95#include <X11/Shell.h>
96#include <X11/StringDefs.h>
97#include <X11/Xutil.h>
98#include <X11/keysym.h>
99#include <X11/Xatom.h>
100#include <X11/Xlib.h>
101#include <X11/Xos.h>
102#include <X11/Xproto.h>
103#if defined(__sgi)
104#include <X11/SGIScheme.h>
105#endif
106
107#include "usleep.h"
108#include "yarandom.h"
109#include "resources.h"
110#include "vroot.h"
111
112
113/* Globals *******************************************************************/
114char*        progname;
115XtAppContext app;
116XrmDatabase  db;
117char*        progclass = XSUBLIM_NAME;
118
119# ifdef __GNUC__
120  __extension__   /* don't warn about "string length is greater than the
121                     length ISO C89 compilers are required to support"
122                     in the following string constant... */
123# endif
124
125char*        defaults[] =
126{
127        ".background:                     #000000",
128        ".foreground:                     #FFFFFF",
129        "*" XSUBLIM_ARG_PHRASES ":"
130         "Submit.\\n"
131         "Conform.\\n"
132         "Obey.\\n"
133         "OBEY. OBEY. OBEY.\\n"
134         "Consume.\\n"
135         "Be silent.\\n"
136         "Fear.\\n"
137         "Waste.\\n"
138         "Money.\\n"
139         "Watch TV.\\n"
140         "Hate yourself.\\n"
141         "Buy needlessly.\\n"
142         "Despair quietly.\\n"
143         "God hates you.\\n"
144         "You are being watched.\\n"
145         "You will be punished.\\n"
146         "You serve no purpose.\\n"
147         "Your contributions are ignored.\\n"
148         "They are laughing at you.\\n"
149         "They lied to you.\\n"
150         "They read your mail.\\n"
151         "They know.\\n"
152         "Surrender.\\n"
153         "You will fail.\\n"
154         "Never question.\\n"
155         "You are a prisoner.\\n"
156         "You are helpless.\\n"
157         "You are diseased.\\n"
158         "Fear the unknown.\\n"
159         "Happiness follows obedience.\\n"
160         "Ignorance is strength.\\n"
161         "War is peace.\\n"
162         "Freedom is slavery.\\n"
163         "Abandon all hope.\\n"
164         "You will be assimilated.\\n"
165         "Resistance is futile.\\n"
166         "Resistance is useless.\\n"
167         "Life is pain.\\n"
168         "No escape.\\n"
169         "What's that smell?\\n"
170         "All praise the company.\\n"
171         "Fnord.\\n",
172        "*" XSUBLIM_ARG_FONT ":           -*-utopia-*-r-*-*-*-600-*-*-p-*-*-*",
173        "*" XSUBLIM_ARG_DELAYSHOW ":      40000",
174        "*" XSUBLIM_ARG_DELAYWORD ":      100000",
175        "*" XSUBLIM_ARG_DELAYPHRASEMIN ": 5000000",
176        "*" XSUBLIM_ARG_DELAYPHRASEMAX ": 20000000",
177        "*" XSUBLIM_ARG_RANDOM ":         true",
178        "*" XSUBLIM_ARG_SCREENSAVER ":    true",
179        "*" XSUBLIM_ARG_OUTLINE":         true",
180        "*" XSUBLIM_ARG_CENTER":          true",
181        NULL
182};
183XrmOptionDescRec options[] =
184{
185        {"-" XSUBLIM_ARG_FONT,          "." XSUBLIM_ARG_FONT,
186         XrmoptionSepArg,0},
187        {"-" XSUBLIM_ARG_DELAYSHOW,     "." XSUBLIM_ARG_DELAYSHOW,
188         XrmoptionSepArg,0},
189        {"-" XSUBLIM_ARG_DELAYWORD,     "." XSUBLIM_ARG_DELAYWORD,
190         XrmoptionSepArg,0},
191        {"-" XSUBLIM_ARG_DELAYPHRASEMIN,"." XSUBLIM_ARG_DELAYPHRASEMIN,
192         XrmoptionSepArg,0},
193        {"-" XSUBLIM_ARG_DELAYPHRASEMAX,"." XSUBLIM_ARG_DELAYPHRASEMAX,
194         XrmoptionSepArg,0},
195        {"-" XSUBLIM_ARG_RANDOM,        "." XSUBLIM_ARG_RANDOM,
196         XrmoptionNoArg,"true"},
197        {"-no-" XSUBLIM_ARG_RANDOM,     "." XSUBLIM_ARG_RANDOM,
198         XrmoptionNoArg,"false"},
199        {"-" XSUBLIM_ARG_FILE,          "." XSUBLIM_ARG_FILE,
200         XrmoptionSepArg,0 },
201#if !defined(VMS)
202        {"-" XSUBLIM_ARG_PROGRAM,       "." XSUBLIM_ARG_PROGRAM,
203         XrmoptionSepArg,0 },
204#endif
205        {"-" XSUBLIM_ARG_SCREENSAVER,   "." XSUBLIM_ARG_SCREENSAVER,
206         XrmoptionNoArg,"true"},
207        {"-no-" XSUBLIM_ARG_SCREENSAVER,"." XSUBLIM_ARG_SCREENSAVER,
208         XrmoptionNoArg,"false"},
209        {"-" XSUBLIM_ARG_OUTLINE,       "." XSUBLIM_ARG_OUTLINE,
210         XrmoptionNoArg,"true"},
211        {"-no-" XSUBLIM_ARG_OUTLINE,    "." XSUBLIM_ARG_OUTLINE,
212         XrmoptionNoArg,"false"},
213        {"-" XSUBLIM_ARG_CENTER,        "." XSUBLIM_ARG_CENTER,
214         XrmoptionNoArg,"true"},
215        {"-no-" XSUBLIM_ARG_CENTER,     "." XSUBLIM_ARG_CENTER,
216         XrmoptionNoArg,"false"},
217        {NULL,                          NULL,
218         0,              0 }
219};
220static int Xsublim_Sig_Last;
221
222
223/* Functions *****************************************************************/
224
225/* Defer signals to protect the server grab ================================ */
226void xsublim_Sig_Catch(int sig_Number)
227{
228        /* BSD needs this reset each time, and it shouldn't hurt anything
229           else */
230        signal(sig_Number,xsublim_Sig_Catch);
231        Xsublim_Sig_Last = sig_Number;
232}
233
234/* This was all basically swiped from driver/remote.c and util/vroot.h */
235static Window xsublim_Ss_GetWindow(Display* ss_Display)
236{
237  Screen *s = DefaultScreenOfDisplay (ss_Display);
238  Window root = XRootWindowOfScreen (s);
239  Window vroot = VirtualRootWindowOfScreen (s);
240  if (root == vroot)
241    return 0;
242  else
243    return vroot;
244}
245
246/* Main ==================================================================== */
247static XErrorHandler Xsublim_Sh_Handler = NULL;
248static int           Xsublim_Sh_Status = 0;
249
250static int xsublim_Sh_Handler(Display* handle_Display,
251            XErrorEvent* handle_Error)
252{
253        if (handle_Error->error_code == BadMatch)
254        {
255                Xsublim_Sh_Status = BadMatch;
256                return 0;
257        }
258        if (Xsublim_Sh_Handler == NULL)
259        {
260                fprintf(stderr,"%s: ",progname);
261                abort();
262        }
263        return (*Xsublim_Sh_Handler)(handle_Display,handle_Error);
264}
265int main(int argc,char* argv[])
266{
267        int               sig_Number;
268        int               sig_Signal[] =
269        {
270                SIGHUP,
271                SIGINT,
272                SIGQUIT,
273                SIGILL,
274                SIGTRAP,
275#if defined(SIGIOT)
276                SIGIOT,
277#endif
278                SIGABRT,
279#if defined(SIGEMT)
280                SIGEMT,
281#endif
282                SIGFPE,
283                SIGBUS,
284                SIGSEGV,
285#if defined(SIGSYS)
286                SIGSYS,
287#endif
288                SIGTERM,
289#if defined(SIGXCPU)
290                SIGXCPU,
291#endif
292#if defined(SIGXFSZ)
293                SIGXFSZ,
294#endif
295#if defined(SIGDANGER)
296                SIGDANGER,
297#endif
298                -1
299        };
300        Widget            app_App;
301        Display*          disp_Display;
302        Window            win_Root;
303        XWindowAttributes attr_Win;
304        XGCValues         gc_ValFore;
305        XGCValues         gc_ValBack;
306        GC                gc_GcFore;
307        GC                gc_GcBack;
308        XFontStruct*      font_Font;
309        char*             font_List[] =
310        {
311                "-*-character-*-r-*-*-*-600-*-*-p-*-*-*",
312                "-*-helvetica-*-r-*-*-*-600-*-*-p-*-*-*",
313                "-*-lucida-*-r-*-*-*-600-*-*-p-*-*-*",
314                "-*-times-*-r-*-*-*-600-*-*-p-*-*-*",
315                "-*-*-*-r-*-sans-*-600-*-*-p-*-*-*",
316                "-*-*-*-r-*-*-*-600-*-*-m-*-*-*",
317                "-*-helvetica-*-r-*-*-*-240-*-*-p-*-*-*",
318                "-*-lucida-*-r-*-*-*-240-*-*-p-*-*-*",
319                "-*-times-*-r-*-*-*-240-*-*-p-*-*-*",
320                "-*-*-*-r-*-sans-*-240-*-*-p-*-*-*",
321                "-*-*-*-r-*-*-*-240-*-*-m-*-*-*",
322                "fixed",
323                NULL
324        };
325        int               font_Index;
326        int               text_Length;
327        int               text_X;
328        int               text_Y;
329        int               text_Width;
330        int               text_Height;
331        char*             text_List[XSUBLIM_TEXT_COUNT];
332        int               text_Used[XSUBLIM_TEXT_COUNT];
333        char              text_Text[XSUBLIM_TEXT_LENGTH+1];
334        char*             text_Phrase;
335        char*             text_Word;
336        int               text_Index;
337        int               text_Item;
338        int               text_Count;
339        struct
340        {
341                int outline_X;
342                int outline_Y;
343        }                 text_Outline[] =
344        {
345                { -1,-1 },
346                {  1,-1 },
347                { -1, 1 },
348                {  1, 1 },
349                {  0, 0 }
350        };
351        int               text_OutlineIndex;
352        XImage*           image_Image = NULL;
353        int               image_X = 0;
354        int               image_Y = 0;
355        int               image_Width = 0;
356        int               image_Height = 0;
357        int               arg_Count;
358        int               arg_FlagCenter;
359        int               arg_FlagOutline;
360        int               arg_FlagScreensaver;
361        int               arg_FlagRandom;
362        int               arg_DelayShow;
363        int               arg_DelayWord;
364        int               arg_DelayPhraseMin;
365        int               arg_DelayPhraseMax;
366        char*             arg_Text;
367        char*             arg_Source;
368
369        /* Set-up ---------------------------------------------------------- */
370
371        /* Catch signals */
372        Xsublim_Sig_Last = -1;
373        for (sig_Number = 0;sig_Signal[sig_Number] != -1;sig_Number++)
374        {
375                signal(sig_Number,xsublim_Sig_Catch);
376        }
377
378        /* Randomize -- only need to do this here because this program
379           doesn't use the `screenhack.h' or `lockmore.h' APIs. */
380# undef ya_rand_init
381        ya_rand_init (0);
382
383        /* Handle all the X nonsense */
384#if defined(__sgi)
385        SgiUseSchemes("none");
386#endif
387        for (arg_Count = 0;options[arg_Count].option != NULL;arg_Count++)
388        {
389                ;
390        }
391        app_App = XtAppInitialize(&app,progclass,options,arg_Count,&argc,argv,
392         defaults,0,0);
393
394        /* jwz */
395        if (argc > 1)
396          {
397            int x = 18;
398            int end = 78;
399            int i;
400            int count = (sizeof(options)/sizeof(*options))-1;
401            fprintf(stderr, "Unrecognised option: %s\n", argv[1]);
402            fprintf (stderr, "Options include: ");
403            for (i = 0; i < count; i++)
404              {
405                char *sw = options [i].option;
406                Bool argp = (options [i].argKind == XrmoptionSepArg);
407                int size = strlen (sw) + (argp ? 6 : 0) + 2;
408                if (x + size >= end)
409                  {
410                    fprintf (stderr, "\n\t\t ");
411                    x = 18;
412                  }
413                x += size;
414                fprintf (stderr, "%s", sw);
415                if (argp) fprintf (stderr, " <arg>");
416                if (i != count-1) fprintf (stderr, ", ");
417              }
418            fprintf (stderr, ".\n");
419            exit (-1);
420          }
421
422        disp_Display = XtDisplay(app_App);
423        db = XtDatabase(disp_Display);
424        XtGetApplicationNameAndClass(disp_Display,&progname,&progclass);
425        win_Root = RootWindowOfScreen(XtScreen(app_App));
426        XtDestroyWidget(app_App);
427
428        /* Get the arguments */
429        arg_FlagCenter = get_boolean_resource(XSUBLIM_ARG_CENTER,"Boolean");
430        arg_FlagOutline = get_boolean_resource(XSUBLIM_ARG_OUTLINE,"Boolean");
431        arg_FlagScreensaver = get_boolean_resource(XSUBLIM_ARG_SCREENSAVER,
432         "Boolean");
433        arg_FlagRandom = get_boolean_resource(XSUBLIM_ARG_RANDOM,"Boolean");
434        arg_DelayShow = get_integer_resource(XSUBLIM_ARG_DELAYSHOW,"Integer");
435        arg_DelayWord = get_integer_resource(XSUBLIM_ARG_DELAYWORD,"Integer");
436        arg_DelayPhraseMin = get_integer_resource(XSUBLIM_ARG_DELAYPHRASEMIN,
437         "Integer");
438        arg_DelayPhraseMax = get_integer_resource(XSUBLIM_ARG_DELAYPHRASEMAX,
439         "Integer");
440        if (arg_DelayPhraseMax < arg_DelayPhraseMin)
441        {
442                arg_DelayPhraseMax = arg_DelayPhraseMin;
443        }
444
445        /* Get the phrases */
446        text_Index = 0;
447        text_Item = 0;
448        text_Count = 0;
449        memset(text_Used,0,sizeof(text_Used));
450        arg_Source = get_string_resource(XSUBLIM_ARG_FILE,"Filename");
451        if (arg_Source != NULL)
452        {
453                FILE*       file_Fs;
454                struct stat file_Stat;
455
456                file_Fs = fopen(arg_Source,"rb");
457                if (file_Fs == NULL)
458                {
459                        fprintf(stderr,"%s: Could not open '%s'\n",progname,
460                         arg_Source);
461                        exit(-1);
462                }
463                if (fstat(fileno(file_Fs),&file_Stat) != 0)
464                {
465                        fprintf(stderr,"%s: Could not stat '%s'\n",progname,
466                         arg_Source);
467                        exit(-1);
468                }
469                arg_Text = calloc(1,file_Stat.st_size+1);
470                if (arg_Text != NULL)
471                {
472                        if (fread(arg_Text,file_Stat.st_size,1,file_Fs) != 1)
473                        {
474                                fprintf(stderr,"%s: Could not read '%s'\n",
475                                 progname,arg_Source);
476                                exit(-1);
477                        }
478                }
479                fclose(file_Fs);
480        }
481        else
482        {
483                arg_Source = get_string_resource(XSUBLIM_ARG_PROGRAM,
484                 "Executable");
485                if (arg_Source != NULL)
486                {
487                        char* exe_Command = calloc(1,strlen(arg_Source)+10);
488                        FILE* exe_Fs;
489
490                        if (exe_Command == NULL)
491                        {
492                                fprintf(stderr,
493                                 "%s: Could not allocate space for '%s'\n",
494                                 progname,arg_Source);
495                                exit(-1);
496                        }
497                        sprintf(exe_Command,"( %s ) 2>&1",arg_Source);
498
499                        exe_Fs = popen(exe_Command,"r");
500                        if (exe_Fs == NULL)
501                        {
502                                fprintf(stderr,"%s: Could not run '%s'\n",
503                                 progname,arg_Source);
504                                exit(-1);
505                        }
506                        arg_Text = calloc(1,XSUBLIM_PROGRAM_SIZE);
507                        if (arg_Text != NULL)
508                        {
509                                if (fread(arg_Text,1,XSUBLIM_PROGRAM_SIZE,
510                                 exe_Fs) <= 0)
511                                {
512                                        fprintf(stderr,
513                                         "%s: Could not read output of '%s'\n",
514                                         progname,arg_Source);
515                                        exit(-1);
516                                }
517                                if (
518                                 strstr(arg_Text,": not found") ||
519                                 strstr(arg_Text,": Not found") ||
520                                 strstr(arg_Text,": command not found") ||
521                                 strstr(arg_Text,": Command not found"))
522                                {
523                                        fprintf(stderr,
524                                         "%s: Could not find '%s'\n",
525                                         progname,arg_Source);
526                                        exit(-1);
527                                }
528                        }
529                        fclose(exe_Fs);
530                }
531                else
532                {
533                        arg_Text =
534                         get_string_resource(XSUBLIM_ARG_PHRASES,"Phrases");
535                        if (arg_Text != NULL)
536                        {
537                                arg_Text = strdup(arg_Text);
538                        }
539                }
540        }
541        if (arg_Text != NULL)
542        {
543                while (((text_Phrase = strtok(arg_Text,"\n")) != NULL) &&
544                 (text_Count < XSUBLIM_TEXT_COUNT))
545                {
546                        arg_Text = NULL;
547                        text_List[text_Count] = text_Phrase;
548                        text_Count++;
549                }
550                text_List[text_Count] = NULL;
551        }
552        if (text_Count == 0)
553        {
554                fprintf(stderr,"%s: No text to display\n",progname);
555                exit(-1);
556        }
557
558        /* Load the font */
559        font_Font = XLoadQueryFont(disp_Display,
560         get_string_resource(XSUBLIM_ARG_FONT,"Font"));
561        font_Index = 0;
562        while ((font_Font == NULL) && (font_List[font_Index] != NULL))
563        {
564                font_Font = XLoadQueryFont(disp_Display,font_List[font_Index]);
565                font_Index++;
566        }
567        if (font_Font == NULL)
568        {
569                fprintf(stderr,"%s: Couldn't load a font\n",progname);
570                exit(-1);
571        }
572
573        /* Create the GCs */
574        XGetWindowAttributes(disp_Display,win_Root,&attr_Win);
575        gc_ValFore.font = font_Font->fid;
576        gc_ValFore.foreground = get_pixel_resource("foreground","Foreground",
577         disp_Display,attr_Win.colormap);
578        gc_ValFore.background = get_pixel_resource("background","Background",
579         disp_Display,attr_Win.colormap);
580        gc_ValFore.subwindow_mode = IncludeInferiors;
581        gc_GcFore = XCreateGC(disp_Display,win_Root,
582         (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValFore);
583        gc_ValBack.font = font_Font->fid;
584        gc_ValBack.foreground = get_pixel_resource("background","Background",
585         disp_Display,attr_Win.colormap);
586        gc_ValBack.background = get_pixel_resource("foreground","Foreground",
587         disp_Display,attr_Win.colormap);
588        gc_ValBack.subwindow_mode = IncludeInferiors;
589        gc_GcBack = XCreateGC(disp_Display,win_Root,
590         (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValBack);
591
592        /* Loop ------------------------------------------------------------ */
593        while (Xsublim_Sig_Last == -1)
594        {
595                /* Once-per-phrase stuff ----------------------------------- */
596
597                /* If we're waiting for a screensaver... */
598                if (arg_FlagScreensaver != FALSE)
599                {
600                        /* Find the screensaver's window */
601                        win_Root = xsublim_Ss_GetWindow(disp_Display);
602                        if (win_Root == 0)
603                        {
604                                usleep(30000000);
605                                continue;
606                        }
607                }
608
609                /* Pick the next phrase */
610                if (arg_FlagRandom != FALSE)
611                {
612                        text_Item = random()%text_Count;
613                        text_Index = 0;
614                }
615                while (text_Used[text_Item] != FALSE)
616                {
617                        text_Index++;
618                        text_Item++;
619                        if (text_Index == text_Count)
620                        {
621                                text_Index = 0;
622                                memset(text_Used,0,sizeof(text_Used));
623                        }
624                        if (text_List[text_Item] == NULL)
625                        {
626                                text_Item = 0;
627                        }
628                }
629                text_Used[text_Item] = TRUE;
630                strncpy(text_Text,text_List[text_Item],
631                 XSUBLIM_TEXT_LENGTH);
632                text_Phrase = text_Text;
633
634                /* Run through the phrase */
635                while (((text_Word = strtok(text_Phrase," \t")) != NULL) &&
636                 (Xsublim_Sig_Last == -1))
637                {
638                        text_Phrase = NULL;
639
640                        /* Once-per-word stuff ----------------------------- */
641
642                        /* Find the text's position */
643                        XGetWindowAttributes(disp_Display,win_Root,&attr_Win);
644                        text_Length = strlen(text_Word);
645                        text_Width = XTextWidth(font_Font,text_Word,
646                         text_Length)+XSUBLIM_TEXT_OUTLINE*2;
647                        text_Height = font_Font->ascent+font_Font->descent+1+
648                         XSUBLIM_TEXT_OUTLINE*2;
649                        if (arg_FlagCenter == FALSE)
650                        {
651                                text_X = random()%(attr_Win.width-text_Width);
652                                text_Y = random()%(attr_Win.height-
653                                 text_Height);
654                        }
655                        else
656                        {
657                                text_X = (attr_Win.width/2)-(text_Width/2);
658                                text_Y = (attr_Win.height/2)-(text_Height/2);
659                        }
660
661                        /* Find the image's position (and pad it out slightly,
662                           otherwise bits of letter get left behind -- are
663                           there boundry issues I don't know about?) */
664                        image_X = text_X-16;
665                        image_Y = text_Y;
666                        image_Width = text_Width+32;
667                        image_Height = text_Height;
668                        if (image_X < 0)
669                        {
670                                image_X = 0;
671                        }
672                        if (image_Y < 0)
673                        {
674                                image_Y = 0;
675                        }
676                        if (image_X+image_Width > attr_Win.width)
677                        {
678                                image_Width = attr_Win.width-image_X;
679                        }
680                        if (image_Y+image_Height > attr_Win.height)
681                        {
682                                image_Height = attr_Win.height-image_Y;
683                        }
684
685                        /* Influence people for our own ends --------------- */
686
687                        /* Grab the server -- we can't let anybody draw over
688                           us */
689                        XSync(disp_Display,FALSE);
690                        XGrabServer(disp_Display);
691                        XSync(disp_Display,FALSE);
692
693                        /* Set up an error handler that ignores BadMatches --
694                           since the screensaver can take its window away at
695                           any time, any call that uses it might choke */
696                        Xsublim_Sh_Status = 0;
697                        Xsublim_Sh_Handler =
698                         XSetErrorHandler(xsublim_Sh_Handler);
699
700                        /* Save the current background */
701                        image_Image = XGetImage(disp_Display,win_Root,image_X,
702                         image_Y,image_Width,image_Height,~0L,ZPixmap);
703
704                        /* If we've successfully saved the background... */
705                        if (image_Image != NULL)
706                        {
707                                if (Xsublim_Sh_Status == 0)
708                                {
709                                        /* Draw the outline */
710                                        if (arg_FlagOutline != FALSE)
711                                        {
712                                                for (text_OutlineIndex = 0;
713                                                 text_Outline[
714                                                 text_OutlineIndex].outline_X
715                                                 != 0;text_OutlineIndex++)
716                                                {
717                                                        /* Y'know, eight
718                                                           character tabs and
719                                                           descriptive variable
720                                                           names become
721                                                           annoying at some
722                                                           point... */
723                                                        XDrawString(
724                                                         disp_Display,
725                                                         win_Root,gc_GcBack,
726                                                         text_X+text_Outline[
727                                                         text_OutlineIndex].
728                                                         outline_X*
729                                                         XSUBLIM_TEXT_OUTLINE,
730                                                         text_Y+
731                                                         (font_Font->ascent)+
732                                                         text_Outline[
733                                                         text_OutlineIndex].
734                                                         outline_Y*
735                                                         XSUBLIM_TEXT_OUTLINE,
736                                                         text_Word,
737                                                         text_Length);
738                                                }
739                                        }
740
741                                        /* Draw the word */
742                                        XDrawString(disp_Display,win_Root,
743                                         gc_GcFore,text_X,
744                                         text_Y+(font_Font->ascent),text_Word,
745                                         text_Length);
746                                }
747                                if (Xsublim_Sh_Status == 0)
748                                {
749                                        /* Wait a bit */
750                                        XSync(disp_Display,FALSE);
751                                        if (Xsublim_Sig_Last == -1)
752                                        {
753                                                usleep(arg_DelayShow);
754                                        }
755       
756                                        /* Restore the background */
757                                        XPutImage(disp_Display,win_Root,
758                                         gc_GcFore,image_Image,0,0,image_X,
759                                         image_Y,image_Width,image_Height);
760                                }
761
762                                /* Free the image */
763                                XDestroyImage(image_Image);
764                        }
765
766                        /* Restore the error handler, ungrab the server */
767                        XSync(disp_Display,FALSE);
768                        XSetErrorHandler(Xsublim_Sh_Handler);
769                        XUngrabServer(disp_Display);
770                        XSync(disp_Display,FALSE);
771
772                        /* Pause between words */
773                        if (Xsublim_Sig_Last == -1)
774                        {
775                                usleep(arg_DelayWord);
776                        }
777                }
778
779                /* Pause between phrases */
780                if (Xsublim_Sig_Last == -1)
781                {
782                        usleep(random()%(arg_DelayPhraseMax-
783                         arg_DelayPhraseMin+1)+arg_DelayPhraseMin);
784                }
785        }
786
787        /* Exit ------------------------------------------------------------ */
788        for (sig_Number = 0;sig_Signal[sig_Number] != -1;sig_Number++)
789        {
790                signal(sig_Number,SIG_DFL);
791        }
792        kill(getpid(),Xsublim_Sig_Last);
793
794        return 0;
795}
Note: See TracBrowser for help on using the repository browser.