/* -*- Mode: C; tab-width: 4 -*- */ /* run --- run an arbitrary mode */ #if !defined( lint ) && !defined( SABER ) static const char sccsid[] = "@(#)run.c 5.00 2000/11/01 xlockmore"; #endif /*- * Copyright (c) 2000 by David Bagley * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * Revision History: * 19-Apr-2000: Written. */ #ifdef STANDALONE #define MODE_run #define PROGCLASS "Run" #define HACK_INIT init_run #define HACK_DRAW draw_run #define run_opts xlockmore_opts #define DEFAULTS "*delay: 1000000 \n" #include "xlockmore.h" /* in xscreensaver distribution */ #else /* STANDALONE */ #include "xlock.h" /* in xlockmore distribution */ #endif /* STANDALONE */ #ifdef MODE_run #ifdef VMS /* Have to set the Logical VAXC$PATH to point to SYS$SYSTEM */ #define DEF_RUNPROGRAM "DECW$XCLOCK.EXE" #else #define DEF_RUNPROGRAM "xclock" #endif #define DEF_GEOMETRYSTRING "geometry" /* some programs do not like "-geometry" but like "-g" */ static char *runprogram; static char *geometrystring; static XrmOptionDescRec opts[] = { {(char *) "-runprogram", (char *) ".run.runprogram", XrmoptionSepArg, (caddr_t) NULL}, {(char *) "-geometrystring", (char *) ".run.geometrystring", XrmoptionSepArg, (caddr_t) NULL} }; static argtype vars[] = { {(void *) & runprogram, (char *) "runprogram", (char *) "Runprogram", (char *) DEF_RUNPROGRAM, t_String}, {(void *) & geometrystring, (char *) "geometrystring", (char *) "GeometryString", (char *) DEF_GEOMETRYSTRING, t_String} }; static OptionStruct desc[] = { {(char *) "-runprogram string", (char *) "program to run (default xclock)"}, {(char *) "-geometrystring string", (char *) "geometry string, could be g for -g, none for none"} }; ModeSpecOpt run_opts = {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; #ifdef USE_MODULES ModStruct run_description = {"run", "init_run", "draw_run", "release_run", "refresh_run", "init_run", (char *) NULL, &run_opts, 3000000, 1, 1, 1, 64, 1.0, "", "Shows another xprogram", 0, NULL}; #endif typedef struct { int numberprocess; int width, height; } runstruct; static runstruct *runs = (runstruct *) NULL; void init_run(ModeInfo * mi) { char geom_buf[50]; char geoms_buf[50]; /* char win_buf[50]; */ XWindowAttributes xgwa; runstruct *rp; if (runs == NULL) { if ((runs = (runstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (runstruct))) == NULL) return; } rp = &runs[MI_SCREEN(mi)]; if (rp->numberprocess == 0 && !MI_IS_ICONIC(mi)) { (void) XGetWindowAttributes(MI_DISPLAY(mi), RootWindowOfScreen(MI_SCREENPTR(mi)), &xgwa); #ifdef DEBUG (void) printf("%dx%d\n", xgwa.width, xgwa.height); #endif (void) sprintf(geom_buf, "%dx%d", xgwa.width, xgwa.height); (void) sprintf(geoms_buf, "-%s", geometrystring); #ifdef VMS #define FORK vfork #else #define FORK fork #endif if ((rp->numberprocess = FORK()) == -1) (void) fprintf(stderr, "Fork error\n"); else if (rp->numberprocess == 0) { if (strcmp(geoms_buf, "-none")) { #ifdef DEBUG (void) printf("running \"%s %s %s\"\n", runprogram, geoms_buf, geom_buf); #endif (void) execlp(runprogram, runprogram, geoms_buf, geom_buf, 0); } else { #ifdef DEBUG (void) printf("running \"%s\"\n", runprogram); #endif (void) execlp(runprogram, runprogram); } } } } /* ARGSUSED */ void draw_run(ModeInfo * mi) { } #if defined(__linux__) || defined(__CYGWIN__) || defined(SOLARIS2) extern int kill(pid_t, int); extern pid_t wait(int *); #else #if 0 extern int kill(int, int); extern pid_t wait(int *); #endif #endif void release_run(ModeInfo * mi) { if (runs != NULL) { int screen; for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { runstruct *rp = &runs[screen]; if (rp->numberprocess > 0) { int n; #ifdef DEBUG (void) printf("killing %d\n", rp->numberprocess); #endif (void) kill(rp->numberprocess, SIGKILL); (void) wait(&n); } } free(runs); runs = (runstruct *) NULL; } } void refresh_run(ModeInfo * mi) { /* Do nothing, it will refresh by itself :) */ } #endif /* MODE_run */