-/*****************************************************************************
+/****************************************************************************
* *
* 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) *
-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
/* 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
#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"
#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",
"*" XSUBLIM_ARG_CENTER": true",
NULL
};
-XrmOptionDescRec options[] =
+
+static XrmOptionDescRec options[] =
{
{"-" XSUBLIM_ARG_FONT, "." XSUBLIM_ARG_FONT,
XrmoptionSepArg,0},
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,
/* 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 */
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 ==================================================================== */
}
return (*Xsublim_Sh_Handler)(handle_Display,handle_Error);
}
+
+
int main(int argc,char* argv[])
{
+ XtAppContext app;
int sig_Number;
int sig_Signal[] =
{
SIGQUIT,
SIGILL,
SIGTRAP,
+#if defined(SIGIOT)
SIGIOT,
+#endif
SIGABRT,
#if defined(SIGEMT)
SIGEMT,
-1
};
Widget app_App;
- Display* disp_Display;
+ Display* dpy;
Window win_Root;
XWindowAttributes attr_Win;
XGCValues gc_ValFore;
int arg_DelayPhraseMin;
int arg_DelayPhraseMax;
char* arg_Text;
+ char* arg_Source;
/* Set-up ---------------------------------------------------------- */
/* 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 ((int) time ((time_t *) 0));
+ ya_rand_init (0);
/* Handle all the X nonsense */
#if defined(__sgi)
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)
{
text_Item = 0;
text_Count = 0;
memset(text_Used,0,sizeof(text_Used));
- arg_Text = get_string_resource(XSUBLIM_ARG_FILE,"Filename");
- if (arg_Text != NULL)
+ 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_Text,"rb");
+ file_Fs = fopen(arg_Source,"rb");
if (file_Fs == NULL)
{
fprintf(stderr,"%s: Could not open '%s'\n",progname,
- arg_Text);
+ arg_Source);
exit(-1);
}
if (fstat(fileno(file_Fs),&file_Stat) != 0)
{
fprintf(stderr,"%s: Could not stat '%s'\n",progname,
- arg_Text);
+ arg_Source);
exit(-1);
}
arg_Text = calloc(1,file_Stat.st_size+1);
if (fread(arg_Text,file_Stat.st_size,1,file_Fs) != 1)
{
fprintf(stderr,"%s: Could not read '%s'\n",
- progname,arg_Text);
+ progname,arg_Source);
exit(-1);
}
}
}
else
{
- arg_Text = get_string_resource(XSUBLIM_ARG_PHRASES,"Phrases");
- if (arg_Text != NULL)
+ arg_Source = get_string_resource(dpy, XSUBLIM_ARG_PROGRAM,
+ "Executable");
+ if (arg_Source != NULL)
{
- arg_Text = strdup(arg_Text);
+ 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)
}
/* 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)
}
/* 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 ------------------------------------------------------------ */
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);
/* 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;
/* 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
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... */
annoying at some
point... */
XDrawString(
- disp_Display,
+ dpy,
win_Root,gc_GcBack,
text_X+text_Outline[
text_OutlineIndex].
}
/* 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);
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);
}
}
/* 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)