This is driving me nuts. GCC does tail recursion optimisation. That
is very nice, and means that if we have something like:

int func(...)
{
do-stuff();

func2(...);
}

then the func2() call can be converted into a 'goto'.

The problem is that this means that if we put a breakpoint in gdb,
or a printf, in the func2, we lose the stack frame for func(), and it appears
that func2 is being called from the caller of func(), rather than func()
itself.

I wish they wouldnt do these "nice" things. Makes debugging a pain, and
am tempted to go back to earlier/very old versions of GCC to stop this
warfare, where "what used to work", stops working and you have to fight
the toolchain.

After my last write up, of finishing the Motif rewrite for CRiSP,
I have made more progress. This centers around the things I had forgotten.

For example, the 'Scale' widget which is used in the color selector
dialog needed to be implemented (from scratch). That took about a day
(nice when things go according to plan).

Then I hit some issues with the default size of a combo field. That
is fixed.

Next up was the protocol manager for a shell widget. What is that you say?
Think of XmAddWMProtocolCallback(). Without this, if you click on the
window manager "X" at the top right of a window, then your app is quickly
terminated (the TCP connection to the X server is severed).

Took me a while to figure out / remember how this all worked. But, suffice
to say, that unless you post an Atom/Property on the window (WM_DELETE_WINDOW), then
the window manager will not ask politely, but just brute force the
termination of the app.

But to put a property on the application shell window is not quite so easy,
especially when we normally call the XmAddWMProtocolCallback() against a
*widget* and not a *window*. A widget may not exist on screen at the
time we call it, and that is why there is complexity in the Motif
library - you are allowed to register interest in these window manager
protocol messages, before the window is 'realised' (i.e. before being
mapped to the screen). When the window is mapped, the appropriate
property is posted on the desktop to allow the window manager to see
what is going on.

Of course, if you try to do something "later" in an application means
creating some form of data structure for later use, and then, making sure
we dont suffer a memory leak.

My implementation of window manager protocols isnt perfect, but sufficient
for what I need.

Why do I bother? I dont know, but what I know is that CRiSP with Motif, statically
linked, occupies 3MB of code memory. With the new Motif replacement, it
is about 2MB.

When CRiSP was first written this was about the size of a large floppy
disk (and 40MB - thats megabytes, not gigabytes) was huge. Now the
size of CRiSP fits in the L2/L3 cache of a cpu.

My experiments to replace the Motif library code in CRiSP with native
code hit a major stumbling block. The first few days of effort were
extremely good - lots of progress and deterministic behavior.

But the menuing code has taken about 3 months - I hope this is now
complete. Why?

Any number of reasons:

I am losing my 'touch'

It is difficult

There are lots of fiddly bits to get right

You choose. The issue with menus is the way input focus moves around
from one widget to another. There are lots of scenarios to get right,
and fixing one of them, would result in some existing feature suddenly
breaking - like a see-saw as the code came together.

One problem I hit is that XtAddGrab/XtRemoveGrab doesnt handle double
registration of a widget particularly well.

The code, whilst trying to be purist and object oriented, in the end
had to be a little dirty - one class having too much intimate knowledge
of what it is dealing with (a menu has menu items, which is mostly separators and
buttons, for instance).

Heres some scenarios to consider:

Click and reclick the menu bar button (should dismiss menu)

Use keyboard to navigate a menu and popup sub menus, and then popdown submenus.

Use ESC to popdown a menu

Click outside the menu to dismiss it; click in another window to dismiss it too

Click on a menu item, and have the menu popdown, and the callback invoked

May seem like simple stuff, but getting it all working is difficult, especially
when grabs are put in place - suddenly input goes to the wrong widget, and
everything you had working, stops working.

Why bother ? Why not just use Qt or Gtk ?

Because I dont want to use them. As good as those toolkits are, they are
not available everywhere, and I dont want dependencies on other toolkits -
toolkits which have a very active development life.

This is akin to the dtrace problem: do you develop software for the
latest and greatest kernel/distro out there, or do you go back
to old releases and ensure your software works with them?