X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fxsublim.c;h=d60fc0dcec009883c9a23df5000b59b8c08be919;hb=c1b9b55ad8d59dc05ef55e316aebf5863e7dfa56;hp=81104d7fea13038182ccf183a1e2c005176ab5b1;hpb=c596d1306f5f92f7eab76224d3b049980a14adcb;p=xscreensaver diff --git a/hacks/xsublim.c b/hacks/xsublim.c index 81104d7f..d60fc0dc 100644 --- a/hacks/xsublim.c +++ b/hacks/xsublim.c @@ -1,8 +1,8 @@ -/***************************************************************************** +/**************************************************************************** * * * xsublim -- Submit. Conform. Obey. * * * - * Copyright (c) 1999 Greg Knauss (greg@eod.com) * + * 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) * @@ -31,6 +31,8 @@ /* 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 @@ -46,17 +48,30 @@ */ +/* 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" @@ -73,6 +88,7 @@ #include #include #include +#include #include #include #include @@ -88,17 +104,23 @@ #include #endif -#include "yarandom.h" #include "usleep.h" +#include "yarandom.h" #include "resources.h" +#include "vroot.h" /* Globals *******************************************************************/ char* progname; -XtAppContext app; -XrmDatabase db; char* progclass = XSUBLIM_NAME; -char* defaults[] = + +# 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", @@ -156,7 +178,8 @@ char* defaults[] = "*" XSUBLIM_ARG_CENTER": true", NULL }; -XrmOptionDescRec options[] = + +static XrmOptionDescRec options[] = { {"-" XSUBLIM_ARG_FONT, "." XSUBLIM_ARG_FONT, XrmoptionSepArg,0}, @@ -174,6 +197,10 @@ XrmOptionDescRec options[] = 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, @@ -195,7 +222,7 @@ static int Xsublim_Sig_Last; /* Functions *****************************************************************/ /* Defer signals to protect the server grab ================================ */ -void xsublim_Sig_Catch(int sig_Number) +static void xsublim_Sig_Catch(int sig_Number) { /* BSD needs this reset each time, and it shouldn't hurt anything else */ @@ -203,120 +230,16 @@ void xsublim_Sig_Catch(int sig_Number) Xsublim_Sig_Last = sig_Number; } -/* Get the screensaver's window ============================================ */ -static XErrorHandler Xsublim_Ss_Handler = NULL; -static int Xsublim_Ss_Status; - /* This was all basically swiped from driver/remote.c and util/vroot.h */ -static int xsublim_Ss_Handler(Display* handle_Display, - XErrorEvent* handle_Error) -{ - if (handle_Error->error_code == BadWindow) - { - Xsublim_Ss_Status = BadWindow; - return 0; - } - if (Xsublim_Ss_Handler == NULL) - { - fprintf(stderr,"%x: ",progname); - abort(); - } - return (*Xsublim_Ss_Handler)(handle_Display,handle_Error); -} static Window xsublim_Ss_GetWindow(Display* ss_Display) { - Window win_Root; - Window win_RootReturn; - Window win_Parent; - Window* win_Child; - Window win_Win; - int child_Count; - int child_Index; - Atom prop_Type; - int prop_Format; - unsigned long prop_Count; - unsigned long prop_Bytes; - char* prop_Value; - int prop_Status; - static Atom XA_SCREENSAVER_VERSION = -1; - static Atom __SWM_VROOT; - - /* Assume bad things */ - win_Win = 0; - win_Child = NULL; - - /* Find the atoms */ - if (XA_SCREENSAVER_VERSION == -1) - { - XA_SCREENSAVER_VERSION = XInternAtom(ss_Display, - "_SCREENSAVER_VERSION",FALSE); - __SWM_VROOT = XInternAtom(ss_Display,"__SWM_VROOT",FALSE); - } - - /* Find a screensaver window */ - win_Root = RootWindowOfScreen(DefaultScreenOfDisplay(ss_Display)); - if (XQueryTree(ss_Display,win_Root,&win_RootReturn,&win_Parent, - &win_Child,&child_Count) != FALSE) - { - if ( - (win_Root == win_RootReturn) && - (win_Parent == 0) && - (win_Child != NULL) && - (child_Count > 0)) - { - for (child_Index = 0;child_Index < child_Count; - child_Index++) - { - XSync(ss_Display,FALSE); - Xsublim_Ss_Status = 0; - Xsublim_Ss_Handler = - XSetErrorHandler(xsublim_Ss_Handler); - prop_Value = NULL; - prop_Status = XGetWindowProperty(ss_Display, - win_Child[child_Index],XA_SCREENSAVER_VERSION, - 0,200,FALSE,XA_STRING,&prop_Type,&prop_Format, - &prop_Count,&prop_Bytes, - (unsigned char**)&prop_Value); - XSync(ss_Display,FALSE); - XSetErrorHandler(Xsublim_Ss_Handler); - if (prop_Value != NULL) - { - XFree(prop_Value); - } - if (Xsublim_Ss_Status == BadWindow) - { - prop_Status = BadWindow; - } - if ((prop_Status == Success) && - (prop_Type != None)) - { - /* See if it's a virtual root */ - prop_Value = NULL; - prop_Status = - XGetWindowProperty(ss_Display, - win_Child[child_Index],__SWM_VROOT,0, - 1,FALSE,XA_WINDOW,&prop_Type, - &prop_Format,&prop_Count,&prop_Bytes, - (unsigned char**)&prop_Value); - if (prop_Value != NULL) - { - XFree(prop_Value); - } - if ((prop_Status == Success) && - (prop_Type != None)) - { - win_Win = - win_Child[child_Index]; - } - } - } - } - } - if (win_Child != NULL) - { - XFree(win_Child); - } - return win_Win; + Screen *s = DefaultScreenOfDisplay (ss_Display); + Window root = XRootWindowOfScreen (s); + Window vroot = VirtualRootWindowOfScreen (s); + if (root == vroot) + return 0; + else + return vroot; } /* Main ==================================================================== */ @@ -338,8 +261,11 @@ static int xsublim_Sh_Handler(Display* handle_Display, } return (*Xsublim_Sh_Handler)(handle_Display,handle_Error); } + + int main(int argc,char* argv[]) { + XtAppContext app; int sig_Number; int sig_Signal[] = { @@ -348,7 +274,9 @@ int main(int argc,char* argv[]) SIGQUIT, SIGILL, SIGTRAP, +#if defined(SIGIOT) SIGIOT, +#endif SIGABRT, #if defined(SIGEMT) SIGEMT, @@ -372,7 +300,7 @@ int main(int argc,char* argv[]) -1 }; Widget app_App; - Display* disp_Display; + Display* dpy; Window win_Root; XWindowAttributes attr_Win; XGCValues gc_ValFore; @@ -385,13 +313,10 @@ int main(int argc,char* argv[]) "-*-character-*-r-*-*-*-600-*-*-p-*-*-*", "-*-helvetica-*-r-*-*-*-600-*-*-p-*-*-*", "-*-lucida-*-r-*-*-*-600-*-*-p-*-*-*", - "-*-times-*-r-*-*-*-600-*-*-p-*-*-*", "-*-*-*-r-*-sans-*-600-*-*-p-*-*-*", "-*-*-*-r-*-*-*-600-*-*-m-*-*-*", - "-*-helvetica-*-r-*-*-*-240-*-*-p-*-*-*", "-*-lucida-*-r-*-*-*-240-*-*-p-*-*-*", - "-*-times-*-r-*-*-*-240-*-*-p-*-*-*", "-*-*-*-r-*-sans-*-240-*-*-p-*-*-*", "-*-*-*-r-*-*-*-240-*-*-m-*-*-*", "fixed", @@ -439,6 +364,7 @@ int main(int argc,char* argv[]) int arg_DelayPhraseMin; int arg_DelayPhraseMax; char* arg_Text; + char* arg_Source; /* Set-up ---------------------------------------------------------- */ @@ -449,8 +375,10 @@ int main(int argc,char* argv[]) signal(sig_Number,xsublim_Sig_Catch); } - /* Randomize */ - srandom((int)time((time_t*)0)); + /* 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) @@ -491,23 +419,22 @@ int main(int argc,char* argv[]) exit (-1); } - disp_Display = XtDisplay(app_App); - db = XtDatabase(disp_Display); - XtGetApplicationNameAndClass(disp_Display,&progname,&progclass); + 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(XSUBLIM_ARG_CENTER,"Boolean"); - arg_FlagOutline = get_boolean_resource(XSUBLIM_ARG_OUTLINE,"Boolean"); - arg_FlagScreensaver = get_boolean_resource(XSUBLIM_ARG_SCREENSAVER, + 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(XSUBLIM_ARG_RANDOM,"Boolean"); - arg_DelayShow = get_integer_resource(XSUBLIM_ARG_DELAYSHOW,"Integer"); - arg_DelayWord = get_integer_resource(XSUBLIM_ARG_DELAYWORD,"Integer"); - arg_DelayPhraseMin = get_integer_resource(XSUBLIM_ARG_DELAYPHRASEMIN, + 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(XSUBLIM_ARG_DELAYPHRASEMAX, + arg_DelayPhraseMax = get_integer_resource(dpy, XSUBLIM_ARG_DELAYPHRASEMAX, "Integer"); if (arg_DelayPhraseMax < arg_DelayPhraseMin) { @@ -519,10 +446,99 @@ int main(int argc,char* argv[]) text_Item = 0; text_Count = 0; memset(text_Used,0,sizeof(text_Used)); - arg_Text = get_string_resource(XSUBLIM_ARG_PHRASES,"Phrases"); + 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) { - arg_Text = strdup(arg_Text); while (((text_Phrase = strtok(arg_Text,"\n")) != NULL) && (text_Count < XSUBLIM_TEXT_COUNT)) { @@ -530,8 +546,8 @@ int main(int argc,char* argv[]) text_List[text_Count] = text_Phrase; text_Count++; } + text_List[text_Count] = NULL; } - text_List[text_Count] = NULL; if (text_Count == 0) { fprintf(stderr,"%s: No text to display\n",progname); @@ -539,12 +555,12 @@ int main(int argc,char* argv[]) } /* Load the font */ - font_Font = XLoadQueryFont(disp_Display, - get_string_resource(XSUBLIM_ARG_FONT,"Font")); + font_Font = XLoadQueryFont(dpy, + get_string_resource(dpy, XSUBLIM_ARG_FONT,"Font")); font_Index = 0; while ((font_Font == NULL) && (font_List[font_Index] != NULL)) { - font_Font = XLoadQueryFont(disp_Display,font_List[font_Index]); + font_Font = XLoadQueryFont(dpy,font_List[font_Index]); font_Index++; } if (font_Font == NULL) @@ -554,22 +570,26 @@ int main(int argc,char* argv[]) } /* Create the GCs */ - XGetWindowAttributes(disp_Display,win_Root,&attr_Win); + XGetWindowAttributes(dpy,win_Root,&attr_Win); gc_ValFore.font = font_Font->fid; - gc_ValFore.foreground = get_pixel_resource("foreground","Foreground", - disp_Display,attr_Win.colormap); - gc_ValFore.background = get_pixel_resource("background","Background", - disp_Display,attr_Win.colormap); + 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(disp_Display,win_Root, + gc_GcFore = XCreateGC(dpy,win_Root, (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValFore); gc_ValBack.font = font_Font->fid; - gc_ValBack.foreground = get_pixel_resource("background","Background", - disp_Display,attr_Win.colormap); - gc_ValBack.background = get_pixel_resource("foreground","Foreground", - disp_Display,attr_Win.colormap); + 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(disp_Display,win_Root, + gc_GcBack = XCreateGC(dpy,win_Root, (GCFont|GCForeground|GCBackground|GCSubwindowMode),&gc_ValBack); /* Loop ------------------------------------------------------------ */ @@ -581,7 +601,7 @@ int main(int argc,char* argv[]) if (arg_FlagScreensaver != FALSE) { /* Find the screensaver's window */ - win_Root = xsublim_Ss_GetWindow(disp_Display); + win_Root = xsublim_Ss_GetWindow(dpy); if (win_Root == 0) { usleep(30000000); @@ -623,7 +643,7 @@ int main(int argc,char* argv[]) /* Once-per-word stuff ----------------------------- */ /* Find the text's position */ - XGetWindowAttributes(disp_Display,win_Root,&attr_Win); + XGetWindowAttributes(dpy,win_Root,&attr_Win); text_Length = strlen(text_Word); text_Width = XTextWidth(font_Font,text_Word, text_Length)+XSUBLIM_TEXT_OUTLINE*2; @@ -669,9 +689,9 @@ int main(int argc,char* argv[]) /* Grab the server -- we can't let anybody draw over us */ - XSync(disp_Display,FALSE); - XGrabServer(disp_Display); - XSync(disp_Display,FALSE); + 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 @@ -681,7 +701,7 @@ int main(int argc,char* argv[]) XSetErrorHandler(xsublim_Sh_Handler); /* Save the current background */ - image_Image = XGetImage(disp_Display,win_Root,image_X, + image_Image = XGetImage(dpy,win_Root,image_X, image_Y,image_Width,image_Height,~0L,ZPixmap); /* If we've successfully saved the background... */ @@ -704,7 +724,7 @@ int main(int argc,char* argv[]) annoying at some point... */ XDrawString( - disp_Display, + dpy, win_Root,gc_GcBack, text_X+text_Outline[ text_OutlineIndex]. @@ -722,7 +742,7 @@ int main(int argc,char* argv[]) } /* Draw the word */ - XDrawString(disp_Display,win_Root, + XDrawString(dpy,win_Root, gc_GcFore,text_X, text_Y+(font_Font->ascent),text_Word, text_Length); @@ -730,30 +750,27 @@ int main(int argc,char* argv[]) if (Xsublim_Sh_Status == 0) { /* Wait a bit */ - XSync(disp_Display,FALSE); + XSync(dpy,FALSE); if (Xsublim_Sig_Last == -1) { usleep(arg_DelayShow); } /* Restore the background */ - XPutImage(disp_Display,win_Root, + XPutImage(dpy,win_Root, gc_GcFore,image_Image,0,0,image_X, image_Y,image_Width,image_Height); } - /* Free the image (and it's goddamned structure - -- the man page for XCreateImage() lies, - lies, lies!) */ + /* Free the image */ XDestroyImage(image_Image); - XFree(image_Image); } /* Restore the error handler, ungrab the server */ - XSync(disp_Display, FALSE); + XSync(dpy,FALSE); XSetErrorHandler(Xsublim_Sh_Handler); - XUngrabServer(disp_Display); - XSync(disp_Display, FALSE); + XUngrabServer(dpy); + XSync(dpy,FALSE); /* Pause between words */ if (Xsublim_Sig_Last == -1)