xmhtml

browser with Motif
git clone git://bvnf.space/xmhtml.git
Log | Files | Refs

commit 90b5d3f382af8c90a5e31c132059b1be209d92c3
Author: aabacchus <ben@bvnf.space>
Date:   Mon,  5 Dec 2022 15:32:32 +0000

init

Diffstat:
A.gitignore | 2++
AMakefile | 9+++++++++
Axmhtml.c | 381+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 392 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +xmhtml +*.o diff --git a/Makefile b/Makefile @@ -0,0 +1,9 @@ +.POSIX: +CFLAGS = -Wall -Og -g +LIBS = -lXmHTML -lXm -lpng -lXt -lXft -lXt -lX11 -ljpeg -lXpm -lfontconfig -lpng16 -lz -lfreetype -lxcb -lglib-2.0 + +all: xmhtml +xmhtml: xmhtml.o + $(CC) $(LDFLAGS) -o $@ xmhtml.o $(LIBS) +clean: + rm -f xmhtml xmhtml.o diff --git a/xmhtml.c b/xmhtml.c @@ -0,0 +1,381 @@ +/***** +* example_1.c : simple demonstration on how to use XmHTML +* +* This file Version $Revision: 1.6 $ +* +* Creation date: Mon Jan 27 02:06:08 GMT+0100 1997 +* Last modification: $Date: 1997/10/23 00:28:37 $ +* By: $Author: newt $ +* Current State: $State: Exp $ +* +* Author: newt +* +* Copyright (C) 1994-1997 by Ripley Software Development +* All Rights Reserved +* +* This file is part of the XmHTML Widget Library. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU [Library] General Public +* License as published by the Free Software Foundation; either +* version 2 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Library General Public License for more details. +* +* You should have received a copy of the GNU [Library] General Public +* License along with this library; if not, write to the Free +* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*****/ +/***** +* ChangeLog +* $Log: example_1.c,v $ +* Revision 1.6 1997/10/23 00:28:37 newt +* XmHTML Beta 1.1.0 release +* +* Revision 1.5 1997/05/28 02:02:49 newt +* Changes to reflect updated convenience function protos. +* +* Revision 1.4 1997/03/20 08:20:37 newt +* enlarged default with and height +* +* Revision 1.3 1997/03/11 20:08:55 newt +* Changed XmHTMLSetText to XmHTMLTextSet +* +* Revision 1.2 1997/03/04 01:02:45 newt +* Added printing of XmHTML version strings +* +* Revision 1.1 1997/02/11 01:58:25 newt +* Initial Revision +* +*****/ + +#include <assert.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> +#include <Xm/Xm.h> +#include <Xm/PushB.h> +#include <Xm/Frame.h> +#include <Xm/Form.h> + +#include <XmHTML/XmHTML.h> + +/*** Private Variable Declarations ***/ +static Widget html; + +struct history { + struct history *prev; + char href[]; +}; +static struct history *history_top; + +/***** +* Change this to change the application class of the examples +*****/ +#define APP_CLASS "HTMLDemos" + +/***** +* Name: exitCB +* Return Type: void +* Description: callback for the exit button +* In: +* widget: button widget id +* client_data:unused +* call_data: unused +* Returns: +* +*****/ +static void +exitCB(Widget widget, XtPointer client_data, XtPointer call_data) +{ + printf("Bye!\n"); + exit(EXIT_SUCCESS); +} + +static void +history_init(void) { + history_top = NULL; +} + +static void +history_push(String href) { + struct history *h = calloc(sizeof (struct history) + strlen(href) + 1, 1); + if (h == NULL) { + perror("malloc"); + exit(1); + } + + strcpy(h->href, href); + h->prev = history_top; + history_top = h; +} + +static String +history_pop(void) { + if (history_top == NULL) + return NULL; + struct history *old = history_top; + String s = malloc(strlen(history_top->href) + 1); + if (s == NULL) { + perror("malloc"); + exit(1); + } + strcpy(s, history_top->href); + history_top = history_top->prev; + free(old); + return s; +} + +static String loadFile(String); +/***** +* Name: anchorCB +* Return Type: void +* Description: XmNactivateCallback for the XmHTML widget +* In: +* widget: widget id, in this case that of the HTML widget +* client_data:data registered with callback, unused +* cbs: XmHTML callback structure. +* Returns: +* nothing. +* Note: +* We don't care what sort of url has been selected. +* Setting the doit field to True instructs XmHTML to do it's own scrolling. +* XmHTML is smart enought to only scroll to a location in this document if +* it really exists. +* Setting the visited field also to True will cause XmHTML to render the +* selected anchor as being visited. +*****/ +static void +anchorCB(Widget widget, XtPointer client_data, + XmHTMLAnchorCallbackStruct *cbs) +{ + cbs->doit = True; + cbs->visited = True; + + fprintf(stderr, "clicked link \"%s\"\n", cbs->href); + String content = loadFile(cbs->href); + if (content != NULL) { + XmHTMLTextSetString(html, content); + history_push(cbs->href); + } + free(content); +} + +static void +history_print(void) { + struct history *h = history_top; + fprintf(stderr, "History:\n"); + for (; h != NULL; h = h->prev) + fprintf(stderr, "%s\n", h->href); + fprintf(stderr, "\n"); +} + +static void +backCB(Widget widget, XtPointer client_data, XtPointer call_data) { + history_print(); + String b = history_pop(); + if (b == NULL) + return; + fprintf(stderr, "loading history \"%s\"\n", b); + String content = loadFile(b); + if (content != NULL) + XmHTMLTextSetString(html, content); + free(content); + free(b); +} + +/***** +* Name: loadFile +* Return Type: String +* Description: loads the contents of the given file. +* In: +* filename: name of the file to load +* Returns: +* contents of the loaded file. +*****/ +static String +loadFile(String filename) +{ + String file_to_open = filename; + FILE *file; + int size; + static String content; + struct stat sb; + + if (stat(filename, &sb) == -1) { + perror(filename); + return NULL; + } + + if (S_ISDIR(sb.st_mode)) { + if (chdir(filename) != 0) { + perror(filename); + return NULL; + } + file_to_open = "index.html"; + } + + size = sb.st_size; + + /* open the given file */ + if((file = fopen(file_to_open, "r")) == NULL) + { + perror(file_to_open); + return(NULL); + } + + /* see how large this file is */ + if (fseek(file, 0, SEEK_END) == -1) + perror("fseek"); + size = ftell(file); + if (size == -1) + perror("ftell"); + rewind(file); + if (size != sb.st_size) + fprintf(stderr, "size %d != st_size %ld\n", size, sb.st_size); + + /* allocate a buffer large enough to contain the entire file */ + if((content = malloc(size+1)) == NULL) + { + fprintf(stderr, "malloc failed for %i bytes\n", size); + exit(EXIT_FAILURE); + } + + /* now read the contents of this file */ + if((fread(content, 1, size, file)) != size) + printf("Warning: did not read entire file!\n"); + + fclose(file); + + /* sanity */ + content[size] = '\0'; + + return(content); +} + +/***** +* Name: main +* Return Type: int +* Description: main for example 1 +* In: +* argc: no of arguments on command line +* argv: array of command line arguments +* Returns: +* EXIT_FAILURE when an error occurs, EXIT_SUCCESS otherwise +* Note: +* this example should be started with the name of a HTML file to display. +*****/ +int +main(int argc, char **argv) +{ + XtAppContext context; + Widget toplevel, form, frame, button, back; + String content; + + fprintf(stderr, "%s, %i\n", XmHTMLVERSION_STRING, XmHTMLGetVersion()); + + /* check command line arguments, but allow for X11 options */ + if(argc < 2) + { + printf("%s: simple XmHTML example\n", argv[0]); + printf("\tUsage: %s <filename>\n", argv[0]); + exit(EXIT_FAILURE); + } + + content = loadFile(argv[1]); + + /* create toplevel widget */ + toplevel = XtVaAppInitialize(&context, APP_CLASS, NULL, 0, + &argc, argv, NULL, NULL, NULL); + + + /* XSynchronize( XtDisplay( toplevel ), True ); */ + + /* create a form as the main container */ + form = XtVaCreateWidget("form", + xmFormWidgetClass, toplevel, + NULL); + + /* create the exit button */ + button = XtVaCreateManagedWidget("Exit", + xmPushButtonWidgetClass, form, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 10, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 10, + NULL); + + /* add the exit callback */ + XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)exitCB, + NULL); + + back = XtVaCreateManagedWidget("Back", + xmPushButtonWidgetClass, form, + XmNtopAttachment, XmATTACH_FORM, + XmNtopOffset, 10, + XmNleftAttachment, XmATTACH_WIDGET, + XmNleftWidget, button, + NULL); + XtAddCallback(back, XmNactivateCallback, backCB, NULL); + + /* create a frame as the html container */ + frame = XtVaCreateManagedWidget("frame", + xmFrameWidgetClass, form, + XmNtopAttachment, XmATTACH_WIDGET, + XmNtopWidget, button, + XmNtopOffset, 10, + XmNleftAttachment, XmATTACH_FORM, + XmNleftOffset, 10, + XmNbottomAttachment, XmATTACH_FORM, + XmNbottomOffset, 10, + XmNrightAttachment, XmATTACH_FORM, + XmNrightOffset, 10, + XmNshadowType, XmSHADOW_IN, + NULL); + + /* create the HTML widget using the default resources */ + html = XtVaCreateManagedWidget("html", + xmHTMLWidgetClass, frame, + XmNmarginWidth, 20, + XmNmarginHeight, 20, + XmNwidth, 600, + XmNheight, 500, + NULL); + + history_init(); + + if(content == NULL) + XmHTMLTextSetString(html, "<html><body>Could not read given " + "file</body></html>"); + else + { + history_push(argv[1]); + XmHTMLTextSetString(html, content); + free(content); + } + + /* add a simple anchor callback so XmHTML can jump to local anchors */ + XtAddCallback(html, XmNactivateCallback, + (XtCallbackProc)anchorCB, NULL); + + /* manage the form */ + XtManageChild(form); + + /* realize the main application */ + XtRealizeWidget(toplevel); + + /* The HTML widget has the focus */ + XmProcessTraversal(html, XmTRAVERSE_CURRENT); + + /* enter the event loop */ + XtAppMainLoop(context); + + /* never reached, but keeps compiler happy */ + exit(EXIT_SUCCESS); +}