joel@DECWRL.DEC.COM (11/24/87)
The resource manager was originally intended for use with the toolkit, but was moved into Xlib so that Xlib could use it too. There are serveral problems with the resource manager as used by the toolkit; these types of errors probably don't show up for non-toolkit users. Below I describe several problems and the changes we have made to address them in an experimental version of the resource manager. In a separate message I include a complete listing of the Xresource.h that I am currently using. If you have any input on these proposals, please reply immediately. We are trying to get the next version of the intrinsics and Xlib (for internal release to MIT, not for distribution) ready. We will assume that silence means assent. 1. "*" and "." notation ------------------------ Chuck Price complained that specifications of "parent.x" and "parent.y" match "parent.child.x" and "parent.child.y". This caused him buggy results and wasted a large amount of his time tracking the cause down. Others have come across the same problem in different guises. I propose two types of specification syntax in the .Xdefaults file. The dot "." is used for tight binding of names: "x.y" means that a match must occur with no intervening names between x and y. The star "*" is used for "wild-card" behavior, where "x*y" means any number of names, including 0, can occur between x and y. A name should be prefixed by * if the first name is not the name or class of an application. If both "." and "*" are valid matches, "." wins over "*". In other words, the entries "*parent.background: green" and "*parent*background: red" makes the parent's background green, and the background of all children red. (For those who use base 3 to figure out which among many matches has first priority, just change to base 5. For each name/class in the resource being fetch, use these values: 0 = no match, 1 = class "*" match, 2 = class "." match, 3 = name "*" match, and 4 = name "." match.) (For those of you who think "*.parent.*.background" is nicer syntax, my experimental routines permit, but do not require, this notation.) Note that this invalidates all existing .Xdefaults files. Compatibility could be maintained by letting "." have its current meaning, and using another character for tight binding. The problem is, I can't thing of another character. Everyone "knows" that "*" means a wild-card that matches anything. We can provide a program or script that to convert existing .Xdefaults files to the new format. It would replace "." with "*", and prefix every resource specification with "*". 2. Resource manager miss caching --------------------------------- The current resource manager converter caches hits, but not misses. Font or color specifications require a round trip to the server; when a color or font is not available this means several unneeded round trips. I propose caching misses as well as hits. This has the added benefit of generating a single warning message for any particular conversion error rather than several identical messages. 3. XrmParseCommand ------------------- We would like to add another option kind to XrmParseCommand. This would allow setting any resources for an application from the command line, rather than only those for which convenient abbreviations have been defined. This new option kind XrmoptionResArg takes the next argument and treats it as if it were a line in a .Xdefaults file. For example, if I have defined "-xrm" to be an XrmoptionsResArg, then I could change the color of all scrollbars in an application by invoking it as: xterm -xrm '*scrollBar.background: red' We would also like to remove the "prependName" argument to XrmParseCommand. It serves no purpose, and none of use can actually remember why we put it there in the first place. Finally, Robert Scheifler has noted that using the ":" character to distinguish the hostname/display argument may cause problems for systems on which ":" may occur in file names, net addresses, or other likely command line arguments. Can we all agree upon "-d <display>" or something as the accepted (and only) way of specifying a display? It's been suggested that such syntax should be the preferred method, and today's notation be a fallback, but that means that anytime you have a non-display argument with ":", you have to specify the display with "-d". You can't just allow the display to default. Yuch. 4. Destructive merging of databases ------------------------------------ Merging of resource databases is quite slow. A complete traversal of one database is made, and each time a leaf is reached it is inserted into the other database, using much the same logic as XrmPutResource. I propose making database merging much faster by (1) merging levels of the database en masse, and (2) copying pointers rather than mallocing bunches of new storage. Unfortunately, this means that the two databases are literally merged together - only one good database results. The pieces of the database being merged in are either incorporated directly into the resulting database, or are freed. All uses of database merging we do or plan to do are not affected by this - we create new databases only to be merged exactly once into another database. If anyone ever wants to merge one database into another, and end up with a merged database as well as the orginal database that was merged, we can provide a routine XrmCopyDatabase for you to use before the merge. I'd just as soon not write this code if it will never be used, though. 5. Removal of automatic conversion ----------------------------------- The various "GetResource" routines take an argument specifying the desired target type, and the resource manager automatically converts the type fetched from the database to the desired type. This type conversion is a 2-input, 1-output converter: the two inputs are the value from the resource database, and the screen argument. This 2-input mechanism worked fine for simple things in X10, and kind of worked for more complicated objects (like pixmaps constructed all of one color). With the inclusion of multiple colormaps, this mechanism does not work well under X11 at all. Right now, ALL toolkit applications on a screen must use the default colormap - there is no way to allocate things as large-grained as a colormap per toolkit application. This is because the screen and resource database input do not constitute enough information to properly convert a color - the colomap is needed, too. The most obvious kludge is to pass in the colormap on resource fetching calls. This still does not solve other problems, like conversion to pixmaps, graphics contexts, etc. Further, the caching mechanism would then have to assume that all conversions are dependent upon both screen and colormap, when in fact many conversion are dependent upon neither. I have defined a conversion mechanism that works for the toolkit, in which a type converter can be specified to take other input sources - data at a fixed address, data at an offset from a base address (which in the toolkit will be the widget base), data referenced by resource name. This mechanism is very toolkit-dependent, though. I can envision other conversion mechanisms for other ways of interacting with the resource manager. I therefore am forced to conclude that the various resource fetching routines should not SPECIFY the desired target type, but should provide a pointer to a type so that they can be RETURNED the storage type. From there, various clients of the resource manager can call their private conversion mechanism. I will send out a description of the new conversion mechanism for the toolkit as soon as I've got it working and am sure it's what we really want. 6. Conversion errors --------------------- XrmConvert prints a message whenever a conversion fails (that is, returns NULL). This results in a warning message that tells you what types were involved (for example, String to Color), but don't tell you the string you are trying to convert. It also results in color conversions on a b/w display generating lots of errors. We would like each conversion to have its own warning message when it cannot perform a conversion. It is okay for a conversion routine to return NULL, yet not report a warning (for example, color conversions on a b/w display should not complain). This eliminates spurious warnings, and provides a detailed message when a real conversion error occurs. The new conversion mechanism defined for the toolkit reports errors on a per-converter basis. Errors are reported using XtWarning, so the standard warning procedure can be replaced by an application if it wants to do something else with them. 7. Various parameter cleanups ------------------------------ Most of these are described briefly below in the appendix. The changes fall into three catagories: (1) Routines no longer used. Procedures in this catagory were used by the X10-based toolkit, but are no longer needed by the latest X11 toolkit. I doubt that they are in general use at all. Unfortunately, we didn't remove all these routines when converting to the new toolkit. (2) Parameter changes resulting from the above proposals. For example, with the "*"/"." notation, an XrmQuarkList does not provide enough information to XrmPutResource. You need to know which separator was used. (3) Routines at the wrong level of abstraction. Some routines take strings, some take quarks. These routines were not originallydefined for general use, and the parameter lists reflect usage of them by the toolkit at the time that the resource manager was moved to Xlib. The routines as described in the following message provide a much more uniform interface. Routines starting with Xrm are high-level entry points (and take strings), routines starting with _Xrm are low-level entry points (and take quarks). 8. Getting rid of XrmAtom -------------------------- This term has historical significance from early versions of the X10 toolkit, but that's about all. An XrmAtom is a char *. We have removed all references to the type "Atom" in the toolkit, and just talk about the type "String" instead. This avoids confusion with server atoms. Although it causes some degree of havoc, I'd just as soon remove all refences to XrmAtoms in Xlib too. I suspect it's too late for this change, but thought I'd mention it anyway. - Joel McCormack (joel@decwrl.dec.com, decwrl!joel) Appendix - changes to interface =============================== Remove procedures XrmNewQuarkList, XrmFreeQuarkList, XrmQuarkListLength, XrmCopyQuarkList, XrmFreeNameList, XrmNameListLength, XrmFreeClassList, XrmClassListLength. These are all artifacts left over from the X10 toolkit. Remove types and procedures XrmTypeConverter, XrmRegisterTypeConverter, XrmConvert. These cannot be defined generally enough to warrant inclusion in Xlib. There will be equivalents of these procedures in the toolkit. Add types XrmBinding, XrmBindingList: typedef enum {XrmBindTightly, XrmBindLoosely} XrmBinding, *XrmBindingList; XrmBindTightly corresponds to ".", XrmBindLoosely corresponds to "*". Add procedure XrmStringToBindingAndQuarkList: void XrmStringToBindingAndQuarkList(name, bindings, quarks) char *name; XrmBindingList bindings; XrmQuarkList quarks; quarks is returned NULL-terminated, bindings is not (it's an enum). Add procedure _XrmPutResource which takes both a binding list and a quark list. Change XrmPutResource to take a string rather than a quark list for the resource name. Add procedure XrmPutStringResource which takes a string for the resource name, and a string for the resource value to put into the database. Add procedure XrmPutLineResource which takes a string in the same format as a line in the default resources file (.Xdefaults), parses it into the resource name and value, and stores it into the database. Change XrmGetResource to take strings rather than quark lists for the name and class lists. Make the destination type specifier be an address parameter to return the type of the resource as stored in the database. Remove the screen parameter - XrmGetResource does not perform a conversion. Return True if found. Add _XrmGetResource to take quark lists for name and class. Make destination type instead be the type of the resource as stored in the database. Return True if found. Change XrmGetSearchList to _XrmGetSearchList. Change XrmGetSearchResource to _XrmGetSearchResource, destination type should be address for return type. Remove the screen parameter. Return True if found. Change "DataBase" to "Database" everywhere. Change names of XrmGetDatabase and XrmLoadDatabase to XrmGetDatabaseFromFile and XrmGetDatabaseFromString (or maybe XrmFileToDatabase and XrmStringToDatabase, I don't care, I just can never remember which does which the way they are now!) Change XrmPutDatabase accordingly. Add XrmoptionResArg to the kinds of command line options. Remove prependName from XrmParseCommand. - Joel McCormack (joel@decwrl.dec.com, decwrl!joel)