xenocara/app/xlockmore/modes/run.c
2006-11-26 11:07:42 +00:00

189 lines
4.6 KiB
C

/* -*- 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 */