[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] WCOWORK Alternatives - long post warning



On Thu, 2005-07-14 at 00:14 +0200, Ingo Schmidt wrote:
> Ok, what do you propose? What features do you want?

Expandability!   Possibility of a work-area-origin drawing system in the
future without another damn mode!   If we are gonna move forward, I want
to go all the way and allow LOTS of features.

> What are your suggestions for improvements in a new AES? How would you
> change the window API in an AES so that programming it would be
> easier? Lets hear your proposals!

Let me jump in and make my own suggestions.  This is just a rough
outline off the top of my head based on what people have been saying on
the strengths and benefits of WCOWORK, and the need for a more modeless
operation, and my own wants for something that can be expanded however
we need it.  Feedback welcome as its taken me a couple hours to write!

First, I do understand that there can be problems with wind_calc().
However, as long as it used sparingly and the results are not remembered
by the application, then the call should work properly even during a
theme change.  The speed should be fine as long as the AES keeps the
values precalculated for each theme.  I would however still want to have
the newer W2F and F2W wind_xget() calls for completeness, and they
should be used when a window handle is available.

Second, don't change existing calls, but add new ones.  Don't make
WF_CURRXYWH work any different.  For wind_create and stuff, if you want
a version that works with working areas instead of full areas, lets make
a new call.  This may help prevent confusion.

Third, don't implement "modes".  I have a feeling that operating modes
may be problematic, and might contribute to development problems that we
haven't yet forseen.

Next, to keep everyone happy about how the AES messages are handled,
lets not change how messages are received by evnt_multi().  All AES
messages stay the same.  Anything new that wants a different coordinate
system should have its coordinates modified by the AES at queue
insertion time.

I find it really difficult to believe that there would be many
circumstances where the event sent from one application to another would
be different for full or working coordinates.  Applications don't tend
to move each other around or resize each other.  Redraws and things of
that sort are more common, and that doesn't change the coordinates
returned, so it should be quite possible to have the AES do any
FULL->WORK coordinate conversion as the message is added to the
application's queue.

Instead of a mode, lets have a new call for processing the event queue.
This would obviously be for new XaAES applications (and anyone else that
implements the new calls) and aren't worried about compatibility with
unsupported operating systems.  The goal is to make the capabilities
offered be beneficial enough to the developer that they would consider
the use for new programs.  

However, while a kernel level implementation of the proposed API would
be most efficient, its assumed that the following represents the
user-level C API and it does not have to have a perfect mapping to
specific AES functions, although it may.  Library authors can certainly
emulate the functionality, although I would recommend that any wrappers
to implement these functions on old AES systems either be an AUTO hack
or some loaded library or whatever.  The application itself should not
try to provide his/her own implementation unless you can specifically
compile out support for older systems and all the wrapper code.  For
example, if Windom were to support this set of functions, there should
be two libraries so authors can make 2 applications - one for XaAES and
newer systems with no compatibility code, and a second version with all
the wrappings in place.  Application authors don't have to provide both,
but I certainly recommend it.

The new API can be as feature-rich as desired.  Instead of a "pass
everything to evnt_multi()", it can be a much simpler
add_event(event_queue, ...) style system where you tell the OS what
messages you want to wait for, and then process it with a "wait" call.
Each set of events only needs to be set once, and you can process new
events as often as you like without resetting the events all over again.

We could have multiple persistent timers, events that wait on GEMDOS
file handles (similar to poll/epoll/kqueue whatever), and when you
"add_event()" to the list you are waiting on, you can determine then if
the results returned to the application through the new wait_event()"
should be based on FULL or WORK coordinates.  

Allow the event system to ignore any message it doesn't want, including
the ability to only handle events for specific windows (see below).
This would mean seperate event queues, with a possible default.
Parameters would depend on what events are passed.  For example,
something vaguely like this, where the first argument to add_event is
the queue handle, the second is what events to look for (32 bits gives
us 32 possible event types, so we have more possibilities, including a
KEY_UP and KEY_DOWN capability for SDL and such), the third is which
window to handle events for or whatever other identifier goes with the
event, with DEFAULT (-1 or 0xFFFFFFFF) meaning "I'll take it if no one
else does".  The last is for flags, modifiers, and other values.  It
would look something like :

