#line 16 "html.c-nw" #include #include #include #include #include #include #include #include #include #include #include #include #include #define USE_STATUS 1 #define USE_BALLOON 0 #line 40 "html.c-nw" typedef struct _IdWidget { long id; Widget w; struct _IdWidget *next; } *IdWidget; typedef struct { W3ADocumentInfo *info; Widget w; /* HTML widget */ #if USE_STATUS Widget status; /* Label with URL */ #endif #ifdef USE_BALLOON Widget balloon; #endif long nchars; /* Needed in infoHTML */ IdWidget idlist; } *Instance; typedef struct _IdInstance { long id; Instance i; struct _IdInstance *next; } *IdInstance; static IdInstance instancelist = NULL; static void store_id(Instance instance, long id, Widget w) { IdWidget h; new(h); h->id = id; h->w = w; h->next = instance->idlist; instance->idlist = h; } static Widget id_to_widget(Instance instance, long id) { IdWidget p; for (p = instance->idlist; p; p = p->next) if (p->id == id) return p->w; return NULL; } static void dispose_idlist(IdWidget list) { if (list) { if (list->id != -1) W3AcloseView(list->id); dispose_idlist(list->next); dispose(list); } } /* store -- store an ID/Instance combination */ static void store(Instance i, long id) { IdInstance h; new(h); h->id = id; h->i = i; h->next = instancelist; instancelist = h; } /* delete -- delete an ID/Instance combination */ static void delete(long id) { IdInstance g, h; assert(instancelist); if (instancelist->id == id) { h = instancelist; instancelist = instancelist->next; dispose(h); } else { assert(instancelist->next); for (h = instancelist; h->next->id != id; h = h->next) assert(h->next); g = h->next; h->next = g->next; dispose(g); } } /* find -- find the Instance associated with an ID */ static Instance find(long id) { IdInstance h; assert(instancelist); for (h = instancelist; h->id != id; h = h->next) assert(h->next); return h->i; } #line 128 "html.c-nw" static void activate_cb(Widget w, XtPointer client_data, XtPointer call_data) { XfwfFTextCallbackStruct *info = (XfwfFTextCallbackStruct *) call_data; XfwfSSGMLData *data = (XfwfSSGMLData *) info->data; char *url = data->url; Instance instance = (Instance) client_data; W3ADocumentInfo *doc; /* debug("html activate: %s\n", data->url); */ #if USE_BALLOON if (instance->balloon) { XtPopdown(instance->balloon); instance->balloon = NULL; } #endif doc = new_doc(); if (data->ismap) { /* Append x,y */ newarray(doc->url, strlen(url) + 25); sprintf(doc->url, "%s?%d,%d", url, info->x, info->y); } else doc->url = newstring(url); doc->referer = newstring(instance->info->url); (void) W3Aprocess(doc, GET_METHOD, NULL, 0); dispose_doc(doc); } #line 161 "html.c-nw" static void activate_form_cb(Widget w, XtPointer client_data, XtPointer call_data) { XfwfActivateFormInfo *info = (XfwfActivateFormInfo *) call_data; Instance instance = (Instance) client_data; W3ADocumentInfo *doc; /* debug("html activate_form: %s\n", info->url); */ #if USE_BALLOON if (instance->balloon) { XtPopdown(instance->balloon); instance->balloon = NULL; } #endif doc = new_doc(); doc->url = newstring(info->url); doc->referer = newstring(instance->info->url); (void) W3Aprocess(doc, info->method, info->data, info->length); dispose_doc(doc); } #line 187 "html.c-nw" static void enterleave_cb(Widget w, XtPointer client_data, XtPointer call_data) { #if USE_STATUS || USE_BALLOON XfwfFTextCallbackStruct *info = (XfwfFTextCallbackStruct *) call_data; XfwfSSGMLData *data = (XfwfSSGMLData *) info->data; Instance instance = (Instance) client_data; URI base, uri; Position x, y; char *url; #endif #if USE_STATUS if (info->reason == XfwfEnter) { if (! URL_parse(data->url, &uri)) return; /* Error in URL */ if (uri.tp == URI_Rel) { if (! URL_parse(instance->info->url, &base)) return; /* ??? */ URL_expand(&uri, base); } url = uri2str(uri); XtVaSetValues(instance->status, XtVaTypedArg, XmNlabelString, XtRString, url, strlen(url), NULL); dispose(url); } else { assert(info->reason == XfwfLeave); XtVaSetValues(instance->status, XtVaTypedArg, XmNlabelString, XtRString, "", 1, NULL); } #endif #if USE_BALLOON if (info->reason == XfwfEnter) { if (! URL_parse(data->url, &uri)) return; /* Error in URL */ if (uri.tp == URI_Rel) { if (! URL_parse(instance->info->url, &base)) return; /* ??? */ URL_expand(&uri, base); } url = uri2str(uri); XtTranslateCoords(instance->w, info->x, info->y, &x, &y); instance->balloon = XtVaCreatePopupShell ("balloon", overrideShellWidgetClass, instance->w, XtNx, x + 5, XtNy, y + 5, NULL); (void) XtVaCreateManagedWidget ("balloon-label", xmLabelWidgetClass, instance->balloon, XtVaTypedArg, XmNlabelString, XtRString, url, strlen(url), NULL); dispose(url); XtPopup(instance->balloon, XtGrabNone); } else { assert(info->reason == XfwfLeave); if (instance->balloon) XtDestroyWidget(instance->balloon); instance->balloon = NULL; } #endif } #line 250 "html.c-nw" static void resolve_cb(Widget w, XtPointer client_data, XtPointer call_data) { XfwfResolveRec *info = (XfwfResolveRec *) call_data; Instance instance = (Instance) client_data; W3ADocumentInfo *doc; long id; /* fprintf(stderr, "resolve image: %s\n", info->url); */ doc = new_doc(); doc->url = newstring(info->url); doc->referer = newstring(instance->info->url); id = W3Asubprocess(doc, GET_METHOD, NULL, 0, info->widget); store_id(instance, id, info->widget); dispose_doc(doc); } EXPORT Bool initHTML(char ***mime_types, int *nrtypes, float **prefs) { static char *types[] = {"text/html"}; static float pref[] = {1.0}; *mime_types = types; *nrtypes = 1; *prefs = pref; return TRUE; } EXPORT Bool openHTML(const W3ADocumentInfo doc, W3AWindow workarea, long id) { Widget w, form, status; Instance instance; Pixmap bg; new(instance); store(instance, id); #if USE_STATUS #define STATUS_HT 20 #if 1 form = XtVaCreateManagedWidget ("html-form", xmFormWidgetClass, workarea, NULL); w = XtVaCreateManagedWidget ("html", xfwfHTML2WidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, STATUS_HT, XtNbase, doc.url, NULL); status = XtVaCreateManagedWidget ("html-status", xmLabelWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, w, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); #else /* 0 */ form = XtVaCreateManagedWidget ("html-form", xmPanedWindowWidgetClass, workarea, NULL); w = XtVaCreateManagedWidget ("html", xfwfHTML2WidgetClass, form, NULL); status = XtVaCreateManagedWidget ("html-status", xmLabelWidgetClass, form, NULL); #endif /* 0 */ #else /* USE_STATUS */ w = XtVaCreateManagedWidget("html", xfwfHTML2WidgetClass, workarea, NULL); #endif XtAddCallback(w, XtNactivate, activate_cb, instance); XtAddCallback(w, XtNactivateForm, activate_form_cb, instance); XtAddCallback(w, XtNenter, enterleave_cb, instance); XtAddCallback(w, XtNleave, enterleave_cb, instance); XtAddCallback(w, XtNresolveURL, resolve_cb, instance); instance->w = w; #if USE_STATUS instance->status = status; #endif #if USE_BALLOON instance->balloon = NULL; #endif instance->info = new_doc(); copy_doc(instance->info, doc); instance->nchars = 0; instance->idlist = NULL; #if 0 /* Nice background (this is not the way it should be done, though) */ if (XpmReadFileToPixmap (XtDisplay(w), RootWindowOfScreen(XtScreen(w)), "Flock.pm", &bg, NULL, NULL) == XpmSuccess) { XtVaSetValues(w, XtNbackgroundPixmap, bg, NULL); XtVaSetValues(XtParent(w), XtNbackgroundPixmap, bg, NULL); } #endif return TRUE; } EXPORT Bool infoHTML(long id, W3ADocumentInfo *info) { Instance instance = find(id); char *s = NULL; XtVaGetValues(instance->w, XtNtitle, &s, NULL); if (s) { dispose(info->title); info->title = newstring(s); trim(info->title); dispose(instance->info->title); instance->info->title = newstring(info->title); } info->size = instance->nchars; return TRUE; } EXPORT int writeHTML(long id, const char *buf, size_t nbytes) { Instance instance = find(id); Widget workarea = XtParent(XtParent(instance->w)); XfwfAddText(instance->w, buf, nbytes); instance->nchars += nbytes; return nbytes; } EXPORT Bool closeHTML(long id) { Instance instance = find(id); #if USE_STATUS XtDestroyWidget(XtParent(instance->w)); #else XtDestroyWidget(instance->w); #endif dispose_doc(instance->info); dispose_idlist(instance->idlist); delete(id); return TRUE; } EXPORT void eventHTML(long id, long source, long eventtype, void *params) { Instance instance = id == -1 ? NULL : find(id); struct _coords {int x, y;}; Widget child; int x, y; if (id == -1) return; /* Not interested in */ /* events to class */ /* debug("HTML viewer %ld received event %ld from %ld\n", id, eventtype, source); */ if (eventtype == POINT_SELECT && (child = id_to_widget(instance, source)) != NULL) { x = ((struct _coords *) params)->x; y = ((struct _coords *) params)->y; XfwfPassClick(instance->w, child, x, y); } }