Behind the Scenes X Agent Support

From: Curtis Chong >Internet:73443.1351@compuserve.com (73443.1351@compuserve.com)
Date: Fri May 27 1994 - 15:50:51 PDT


To: Internet:nfb-rd@nfbcal.org

Greetings:

I received the following rather lengthy post from the DACX
electronic mailing list. Those of you who have a burning desire to
do something about Unix and access to X Windows should read this
carefully, thoughtfully, and with a view toward making some kind of
an appropriate response. I will be the first to admit that I know
nothing about Unix, but I am interested in working toward the day
when blind people will achieve access to X Windows, the GUI for
Unix.

Again, be forewarned. This *IS* lengthy!

=================================================================

From: shl@cc.gatech.edu (Susan Liebeskind)
Message-Id: <199405261951.PAA23090@gvu1.cc.gatech.edu>
Subject: Repost from x-agent list: thoughts on behind the scenes ext.agent sup.
To: dacx@trace15.waisman.wisc.edu
Date: Thu, 26 May 1994 15:51:43 -0400 (EDT)
X-Mailer: ELM [version 2.4 PL23]
Content-Type: text
Content-Length: 16985

[Mark Novak requested I post this on the DACX list, in case there are
people on this list who don't also subscribe to the x-agent mailing
list run by the x consortium. If you aren't yet on the x-agent list and
want to join, send a message to:

     x-agent-request@x.org

The body of this message should contain the single word "subscribe".
The subject line of the message will be ignored.

Of course, you folks who do subscribe to that list have been inundated by
copies of it -- the mailer at x.org was out of sorts, and shot at least 2
copies out to everyone on the list, until the sysadmin caught it. Sigh.
I hope it's fixed now.

Susan ]

------------repost of message and proposed ExtAgent.h file ---------------

Subject: thoughts on addit. behind-the scenes ext agent support in Xt
To: x-agent@x.org
Date: Wed, 25 May 1994 14:18:36 -0400 (EDT)

Donna Converse has asked me to post the current state of the design with
regards to adding additional, behind-the-scenes support for external agents
monitoring Xt-based clients. This is separate from the sample Remote Access
Protocol library (RAP) Georgia Tech has been and continues to work on.
However, it is support needed by any agent protocol, so clients can speak the
protocol without requiring source code changes to communicate with an agent.

The Consortium would like to hear from you, via this list, with your comments
on the current design. Does it meet the needs of installing whatever external
agent you have in mind? As always, all final decisions are made by the X
Consortium staff (sounds like a photography contest, doesn't it?) but your
feedback is important -- they want to hear what you have to say.

The goal is to include this new functionality in a patch that will come out
concurrent with the contrib archive, so the sooner you respond, the sooner
you'll see the patch :-) Keep in mind that the contrib deadline is
June 6.

********************************************************************

BACKGROUND

The new external agent hooks in R6 (documented in the R6 Intrinsics
Ref. manual, pp 213-219) go a long way towards providing access to the
graphical state of the interface. But this brings up a question - "how does
that information become known to the agent in the first place?". There is no
automatic way for that information to be dispatched from a client to an
interested agent. Yes, individual agents will provide their own protocols
(like RAP) for communicating with clients. But how can these protocols be
installed on the clients in an agent-independent fashion?

********************************************************************

SUMMARY OF THE CURRENT DESIGN

There will be several new APIS added to the Xmu library. A new file, called
ExtAgent.h, will contain the API for these new functions (You'll see a stub
version of this file in the current R6 release). I'll post these APIs in a
separate message. ExtAgent.c will contain their implementation.

Writers of external agents will need to provide

        a) a protocol library for clients to link against
        b) a routine to initialize the protocol in the client
        c) the external agent (of course)

The protocol initializer routine (or PI routine for the sake of brevity) will
handle any other bookkeeping needed to setup the communications link. For
example, the sample RAP protocol uses the ICE framework and thus its PI routine
makes a call to set up the ICE connection.

The Xmu library will maintain a table of these protocol initializer
routines, a typedef for these routines, and will provide functions to add to,
delete from and inspect the contents of this table.

Any client capable of being monitored by an agent must have its PI routine
installed in its address space (see below for how we're planning to make
clients RAP-aware without requiring source-code level changes). To cause this
to happen, the client will need to be relinked against the agent's protocol
library to make it aware of the agent. The support to install the PI is
provided in ExtAgent.h with a call to XmuAddExternalAgentInitializer.

The current proposed mechanism for executing the PI routine, and thereby
installing the protocol, is through a ClientMessage event, just like Editres.
Check out the R6 Xaw/Vendor.c file and you'll see the XtAddEventHandler call
that adds a new handler.

