[Xr] What happended to the idea of getting rid of the xrs argument?

Bill Spitzak spitzak at d2.com
Thu Jun 5 11:25:57 PDT 2003

On Thursday 05 June 2003 02:00 am, Michael Meeks wrote:
> On Tue, 2003-06-03 at 05:11, Bill Spitzak wrote:
> > The only way to implement the above in any reasonable way is to have the
> > toolkit provide a wrapper for every Xr call
> 	Perhaps I'm missing something blindingly obvious; but why would a
> wrapper be needed per call ? surely you can manage your own per thread
> closure, with an accessor / push / pop / whatever for your external
> users - if you're concerned about the complexity of exporting the Xr
> API.

What I meant is if there is an XrFoo(xrs,...) call, people have suggested 
that this is object-oriented in that you can write a toolkit where you do 
widget.Foo(...). As far as I know this can only be done by writing a method 
called "Foo" into the toolkit. Then if *new* Xr comes out with 
XrWhizBang(...) nobody using the toolkit can call it until the toolkit 
authors add widget.WhizBang() to the toolkit.

This is obviously a minor problem, especially for an open-source toolkit. I 
am much more concerned with the fact that code that says widget.Foo() will 
not port to another toolkit that says widget.XrFoo() or says Foo(widget) or 
says XrFoo(widget.XrState()), or any of the hundreds of other possibilities 
that I have seen done with Win32 and Xlib GC's. In my opinion, only by having 
an implied static XrState can you enforce uniform calling of Xr, and I think 
that is vitally important for Xr to be a popular interface.

Maybe instead of enforcing how Xr is called, it can be encouraged, so that 
drawing code can be easily cut and pasted between toolkits or between parts 
of toolkits. To do this, strongly encourage people to write their code so 
that the literal text "xrs" means the current XrState. This can be done with 
a macro, a local variable that you use toolkit-specific code to initialize, 
or as an argument to functions. So this would be good toolkit-level code:

void MyWidget::draw() {
  XrState* xrs = this->get_xrs(); // toolkit-specific
  XrRectangle(xrs,...); // not toolkit-specific
  XrFill(xrs,...);// not toolkit-specific
  this->done_with_xrs(xrs); // toolkit-specific

An alternative toolkit may be written like this:

void MyWidget::draw(XrState* xrs) {

Another toolkit might do this (though there are obvious problems with this 

#define xrs (this->something())

Another toolkit might do this (this is what fltk will do):

extern XrState* xrs;

Here is an example of a non-toolkit function. By writing it this way it can 
be inserted into any existing program using Xr, or the programmer can cut 
pieces out of it and insert them into other parts of their program using Xr:

void NiftyDrawing(XrState* xrs) {

This *may* get the advantages I see from a static XrState. However I still 
see problems with this. First of all it requires all inner functions that 
draw to somehow get an XrState as an argument. This can be nearly impossible, 
for instance fltk has objects called "boxtypes" which draw different borders, 
they are currently called with box->draw(x,y,w,h). Contrary to what some 
other people seem to think about objects here, the "box" object has NO idea 
what "surface" it is drawing on, and I cannot believe this situation is 
uncommon (think about fonts, are they expected to have an xrs inside them?). 
So the box cannot do anything with itself to find out the xrs. Therefore I 
either have to rewrite the method to box->draw(xrs,x,y,w,h) (which would 
introduce the fact that XrState exists into the supposedly portable fltk 
header files) or I have to use a global variable to hold the current xrs.

I believe this is not fltk-specific, this problem is *extremely* common, and 
the end result is that everybody will have to put the xrs into a global 
variable sometime anyway.

                   ,~,~,~,~ ~ ~ ~ ~
     /\_       _|_========___         Bill Spitzak
 ~~~/\/\\~~~~~~\____________/~~~~~~~~ spitzak at d2.com

More information about the cairo mailing list