[comp.windows.x] Bug in Athena scrollbar widget

net@TUB.BITNET (Oliver Laumann) (12/15/88)

The srollbar widget has resources of the representation type XtRFloat
(e.g. `shown').  These resources are declared as `float'.

This is wrong; it is impossible to set a resource of type `float'
using XtSetValues() (for instance, a float cannot be assigned to an
XtArgVal).  The type should be float* instead.

(By the way, is this the reason why the widget class exports a function
XtScrollbarSetThumb, which would not be necessary if one could set
the resources directly? :-)

Regards,
--
Oliver Laumann              net@TUB.BITNET              net@tub.UUCP

kit@ATHENA.MIT.EDU (Chris D. Peterson) (12/17/88)

> From: Oliver Laumann <net%TUB.BITNET@mitvma.mit.edu>
>
> The srollbar widget has resources of the representation type XtRFloat
> (e.g. `shown').  These resources are declared as `float'.
>
> This is wrong; it is impossible to set a resource of type `float'
> using XtSetValues() (for instance, a float cannot be assigned to an
> XtArgVal).  The type should be float* instead.
>
> (By the way, is this the reason why the widget class exports a function
> XtScrollbarSetThumb, which would not be necessary if one could set
> the resources directly? :-)

In general there is no requirement that a resource be able to fit into an
XtArgVal and the float is no exception.  If the resource is larger than a 
XtArgVal then you need to pass a pointer to the resource into XtSetValues.
The Toolkit does all of the right things to store that actual of then
resource into the Widget instance.  

Now on to the specific problem:

A float is a special case, since it will sometimes fit into an XtArgVal, and
sometimes it won't (it depends on the machine that you are using).  At compile
time you should know whether or not it will fit, so that you can
decide to pass the value of the float, or a pointer to the float
to XtSetValues.

Although using the convience routine XtScrollbarSetThumb() makes all
of the ugly size checking unnecessary in this particular case. 

						Chris D. Peterson     
						MIT X Consortium /
						Project Athena 

Net:	kit@athena.mit.edu		
Phone: (617) 253 - 1326			
USMail: MIT - Room E40-342C		
	77 Massachusetts Ave.		
	Cambridge, MA 02139		

net@TUB.BITNET (Oliver Laumann) (12/19/88)

> > The srollbar widget has resources of the representation type XtRFloat
> > (e.g. `shown').  These resources are declared as `float'.
> >
> > This is wrong; it is impossible to set a resource of type `float'
> > using XtSetValues() (for instance, a float cannot be assigned to an
> > XtArgVal).  The type should be float* instead.
>
> In general there is no requirement that a resource be able to fit into an
> XtArgVal and the float is no exception.  If the resource is larger than a
> XtArgVal then you need to pass a pointer to the resource into XtSetValues.

I don't quite understand what this has to do with the specific problem
I mentioned.  If I am assumed to store a pointer to a float into an
XtArgVal, then the type for XtRFloat is `float*', not `float'.

However, the relevant scrollbar fields are declared like this:

   float top;
   float shown;

and referenced like

   ScrollbarWidget w = ...;
   w->scrollbar.top = 0.5;

Thus, something like

   float f = 0.5; Arg a[1];

   XtSetArg (a[0], XtNtop, &f);
   XtSetValues (widget, a, ONE);

would not work (I have just tried it).  If this is not a bug then I would
appreciate if you could show me how the `float' resources can be set
by means of XtSetValues.  Am I missing something?

Regards,
--
Oliver Laumann              net@TUB.BITNET              net@tub.UUCP

swick@ATHENA.MIT.EDU (Ralph R. Swick) (12/20/88)

> If I am assumed to store a pointer to a float into an
> XtArgVal, then the type for XtRFloat is `float*', not `float'.

The XtR representation name corresponding to a particular data
format is not necessarily a function of the number of bytes in
the storage representation.  There is certainly no architectual
requirement to this effect.  The XtR name is merely a tag to
allow portable software to match data types; the correspondence
between the tag and the storage representation is defined by a
table, not by an algorithm.  'Intrinsics' defines the tag for
C-type 'float' to be 'XtRFloat'.  If a widget wants to define
a resource of type 'float*', it will need to declare a new
representation tag (e.g. XtRFloatPointer).

> show me how the `float' resources can be set
> by means of XtSetValues.

As you pointed out earlier, portable software cannot assume a priori
that XtArgVals are big enough to hold a float and must therefore test
before deciding whether an individual entry in an arglist is by-value
or by-reference.  This is machine dependent, but the rule is simple
and the answer is known at compile time.  This is true for _any_
data type not in the list given in the first paragraph of section 2.4.1
of 'Intrinsics'.

Given the propensity of C to do type conversions, it may be necessary
in some cases to defeat this automatic 'feature' of the language.
This is true of the X11R3 implementation of Intrinsic.h, so if
sizeof(float) <= sizeof(XtArgVal) in your implementation, you'll have
to use something equivalent to bcopy() to move the bytes rather than a
direct assignment.