/* * Reload Xdefaults onto root window * * Dave Porter 7-Mar-1989 * ----------------------- * * This program is based on the observation that the DECwindows * session manager stores the contents of the Xdefaults file, merged * with some more resource definitions from session mananger data files, * as a string-valued property on the root window. * * This program fetches the old value of the property and the new * contents of Xdefaults, merges the two together, and rewrites * the property value. * * Restrictions: * * Resource values can be changed, or new resources added. They * cannot be deleted by this program (because the new Xdefaults is * merged into the previous stored list of resources). * * The total length of the resource list is limited by the constant * defined as MAXLEN (as some sort of sanity check). Recompile from * source if you have a huge Xdefaults database. * * Bugs: * * When the session manager stores the data on the root window, it * doesn't include and resources that are explicitly for it (resources * with names starting with "sm." or "sm*", as far as I can tell). * This program doesn't bother with such trifles, so some extraneous * session manager resource definitions end up being stored. This appears * to be harmless. * */ #include #include #include #include #include #include #define XDEFAULTS "sys$login:decw$xdefaults.dat" #define MAXLEN 4096L /* 4K chars */ main() { Display *dpy; Screen *scr; Window root; Atom ptype; int pform; unsigned long nitems, nafter; unsigned char *prop; XrmDatabase old, new; char *temp, *ptr; FILE *file; int len; dpy = XOpenDisplay(0); if (dpy==0) { printf("can't open display\n"); exit(-1); } scr = XDefaultScreenOfDisplay(dpy); root = XRootWindowOfScreen(scr); XrmInitialize(); /* * get current database, stored as a string-valued * property on the root window */ XGetWindowProperty( dpy, root, XA_RESOURCE_MANAGER, 0L, MAXLEN/4, 0, AnyPropertyType, &ptype, &pform, &nitems, &nafter, &prop); if (ptype==None) { printf("property not found on root\n"); exit(-1); } if (ptype!=XA_STRING || pform!=8) { printf("unexpected property data read\n"); exit(-1); } if (nafter) { printf("property too big (%ld bytes)\n", nitems+nafter); exit(-1); } printf("old: %ld bytes\n", nitems); /* * convert into resource manager database * */ old = XrmGetStringDatabase(prop); if (old==NULL) { printf("error reconverting old property value\n"); exit(-1); } /* * be tidy and free up the Xlib memory used for the * property string */ Xfree(prop); /* * read in new file and convert to database * format */ new = XrmGetFileDatabase(XDEFAULTS); if (new==NULL) { printf("can't open %s\n", XDEFAULTS); exit(-1); } /* * merge new database into the old. the 'new' resources * overwrite the old, and 'new' is itself destroyed. */ XrmMergeDatabases(new, &old); /* * now we want to convert the merged database back to * a string. there doesn't seem to be any way to do this, * so we resort to writing it out to a file and then * reading the file in. yecch. */ temp = tmpnam(NULL); XrmPutFileDatabase(old, temp); file = fopen(temp,"r"); if (file==NULL) { printf("can't open %s\n", temp); exit(-1); } prop = malloc(MAXLEN); if (prop==0) { printf("malloc failed\n"); exit(-1); } ptr = prop; len = MAXLEN; nitems = 0; while (len>0 && fgets(ptr, len, file)!=NULL) { int n = strlen(ptr); ptr += n; len -= n; nitems += n; } if(ferror(file)) { printf("error %d reading %s\n", ferror(file), temp); exit(-1); } if(!feof(file)) { printf("internal storage exceeded (%ld bytes)\n", MAXLEN); exit(-1); } fclose(file); remove(temp); /* * Ok, now we can rewrite the root property */ printf("new: %ld bytes\n", nitems); XChangeProperty( dpy, root, XA_RESOURCE_MANAGER, ptype, pform, PropModeReplace, prop, nitems ); XSync(dpy, 0); }