[comp.windows.x] Does anyone have a fix for R4/PL1 XGetDefault?

casey@gauss.llnl.gov (Casey Leedom) (02/10/90)

  Under R4, XGetDefault doesn't work 100%.  If you attempt to do an
XGetDefault(dpy, prog, "foo.bar"), XGetDefault won't break the string
"foo.bar" up into separate ``Quarks'' and therefore won't match the
desired resource.  I've got a bug report in to MIT, but I don't know when
we'll see a fix from them.

  I know of two programs which are affected by this bug: xgraph and awm.
There are probably more.  I'm not worried about xgraph because it's
incorrect for it to use XGetDefault.  But awm really doesn't have a
choice.  It uses XGetDefault to go for it's ``<prog>*wm_option.foo''
resources.

  Normally I'd just wait till MIT came out with the official fix, but I
have users banging on me about awm being broken.  Also, normally I'd fix
the problem myself if I needed to, but I don't understand the code or
conventions in this area.  Please email patches to me and I will post the
one that works correctly and seems cleanest.  Thanks for your help.

Casey

casey@gauss.llnl.gov (Casey Leedom) (02/12/90)

  Well, I didn't get a grand rush of fixes for this problem, so I was
forced to try my own hand at the code.  I think I've got an appropriate
fix.  It certainly seems to work in any case.  I will gladly accept
criticism that will lead to a better fix.  This fix is also being send to
xbugs.

Casey

-----
From: casey@gauss.llnl.gov (Casey Leedom)
To: xbugs@expo.lcs.mit.edu
Subject: R4/PL2 XGetDefault doesn't handle complex resource names
-------
VERSION:
    R4; fix-1 and fix-2 applied

AREA:
    mit/lib/X/XGetDflt.c

SYNOPSIS:
    XGetDefault doesn't work 100%.  If you attempt to do an XGetDefault(dpy,
    prog, "foo.bar"), XGetDefault won't break the string "foo.bar" up into
    separate ``Quarks'' and therefore won't match the desired resource.

REPEAT BY:
    By inspection.  Note that XGetDefault simply passes the ``name''
    parameter directly to XrmStringToName without any attempt to break
    the string up into it's constituent parts.

SAMPLE FIX:
    Not being familiar with this code, I can't make any guarantees about
    the appropriateness of my fix.  There may be a much better way of
    fixing this problem.  I particularly don't like the fixed name array
    size of 100, but this kind of code permeates the X library, so I
    didn't know what to do (I couldn't find an example of how to do it
    Right.)  On the other hand, the fix does work in all the cases I've
    tested ...  Buyer beware.