Specifically: To start the communication between an agent and a client, the
agent will send a ClientMessage event to a given client, signalling the agent
wishes to monitor that client. One of the data fields in the Client Message
will contain a special token that is interpreted on the client side as a signal
to setup a new protocol. The message also contains the atomized name of a
property which holds the name of the protocol being initialized (this is all
done with the X Selection mechanism). The Client Message handler in the
client retrieves the protocol name, looks for it in the table of initializers,
and if it finds the corresponding PI routine, executes it to set up the
protocol.

********************************************************************

A KEY RESTRICTION ON THE DESIGN

No changes could be made to the Xt API without going through the official
standards changing process. Therefore, grafting this support into Xt was not
possible.

We worked around this by adding changes to the Xmu API. The Xmu libraries,
unlike the Xt libraries, are not standardized, being a miscellanous collection
of routines. Of course, not all installations ship with Xmu, but if needed,
any developer could obtain Xmu and build it him/herself.

********************************************************************

ADVANTAGES OF CURRENT DESIGN

1) It's clean and simple. One call does it all. It provides agent writers
with a way to register new protocols without prior knowledge of the protocol in
Xt.

2) It can easily be grafted onto future versions of Xt. The table and
supporting routines are encapsulated inside the single ExtAgent file and can
easily be moved into the Xt in the next go-round for the Intrinsics.

3) If this design moves inside Xt, then the initializers for a well known agent
(like a screen reader or testing tool) could be installed as part of
XtAppInitialize. All that would be needed is to have Xt clients link against
the agent`s protocol library, and somewhere in Xt, add the
XmuAddExternalAgentInitializer call for that agent.

4) No client side code needs to be changed in order to make them aware of
external agents. Only a relink is required. However, if client side code is
changed to take advantage of an agent, only the call to the routine
XmuAddExternalAgentInitializer gets added.

COMMENTARY: Since the external agent initialization support is not an integral
part of Xt, (like the Session manager support for example) there is not a nice
clean solution to the problem of installing PIs in the client address space.
In general, you shouldn't have to make clients aware of specific agents. You
can make this happen, but it's not pretty. What we'll be doing for the RAP
libraries is definitely a hack, but it does work...

We take advantage of a C++ side effect by using a function to initialize a
static global variable. The function calls the routine to add a protocol
initializer routine to the initializer table. This hack requires the use of
C++, since C doesn't have the ability to initialize a variable with a function.
If anyone knows how to accomplish the same thing in a platform independent way
using C, I`d like to hear it.

5) Right now, the ClientMessage event handler for the external agent client
messsage is installed only on the Xaw VendorShell initialization, making it
specific to the applications built with the Xaw widget set. But the mechanism
is encapsulated so that other VendorShells (like Motif etc.) can easily
add this support.

