/* * resource.c * Manage resources for gmemusage * * Copyright (C) 1997, 1998 by Raju Mathur. * Lots of code and ideas shamelessly stolen from xlockmore-3.0/resource.c * * See file COPYING (included in this distribution) for copyright information. */ #include #include #include #include #include #include #include #include #include "common.h" #include "defaults.h" /* * Built-in defaults */ #define DEF_FONT "fixed" #define DEF_GEOMETRY "320x400" #define DEF_NCOLORS "3" #ifdef PASTEL_COLORS #define DEF_COLOR1 "maroon" #define DEF_COLOR2 "OliveDrab" #define DEF_COLOR3 "SlateBlue" #else #define DEF_COLOR1 "red" #define DEF_COLOR2 "green" #define DEF_COLOR3 "blue" #endif #define DEF_COLOR4 "" #define DEF_COLOR5 "" #define DEF_COLOR6 "" #define DEF_COLOR7 "" #define DEF_COLOR8 "" #define DEF_COLOR9 "" #define DEF_FOREGROUND "black" #define DEF_BACKGROUND "grey4" #define DEF_UPDATE "5" #define DEF_THRESHHOLD "400" #define DEF_CLASSNAME "Gmemusage" static XrmOptionDescRec optionTable [] = { { "-geometry" , ".geometry" , XrmoptionSepArg , (caddr_t) NULL } , { "-ncolors" , ".ncolors" , XrmoptionSepArg , (caddr_t) NULL } , { "-color1" , ".color1" , XrmoptionSepArg , (caddr_t) NULL } , { "-color2" , ".color2" , XrmoptionSepArg , (caddr_t) NULL } , { "-color3" , ".color3" , XrmoptionSepArg , (caddr_t) NULL } , { "-color4" , ".color4" , XrmoptionSepArg , (caddr_t) NULL } , { "-color5" , ".color5" , XrmoptionSepArg , (caddr_t) NULL } , { "-color6" , ".color6" , XrmoptionSepArg , (caddr_t) NULL } , { "-color7" , ".color7" , XrmoptionSepArg , (caddr_t) NULL } , { "-color8" , ".color8" , XrmoptionSepArg , (caddr_t) NULL } , { "-color9" , ".color9" , XrmoptionSepArg , (caddr_t) NULL } , { "-font" , ".font" , XrmoptionSepArg , (caddr_t) NULL } , { "-foreground" , ".foreground" , XrmoptionSepArg , (caddr_t) NULL } , { "-background" , ".background" , XrmoptionSepArg , (caddr_t) NULL } , { "-update" , ".update" , XrmoptionSepArg , (caddr_t) NULL } , { "-threshhold" , ".threshhold" , XrmoptionSepArg , (caddr_t) NULL } , } ; const int optionEntries = sizeof ( optionTable ) / sizeof ( optionTable [0] ) ; static XrmOptionDescRec displayTable [] = { { "-display" , ".display" , XrmoptionSepArg , (caddr_t) NULL } } ; const int displayEntries = sizeof ( displayTable ) / sizeof ( displayTable [0] ) ; static XrmOptionDescRec nameTable [] = { { "-name" , ".name" , XrmoptionSepArg , (caddr_t) NULL } } ; const int nameEntries = sizeof ( nameTable ) / sizeof ( nameTable [0] ) ; /* * Variables holding default values */ static char *dName ; char *dGeometry , *dDisplay , *dFont , *dForeground , *dBackground , *dColor [MaxColors] ; int dnColors , dUpdate , dThreshhold ; #define t_String 0 #define t_Int 1 typedef struct { caddr_t *var; char *name; char *class; char *def; int type; } argtype; /* * Warning! If you change anything here do also modify the Help function * accordingly. */ static argtype optionVars[] = { { (caddr_t *) &dFont , "font" , "Font" , DEF_FONT , t_String } , { (caddr_t *) &dGeometry , "geometry" , "Geometry" , DEF_GEOMETRY , t_String } , { (caddr_t *) &dnColors , "ncolors" , "NColors" , DEF_NCOLORS , t_Int } , { (caddr_t *) &dColor [0] , "color1" , "Color" , DEF_COLOR1 , t_String } , { (caddr_t *) &dColor [1] , "color2" , "Color" , DEF_COLOR2 , t_String } , { (caddr_t *) &dColor [2] , "color3" , "Color" , DEF_COLOR3 , t_String } , { (caddr_t *) &dColor [3] , "color4" , "Color" , DEF_COLOR4 , t_String } , { (caddr_t *) &dColor [4] , "color5" , "Color" , DEF_COLOR5 , t_String } , { (caddr_t *) &dColor [5] , "color6" , "Color" , DEF_COLOR6 , t_String } , { (caddr_t *) &dColor [6] , "color7" , "Color" , DEF_COLOR7 , t_String } , { (caddr_t *) &dColor [7] , "color8" , "Color" , DEF_COLOR8 , t_String } , { (caddr_t *) &dColor [8] , "color9" , "Color" , DEF_COLOR9 , t_String } , { (caddr_t *) &dForeground , "foreground" , "Foreground" , DEF_FOREGROUND , t_String } , { (caddr_t *) &dBackground , "background" , "Background" , DEF_BACKGROUND , t_String } , { (caddr_t *) &dUpdate , "update" , "Interval" , DEF_UPDATE , t_Int } , { (caddr_t *) &dThreshhold , "threshhold" , "Threshhold" , DEF_THRESHHOLD , t_Int } , } ; const int nVars = sizeof ( optionVars ) / sizeof ( optionVars [0] ) ; /* * Print out the help message. This'll need to be kept up-to-date as and when * commandline options change. */ static void Help ( void ) { fprintf ( stderr , "gmemusage ver %s by Raju (OldMonk) Mathur\n" "Usage: %s [options]\n" "where options (defaults/resources in brackets) are:\n" " -name resourcename Class name to use for resources (%s) (name)\n" " -display display X server to contact ($DISPLAY) (display)\n" " -geometry geometry Initial window geometry (%s) (geometry)\n" " -font font Text font (%s) (font)\n" " -background color Color to use for window background (%s) (background)\n" " -update seconds Update interval (%s) (update)\n" " -threshhold kb Threshhold to merge small processes (%s) (threshhold)\n" " -ncolors ncolors How many colors to use (%s) (ncolors)\n" " -color1 color color 1 (%s) (color1)\n" " -color2 color color 2 (%s) (color2)\n" " -color3 color color 3 (%s) (color3)\n" " -color[4-9] color colors 4 to 9 (undefined) (color4-color9)\n" " -help Print this message\n" , version , progname , DEF_CLASSNAME , DEF_GEOMETRY , DEF_FONT , DEF_BACKGROUND , DEF_UPDATE , DEF_THRESHHOLD , DEF_NCOLORS , DEF_COLOR1 , DEF_COLOR2 , DEF_COLOR3 ) ; } /* * Begin shameless thefts mentioned earlier. All I did was (1) remove the * extra cases for t_Float and t_Bool and (2) hit ESC C-q at the opening * brace in Xemacs for this function. */ static void GetResource ( XrmDatabase database , char *parentname , char *parentclass , char *name , char *class , int valueType , char *def , caddr_t *valuep ) { char *type; XrmValue value; char *string; char buffer[1024]; char fullname[1024]; char fullclass[1024]; int len; (void) sprintf(fullname, "%s.%s", parentname, name); (void) sprintf(fullclass, "%s.%s", parentclass, class); if (XrmGetResource(database, fullname, fullclass, &type, &value)) { string = value.addr; len = value.size; } else { string = def; len = strlen(string); } (void) strncpy(buffer, string, sizeof(buffer)); buffer[sizeof(buffer) - 1] = '\0'; switch (valueType) { case t_String: { char *s = (char *) malloc(len + 1); if (s == (char *) NULL) { fprintf ( stderr ,"%s: GetResource - couldn't allocate memory" , progname ) ; perror ( "" ) ; exit ( 1 ) ; } (void) strncpy(s, string, len); s[len] = '\0'; *((char **) valuep) = s; } break; case t_Int: *((int *) valuep) = atoi(buffer); break; } } static XrmDatabase optionDB = NULL , serverDB = NULL , mergedDB = NULL ; /* * External interface to resources. Again, shamelessly stolen from * xlockmore-3.0 source. I don't want to do what xlockmore does: open the * display within the GetResource, so we'll break that function up into * two seperate pieces: the first one will get the "name" and "display" * resources, return ot the parent which will then open the display * and then call the second one which will get the rest of the resources. */ void GetInitialResources ( int *argc , char **argv ) { XrmDatabase nameDB = NULL , displayDB = NULL ; XrmInitialize () ; /* * Get -name if we need to look for resources under another name. */ XrmParseCommand ( &nameDB , nameTable , nameEntries , progname , argc , argv ) ; GetResource ( nameDB , progname , "*" , "name" , "Name" , t_String , DEF_CLASSNAME , &dName ) ; XrmParseCommand ( &displayDB , displayTable , displayEntries , progname , argc , argv ) ; dDisplay = getenv ( "DISPLAY" ) ; if ( !dDisplay ) { dDisplay = "" ; } GetResource ( displayDB , progname , dName , "display" , "Display" , t_String , dDisplay , &dDisplay ) ; #if 0 printf("name %s, display %s\n",dName,dDisplay); #endif XrmMergeDatabases ( nameDB , &mergedDB ) ; XrmMergeDatabases ( displayDB , &mergedDB ) ; return ; } /* * Now get the rest of the resources. This function will be called after the * display has been opened by the application. I'm not going to look in * ~/.Xdefaults or ~/.Xresources (presumably rdb has already set those values * in the display RDB) and not in .../app-defaults/... since we are not looking * at an app-default file for the app yet. * * So finally the databases we are left with are: * - Server resources (presumably from rdb(1)) * - cmdline resources * - environment (for DISPLAY) */ void GetResources ( Display *display , int argc , char **argv ) { char *serverString ; register int i ; serverString = XResourceManagerString ( display ) ; if ( serverString ) { serverDB = XrmGetStringDatabase ( serverString ) ; (void) XrmMergeDatabases ( serverDB , &mergedDB ) ; } XrmParseCommand ( &optionDB , optionTable , optionEntries , progname , &argc , argv ) ; /* * Now there shouldn't be any arguments left at all. If there are any, * they're errors and we should flag them. */ if ( argc > 1 ) /* argv[0] still remains, presumably */ { if ( strcmp ( argv [1] , "-help" ) ) { fprintf ( stderr , "%s: unknown option %s\n" , progname , argv [1] ) ; } Help () ; exit ( 1 ) ; } XrmMergeDatabases ( optionDB , &mergedDB ) ; for ( i = 0 ; i < nVars ; i++ ) { GetResource ( mergedDB , progname , dName , optionVars [i] . name , optionVars [i] . class , optionVars [i] . type , optionVars [i] . def , optionVars [i] . var ) ; } XrmDestroyDatabase ( mergedDB ) ; return ; }