]>
The browser starts applets and feeds them data, but it will also execute tasks on behalf of the applets, such as retrieving a new document and displaying a previous document.
The file w3a.h
defines the
structs W3ADocumentInfo
and
W3ABrowserInfo
:
typedef struct { char *url; char *mime_type; char *mime_params; char *title; char *referer; /* NULL if not known */ char *status; /* e.g. "403 not found" */ char *location; /* For redirect if status = 3xx */ long size; /* in bytes, -1 if unknown */ } W3ADocumentInfo; typedef struct { char *version; /* browser name & version */ int nformats; /* # of accepted formats */ char **formats; /* accepted formats */ float *preferences; /* Each in (0,1] */ } W3ABrowserInfo;
When a function changes a field in
W3ADocumentInfo
, it must free the previous contents
and allocate new space on the heap.
The type W3AWindow
is defined in the w3a.h
file to be the correct type
for the platform under which the browser and applets run. Under X
it will be an alias for Widget
, on other systems it
will be something else.
In the following, reference is made to a type Bool
and constants FALSE
and TRUE
. In the w3a.h
file, they are defined as
macros for int
, 0 and 1, respectively.
All browsers that support at least one of W3A/A, W3A/F, W3A/V, W3A/P, and W3A/U, must also provide the following functions:
Bool W3Aprocess(W3ADocumentInfo *info,
int method, const char *data, size_t nbytes)
This is the function that an applet calls when it wants to
follow a hyperlink, for example, when the user clicks in a
viewer. When the GET_METHOD
or DELETE_METHOD
, the
data
and nbytes
arguments are not
used. The other two methods, PUT_METHOD
and
POST_METHOD
, require that data
holds
the data to be sent to server in the body of the request.
In the url
,
title
and referer
fields must be
initialized, but the latter two may be NULL
. All
other fields must be set to NULL
(and
size
to -1). On successful return all other fields
will have been filled in (and title
and
size
may have changed). When the function returns
with FALSE
, errno
will have
been set and status
may have have been filled in
with a (human readable) status response, such as returned, e.g.,
by HTTP servers.
There are two possible semantics for this function In a browser without parallel threads, the function returns when the document has been fully received and is being displayed or when the retrieval is broken off (by the user, or because of an error). The returned value indicates the success of this operation.
In a browser that is multi-threaded, the browser may retrieve
just enough to be able to start the right viewer, and then do a
Note: The latter option, while allowing a faster
turn-around to the user, may have a few complications: we
cannot expect all viewers to be written for concurrent
operation, therefore the browser must buffer the data and only
call the viewer's fork()
, leaving the task of copying incoming data
to a child process. The returned value only indicates that the
initial part of the document was received OK.
writeXXX()
function from the
main thread, because otherwise it could happen that the viewer
is analysing its data while new data is being added at the
same time. Also, how expensive is it to do a
fork()
in a program as large as the browser?
Important: a browser may wish to close the previous
viewer before opening another one, which means that a viewer
instance that calls Question: Maybe W3Aprocess
may not `exist'
anymore when the call returns. More precisely: the viewer may
have received a closeXXX
call in the mean time,
destroying windows and datastructures.
W3Aprocess
needs
another argument: the ID of the viewer that calls it. That way
the browser knows in which window the hyper-jump originated,
which could be useful for a browser with multiple top-level
windows.
long W3Asubprocess(W3ADocumentInfo *info, int
method, const char *data, size_t nbytes, W3AWindow
window)
This function may be called by a viewer when it want to
retrieve and view a sub-document, such as an in-line image. The
browser will retrieve the document (by itself or via the
appropriate agent) and will display it (again by itself or via
the appropriate viewer), but it will not open a new window for
it. Instead, it will pass the window
on to the
viewer.
The return code is the id of the viewer that is displaying the document, or -1 in case of an error.
The browser will not notify applets via the event
broadcasting mechanism (W3Aevent()
below) that a
new document is opened. Also, when the browser closes viewers,
it will not close the viewer for this subdocument. It is the
task of the viewer that called W3Asubprocess
to
close the sub-viewer (by calling W3AcloseView
, see
below.)
int W3AopenDoc(const char *url,
int method, int flags, const char *referer)
Directs the browser to retrieve (method =
GET_METHOD
), put (PUT_METHOD
), or post
(POST_METHOD
) a document, without displaying it.
The function returns a file descriptor that must be used in
calls to W3AreadDoc()
or W3AwriteDoc()
and it may also be used in calls to select()
The W3Aread
and W3Awrite
functions. On Unix, the only possible flag is currently
O_NONBLOCK
, which causes the functions to return
immediately, without waiting for the operation to complete.
Question: The caller of this function (probably
a viewer wanting in-line images) may wish to specify the
particular formats that it prefers. The HTTP protocol allows a
single URL to stand for a family of documents each in a
different format. How should the caller communicate its
desires to the browser? Via an extra argument or a
variable-length list of arguments: NULL
if no such URL is available.
format1, pref1,
format2, pref2,...
?
Bool W3AinfoDoc(int fd, W3ADocumentInfo
*info_return)
Provide information about a document being retrieved. When a
failure occured while opening, reading or writing the document,
this function can also be called to get the reason: it will be
recorded in the status
field.
int W3AreadDoc(int fd, char *buf,
size_t bufsiz)
The W3Aopen()
. The return value is the number of
characters read, or -1 in case of error. A return of 0 means end
of file.
When the O_NONBLOCK
flag was set in the call to
W3Aopen
, the function returns immediately, whether
or not characters were available. In the latter case, the return
code is -1 and errno
is set to EAGAIN
.
int W3AwriteDoc(int fd, const char *buf,
size_t nchars)
The function tries to write O_NONBLOCK
flag has been set.
A return of -1 indicates an error, except when errno =
EAGAIN
; the latter can only happen when
O_NONBLOCK
has been set and it indicates that the
call could not be satisfied immediately, but that the caller
should try again.
Bool W3AcloseDoc(int fd)
Closes the connection and invalidates the file descriptor.
long W3AopenView(const W3ADocumentInfo doc,
W3AWindow window)
A viewer can call this function to open another viewer in a sub-window. The browser will start the appropriate viewer and return its ID, or -1 in case of an error.
int W3AwriteView(long id, const char *buf, size_t
nchars)
This function is used to send data to be displayed to a
viewer previously opened with W3AopenView
. The
return code is equal to nchars
or -1 in case of an
error.
Bool W3AcloseView(long id)
Closes a viewer previously opened with
W3AopenView
.
int W3AresolveURN(const char *urn, char
***url_list_return)
Currently returns -1, indicating that the URN could not be resolved.
void W3AbrowserInfo(W3ABrowserInfo
*info)
Returns information about the browser and its capabilities.
For example, an HTTP agent needs this to construct the `Accept:'
headers required by the HTTP protocol.
Question: The information may change, depending
on context (see the note on
W3Aopen
). Maybe this function needs an extra
fd
argument by which the agent identifies
itself?
void W3Aevent(long id, long
eventtype, void *params)
When a viewer or user function has an event to report, it
calls W3Aevent
, which in turn calls the event
functions of all other viewers and user functions. See the
explanation below.
W3AWindow W3Atoplevel(void)
The W3Atoplevel
function returns a window
(widget) that can be used as a parent for pop-up windows. It
should not be used as a parent for normal windows, since it
might not be `mapped' (i.e., visible on the screen).
Question: There are many useful, though not
essential functions that many applets share. The browser could
offer them, or do we create libWWWutils
and simply
recommend that authors use it?
In some viewers, events can happen that do not immediately cause a new document to be loaded, but that might cause other viewers to do something. For example, two viewers might be synchronized in such a way that a mouse click in one of them causes both windows to display a new image.
Since it not clear at this point what types of events must be supported, W3A only defines an abstract mechanism. The contents and the semantics of events will have to be standardized in some way, or there has to be a way for viewers to agree on events. This is a matter for a future revision.
The current mechanism is very simple: events are identified by a number and may have a single parameter in the form of an untyped pointer. There is no mechanism for filtering events. All events are treated the same and all viewers receive all events.
At the moment, there is only one defined event type, which is
used by the browser itself. It has event code 1, and indicates
that the browser (successfully) executed a
W3Aprocess
. Applets that are interested in keeping
track of the `current' document, such as hotlist or history
applets, can use this. The event-dependent info will be a
pointer to a W3ADocumentInfo
structure, describing
the document that was just opened for viewing. (Note that the
browser may send this event more than once for the same
document, for example when the document's title changes. Applets
must be prepared for this.)
The browser functions as the central event dispatcher. It has
a function W3Aevent
that an applet calls when it
has an event to report. The W3Aevent
function then
calls every viewer (except the originator of the event) with the
same arguments that it received itself.
Every viewer and every user function must have an exported
function eventXXX
, with four arguments: the
applet's ID (long
), the ID of the applet in which
the event originated (long
), the event type
(long
), and a pointer to event-dependent info
(void *
). Simple viewers that don't need events
must still supply an (empty) function.
Sub-viewers that have been opened by W3AopenView
will also be called by the browser. This means that the viewer
that opened the sub-viewers does not have to do so itself. But a
parent viewer is free to call the eventXXX
functions of its sub-viewers if it wants to.
Examples of situations where the event mechanism is usefule are the following:
Clickable images, either in the old way
( Question: it would be nice if the image viewer
did handle the hyperlinks itself, though. Because
it could then give some visual feedback, especially in the
case of ISMAP
) or the new (FIG
) can be
displayed with sub-viewers that do not know that the image
they display is actually an anchor. Instead, they generate an
event when the user clicks on them and call
W3Aevent
with the mouse coordinates as arguments.
The parent viewer's eventHTML
function will be
called and it can process the event.
FIG
images, where the hotspots are
known. A special viewer is needed for this, but how are the
hotspots communicated to that viewer?
Certain input fields in HTML forms could be handled by sub-viewers. A viewer for a scribble field, for example, could use the event mechanism to notify the HTML viewer that the user has started (or ended?) scribbling and pass a pointer to the resulting drawing as parameter.
A slide show might want to use a clock to time the images and other displays. A special timer applet could be the source of the timing signals. The slide show viewer could open a sub-viewer of type `application/x-clock' that generated a clock-tick event every few seconds.
When the above functions fail, they set the errno
variable. functions exported by applets should also set this
variable when they fail. Apart form the values already defined
by the OS libraries, the following four extra values are
defined in w3a.h
:
EURL
Syntax error in URL
EMETHOD
Illegal method
ENYI
Not yet implemented
ETYPE
No applet for this type
EFORMAT
Error in data
EUSER
Interrupted by user
The interpretation of Note: Error handling is still a weak spot;
something more has to be said about the proper use of
EUSER
depends on the
context. It is recommended that an HTML viewer that encounters
this error while retrieving in-line images should not
retrieve any further images.
errno