*** mit/lib/X/XGetDflt.c-dist	Tue Jan 30 18:35:20 1990
--- mit/lib/X/XGetDflt.c	Sun Feb 11 22:32:00 1990
***************
*** 124,134 ****
  	register char *name;		/* name of option program wants */
  #endif
  {					/* to get, for example, "font"  */
! 	XrmName names[3];
! 	XrmClass classes[3];
  	XrmRepresentation fromType;
  	XrmValue result;
  	char *progname;
  
  	/*
  	 * strip path off of program name (XXX - this is OS specific)
--- 124,136 ----
  	register char *name;		/* name of option program wants */
  #endif
  {					/* to get, for example, "font"  */
! 	XrmName names[100];	/* 100: YECH -- and XrmStringToNameList */
! 	XrmClass classes[100];	/* does not even let us pass in this limit */
  	XrmRepresentation fromType;
  	XrmValue result;
  	char *progname;
+ 	register XrmClass classp;
+ 	register int i;
  
  	/*
  	 * strip path off of program name (XXX - this is OS specific)
***************
*** 150,160 ****
  	UnlockDisplay(dpy);
  
  	names[0] = XrmStringToName(progname);
- 	names[1] = XrmStringToName(name);
- 	names[2] = NULLQUARK;
  	classes[0] = XrmStringToClass("Program");
! 	classes[1] = XrmStringToClass("Name");
! 	classes[2] = NULLQUARK;
  	(void)XrmQGetResource(dpy->db, names, classes, &fromType, &result);
  	return (result.addr);
  }
--- 152,163 ----
  	UnlockDisplay(dpy);
  
  	names[0] = XrmStringToName(progname);
  	classes[0] = XrmStringToClass("Program");
! 	XrmStringToNameList(name, &names[1]);
! 	classp = XrmStringToClass("Name");
! 	for (i = 1; names[i] != NULLQUARK; i++)
! 		classes[i] = classp;
! 	classes[i] = NULLQUARK;
  	(void)XrmQGetResource(dpy->db, names, classes, &fromType, &result);
  	return (result.addr);
  }

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (02/20/90)

    Under R4, XGetDefault doesn't work 100%.

Yes, it does (modulo the bug in the prototype declaration).

    If you attempt to do an XGetDefault(dpy, prog, "foo.bar"), XGetDefault
    won't break the string "foo.bar" up into separate ``Quarks'' and therefore
    won't match the desired resource.

That's correct.  XGetDefault is *not supposed* to handle multi-level resources,
it was only designed to handle single-level resources.  I suspect it is largely
by accident that abuse of it worked in R3.

    I've got a bug report in to MIT, but I don't know when
    we'll see a fix from them.

I don't think you'll see one from us, since it isn't considered a bug.

casey@gauss.llnl.gov (Casey Leedom) (02/20/90)

| From: rws@EXPO.LCS.MIT.EDU (Bob Scheifler)
| 
|     Under R4, XGetDefault doesn't work 100%.
| 
| Yes, it does (modulo the bug in the prototype declaration).
| 
|     If you attempt to do an XGetDefault(dpy, prog, "foo.bar"), XGetDefault
|     won't break the string "foo.bar" up into separate ``Quarks'' and
|     therefore won't match the desired resource.
| 
| That's correct.  XGetDefault is *not supposed* to handle multi-level
| resources, it was only designed to handle single-level resources.  I
| suspect it is largely by accident that abuse of it worked in R3.
| 
|     I've got a bug report in to MIT, but I don't know when we'll see a
|     fix from them.
| 
| I don't think you'll see one from us, since it isn't considered a bug.

  Well piss me off!  Why the hell didn't someone answer this way
sooner?!  I thought I wasn't seeing a response from someone in authority
because they didn't have the time for the fix.  How long would it have
taken you to write this response a month ago when I first asked?  (Note
that you're responding to my second posting.)

  Now I've gone and implemented a ``fix'' for XGetDefault that's not
compatible with what you describe as Proper Behavior.  That time has now
been wasted and I still need to come up with a fix for awm that makes
sense.  And as I maintain almost a hundred machines running on four
different architectures, it will now take me three days to just back out
the XGetDefault change.

  As for Proper Behavior: DOCUMENT IT DAMN IT!!!  There is no explicit
mention of this ``Proper Behavior'' in the XGetDefault manual page.  And
it should be pointed out that this is a particularly non-useful
definition of Proper Behavior.  It sure as hell isn't consistent with the
other resource routines which do break up multi-level name
specifications.  What is the rationale for not supporting multi-level
resource names in XGetDefault??  Are you simply trying to discourage its
use?  If so, mark it as deprecated in the manual page!

  I don't know what the hell I'm going to do for awm now.  I'll probably
have to do some weird-ass dynamic building of XtResourceList's ...  What
a pain.

Pissed off,
Casey

jg@athabasca.crl.dec.com (Jim Gettys) (02/20/90)

In article <49225@lll-winken.LLNL.GOV>, casey@gauss.llnl.gov (Casey
Leedom) writes:
> 
>   Well piss me off!  Why the hell didn't someone answer this way
> sooner?!  I thought I wasn't seeing a response from someone in authority
> because they didn't have the time for the fix.  How long would it have
> taken you to write this response a month ago when I first asked?  (Note
> that you're responding to my second posting.)

Maybe they were a bit busy a month ago.  I seem to remember a release
around then, and an X conference around then; not to mention the fact
that the message rate on the newsgroup was around 75 or more a day a
month ago.  And some of us are involved in other things than answering
each and every news posting.  At that message rate, it is a bit hard to
deal with figuring out which ones should or shouldn't be answered.  As
someone whose job is supposed to be things other than answering
questions on Usenet, I know that I ignored a whole pile of postings
around then.

> 
>   As for Proper Behavior: DOCUMENT IT DAMN IT!!!  There is no explicit
> mention of this ``Proper Behavior'' in the XGetDefault manual page.  And
> it should be pointed out that this is a particularly non-useful
> definition of Proper Behavior.  It sure as hell isn't consistent with the
> other resource routines which do break up multi-level name
> specifications.  What is the rationale for not supporting multi-level
> resource names in XGetDefault??  Are you simply trying to discourage its
> use?  If so, mark it as deprecated in the manual page!
> 
>   I don't know what the hell I'm going to do for awm now.  I'll probably
> have to do some weird-ass dynamic building of XtResourceList's ...  What
> a pain.
> 
> Pissed off,
> Casey

Changes to the specifications are not made lightly.  I can (and will)
agree that the specification is not clear on this point.  I suspect that
well-meaning people can and will disagree on the correct interpretation
on what XGetDefault should do.  My intent was that it be mostly for the
convienience of people moving X10 programs to X11; it should have been
moved to the compatibility library some time ago (probably
should have been there on day one).  There has been some discussion on
this point in recent mailing list messages.  But such a move does not
get made without public comment and review.

I have, however, seen few messages on this news group with the tone of
your message. I hope I don't see many more, for they surely discourage
people from bothering with answering peoples questions, if they get
flamed at in public.  I hope not to see
any more.

I believe you owe Bob an apology.  If anyone deserved flaming at, it
might be me, for not having written the spec better.  But I don't think
public flames serve
anyone for anything.
				- Jim Gettys

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (02/20/90)

    Well piss me off!  Why the hell didn't someone answer this way
    sooner?! 

Well geez, why didn't you solve all the world's problems in 30 seconds
when I wished on a star three years ago?  You seem mighty demanding of
fast response on a piece of software you probably paid nothing for, and
continue to pay nothing for in the way of support services.  Why don't
try putting yourself in our shoes, and imagine thousands of people asking
you for perfect response time for any and all queries sent to you, even
though it's only supposed to be a small part of your job.  We try rather
hard to respond to questions, but we also try hard to get real work done.
If our response time is not always to your expectations, I guess you'll
have to lower your expectations.  (If you don't like our level of support,
you're welcome to join the X Consortium, so we can serve you better. :-)

    I thought I wasn't seeing a response from someone in authority
    because they didn't have the time for the fix.

If your posting went to comp.windows.x/xpert, perhaps you didn't see a
response because of one of:

a) it never arrived
b) we were simply too busy with other things, and it got "aged out"
c) we somehow skipped your original posting (sometimes we're human, and
   we actually fail to read all messages in perfect detail)
d) your original posting had the word "awm" in it, and got skipped over
   automagically to avoid throwing up
e) we saw your posting, but our reply got lost
f) person A thought person B would answer it, and vice versa

    How long would it have
    taken you to write this response a month ago when I first asked?

Since I can't recall the exact circumstances, I don't know.  We did
receive your report to xbugs sent Jan 20, and it is on file with the
comment that the code is correct but better doc is needed.  I must
assume that you were sent a reply, since that is SOP and I actually
processed the bug myself, although I have no way of verifying whether
the reply indicated that the code was correct, or if you got the reply.
I would guess that I did indeed reply with the information, but if I
didn't, it was simply an oversight on my part.

    As for Proper Behavior: DOCUMENT IT DAMN IT!!!

Yes, this is a very nice thing to do.  Of course, for a system as complex
as X, it is rather difficult to document everything to the necessary
level for understanding by each and every reader.  It is a continual
process of improvement.  Your bug report is noted.  We are not perfect.

    What is the rationale for not supporting multi-level
    resource names in XGetDefault??

XGetDefault is basically an X10 compatibility routine (and probably should
have been place in an appendix).  I don't believe X10 supported multi-level
resources.  The code uses the class "Program.Name" (of course this should be
documented too, but isn't).  A basic requirement of all the resource routines
is that the length of the class list match the length of the name list.

    Are you simply trying to discourage its
    use?  If so, mark it as deprecated in the manual page!

That's probably a very good idea.

casey@gauss.llnl.gov (Casey Leedom) (02/20/90)

  Sorry Bob.  I probably shouldn't have sent that last letter off.  I was
very irked which should have told me to go and soak my head for a while
before posting.

  Let me put it a different way: what should an application like awm do
when it wants to dynamically get resources?  It strikes me that a nice
simple interface like XGetDefault is desirable for this.  Having to
construct an XtResource structure array in order to use
XtGetApplicationResources does not strike me as desirable.

  Also, what are the fundamental objections to making XGetDefault handle
multi-level resources.  If the X Consortium is really planning on nuking
XGetDefault, I hope they are planning on replacing it with something
simple to use for simple (or in awm's case, dynamic) cases.

Casey

keith@EXPO.LCS.MIT.EDU (Keith Packard) (02/20/90)

>  Also, what are the fundamental objections to making XGetDefault handle
> multi-level resources.  If the X Consortium is really planning on nuking
> XGetDefault, I hope they are planning on replacing it with something
> simple to use for simple (or in awm's case, dynamic) cases.

One could always use the Xrm functions XrmGetResource or XrmQGetResource.
A nice feature of using the XrmQGetResource function would be that the
application could save a considerable number of XrmStringToQuark calls.

To initialize the database you'd need to call XGetDefault on some bogus
resource (or duplicate the code from mit/lib/X/XGetDflt.c), then use
dpy->db for the Xrm functions.

I believe the Xrm functions are documented in the Xlib manual.

Keith Packard
MIT X Consortium

casey@gauss.llnl.gov (Casey Leedom) (02/21/90)

| From: keith@EXPO.LCS.MIT.EDU (Keith Packard)
| 
| >   Also, what are the fundamental objections to making XGetDefault handle
| > multi-level resources.  If the X Consortium is really planning on nuking
| > XGetDefault, I hope they are planning on replacing it with something
| > simple to use for simple (or in awm's case, dynamic) cases.
| 
| One could always use the Xrm functions XrmGetResource or XrmQGetResource.
| A nice feature of using the XrmQGetResource function would be that the
| application could save a considerable number of XrmStringToQuark calls.
| 
| To initialize the database you'd need to call XGetDefault on some bogus
| resource (or duplicate the code from mit/lib/X/XGetDflt.c), then use
| dpy->db for the Xrm functions.
| 
| I believe the Xrm functions are documented in the Xlib manual.

  They are.  It will probably take me about a day to rewrite XGetDefault
in terms of these routines since I don't have enough background in X
programming to get myself out of a wet paper sack.  And in the end I will
have done exactly that: simply rewritten XGetDefault using a different
set of routines.

  Again, I don't understand the reluctance to keep something usefully
simple like XGetDefault around.  I could well understand a desire to put
it in Xt as XtGetDefault along with the other resource helper routines.
Even the MIT software uses XGetDefault extensively.  In mit/clients I
count 23 calls to XGetDefault in 4 clients (there are two more references
to it in xrdb's manual page.)  In all there are 90 references to
XGetDefault throughout the mit subdirectory as program calls and
tutorial/documentation references.

  Please forgive my earlier flame and don't let its tone back you into a
corner on this.  I truly think that there's a place for an extremely
simple interface to the resource database.

Casey

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (02/22/90)

    And in the end I will have done exactly that: simply rewritten
    XGetDefault using a different set of routines.

Perhaps not.  And even if you did, you'd at least have had to answer at
least one basic question (what to do for class names), and in the process
hopefully understood why XGetDefault as it stands is a crock.

    Again, I don't understand the reluctance to keep something usefully
    simple like XGetDefault around.

It is around.  It is simple.  You're trying to make it more complicated, by
arguing that a former abuse of it should still work. :-)

    Even the MIT software uses XGetDefault extensively.  In mit/clients I
    count 23 calls to XGetDefault in 4 clients (there are two more references
    to it in xrdb's manual page.)

Yes, 4 clients that we sorely wish we had had time to rewrite for R4, clients
largely left over from X10 days.

casey@gauss.llnl.gov (Casey Leedom) (03/08/90)

[[Sorry for the late follow up on this.  We've had some problems here
that have kept me occupied the last few days.]]

| From: rws@EXPO.LCS.MIT.EDU (Bob Scheifler)
| 
|     And in the end I will have done exactly that: simply rewritten
|     XGetDefault using a different set of routines.
| 
| Perhaps not.  And even if you did, you'd at least have had to answer at
| least one basic question (what to do for class names), and in the process
| hopefully understood why XGetDefault as it stands is a crock.

  As a lot of backwards compatible routines are unfortunately.  But the
simplifying assumptions that XGetDefault makes turn out to be generally
useful in a lot of simple situations.  The fact that XGetDefault uses the
class "Program" for the first QUARK and "Name" for the remaining QUARKs
works for these programs quite nicely.

|     Again, I don't understand the reluctance to keep something usefully
|     simple like XGetDefault around.
| 
| It is around.  It is simple.  You're trying to make it more complicated,
| by arguing that a former abuse of it should still work. :-)

  I'm not arguing that it should be more complicated.  The fact that it
doesn't behave as one would expect it to makes it more complicated.
Remember, we're talking user programming models here, not the particular
implementation of XGetDefault.

  And as for ``former abuse'', I've checked XGetDefault out in all the
versions of X that I have access to: 10.4, 11.2, 11.3 and 11.4.  We
already know that XGetDefault worked for multi-level resources in 11.3
and doesn't in 11.4.  It turns out XGetDefault works quite nicely for
multi-level resources under both 10.4 and 11.2.  As a compatibility
routine its current behavior isn't.

  Additionally the 10.4 documentation, while never explicitly stating that
XGetDefault handles multi-level resources, mentions several examples of
multi-level resources (see X.1) with specific mention to XGetDefault.

Casey

P.S.  Here is a small program to test XGetDeault.  I'd appreciate hearing
    of results for any other versions of the X Window System.

-----
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	XGD
# This archive created: Sat Feb 24 15:55:38 1990
export PATH; PATH=/bin:/usr/bin:$PATH
if test ! -d 'XGD'
then
	mkdir 'XGD'
fi
cd 'XGD'
if test -f 'Imakefile'
then
	echo shar: "will not over-write existing file 'Imakefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Imakefile'
XLOCAL_LIBRARIES = $(XLIB)
X        DEPLIBS = $(DEPXLIB)
X        DEFINES = -DX11
X
X           SRCS = foo.c
X           OBJS = foo.o
X
XComplexProgramTarget(foo)
SHAR_EOF
fi
if test -f 'foo.c'
then
	echo shar: "will not over-write existing file 'foo.c'"
else
sed 's/^X//' << \SHAR_EOF > 'foo.c'
X#include <stdio.h>
X#ifdef X11
X#include <X11/Xlib.h>
X#endif
X
X#ifndef X11
Xextern char *XGetDefault();
X#endif
X
Xmain(argc, argv)
X	int argc;
X	char *argv[];
X{
X	char *myname;
X	char *program, *resource, *value;
X#ifdef X11
X	Display *dpy;
X#endif
X
X	myname = argv[0];
X	if (argc != 3) {
X		fprintf(stderr, "usage: %s program resource\n", myname);
X		exit(1);
X	}
X	program = argv[1];
X	resource = argv[2];
X
X#ifdef X11
X	dpy = XOpenDisplay("");
X	if (dpy == NULL) {
X		fprintf(stderr, "%s: unable to open display\n", myname);
X		exit(1);
X	}
X#endif
X
X#ifdef X11
X	value = XGetDefault(dpy, program, resource);
X#else
X	value = XGetDefault(program, resource);
X#endif
X	if (value != NULL)
X		puts(value);
X
X#ifdef X11
X	XCloseDisplay(dpy);
X#endif
X	exit(0);
X}
SHAR_EOF
fi
cd ..
exit 0
#	End of shell archive