[comp.windows.x] Proposed resource manager changes

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)