QHANDLE main;
QHANDLE dialog;

// Default event queue, window coordinates auto-translated
// to work area coordinates.  MU_AES is short for all
// TOS compatible AES events that don't go anywhere else.
main = new_queue();
add_event(main, MU_AES, DEFAULT, CRD_WORK);

// Who know why, but we have some special dialog window
// that wants the FULL window coordinates, and we
// want it to get its own event queue.
dialog = new_queue();
add_event(dialog, MU_BUTTON, diagwindow, CRD_FULL);

Now, you can add and delete events from either queue with the
appropriate calls.   To actually make the equivalent of evnt_multi(),
you would do something like:

EVNTHANDLE ev;
ev = wait_queue_event (main);

To wait for events in both queues, maybe something like:

QHANDLE all[3];
EVNTHANDLE ev;
all[0] = main;
all[1] = dialog;

// Loop here
ev = wait_multi(all,2);

Note the pointer to an array of all queues.  In addition to COORD_WORK
and COORD_FULL, you also could have other flags such as the priority for
that queue (anyone want priorities?).  I assume that the EVNTHANDLE is
some pointer to a structure or something like that or other than would
have a pointer back to the queue it came out of.  I'd rather not have a
timeout on the wait* calls as threading can be much more efficient and
we can already do multiple timers.  Maybe something like :

// Just 1 timer to fire in 5 seconds, 
// has "timerid1" in event to identify it
add_event (main, MU_ALARM, timerid1, 5000);

// Fire a timer every second until event deleted
// has "timerid2" in event to identify it
add_event (main, MU_TIMER, timerid2, 1000);

You can also use the multi-queue system for threads, using tfork(), and
do something like:

main thread - all unhandled events:
	wait_queue_events(main);

the "dialog" handler thread - clicks in dialog window:
	wait_queue_events(dialog);

This is passing around significantly less data for each event call and
can allow "libraries" to have their own event queue for the window or
set of windows they control, or implement priorities, or some
combination.

Maybe our dialog thread is reading a pipe or socket:

add_event (dialog, MU_FILE, filehandle, EDGE_TRIGGER);
And things get interesting!  Socket, pipe, and file IO right in the
GEM event loop.  Should already be possible to put a select() in another
thread but this could be cleaner for things like TOSWIN.

Note that you should not normally OR together alarm, timer, file or GUI
type of events.  Multiple GUI events can be OR'd together providing they
will all operate on the same window with the same mode.  In other cases,
seperate add_event() calls should be made.   There should also be a
delete_event() so you can stop the events, and maybe even a
pause_event() and unpause_event() that would allow events to still be
queued, but not reported.  Delete and Pause/Unpause would not use the
last parameter, but would use the rest of the add_event parameters.

Also for completeness a 
	get_event_attribute (queue, event, id)
Which would return the last parameter of the add_event which is given
for that event type and id.

And ..
	add_event (queue, MU_USERDEF, myvalueid, somepointer);
To record a userdefined value that can be returned later with the above
get_event_attribute call.  Useful for callback systems, or just storing
various values and pointers in the queue.  The AES itself wouldn't
actually be storing these values.  It would done in the user-level API.

Future expansions ..

If their is ever an extension to the VDI so you can open a virtual
workstation to the window working area itself, you can simply ignore
most AES messages (don't add_event those messages and the AES will try
to "do the right thing" automatically) and a COORD_ZERO flag could allow
returning coordinates relative to the window working area itself.  We
don't care about the location of the window if the coordinates passed to
the VDI are relative to the window!   We can return the mouse's real
coordinates as well as the relative coordinates (real coordinates would
be needed for drop to another app I think).  

This means VDI drawing, mouse click event locations, drag-drop
locations, and everything else of that sort, all treat the start of the
window working area as the origin point instead of the screen being the
origin.  This would require some additional wind_get() calls to get the
rectangle list relative to the window work area instead of relative to
the screen.   Its also conceivable that if we get this far, we won't
need a redraw message since the VDI workstation could very well be
treated as "canvas" object that can automatically redraw portions of the
screen under AES control without ever telling the application (either
via an off-screen bitmap or a display list).  This pretty much "stick
graphics to the window and tell it when to scroll or clear the displaty
list" and the AES does the rest.