1 /* $XConsortium: resource.c /main/4 1996/06/19 09:47:56 mustafa $ */
5 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
6 * (c) Copyright 1993, 1994 International Business Machines Corp. *
7 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
8 * (c) Copyright 1993, 1994 Novell, Inc. *
11 * resource.c - resource management for dtscreen, the X Window System lockscreen.
13 * Copyright (c) 1991 by Patrick J. Naughton.
15 * See dtscreen.c for copying information.
18 * 25-Sep-91: added worm mode.
19 * 06-Jun-91: Added flame mode.
20 * 16-May-91: Added random mode and pyro mode.
21 * 26-Mar-91: CheckResources: delay must be >= 0.
22 * 29-Oct-90: Added #include <ctype.h> for missing isupper() on some OS revs.
23 * moved -mode option, reordered Xrm database evaluation.
24 * 28-Oct-90: Added text strings.
25 * 26-Oct-90: Fix bug in mode specific options.
26 * 31-Jul-90: Fix ':' handling in parsefilepath
27 * 07-Jul-90: Created from resource work in dtscreen.c
38 #include <X11/Xresource.h>
40 /* include file for message texts */
43 #define MF_DTSCREEN "dtscreen.cat"
46 extern nl_catd scmc_catd; /* Cat descriptor for scmc conversion */
49 * Declare external interface routines for supported screen savers.
52 extern void inithop();
53 extern void drawhop();
55 extern void initlife();
56 extern void drawlife();
58 extern void initqix();
59 extern void drawqix();
61 extern void initimage();
62 extern void drawimage();
64 extern void initblank();
65 extern void drawblank();
67 extern void initswarm();
68 extern void drawswarm();
70 extern void initrotor();
71 extern void drawrotor();
73 extern void initpyro();
74 extern void drawpyro();
76 extern void initflame();
77 extern void drawflame();
79 extern void initworm();
80 extern void drawworm();
85 void (*lp_callback) ();
92 static char randomstring[] = "random";
94 static LockStruct LockProcs[] = {
95 {"hop", inithop, drawhop, 0, 1000, 1.0, "Hopalong iterated fractals"},
96 {"qix", initqix, drawqix, 30000, 64, 1.0, "Spinning lines a la Qix(tm)"},
97 {"image", initimage, drawimage, 2000000, 8, 0.3, "Random bouncing image"},
98 {"life", initlife, drawlife, 1000000, 100, 1.0, "Conway's game of Life"},
99 {"swarm", initswarm, drawswarm, 10000, 100, 1.0, "Swarm of bees"},
100 {"rotor", initrotor, drawrotor, 10000, 4, 0.4, "Rotor"},
101 {"pyro", initpyro, drawpyro, 15000, 40, 1.0, "Fireworks"},
102 {"flame", initflame, drawflame, 10000, 20, 1.0, "Cosmic Flame Fractals"},
103 {"worm", initworm, drawworm, 10000, 20, 1.0, "Wiggly Worms"},
104 {"blank", initblank, drawblank, 5000000, 1, 1.0, "Blank screen"},
105 {randomstring, NULL, NULL, 0, 0, 0.0, "Random mode"},
107 #define NUMPROCS (sizeof LockProcs / sizeof LockProcs[0])
110 extern char *getenv();
112 #ifndef DEF_FILESEARCHPATH
113 #define DEF_FILESEARCHPATH "/usr/lib/X11/%T/%N%S"
115 #define DEF_DISPLAY ":0"
116 #define DEF_MODE "swarm"
117 #define DEF_BG "White"
118 #define DEF_FG "Black"
119 #define DEF_BC "100" /* vectors (or whatever) per batch */
120 #define DEF_DELAY "200000"/* microseconds between batches */
121 #define DEF_NICE "10" /* dtscreen process nicelevel */
122 #define DEF_SAT "1.0" /* color ramp saturation 0->1 */
123 #define DEF_CLASSNAME "Dtscreen"
125 static char *classname;
126 static char modename[1024];
127 static char modeclass[1024];
129 static XrmOptionDescRec genTable[] = {
130 {"-mode", ".mode", XrmoptionSepArg, (caddr_t) NULL},
131 {"-mono", ".mono", XrmoptionNoArg, (caddr_t) "on"},
132 {"+mono", ".mono", XrmoptionNoArg, (caddr_t) "off"},
133 {"-nice", ".nice", XrmoptionSepArg, (caddr_t) NULL},
134 {"-create", ".create", XrmoptionNoArg, (caddr_t) "on"},
136 #define genEntries (sizeof genTable / sizeof genTable[0])
138 /*************************************************************/
139 /** This table was changed for AIX. In order to read these **/
140 /** command line options properly, the specifier field must **/
141 /** be built on the fly. **/
142 /*************************************************************/
143 static XrmOptionDescRec modeTable[] = {
144 {"-delay", NULL, XrmoptionSepArg, (caddr_t) NULL},
145 {"-batchcount", NULL, XrmoptionSepArg, (caddr_t) NULL},
146 {"-saturation", NULL, XrmoptionSepArg, (caddr_t) NULL},
148 #define modeEntries (sizeof modeTable / sizeof modeTable[0])
150 static XrmOptionDescRec cmdlineTable[] = {
151 {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
152 {"-xrm", NULL, XrmoptionResArg, (caddr_t) NULL},
154 #define cmdlineEntries (sizeof cmdlineTable / sizeof cmdlineTable[0])
156 static XrmOptionDescRec nameTable[] = {
157 {"-name", ".name", XrmoptionSepArg, (caddr_t) NULL},
166 static OptionStruct opDesc[] = {
167 {"-help", "print out this message"},
168 {"-resources", "print default resource file to standard output"},
169 {"-display displayname", "X server to contact"},
170 {"-/+mono", "turn on/off monochrome override"},
171 {"-delay usecs", "microsecond delay between screen updates"},
172 {"-batchcount num", "number of things per batch"},
173 {"-nice level", "nice level for dtscreen process"},
174 {"-saturation value", "saturation of color ramp"},
175 {"-create", "create a window in which to draw"},
177 #define opDescEntries (sizeof opDesc / sizeof opDesc[0])
202 static argtype genvars[] = {
203 {(caddr_t *) &nicelevel, "nice", "Nice", DEF_NICE, t_Int},
204 {(caddr_t *) &mono, "mono", "Mono", "off", t_Bool},
205 {(caddr_t *) &create, "create", "Create", "off", t_Bool},
207 #define NGENARGS (sizeof genvars / sizeof genvars[0])
209 static argtype modevars[] = {
210 {(caddr_t *) &delay, "delay", "Delay", DEF_DELAY, t_Int},
211 {(caddr_t *) &batchcount, "batchcount", "BatchCount", DEF_BC, t_Int},
212 {(caddr_t *) &saturation, "saturation", "Saturation", DEF_SAT, t_Float},
214 #define NMODEARGS (sizeof modevars / sizeof modevars[0])
224 fprintf(stderr, "%s: bad command line option: %s.\n\n",
225 ProgramName, badOption);
227 fprintf(stderr, catgets(scmc_catd, 2, 1,
228 "%s: Bad command line option: %s.\n\n"),
229 ProgramName, badOption);
232 fprintf(stderr, "usage: %s", ProgramName);
233 col = 8 + strlen(ProgramName);
234 for (i = 0; i < opDescEntries; i++) {
235 len = 3 + strlen(opDesc[i].opt); /* space [ string ] */
236 if (col + len > 79) {
237 fprintf(stderr, "\n "); /* 3 spaces */
240 fprintf(stderr, " [%s]", opDesc[i].opt);
244 len = 8 + strlen(LockProcs[0].cmdline_arg);
245 if (col + len > 79) {
246 fprintf(stderr, "\n "); /* 3 spaces */
249 fprintf(stderr, " [-mode %s", LockProcs[0].cmdline_arg);
251 for (i = 1; i < NUMPROCS; i++) {
252 len = 3 + strlen(LockProcs[i].cmdline_arg);
253 if (col + len > 79) {
254 fprintf(stderr, "\n "); /* 3 spaces */
257 fprintf(stderr, " | %s", LockProcs[i].cmdline_arg);
260 fprintf(stderr, "]\n");
263 fprintf(stderr, "\nType %s -help for a full description.\n\n",
266 fprintf(stderr, catgets(scmc_catd, 2, 2,
267 "\nType %s -help for a full description.\n\n"),
279 fprintf(stderr, "usage:\n %s [-options ...]\n\n", ProgramName);
280 fprintf(stderr, "where options include:\n");
283 fprintf(stderr, catgets(scmc_catd, 2, 3,
284 "Usage:\n %s [-options ...]\n\n\
285 where options include:\n"), ProgramName);
288 for (i = 0; i < opDescEntries; i++) {
289 fprintf(stderr, " %-28s %s\n", opDesc[i].opt, opDesc[i].desc);
293 fprintf(stderr, " %-28s %s\n", "-mode mode", "animation mode");
294 fprintf(stderr, " where mode is one of:\n");
296 fprintf(stderr, catgets(scmc_catd, 2, 5,
297 " %-28s %s\n\t where mode is one of:\n"),
298 "-mode mode", "animation mode");
300 for (i = 0; i < NUMPROCS; i++) {
301 fprintf(stderr, " %-23s %s\n",
302 LockProcs[i].cmdline_arg, LockProcs[i].desc);
314 printf("%s.mode: %s\n", classname, DEF_MODE);
316 for (i = 0; i < NGENARGS; i++)
317 printf("%s.%s: %s\n",
318 classname, genvars[i].name, genvars[i].def);
320 for (i = 0; i < NUMPROCS - 1; i++) {
321 printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
322 "delay", LockProcs[i].def_delay);
323 printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
324 "batchcount", LockProcs[i].def_batchcount);
325 printf("%s.%s.%s: %g\n", classname, LockProcs[i].cmdline_arg,
326 "saturation", LockProcs[i].def_saturation);
345 GetResource(database, parentname, parentclass,
346 name, class, valueType, def, valuep)
347 XrmDatabase database;
354 caddr_t *valuep; /* RETURN */
361 char fullclass[1024];
364 sprintf(fullname, "%s.%s", parentname, name);
365 sprintf(fullclass, "%s.%s", parentclass, class);
366 if (XrmGetResource(database, fullname, fullclass, &type, &value)) {
371 len = strlen(string);
373 (void) strncpy(buffer, string, sizeof(buffer));
374 buffer[sizeof(buffer) - 1] = '\0';
380 s = (char *) malloc(len + 1);
381 if (s == (char *) NULL)
383 error("%s: GetResource - couldn't allocate memory");
386 fprintf(stderr, catgets(scmc_catd, 2, 18,
387 "%s: GetResource - couldn't allocate memory.\n"),ProgramName);
391 (void) strncpy(s, string, len);
393 *((char **) valuep) = s;
398 *((int *) valuep) = (!strcmp(buffer, "true") ||
399 !strcmp(buffer, "on") ||
400 !strcmp(buffer, "enabled") ||
401 !strcmp(buffer, "yes")) ? True : False;
404 *((int *) valuep) = atoi(buffer);
407 *((float *) valuep) = (float) atof(buffer);
414 parsefilepath(xfilesearchpath, TypeName, ClassName)
415 char *xfilesearchpath;
419 XrmDatabase database = NULL;
420 char appdefaults[1024];
424 src = xfilesearchpath;
425 appdefaults[0] = '\0';
437 (void) strcat(dst, TypeName);
439 dst += strlen(TypeName);
442 (void) strcat(dst, ClassName);
444 dst += strlen(ClassName);
453 } else if (*src == ':') {
454 database = XrmGetFileDatabase(appdefaults);
455 if (database == NULL) {
460 } else if (*src == '\0') {
461 database = XrmGetFileDatabase(appdefaults);
471 /*******************************************************************/
472 /** screenIOErrorHandler **/
474 /** this function will exit cleanly when the connection is broken **/
475 /*******************************************************************/
476 static int screenIOErrorHandler(dpy)
486 if (display != NULL) {
487 char *colon = strchr(display, ':');
488 int n = colon - display;
492 error("%s: Malformed -display argument, \"%s\"\n", display);
495 fprintf(stderr, catgets(scmc_catd, 2, 19,
496 "%s: Malformed -display argument: %s.\n"), ProgramName,display);
503 if (!(dsp = XOpenDisplay(display)))
505 error("%s: unable to open display %s.\n", display);
508 fprintf(stderr, catgets(scmc_catd, 2, 17,
509 "%s: Unable to open display %s.\n"),ProgramName, display);
514 XSetIOErrorHandler(screenIOErrorHandler);
524 fprintf(stderr, "%s.%s: %s\n",
525 class, var.name, *((char **) var.var));
528 fprintf(stderr, "%s.%s: %s\n",
529 class, var.name, *((int *) var.var)
533 fprintf(stderr, "%s.%s: %d\n",
534 class, var.name, *((int *) var.var));
537 fprintf(stderr, "%s.%s: %g\n",
538 class, var.name, *((float *) var.var));
545 GetResources(argc, argv)
549 XrmDatabase RDB = NULL;
550 XrmDatabase modeDB = NULL;
551 XrmDatabase nameDB = NULL;
552 XrmDatabase cmdlineDB = NULL;
553 XrmDatabase generalDB = NULL;
554 XrmDatabase homeDB = NULL;
555 XrmDatabase applicationDB = NULL;
556 XrmDatabase serverDB = NULL;
557 XrmDatabase userDB = NULL;
564 /***************************/
565 /** new variables for AIX **/
566 /***************************/
567 char delaySpecifier[64];
568 char batchcountSpecifier[64];
569 char saturationSpecifier[64];
573 for (i = 0; i < argc; i++) {
574 if (!strncmp(argv[i], "-help", strlen(argv[i])))
580 * get -name arg from command line so you can have different resource
581 * files for different configurations/machines etc...
583 XrmParseCommand(&nameDB, nameTable, 1, ProgramName,
585 GetResource(nameDB, ProgramName, "*", "name", "Name", t_String,
586 DEF_CLASSNAME, &classname);
588 homeenv = getenv("HOME");
592 env = getenv("XFILESEARCHPATH");
593 applicationDB = parsefilepath(env ? env : DEF_FILESEARCHPATH,
594 "app-defaults", classname);
596 XrmParseCommand(&cmdlineDB, cmdlineTable, cmdlineEntries, ProgramName,
599 userpath = getenv("XUSERFILESEARCHPATH");
601 env = getenv("XAPPLRESDIR");
603 sprintf(userfile, "%s/%%N:%s/%%N", env, homeenv);
605 sprintf(userfile, "%s/%%N", homeenv);
608 userDB = parsefilepath(userpath, "app-defaults", classname);
610 (void) XrmMergeDatabases(applicationDB, &RDB);
611 (void) XrmMergeDatabases(userDB, &RDB);
612 (void) XrmMergeDatabases(cmdlineDB, &RDB);
614 env = getenv("DISPLAY");
615 GetResource(RDB, ProgramName, classname, "display", "Display", t_String,
616 env ? env : DEF_DISPLAY, &display);
618 serverString = XResourceManagerString(dsp);
620 serverDB = XrmGetStringDatabase(serverString);
621 (void) XrmMergeDatabases(serverDB, &RDB);
624 sprintf(buf, "%s/.Xdefaults", homeenv);
625 homeDB = XrmGetFileDatabase(buf);
626 (void) XrmMergeDatabases(homeDB, &RDB);
629 XrmParseCommand(&generalDB, genTable, genEntries, ProgramName, &argc, argv);
630 (void) XrmMergeDatabases(generalDB, &RDB);
632 GetResource(RDB, ProgramName, classname, "mode", "Mode", t_String,
633 DEF_MODE, (caddr_t *) &mode);
636 * if random< mode, then just grab a random entry from the table
638 if (!strcmp(mode, randomstring))
639 mode = LockProcs[random() % (NUMPROCS - 2)].cmdline_arg;
641 sprintf(modename, "%s.%s", ProgramName, mode);
642 sprintf(modeclass, "%s.%s", classname, mode);
645 /*********************************************************************/
646 /** New code for AIX **/
647 /** We must build the specifier fields of the modeTable on the fly. **/
648 /*********************************************************************/
649 sprintf(delaySpecifier, ".%s.delay", mode);
650 sprintf(batchcountSpecifier, ".%s.batchcount", mode);
651 sprintf(saturationSpecifier, ".%s.saturation", mode);
652 modeTable[0].specifier = delaySpecifier;
653 modeTable[1].specifier = batchcountSpecifier;
654 modeTable[2].specifier = saturationSpecifier;
657 XrmParseCommand(&modeDB, modeTable, modeEntries, ProgramName, &argc, argv);
658 (void) XrmMergeDatabases(modeDB, &RDB);
660 /* Parse the rest of the command line */
661 for (argc--, argv++; argc > 0; argc--, argv++) {
664 switch (argv[0][1]) {
674 /* the RDB is set, now query load the variables from the database */
676 for (i = 0; i < NGENARGS; i++)
677 GetResource(RDB, ProgramName, classname,
678 genvars[i].name, genvars[i].class,
679 genvars[i].type, genvars[i].def, genvars[i].var);
681 for (i = 0; i < NMODEARGS; i++)
682 GetResource(RDB, modename, modeclass,
683 modevars[i].name, modevars[i].class,
684 modevars[i].type, modevars[i].def, modevars[i].var);
686 (void) XrmDestroyDatabase(RDB);
696 Syntax("-batchcount argument must be positive.");
697 if (saturation < 0.0 || saturation > 1.0)
698 Syntax("-saturation argument must be between 0.0 and 1.0.");
700 Syntax("-delay argument must be positive.");
702 for (i = 0; i < NUMPROCS; i++) {
703 if (!strncmp(LockProcs[i].cmdline_arg, mode, strlen(mode))) {
704 init = LockProcs[i].lp_init;
705 callback = LockProcs[i].lp_callback;
711 fprintf(stderr, "Unknown mode: ");
713 fprintf(stderr, catgets(scmc_catd, 2, 7,