Loading applets
[[find_viewer]] looks for a viewer that matches the indicated
MIME type. If it has not been loaded, it will be loaded now. The
function returns a pointer to the viewer or [[NULL]].
[[find_agent]] is similar, but it looks for an agent matching a
protocol.
[[find_printer]] is analogous to [[find_viewer]].
[[find_filter]] looks for a filter that can convert from a given
MIME type to something else. The function looks among the
filters with number greater than or equal to [[n]].
[[init_all_user_functions]] loads and initializes all user
functions. Since these applets may want to create windows, this
can only be done after the browser has created the initial
windows. This function should be called only once, but nothing
happens when it is called again.
TO DO: use proxy if defined.
<<*>>=
#include "config.h"
#include
#include
#include
#include
#include
#include
/* #include */
#include "w3a.h"
#include "str.h"
#include "pushbuttons.h"
#include "rcfile.e"
#include "globals.e"
typedef struct {
int function, code;
} FunctionCallbackInfo;
static W3ABrowserInfo browser_info = {
"Argo/1.0",
0,
NULL,
NULL,
};
/*
* The following could be done with macros, for more efficiency
*/
EXPORT Bool viewer_open(int viewer, const W3ADocumentInfo doc,
W3AWindow win, long id)
{
assert(0 <= viewer && viewer < nrviewers);
return viewers[viewer].open(doc, win, id);
}
EXPORT int viewer_write(int viewer, long id, const char *buf, size_t nbytes)
{
assert(0 <= viewer && viewer < nrviewers);
return viewers[viewer].write(id, buf, nbytes);
}
EXPORT Bool viewer_close(int viewer, long id)
{
assert(0 <= viewer && viewer < nrviewers);
return viewers[viewer].close(id);
}
EXPORT Bool viewer_info(int viewer, long id, W3ADocumentInfo *doc)
{
assert(0 <= viewer && viewer < nrviewers);
return viewers[viewer].info(id, doc);
}
EXPORT void viewer_event(int viewer, long id, long sourceid,
long eventtype, void *params)
{
assert(0 <= viewer && viewer < nrviewers);
viewers[viewer].event(id, sourceid, eventtype, params);
}
EXPORT int agent_open(int agent, const char *url, int method, int flags,
const char *referer)
{
assert(0 <= agent && agent < nragents);
return agents[agent].open(url, method, flags, referer);
}
EXPORT Bool agent_done(int agent, int fd)
{
assert(0 <= agent && agent < nragents);
return agents[agent].done(fd);
}
EXPORT int agent_peek(int agent, int fd)
{
assert(0 <= agent && agent < nragents);
return agents[agent].peek(fd);
}
EXPORT int agent_read(int agent, int fd, char *buf, size_t nbytes)
{
assert(0 <= agent && agent < nragents);
return agents[agent].read(fd, buf, nbytes);
}
EXPORT int agent_write(int agent, int fd, const char *buf, size_t nbytes)
{
assert(0 <= agent && agent < nragents);
return agents[agent].write(fd, buf, nbytes);
}
EXPORT Bool agent_close(int agent, int fd)
{
assert(0 <= agent && agent < nragents);
return agents[agent].close(fd);
}
EXPORT Bool agent_delete(int agent, const char *url)
{
assert(0 <= agent && agent < nragents);
return agents[agent].delete(url);
}
EXPORT Bool agent_info(int agent, int fd, W3ADocumentInfo *doc)
{
assert(0 <= agent && agent < nragents);
return agents[agent].info(fd, doc);
}
EXPORT Bool filter_open(int filter, const char *from_type,
const char *from_params, const char *to_type,
const char *to_params, long id)
{
assert(0 <= filter && filter < nrfilters);
return filters[filter].open(from_type, from_params, to_type,
to_params, id);
}
EXPORT int filter_write(int filter, long id, const char *buf, size_t nbytes)
{
assert(0 <= filter && filter < nrfilters);
return filters[filter].write(id, buf, nbytes);
}
EXPORT int filter_read(int filter, long id, char *buf, size_t nbytes)
{
assert(0 <= filter && filter < nrfilters);
return filters[filter].read(id, buf, nbytes);
}
EXPORT Bool filter_close(int filter, long id)
{
assert(0 <= filter && filter < nrfilters);
return filters[filter].close(id);
}
EXPORT Bool function_doit(int function, int code, int mid_x, int mid_y)
{
assert(0 <= function && function < nrfunctions);
return userfns[function].doit(code, mid_x, mid_y);
}
EXPORT void function_event(int function, long sourceid,
long eventtype, void *params)
{
assert(0 <= function && function < nrfunctions);
userfns[function].event(sourceid, eventtype, params);
}
EXPORT Bool printer_open(int printer, const W3ADocumentInfo doc, long id)
{
assert(0 <= printer && printer < nrprinters);
return printers[printer].open(doc, id);
}
EXPORT int printer_write(int printer, long id, const char *buf, size_t nbytes)
{
assert(0 <= printer && printer < nrprinters);
return printers[printer].write(id, buf, nbytes);
}
EXPORT Bool printer_close(int printer, long id)
{
assert(0 <= printer && printer < nrprinters);
return printers[printer].close(id);
}
#ifndef hp9000s300
#define INIT "init"
#define OPEN "open"
#define DONE "done"
#define PEEK "peek"
#define READ "read"
#define WRITE "write"
#define CLOSE "close"
#define DELETE "delete"
#define INFO "info"
#define DO "do"
#define EVENT "event"
#else
#define INIT "_init"
#define OPEN "_open"
#define DONE "_done"
#define PEEK "_peek"
#define READ "_read"
#define WRITE "_write"
#define CLOSE "_close"
#define DELETE "_delete"
#define INFO "_info"
#define DO "_do"
#define EVENT "_event"
#endif
static void load_viewer(int viewer)
{
char init[256], open[256], write[256], close[256], info[256], event[256];
Viewer *v = &viewers[viewer];
shl_t h;
sprintf(init, "%s%s", INIT, strip2str(v->suffix));
sprintf(open, "%s%s", OPEN, strip2str(v->suffix));
sprintf(write, "%s%s", WRITE, strip2str(v->suffix));
sprintf(close, "%s%s", CLOSE, strip2str(v->suffix));
sprintf(info, "%s%s", INFO, strip2str(v->suffix));
sprintf(event, "%s%s", EVENT, strip2str(v->suffix));
if (! (h = shl_load(strip2str(v->file), BIND_IMMEDIATE|BIND_NONFATAL, 0)))
error("Error loading %s\n\t(%s)\n", strip2str(v->file),
strerror(errno));
if (shl_findsym(&h, init, TYPE_PROCEDURE, (void *)&v->init) != 0)
error("Error loading %s (%s)\n", init, strerror(errno));
if (shl_findsym(&h, open, TYPE_PROCEDURE, (void *)&v->open) != 0)
error("Error loading %s (%s)\n", open, strerror(errno));
if (shl_findsym(&h, write, TYPE_PROCEDURE, (void *)&v->write) != 0)
error("Error loading %s (%s)\n", write, strerror(errno));
if (shl_findsym(&h, close, TYPE_PROCEDURE, (void *)&v->close) != 0)
error("Error loading %s (%s)\n", close, strerror(errno));
if (shl_findsym(&h, info, TYPE_PROCEDURE, (void *)&v->info) != 0)
error("Error loading %s (%s)\n", info, strerror(errno));
if (shl_findsym(&h, event, TYPE_PROCEDURE, (void *)&v->event) != 0)
error("Error loading %s (%s)\n", info, strerror(errno));
}
static void load_agent(int agent)
{
char init[256], open[256], read[256], write[256], close[256];
char delete[256], info[256], peek[256], done[256];
Agent *a = &agents[agent];
shl_t h;
sprintf(init, "%s%s", INIT, strip2str(a->suffix));
sprintf(open, "%s%s", OPEN, strip2str(a->suffix));
sprintf(write, "%s%s", WRITE, strip2str(a->suffix));
sprintf(done, "%s%s", DONE, strip2str(a->suffix));
sprintf(peek, "%s%s", PEEK, strip2str(a->suffix));
sprintf(read, "%s%s", READ, strip2str(a->suffix));
sprintf(close, "%s%s", CLOSE, strip2str(a->suffix));
sprintf(delete, "%s%s", DELETE, strip2str(a->suffix));
sprintf(info, "%s%s", INFO, strip2str(a->suffix));
if (! (h = shl_load(strip2str(a->file), BIND_IMMEDIATE|BIND_NONFATAL, 0)))
error("Error loading %s (%s)\n", strip2str(a->file), strerror(errno));
if (shl_findsym(&h, init, TYPE_PROCEDURE, (void *)&a->init) != 0)
error("Error loading %s (%s)\n", init, strerror(errno));
if (shl_findsym(&h, open, TYPE_PROCEDURE, (void *)&a->open) != 0)
error("Error loading %s (%s)\n", open, strerror(errno));
if (shl_findsym(&h, done, TYPE_PROCEDURE, (void *)&a->done) != 0)
error("Error loading %s (%s)\n", done, strerror(errno));
if (shl_findsym(&h, peek, TYPE_PROCEDURE, (void *)&a->peek) != 0)
error("Error loading %s (%s)\n", peek, strerror(errno));
if (shl_findsym(&h, read, TYPE_PROCEDURE, (void *)&a->read) != 0)
error("Error loading %s (%s)\n", read, strerror(errno));
if (shl_findsym(&h, write, TYPE_PROCEDURE, (void *)&a->write) != 0)
error("Error loading %s (%s)\n", write, strerror(errno));
if (shl_findsym(&h, close, TYPE_PROCEDURE, (void *)&a->close) != 0)
error("Error loading %s (%s)\n", close, strerror(errno));
if (shl_findsym(&h, delete, TYPE_PROCEDURE, (void *)&a->delete) != 0)
error("Error loading %s (%s)\n", delete, strerror(errno));
if (shl_findsym(&h, info, TYPE_PROCEDURE, (void *)&a->info) != 0)
error("Error loading %s (%s)\n", info, strerror(errno));
}
static void load_filter(int filter)
{
char init[256], open[256], read[256], write[256], close[256];
Filter *f = &filters[filter];
shl_t h;
sprintf(init, "%s%s", INIT, strip2str(f->suffix));
sprintf(open, "%s%s", OPEN, strip2str(f->suffix));
sprintf(write, "%s%s", WRITE, strip2str(f->suffix));
sprintf(read, "%s%s", READ, strip2str(f->suffix));
sprintf(close, "%s%s", CLOSE, strip2str(f->suffix));
if (! (h = shl_load(strip2str(f->file), BIND_IMMEDIATE|BIND_NONFATAL, 0))
|| shl_findsym(&h, init, TYPE_PROCEDURE, (void *)&f->init) != 0
|| shl_findsym(&h, open, TYPE_PROCEDURE, (void *)&f->open) != 0
|| shl_findsym(&h, read, TYPE_PROCEDURE, (void *)&f->read) != 0
|| shl_findsym(&h, write, TYPE_PROCEDURE, (void *)&f->write) != 0
|| shl_findsym(&h, close, TYPE_PROCEDURE, (void *)&f->close) != 0)
error("Error loading %s\n\t(%s, %s, %s, %s, %s)\n\t(%s)\n",
strip2str(f->file), init, open, read, write, close,
strerror(errno));
}
static void load_printer(int printer)
{
Printer *p = &printers[printer];
char init[256], open[256], write[256], close[256];
shl_t h;
sprintf(init, "%s%s", INIT, strip2str(p->suffix));
sprintf(open, "%s%s", OPEN, strip2str(p->suffix));
sprintf(write, "%s%s", WRITE, strip2str(p->suffix));
sprintf(close, "%s%s", CLOSE, strip2str(p->suffix));
if (! (h = shl_load(strip2str(p->file), BIND_IMMEDIATE|BIND_NONFATAL, 0))
|| shl_findsym(&h, init, TYPE_PROCEDURE, (void *)&p->init) != 0
|| shl_findsym(&h, open, TYPE_PROCEDURE, (void *)&p->open) != 0
|| shl_findsym(&h, write, TYPE_PROCEDURE, (void *)&p->write) != 0
|| shl_findsym(&h, close, TYPE_PROCEDURE, (void *)&p->close) != 0)
error("Error loading %s\n\t(%s, %s, %s, %s)\n\t(%s)\n",
strip2str(p->file), init, open, write, close, strerror(errno));
}
static void function_cb(Widget w, XtPointer client_data, XtPointer call_data)
{
FunctionCallbackInfo *info = (FunctionCallbackInfo *) client_data;
/* TO DO: compute real mid_x and mid_y */
/* TO DO: do something with failure */
if (! function_doit(info->function, info->code, 100, 100)) ;
}
static void load_function(int function)
{
char init[256], doit[256], event[256];
UserFunction *f = &userfns[function];
shl_t h;
sprintf(init, "%s%s", INIT, strip2str(f->suffix));
sprintf(doit, "%s%s", DO, strip2str(f->suffix));
sprintf(event, "%s%s", EVENT, strip2str(f->suffix));
if (! (h = shl_load(strip2str(f->file), BIND_IMMEDIATE|BIND_NONFATAL, 0)))
error("Error linking %s (%s)\n", strip2str(f->file), strerror(errno));
if (shl_findsym(&h, init, TYPE_PROCEDURE, &f->init) != 0)
error("Error loading \"%s\" (%s)\n", init, strerror(errno));
if (shl_findsym(&h, doit, TYPE_PROCEDURE, &f->doit) != 0)
error("Error loading \"%s\" (%s)\n", doit, strerror(errno));
if (shl_findsym(&h, event, TYPE_PROCEDURE, &f->event) != 0)
error("Error loading \"%s\" (%s)\n", event, strerror(errno));
}
EXPORT int find_viewer(const char *mime_type)
{
int v, i;
for (v = 0; v < nrviewers; v++)
for (i = 0; i < viewers[v].nrtypes; i++)
if (fnmatch(viewers[v].mime_types[i], mime_type, FNM_PATHNAME) == 0)
return v;
return -1;
}
EXPORT int find_agent(const char *protocol) /* TO DO: use proxy */
{
int a, i;
for (a = 0; a < nragents; a++)
for (i = 0; i < agents[a].nrprotocols; i++)
if (eq(agents[a].protocols[i], protocol))
return a;
return -1;
}
EXPORT int find_filter(const char *from, int n)
{
int f, i;
for (f = 0; f < nrfilters; f++)
for (i = 0; i < filters[f].nrfromto; i++)
if (fnmatch(filters[f].from[i], from, 0) == 0)
return f;
return -1;
}
EXPORT int find_printer(const char *mime_type)
{
int p, i;
for (p = 0; p < nrprinters; p++)
for (i = 0; i < printers[p].nrtypes; i++)
if (fnmatch(printers[p].mime_types[i], mime_type, 0) == 0)
return p;
return -1;
}
static void init_browser_info(void)
{
float *preferences;
char **formats;
int n, i, j;
j = 0;
for (n = 0; n < nrviewers; n++)
for (i = 0; i < viewers[n].nrtypes; i++)
j++;
for (n = 0; n < nrfilters; n++)
for (i = 0; i < filters[n].nrfromto; i++)
j++;
newarray(formats, j);
newarray(preferences, j);
j = 0;
for (n = 0; n < nrviewers; n++)
for (i = 0; i < viewers[n].nrtypes; i++, j++) {
formats[j] = viewers[n].mime_types[i];
preferences[j] = viewers[n].prefs[i];
}
for (n = 0; n < nrfilters; n++)
for (i = 0; i < filters[n].nrfromto; i++, j++) {
formats[j] = filters[n].from[i];
preferences[j] = filters[n].prefs[i];
}
browser_info.formats = formats;
browser_info.preferences = preferences;
browser_info.nformats = j;
}
#define initerr(x) \
error("Error while calling init%s (%s)\n", \
strip2str(x.suffix), strerror(errno));
EXPORT void init_all_applets()
{
char **labels;
ThreeIcons *icons_data;
FunctionCallbackInfo *info;
int nrlabels, i, j;
Widget w;
for (i = 0; i < nragents; i++) {
if (! agents[i].init) load_agent(i);
if (! agents[i].init(&agents[i].protocols, &agents[i].nrprotocols))
initerr(agents[i]);
}
for (i = 0; i < nrviewers; i++) {
if (! viewers[i].init) load_viewer(i);
if (! viewers[i].init(&viewers[i].mime_types, &viewers[i].nrtypes,
&viewers[i].prefs))
initerr(viewers[i]);
}
for (i = 0; i < nrfilters; i++) {
if (! filters[i].init) load_filter(i);
if (! filters[i].init(&filters[i].from, &filters[i].to,
&filters[i].nrfromto, &filters[i].prefs))
initerr(filters[i]);
}
for (i = 0; i < nrprinters; i++) {
if (! printers[i].init) load_printer(i);
if (! printers[i].init(&printers[i].mime_types, &printers[i].nrtypes))
initerr(printers[i]);
}
for (i = 0; i < nrfunctions; i++) {
char *h;
if (! userfns[i].init) load_function(i);
new(h); userfns[i].id = (long) h; /* Unique ID */
if (! userfns[i].init(userfns[i].id, &labels, &icons_data, &nrlabels))
initerr(userfns[i]);
/* Add labels to menu and icons to toolbar */
for (j = 0; j < nrlabels; j++) {
new(info);
info->function = i;
info->code = j + 1;
w = XtVaCreateManagedWidget /* Add labels to menu */
(labels[j], xmPushButtonGadgetClass, functionsmenu, NULL);
XtAddCallback(w, XmNactivateCallback, function_cb, info);
w = XmCreatePixmapPushButtonGadget /* Add buttons to toolbar */
(tools, labels[j], icons_data[j][0], icons_data[j][1],
icons_data[j][2], NULL, 0);
XtManageChild(w);
XtAddCallback(w, XmNactivateCallback, function_cb, info);
}
}
init_browser_info();
}
EXPORT void W3AbrowserInfo(W3ABrowserInfo *info)
{
assert(browser_info.formats);
*info = browser_info;
}