COMMENTARY: As mentioned before, check out the R6 version Xaw/Vendor.c file and
you`ll see the proposed event handler already in place. The handler is
currently a stub, but would eventually contain the support discussed above in
the form of a patch, if we use the ClientMessage approach. Any other widget
sets (like Motif 2.0) that wish to use the mechanism can add the extra
XtAddEventHandler call to their vendor shells. Of course, Motif doesn't
require the use of Xmu, so the mechanism in Xmu could go somewhere inside Motif
-- that can be dealt with if this approach is accepted by the Consortium.

********************************************************************

In general, the Consortium seems OK with the basics of the design (the table of
initializers approach) except for the timing of the mechanism used to trigger
the PI for a given agent. Clearly, I don't speak for the Consortium. -- this
is my interpretation, not theirs.

But specifically, they are interested in hearing about alternatives to what
I've delineated as disadvantages of the design. This client message approach
certainly works, but it might not be the best solution.

********************************************************************
 
DISADVANTAGES OF CURRENT DESIGN (and what Donna et. al specifically want
comments on)

1) The use of the ClientMessage event to start the ball rolling and X
Selections to pass data between agent and client requires that the agent open a
display connection to the same display that its clients are using.

COMMENTARY: Is this a burden on the agent community, that an agent be required
to be a nominal X client itself? Maybe this is not such a big deal?

2) The rendezvous between a new client and a running agent does not occur as
early as it could. The external agent hooks are available for use as soon as
the display connection is initialized in the client. But the ClientMessage
can't be sent until the first window is created. An new client is capable of
being monitored via the agent hooks sooner than a ClientMesssage will allow it.

COMMENTARY: There seems to be no easy way to have the agent detect that a new
display connection has been opened (like a callback, or event to watch for).
Are there some alternatives, besides using the ClientMessage, that could make
for an earlier initialization?

We here at Tech came up with an alternative that would permit early rendezvous
(involving a well-known property containing external agent names and the C++
global initializer side effect - I won't go into details here), BUT that gets
PI routines installed *too* early, before the display connection is made.. How
can we install a protocol initializer routine at the earliest possible moment
in a brand new client?

********************************************************************

CAVEATS

There is a lot I have *not* covered here about external agents proper (like how
they find out what clients are currently running, and how they detect the
existence of new clients). That's the topic of additional mail messages. The
purpose of this message is to solicit comment on the mechanism used to trigger
the initializion of an external agent protocol, and alas, in a relatively short
time frame.

I've tried to represent what I understand to be the Consortium position on this
design. If I've misstated something, that's my goof, and I have no doubt
someone from the Consortium will hasten to correct me :-)

And lastly, some of the problems with the design have to do with the fact that
the external agent initialization is not integrated into Xt. When it comes
time for R7, or perhaps when Motif 2.1 comes out, the design can and should be
revisited. If there are problems now, we'll have a chance to fix them before
it is all set in stone.

-----------

Please post your comments to this list -- it should be alive and working,
though it has been dormant. Just to be sure, please cc me (shl@cc.gatech.edu)
and I'll make sure that everything gets passed onto Donna & Co in the event
your posting doesn't make it out to the list.

Thanks.

Susan Liebeskind
shl@cc.gatech.edu

--------------clip here for new API for ExtAgent.h -------------

/*

Copyright (c) 1994 X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the X Consortium.

*/

/*
 * The interfaces described by this header file are for miscellaneous utilities
 * and are not part of the Xlib standard.
 */

#ifndef _XMU_EXTAGENT_H_
#define _XMU_EXTAGENT_H_

#include <X11/Intrinsic.h>
#include <X11/Xfuncproto.h>

/*
 * Atoms used by External Agent Support
 */
#define EXTAGENT_NAME "ExternalAgent"

/*
 * Format for the client message event data.
 */
#define EXTAGENT_FORMAT 32

/* Result Codes for External Agent initialization */

typedef enum {
   EXTAGENT_Success,
   EXTAGENT_BadProtoName,
   EXTAGENT_ReplacedProto,
   EXTAGENT_MallocError}
ExternalAgentResultCode;

   
   
/*
 * The initializer functions take a widget as an argument (which they can
 * then use to retrieve an app context, display, or whatever), and a pointer
 * to the event that will trigger the initializer call. This
 * event may contain extra data for the initializer to consult. This
 * will be handled by convention between the agent and the agent initializer
 * function.
 *
 * There is no return value to indicate success or failure, as there is no
 * easy way to pass it back (XtSelectionCallbackProc has no return value).
 */

typedef void (*XmuExternalAgentInitializer)(
#if NeedFunctionPrototypes
    Widget w /* widget id for top level shell */,
    XClientMessageEvent *trigger_event /* event triggering initializer call*/
#endif
);
              

_XFUNCPROTOBEGIN

/*
 * XmuAddExternalAgentInitializer installs the named protocol in
 * the table of protocol initializers. If the named protocol is already
 * in the table, the initializer function is overwritten. Returns TRUE
 * or FALSE depending on whether it succeeded or failed.
 */
              
extern Boolean XmuAddExternalAgentInitializer(
#if NeedFunctionPrototypes
    char * proto_name /* protocol to install*/,
    XmuExternalAgentInitializer initializer_func /*initializer func */,
    ExternalAgentResultCode *result_code /*more info on action */
#endif
);

/*
 * XmuGetExternalAgentInitializer returns the initializer function
 * currently associated with the specified name, or NULL if no such
 * initializer exists.
 */
XmuExternalAgentInitializer
XmuGetExternalAgentInitializer(
#if NeedFunctionPrototypes
    char * proto_name /* protocol to lookup */
#endif
);

/*
 * XmuGetExternalAgentInitializerList returns a pointer to a null terminated
 * array of strings, containing the names of all the installed prototypes, If
 * no protocols are installed, NULL is returned.
 *
 * Function caller must free the memory allocated for this function call. */

char **
XmuGetExternalAgentInitializerList(
#if NeedFunctionPrototypes
    void
#endif
);

/*
 * XmuRemoveExternalAgentInitializer removes the association between
 * a protocol name and initializer function from the table. If the specified
 * protocol name doesn't exist no action is taken.
 */
void
XmuRemoveExternalAgentInitializer(
#if NeedFunctionPrototypes
    char * proto_name /* protocol to remove */
#endif
);

/*
 * XmuRegisterExternalAgent is the actual client message event handler which is
installed
 * on the shells.
 */
void
XmuRegisterExternalAgent(
#if NeedFunctionPrototypes
    Widget w, /* the shell widget */
    XtPointer client_data, /* not used */
    XEvent *event, /* the client message event */
    Boolean *cont /* not used */
#endif
);

_XFUNCPROTOEND

#endif /* _XMU_EXTAGENT_H_ */

-- 
===========================================================================
Susan Liebeskind (shl@cc.gatech.edu) 
GTRI/CSITD/ITTL
347 Ferst St
Atlanta, GA  30332-0800                  Phone 404-894-4266   

=================================================================

Cordially,

Curtis Chong



This archive was generated by hypermail 2b29 : Sun Dec 02 2012 - 01:30:03 PST