--- /dev/null
+/*
+ * Cl.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Thu Apr 16 22:08:27 1992 tvr
+ * Last modified: Wed May 13 13:27:58 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+
+#include "Cl.h"
+
+#include "HTStyle.h"
+#include "HTParse.h"
+#include "HText.h"
+#include "tcp.h"
+
+#include "../HText/HText.h"
+
+extern HText_t *HtLocalText;
+
+int WWWErwiseStatus;
+ClConnection_t *WWWErwiseConnection;
+
+void cl_free_connection ();
+
+/*
+ * Where to load this file ?
+ */
+
+char *WWWErwiseFileLoadName = 0;
+
+/*
+ * Open connection. Allocate strutures.
+ */
+
+ClConnection_t *
+ClOpenConnection (address)
+ char *address;
+{
+ int status;
+ ClConnection_t *p = (ClConnection_t *) malloc (sizeof (*p));
+
+ /*
+ * Some validation checks
+ */
+
+ if (!p)
+ return p;
+
+ if (!address)
+ return NULL;
+
+ memset (p, 0, sizeof (*p));
+
+ p->address = (char *) strdup (address);
+
+ /*
+ * If we wish to load to file, open fd here
+ */
+
+ if (WWWErwiseFileLoadName)
+ {
+
+ p->load_to_file_fd =
+ open (WWWErwiseFileLoadName, O_WRONLY | O_CREAT, 0666);
+
+ free (WWWErwiseFileLoadName);
+
+ WWWErwiseFileLoadName = 0;
+
+ if (p->load_to_file_fd < 0)
+ {
+
+ printf ("ClOpenConnection: Cannot load to file '%s'\n",
+ WWWErwiseFileLoadName);
+
+ ClCloseConnection (p);
+
+ return 0;
+ }
+
+ p->load_to_file = 1;
+ }
+
+
+ /*
+ * Kludge #1:
+ * Call common code to get socket fd. Also set state to some value so
+ * that ReadData calls some function that makes sense.
+ */
+
+ WWWErwiseConnection = p;
+
+ WWWErwiseStatus = CL_CONTINUES;
+
+ p->status = HTLoadAbsolute (address, 0);
+
+ if ((WWWErwiseStatus == CL_FAILED) ||
+ (WWWErwiseStatus == CL_ALREADY_LOADED))
+ {
+
+ ClCloseConnection (p);
+
+ return NULL;
+ }
+
+ return p;
+}
+
+
+/*
+ * Read data or poll connection opening
+ */
+struct HText *
+ClReadData (connection, how_done, fd)
+ ClConnection_t *connection;
+ int *how_done;
+ int *fd;
+{
+ int continues;
+
+ void (*tmpf) ();
+
+ WWWErwiseStatus = CL_CONTINUES;
+
+ WWWErwiseConnection = connection;
+
+ /*
+ * If loading was on non-blocking mode ?
+ */
+ if (!connection->function)
+ {
+
+ *fd = connection->fd;
+
+ if (connection->status)
+ {
+
+ *how_done = CL_COMPLETED;
+
+ ClCloseConnection (connection);
+
+ return HtLocalText;
+
+ }
+ else
+ {
+
+ *how_done = CL_FAILED;
+
+ ClCloseConnection (connection);
+
+ return 0;
+
+ }
+ }
+
+ /*
+ * Try max 3 pollings at one call. This makes loading faster but does not
+ * get too much cpu
+ */
+ for (continues = 3; continues > 0; continues--)
+ {
+
+ tmpf = *connection->function;
+
+ if (*connection->function)
+ (void) (*connection->function) ();
+
+ /*
+ * If mode is going to change to poll, set it now
+ */
+ if (*connection->function == WWWErwiseSetPoll)
+ (void) WWWErwiseSetPoll ();
+
+ /*
+ * Can we try next polling?
+ */
+ if ((*connection->function == tmpf) || (*how_done != CL_CONTINUES) ||
+ (connection->select_fd))
+ {
+
+ continues = 0;
+ }
+ }
+
+ *how_done = WWWErwiseStatus;
+
+ *fd = connection->select_fd;
+
+ if (*how_done == CL_FAILED)
+ {
+
+ ClCloseConnection (connection);
+
+ return NULL;
+ }
+
+ if (*how_done == CL_COMPLETED)
+ {
+
+ ClCloseConnection (connection);
+
+ return HtLocalText; /* global variable because @#$#$ <censored> */
+ }
+
+ return NULL;
+}
+
+
+/*
+ * User wants to terminate a connection
+ */
+
+void
+ClCloseConnection (connection)
+ ClConnection_t *connection;
+{
+ if (connection->load_to_file)
+ {
+
+ close (connection->load_to_file_fd);
+ }
+
+ if (connection->fd)
+ {
+
+ shutdown (connection->fd, 2);
+
+ close (connection->fd);
+ }
+
+ if (connection->secondary_fd)
+ {
+
+ shutdown (connection->secondary_fd, 2);
+
+ close (connection->secondary_fd);
+ }
+
+ cl_free_connection (connection);
+}
+
+
+
+/*
+ * read data from local buffer. If no data on buffer, make normal read
+ */
+int
+cl_read_data (fd, data, length)
+ int fd;
+ char *data;
+ int length;
+{
+ ClConnection_t *p = WWWErwiseConnection;
+
+ cl_data_t *b = p->buffer_first;
+
+ int howmuch = 0;
+
+ if (p->buffer_last)
+ {
+ if (!b)
+ return 0;
+
+ if (length < b->size)
+ {
+
+ memcpy (data, b->data, length);
+
+ howmuch = length;
+
+ b->size -= length;
+
+ b->data += length;
+ }
+ else
+ {
+
+ memcpy (data, b->data, b->size);
+
+ howmuch = b->size;
+
+ free (b->freeptr);
+
+ if (b->next)
+ {
+ b->next->prev = 0;
+ p->buffer_first = b->next;
+ }
+ else
+ {
+ p->buffer_first = 0;
+ }
+ free (b);
+ }
+ }
+ else
+ {
+ return NETREAD (fd, data, length);
+ }
+ return howmuch;
+}
+
+
+
+/*
+ * Free everything connection structure has malloced (and not yet freed)
+ */
+
+void
+cl_free_connection (connection)
+ ClConnection_t *connection;
+{
+ if (connection->address)
+ free (connection->address);
+
+ if (connection->addr)
+ free (connection->addr);
+
+ if (connection->command)
+ free (connection->command);
+
+ if (connection->buffer_first)
+ {
+ cl_data_t *p = connection->buffer_first;
+
+ while (p)
+ {
+
+ cl_data_t *p2 = p;
+
+ free (p->freeptr);
+
+ free (p);
+
+ p = p2->next;
+ }
+ }
+
+ /*
+ * NOTE!
+ * anAnchor or diag should not be freed (at least they are not on
+ * original common code.
+ */
+}
+
+
+/*
+ * Return true if loading to file is supported with this address
+ */
+int
+ClCanLoadToFile (address)
+ char *address;
+{
+ char *access;
+
+ if (!address)
+ {
+ return 0;
+ }
+
+ access = HTParse (address, "", PARSE_ACCESS);
+
+ if (!strcmp (access, "html"))
+ {
+
+ free (access);
+
+ return 1;
+ }
+
+ if (!strcmp (access, "file"))
+ {
+
+ free (access);
+
+ return 1;
+ }
+
+ free (access);
+
+ return 0;
+}
+
+
+/*
+ * Are we loading this connection to file ?
+ */
+int
+ClConnectionOnLoadToFileMode (connection)
+ ClConnection_t *connection;
+{
+ if (!connection)
+ return 0;
+
+ return connection->load_to_file;
+}
+
+
+void
+ClSetFileNameForLoadingToFile (char *filename)
+{
+ if (filename)
+ WWWErwiseFileLoadName = (char *) strdup (filename);
+ else
+ WWWErwiseFileLoadName = NULL;
+}
--- /dev/null
+/*
+ * Cl.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Thu Apr 16 21:40:39 1992 tvr
+ * Last modified: Wed May 13 00:11:13 1992 tvr
+ *
+ */
+
+#include "HTAnchor.h"
+#include "HTStyle.h"
+#include "HText.h"
+
+/*
+ * Data is store on linked list
+ */
+typedef struct cl_data_s
+{
+ struct cl_data_s *next;
+ struct cl_data_s *prev;
+ void *data;
+ void *freeptr;
+ int size;
+} cl_data_t;
+
+
+/*
+ * This structure contains all information needed to accomplish this
+ * connection.
+ */
+typedef struct ClConnection_s
+{
+ /*
+ * address of this connection
+ */
+ char *address;
+
+ /*
+ * Fd of the connection. Also ftp connection data channel.
+ */
+ int fd;
+ int secondary_fd;
+
+ /*
+ * If this fd is not set connection has to be polled. If it is NOT
+ * set, connection has to be selected (must not poll!)
+ */
+ int select_fd;
+
+ /*
+ * Function of this state machine
+ */
+ void (**function) ();
+
+ /*
+ * Store junk here (address of data on connect() )
+ */
+ void *addr;
+ int addr_size;
+
+ /*
+ * Store command to write to the net here
+ */
+ char *command;
+
+ /*
+ * Data Buffer
+ */
+ cl_data_t *buffer_first;
+ cl_data_t *buffer_last;
+
+ /*
+ * stuff given to HTLoadHTTP()
+ */
+ int diag;
+ struct HTAnchor *anAnchor;
+
+ /*
+ * How happened with load if on nonblocking mode
+ */
+ int status;
+
+ /*
+ * Hostname on ftp connections
+ */
+ char *ftphost;
+
+ /*
+ * Data port on ftp connections
+ */
+ int port;
+
+
+ /*
+ * Load to file ?
+ */
+ int load_to_file;
+ int load_to_file_fd;
+
+} ClConnection_t;
+
+
+/*
+ * More data is to be read
+ */
+#define CL_CONTINUES 0
+
+/*
+ * Connection completed
+ */
+#define CL_COMPLETED 1
+
+/*
+ * Connection failed
+ */
+#define CL_FAILED 2
+
+/*
+ * Document already loaded (error)
+ */
+#define CL_ALREADY_LOADED 3
+
+
+/*
+ * Prototypes
+ */
+ClConnection_t *ClOpenConnection (char *address);
+
+struct HText *ClReadData (ClConnection_t * connection, int *how_done, int *fd);
+
+void ClSetOptions (ClConnection_t * connection, int argc, char *argv[]);
+
+void ClCloseConnection (ClConnection_t * connection);
+
+int ClCanLoadToFile (char *address);
+
+void ClSetFileNameForLoadingToFile (char *filename);
+
+int ClConnectionOnLoadToFileMode (ClConnection_t * connection);
+
+/*
+ * Globals
+ */
+
+extern int WWWErwiseStatus;
+extern ClConnection_t *WWWErwiseConnection;
+
+void WWWErwiseConnect ();
+void WWWErwiseSendCommand ();
+void WWWErwiseReadData ();
+void WWWErwiseParse ();
+
+
+/*
+ * Internals
+ */
+
+void WWWErwiseFtpUser ();
+void WWWErwiseFtpPass ();
+void WWWErwiseFtpPassive ();
+void WWWErwiseFtpGetPassive ();
+void WWWErwiseFtpGetCommand ();
+void WWWErwiseFtpDataChannel ();
+void WWWErwiseFtpCheckForError ();
+void WWWErwiseFtpBinary ();
+void WWWErwiseCheckParse ();
+void WWWErwiseSetPoll ();
+void WWWErwiseSetSelect ();
+void WWWErwiseTerminateIfLoadToFile ();
+
+int cl_start_connection ();
+
+/*
+ * Debug ...
+ */
+
+#define CL_DEBUG(a) printf a
--- /dev/null
+/*
+ * ClConnection.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Mon Apr 20 19:29:14 1992 tvr
+ * Last modified: Wed May 13 00:53:24 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include "Cl.h"
+
+#include "HTParse.h"
+#include "HTFormat.h"
+#include "HTAnchor.h"
+#include "tcp.h"
+
+#include "../HText/HText.h"
+
+extern HText_t *HtLocalText;
+
+
+/*
+ * Poll connecting until connection completes.
+ */
+void
+WWWErwiseConnect ()
+{
+ int status;
+
+ CL_DEBUG (("Poll connect\n"));
+
+ status = connect (WWWErwiseConnection->fd,
+ (struct sockaddr *) WWWErwiseConnection->addr,
+ WWWErwiseConnection->addr_size);
+ if (status < 0 && (errno != EISCONN))
+ {
+ if ((errno == EALREADY) || (errno == EINPROGRESS))
+ {
+ /*
+ * Would block
+ */
+ return;
+ }
+
+ CL_DEBUG (("Cannot connect(%d)\n", errno));
+
+ /*
+ * Cannot connect
+ */
+ WWWErwiseStatus = CL_FAILED;
+
+ return;
+ }
+
+ /*
+ * Connected. Get next function from the list of things to do.
+ * Also, stop polling.
+ */
+
+ free (WWWErwiseConnection->addr);
+
+ WWWErwiseConnection->addr = NULL;
+
+ WWWErwiseConnection->function++;
+}
+
+
+
+/*
+ * Instead of connect, this function is called. Store needed data to
+ * poll connecting later.
+ */
+int
+erwise_connect (fd, addr, size)
+ int fd;
+ struct sockaddr *addr;
+ int size;
+{
+ int status;
+
+ CL_DEBUG (("Try to Connect\n"));
+
+ status = connect (fd, addr, size);
+
+ if (status < 0)
+ {
+ switch (errno)
+ {
+ case EINPROGRESS:
+ case EISCONN:
+ case EALREADY:
+ break;
+
+ default:
+ CL_DEBUG (("Cannot connect (first try %d)\n", errno));
+ return -1;
+ }
+ }
+
+ /*
+ * Duplicate what to connect
+ */
+ WWWErwiseConnection->addr = (void *) malloc (size);
+
+ memcpy (WWWErwiseConnection->addr, addr, size);
+
+ WWWErwiseConnection->addr_size = size;
+
+ /*
+ * OK
+ */
+ return 0;
+}
+
+
+
+
+
+/*
+ * Send command to net
+ */
+
+void
+WWWErwiseSendCommand ()
+{
+ int status;
+
+ CL_DEBUG (("Send Command\n"));
+
+ status = NETWRITE (WWWErwiseConnection->fd,
+ WWWErwiseConnection->command,
+ (int) strlen (WWWErwiseConnection->command));
+
+ if (status == strlen (WWWErwiseConnection->command))
+ {
+ /*
+ * Succeeded
+ */
+ free (WWWErwiseConnection->command);
+ WWWErwiseConnection->command = 0;
+
+ WWWErwiseConnection->function++;
+
+ }
+ else if (status < 0)
+ {
+ /*
+ * Failed
+ */
+ CL_DEBUG (("SendCommand failed\n"));
+
+ WWWErwiseStatus = CL_FAILED;
+ return;
+ }
+ else
+ {
+ /*
+ * Partial read
+ */
+ char *tmp = WWWErwiseConnection->command;
+
+ WWWErwiseConnection->command = (char *) strdup (tmp + status);
+ free (tmp);
+ }
+}
+
+
+#define ERWISE_BLOCK 8192
+
+/*
+ * Read data until all data is read
+ */
+
+void
+WWWErwiseReadData ()
+{
+ char tmp[ERWISE_BLOCK];
+
+ int i;
+
+ i = read (WWWErwiseConnection->fd,
+ tmp,
+ ERWISE_BLOCK);
+
+ CL_DEBUG (("got %d bytes\n", i));
+
+ /*
+ * Append data to (memory) buffer or to file.
+ */
+ if (i > 0)
+ {
+
+ /*
+ * Load directly to file ?
+ */
+
+ if (WWWErwiseConnection->load_to_file)
+ {
+ int st;
+
+ st = write (WWWErwiseConnection->load_to_file_fd,
+ tmp,
+ i);
+
+ if (st != i)
+ {
+ WWWErwiseStatus = CL_FAILED;
+ }
+
+ return;
+ }
+
+ if (!WWWErwiseConnection->buffer_first)
+ {
+
+ WWWErwiseConnection->buffer_first =
+ WWWErwiseConnection->buffer_last =
+ (cl_data_t *) malloc (sizeof (cl_data_t));
+
+ memset (WWWErwiseConnection->buffer_first, 0, sizeof (cl_data_t));
+
+ WWWErwiseConnection->buffer_first->data =
+ WWWErwiseConnection->buffer_first->freeptr =
+ (void *) malloc (i);
+
+ WWWErwiseConnection->buffer_first->size = i;
+
+ memcpy (WWWErwiseConnection->buffer_first->data, tmp, i);
+
+ }
+ else
+ {
+
+ cl_data_t *p = (cl_data_t *) malloc (sizeof (cl_data_t));
+
+ memset (p, 0, sizeof (cl_data_t));
+
+ p->data = p->freeptr = (void *) malloc (i);
+
+ p->size = i;
+
+ memcpy (p->data, tmp, i);
+
+ p->prev = WWWErwiseConnection->buffer_last;
+
+ WWWErwiseConnection->buffer_last->next = p;
+
+ WWWErwiseConnection->buffer_last = p;
+ }
+
+ return;
+ }
+
+ if (i < 0 && (errno != EWOULDBLOCK))
+ {
+ CL_DEBUG (("ReadData failed\n"));
+ WWWErwiseStatus = CL_FAILED;
+ }
+
+ if (i == 0)
+ {
+ WWWErwiseConnection->function++;
+ return;
+ }
+}
+
+
+
+/*
+ * Parse data that has been read
+ */
+
+void
+WWWErwiseParse ()
+{
+ /*
+ * XXXXXX If saving to file, don't parse
+ */
+
+ HTParseFormat (WWWErwiseConnection->diag ? WWW_PLAINTEXT : WWW_HTML,
+ WWWErwiseConnection->anAnchor,
+ WWWErwiseConnection->fd);
+
+ (void) HTClose (WWWErwiseConnection->fd);
+
+ /*
+ * XXXXX free connection structure
+ */
+ WWWErwiseStatus = CL_COMPLETED;
+ WWWErwiseConnection->function++;
+}
+
+
+
+/*
+ * If we are loading to file, nothing else needs to be done ...
+ */
+void
+WWWErwiseTerminateIfLoadToFile ()
+{
+ if (WWWErwiseConnection->load_to_file)
+ {
+ HtLocalText = 0;
+
+ while (*WWWErwiseConnection->function)
+ {
+ WWWErwiseConnection->function++;
+ }
+
+ WWWErwiseStatus = CL_COMPLETED;
+
+ }
+ else
+ {
+ WWWErwiseConnection->function++;
+ }
+}
--- /dev/null
+/*
+ * ClFTP.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Sun Apr 19 22:42:51 1992 tvr
+ * Last modified: Mon May 11 23:30:15 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include "Cl.h"
+
+#include "HTParse.h"
+#include "HTUtils.h"
+#include "tcp.h"
+#include "HTAnchor.h"
+
+#define IPPORT_FTP 21
+
+/*
+ * Erwise's own ftp load function. Setup all things to be done
+ */
+
+PUBLIC int HTFTP_open_file_read
+ARGS2 (
+ char *, name,
+ HTParentAnchor *, anchor
+)
+{
+ int status;
+
+ /*
+ * Set up a list of things to do
+ */
+
+ {
+ static void (*functions[]) () =
+ {
+ WWWErwiseConnect,
+ WWWErwiseSetSelect,
+ WWWErwiseFtpGetCommand, /* get junk */
+
+ WWWErwiseSetPoll,
+ WWWErwiseFtpUser, /* Send user */
+ WWWErwiseSendCommand,
+ WWWErwiseSetSelect,
+ WWWErwiseFtpGetCommand,
+
+ WWWErwiseSetPoll,
+ WWWErwiseFtpPass, /* send pass */
+ WWWErwiseSendCommand,
+ WWWErwiseSetSelect,
+ WWWErwiseFtpGetCommand,
+
+ WWWErwiseSetPoll,
+ WWWErwiseFtpBinary, /* set binary mode */
+ WWWErwiseSendCommand,
+ WWWErwiseSetSelect,
+ WWWErwiseFtpGetCommand,
+
+ WWWErwiseSetPoll,
+ WWWErwiseFtpPassive, /* set passive mode */
+ WWWErwiseSendCommand,
+ WWWErwiseSetSelect,
+
+ WWWErwiseFtpGetPassive, /* Get reply and request a file */
+ WWWErwiseSetPoll,
+ WWWErwiseSendCommand,
+
+ WWWErwiseFtpDataChannel, /* make connection */
+ WWWErwiseConnect,
+
+ WWWErwiseFtpCheckForError,/* check for file not found etc ... */
+
+ WWWErwiseSetSelect, /* read data */
+ WWWErwiseReadData,
+
+ WWWErwiseSetPoll, /* parse stuff */
+ WWWErwiseTerminateIfLoadToFile,
+ WWWErwiseParse,
+ NULL,
+ };
+ WWWErwiseConnection->function = functions;
+ }
+
+ /*
+ * Set up information needed later
+ */
+
+ WWWErwiseConnection->ftphost = HTParse (name, "", PARSE_HOST);
+
+ WWWErwiseConnection->anAnchor = anchor;
+
+ /*
+ * Start connecting to data port
+ */
+
+ status = cl_start_connection (WWWErwiseConnection->ftphost,
+ WWWErwiseConnection,
+ IPPORT_FTP);
+
+ /*
+ * FTP mode on formatting is PLAINTEXT
+ */
+
+ WWWErwiseConnection->diag = 1;
+
+ return status;
+}
+
+
+/*
+ * Send misc commands to data flow
+ */
+
+void
+WWWErwiseFtpUser ()
+{
+ CL_DEBUG (("FTP: send user\n"));
+
+ WWWErwiseConnection->command = strdup ("USER ftp\r\n");
+
+ WWWErwiseConnection->function++;
+}
+
+void
+WWWErwiseFtpPass ()
+{
+ char tmp[8192], hostname[1024];
+
+ CL_DEBUG (("FTP: send pass\n"));
+
+ if (!gethostname (hostname, 1024))
+ {
+ strcpy (hostname, "noname.rupu");
+ }
+
+ sprintf (tmp, "PASS erwise@%s\r\n", hostname);
+
+ WWWErwiseConnection->command = strdup (tmp);
+
+ WWWErwiseConnection->function++;
+}
+
+void
+WWWErwiseFtpPassive ()
+{
+ CL_DEBUG (("FTP: send pasv\n"));
+
+ WWWErwiseConnection->command = strdup ("PASV\r\n");
+
+ WWWErwiseConnection->function++;
+}
+
+void
+WWWErwiseFtpBinary ()
+{
+ CL_DEBUG (("FTP: set binary\n"));
+
+ WWWErwiseConnection->command = strdup ("TYPE I\r\n");
+
+ WWWErwiseConnection->function++;
+}
+
+
+/*
+ * Get junk commands return when the are accomplished
+ */
+
+#define ERWISE_BL_SIZE 8192
+
+void
+WWWErwiseFtpGetCommand ()
+{
+ char tmp[ERWISE_BL_SIZE];
+
+ int i;
+
+ i = NETREAD (WWWErwiseConnection->fd, tmp, ERWISE_BL_SIZE);
+
+ if ((i == -1) && (errno == EWOULDBLOCK))
+ {
+ return;
+ }
+
+ CL_DEBUG (("FTP: got %s\n", tmp));
+
+ if ((tmp[0] < '2') || (tmp[0] > '3'))
+ {
+
+ WWWErwiseStatus = CL_FAILED;
+
+ return;
+
+ }
+
+ WWWErwiseConnection->function++;
+
+}
+/*
+ * Get return code from passive command
+ */
+
+void
+WWWErwiseFtpGetPassive ()
+{
+ char tmp[1024], *p;
+ int a1, a2, a3, a4;
+ int p1, p2, port;
+
+ int i;
+
+ i = NETREAD (WWWErwiseConnection->fd, tmp, 1024);
+
+ if ((i == -1) && (errno == EWOULDBLOCK))
+ {
+ return;
+ }
+
+ tmp[i] = 0;
+
+ CL_DEBUG (("FTP: got passive %s\n", tmp));
+
+ /*
+ * Get to the line which is reply from PASV command.
+ * Check for errors on the way.
+ */
+
+ p = tmp;
+
+ i = 1;
+
+ while (i)
+ {
+ if ((*p >= '0') && (*p <= '9'))
+ {
+ if (!strncmp ("227", p, 3))
+ {
+ i = 0;
+ continue;
+ }
+
+ if ((p[0] < '2') || (tmp[0] > '3'))
+ {
+ WWWErwiseStatus = CL_FAILED;
+ return;
+ }
+ }
+
+ /*
+ * Get next line
+ */
+ while (*p && (*p != '\n'))
+ p++;
+
+ p++;
+
+ if (!*p)
+ {
+ /*
+ * no line but no errors yet
+ */
+ return;
+ }
+ }
+
+ /*
+ * Correct line, get port
+ */
+
+ while (*p && (*p != '('))
+ p++;
+
+ if (!*p)
+ {
+ /*
+ * 227 but no address / port ??
+ */
+
+ WWWErwiseStatus = CL_FAILED;
+
+ return;
+ }
+
+ sscanf (p, "(%d,%d,%d,%d,%d,%d)", &a1, &a2, &a3, &a4, &p1, &p2);
+
+ port = p1 * 256 + p2;
+
+ printf ("ErwiseFTP: got connection to %d.%d.%d.%d on port %d\n",
+ a1, a2, a3, a4, port);
+
+ /*
+ * send receive command too
+ */
+
+ {
+ char *filename = HTParse (WWWErwiseConnection->address, "",
+ PARSE_PATH + PARSE_PUNCTUATION);
+
+ sprintf (tmp, "RETR %s\r\n", filename);
+
+ WWWErwiseConnection->command = strdup (tmp);
+ }
+
+ WWWErwiseConnection->port = port;
+
+ WWWErwiseConnection->function++;
+}
+
+
+/*
+ * Make data channel connection
+ */
+void
+WWWErwiseFtpDataChannel ()
+{
+ /*
+ * Set data flow port to secondary so that it can be closed properly
+ */
+
+ WWWErwiseConnection->secondary_fd = WWWErwiseConnection->fd;
+
+ cl_start_connection (WWWErwiseConnection->ftphost,
+ WWWErwiseConnection,
+ WWWErwiseConnection->port);
+
+ WWWErwiseConnection->function++;
+}
+
+
+
+/*
+ * Start connection. Make sure it is nonblocking one.
+ */
+
+int
+cl_start_connection (host, connection, port)
+ char *host;
+ ClConnection_t *connection;
+ int port;
+{
+ /*
+ * Code partly from get_connection()
+ */
+
+ int s;
+
+ struct hostent *phost; /* Pointer to host -- See netdb.h */
+ struct sockaddr_in soc_address; /* Binary network address */
+ struct sockaddr_in *sin = &soc_address;
+
+/* Set up defaults:
+*/
+ sin->sin_family = AF_INET; /* Family, host order */
+ sin->sin_port = htons (port);
+
+/* Get node name:
+*/
+ {
+ if (*host >= '0' && *host <= '9')
+ { /* Numeric node address: */
+ sin->sin_addr.s_addr = inet_addr (host); /* See arpa/inet.h */
+
+ }
+ else
+ { /* Alphanumeric node name: */
+ phost = gethostbyname (host); /* See netdb.h */
+ if (!phost)
+ {
+ if (TRACE)
+ printf (
+ "FTP: Can't find internet node name `%s'.\n",
+ host);
+
+ WWWErwiseStatus = CL_FAILED;
+
+ return -1;
+ }
+ memcpy (&sin->sin_addr, phost->h_addr, phost->h_length);
+ }
+
+ if (TRACE)
+ printf (
+ "FTP: Parsed remote address as port %d, inet %d.%d.%d.%d\n",
+ (unsigned int) ntohs (sin->sin_port),
+ (int) *((unsigned char *) (&sin->sin_addr) + 0),
+ (int) *((unsigned char *) (&sin->sin_addr) + 1),
+ (int) *((unsigned char *) (&sin->sin_addr) + 2),
+ (int) *((unsigned char *) (&sin->sin_addr) + 3));
+ } /* scope of p1 */
+
+
+ {
+ int status;
+
+ s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (s < 0)
+ {
+ WWWErwiseStatus = CL_FAILED;
+
+ return -1;
+ }
+
+ connection->fd = s;
+
+ /*
+ * Must NOT select connection now. Must poll.
+ */
+ connection->select_fd = 0;
+
+ (void) fcntl (s, F_SETFL, O_NONBLOCK);
+ (void) fcntl (s, F_SETFL, FNDELAY);
+
+ status = erwise_connect (s,
+ (struct sockaddr *) & soc_address,
+ sizeof (soc_address));
+ }
+
+ /*
+ * everything done
+ */
+
+ return s;
+}
+
+
+
+/*
+ * Check for errors when retr is sent
+ */
+
+void
+WWWErwiseFtpCheckForError ()
+{
+ fd_set readfds;
+ fd_set exceptionfds;
+
+ struct timeval tv;
+
+ int fd, fd2;
+
+ fd = WWWErwiseConnection->fd;
+ fd2 = WWWErwiseConnection->secondary_fd;
+
+ tv.tv_sec = tv.tv_usec = 0;
+
+ FD_ZERO (&readfds);
+ FD_SET (fd, &readfds);
+ FD_SET (fd2, &readfds);
+
+ FD_ZERO (&exceptionfds);
+ FD_SET (fd, &exceptionfds);
+ FD_SET (fd2, &exceptionfds);
+
+ select ((fd > fd2 ? fd : fd2) + 1, &readfds, NULL, &exceptionfds, &tv);
+
+ /*
+ * Error on either data or command channel
+ */
+ if (FD_ISSET (fd, &exceptionfds) || FD_ISSET (fd2, &exceptionfds))
+ {
+
+ WWWErwiseStatus = CL_FAILED;
+
+ return;
+ }
+
+ /*
+ * Data is flowing (OK)
+ */
+ if (FD_ISSET (fd, &readfds))
+ {
+
+ WWWErwiseConnection->function++;
+
+ return;
+ }
+
+ /*
+ * Anything here is considered an error
+ */
+ if (FD_ISSET (fd2, &readfds))
+ {
+
+ WWWErwiseStatus = CL_FAILED;
+
+ return;
+ }
+}
--- /dev/null
+/*
+ * ClHTTP.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Fri Apr 17 23:43:01 1992 tvr
+ * Last modified: Mon May 11 23:29:10 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include "Cl.h"
+
+#include "HTParse.h"
+#include "HTFormat.h"
+#include "HTAnchor.h"
+#include "tcp.h"
+
+
+
+/*
+ * We want that loading won't kill the whole f*king client.
+ *
+ * This is a kludge ;)
+ */
+
+PUBLIC int HTLoadHTTP
+ARGS4 (CONST char *, arg,
+ CONST char *, gate,
+ HTAnchor *, anAnchor,
+ int, diag)
+{
+ /*
+ * Most code from old loading function
+ */
+
+ int s;
+ int status;
+ char *command;
+
+ struct sockaddr_in soc_address; /* Binary network address */
+ struct sockaddr_in *sin = &soc_address;
+
+ if (!arg)
+ return -3; /* Bad if no name sepcified */
+ if (!*arg)
+ return -2; /* Bad if name had zero length */
+
+/* Set up defaults:
+*/
+ sin->sin_family = AF_INET; /* Family, host order */
+ sin->sin_port = htons (TCP_PORT); /* Default: new port, */
+
+ if (TRACE)
+ {
+ if (gate)
+ fprintf (stderr,
+ "HTTPAccess: Using gateway %s for %s\n", gate, arg);
+ else
+ fprintf (stderr, "HTTPAccess: Direct access for %s\n", arg);
+ }
+
+/* Get node name and optional port number:
+*/
+ {
+ char *p1 = HTParse (gate ? gate : arg, "", PARSE_HOST);
+ HTParseInet (sin, p1);
+ free (p1);
+ }
+
+
+/* Now, let's get a socket set up from the server for the sgml data:
+*/
+ s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ (void) fcntl (s, F_SETFL, O_NONBLOCK);
+ (void) fcntl (s, F_SETFL, FNDELAY);
+
+ /*
+ * Now. Do first attempt to connect.
+ */
+ status = erwise_connect (s,
+ (struct sockaddr *) & soc_address,
+ sizeof (soc_address));
+
+ if (s < 0)
+ {
+ /*
+ * Fail
+ */
+ /*free(command);*/
+ return -1;
+ }
+
+ if (TRACE)
+ printf ("HTTP connected, socket %d\n", s);
+
+/* Ask that node for the document,
+** omitting the host name & anchor if not gatewayed.
+*/
+ if (gate)
+ {
+ command = malloc (4 + strlen (arg) + 1 + 1);
+ strcpy (command, "GET ");
+ strcat (command, arg);
+ }
+ else
+ { /* not gatewayed */
+ char *p1 = HTParse (arg, "", PARSE_PATH | PARSE_PUNCTUATION);
+ command = malloc (4 + strlen (p1) + 1 + 1);
+ strcpy (command, "GET ");
+ strcat (command, p1);
+ free (p1);
+ }
+ strcat (command, "\r\n"); /* Include CR for telnet compat. */
+
+
+ if (TRACE)
+ printf ("HTTP writing command `%s' to socket %d\n", command, s);
+
+#ifdef NOT_ASCII
+ {
+ char *p;
+ for (p = command; *p; p++)
+ {
+ *p = TOASCII (*p);
+ }
+ }
+#endif
+
+ /*
+ * Ok. Everything is now set up. Set functionpointers so that
+ * the rest of loading works ok.
+ */
+
+ {
+ static void (*functions[]) () =
+ {
+ WWWErwiseConnect,
+ WWWErwiseSendCommand,
+ WWWErwiseSetSelect,
+ WWWErwiseReadData,
+ WWWErwiseSetPoll,
+ WWWErwiseTerminateIfLoadToFile,
+ WWWErwiseParse,
+ NULL,
+ };
+ WWWErwiseConnection->function = functions;
+ }
+
+ WWWErwiseConnection->command = command;
+
+ WWWErwiseConnection->diag = diag;
+
+ WWWErwiseConnection->anAnchor = anAnchor;
+
+ /*
+ * Cheat HTOpen()
+ */
+ return s;
+}
--- /dev/null
+/*
+ * ClMisc.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Mon Apr 20 19:27:04 1992 tvr
+ * Last modified: Mon Apr 20 19:48:47 1992 tvr
+ *
+ */
+
+#include "Cl.h"
+
+
+/*
+ * Set mode to poll or to select connection
+ */
+
+void
+WWWErwiseSetPoll ()
+{
+ CL_DEBUG (("SetPoll\n"));
+
+ WWWErwiseConnection->select_fd = 0;
+
+ WWWErwiseConnection->function++;
+}
+
+void
+WWWErwiseSetSelect ()
+{
+ CL_DEBUG (("SetSelect\n"));
+
+ WWWErwiseConnection->select_fd = WWWErwiseConnection->fd;
+
+ WWWErwiseConnection->function++;
+}
--- /dev/null
+#
+#
+#
+
+#define IHavesubdirs
+#define PassCDebugFlags
+
+ OBJS = Cl.o ClHTTP.o ClFTP.o ClMisc.o ClConnection.o
+ SRCS = Cl.c ClHTTP.c ClFTP.c ClMisc.c ClConnection.c
+ SUBDIRS = WWWLibrary
+ DEFINES = -I$(SUBDIRS)
+
+NormalLibraryTarget(Cl, $(OBJS))
+
+MakeSubdirs($(SUBDIRS))
+MakefileSubdirs($(SUBDIRS))
+DependTarget()
+DependSubdirs($(SUBDIRS))
+
+
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a10826>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../.
+ CURRENT_DIR = ./Cl
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+
+ OBJS = Cl.o ClHTTP.o ClFTP.o ClMisc.o ClConnection.o
+ SRCS = Cl.c ClHTTP.c ClFTP.c ClMisc.c ClConnection.c
+ SUBDIRS = WWWLibrary
+ DEFINES = -I$(SUBDIRS)
+
+all:: libCl.a
+
+libCl.a: $(OBJS)
+ $(RM) $@
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+all::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "making" all "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) all); \
+ done
+
+Makefiles::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ echo "making Makefiles in $(CURRENT_DIR)/$$i..."; \
+ case "$$i" in \
+ ./?*/?*/?*/?*) newtop=../../../../ sub=subsubsubsub;; \
+ ./?*/?*/?*) newtop=../../../ sub=subsubsub;; \
+ ./?*/?*) newtop=../../ sub=subsub;; \
+ ./?*) newtop=../ sub=sub;; \
+ */?*/?*/?*) newtop=../../../../ sub=subsubsubsub;; \
+ */?*/?*) newtop=../../../ sub=subsubsub;; \
+ */?*) newtop=../../ sub=subsub;; \
+ *) newtop=../ sub=sub;; \
+ esac; \
+ case "$(TOP)" in \
+ /?*) newtop= upprefix= ;; \
+ *) upprefix=../ ;; \
+ esac; \
+ $(MAKE) $${sub}dirMakefiles UPPREFIX=$$upprefix NEWTOP=$$newtop \
+ MAKEFILE_SUBDIR=$$i NEW_CURRENT_DIR=$(CURRENT_DIR)/$$i;\
+ done
+
+subdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+subsubdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+subsubsubdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+subsubsubsubdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+depend::
+ $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+depend::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "depending" "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) depend); \
+ done
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+/* Access Manager HTAccess.c
+** ==============
+*/
+
+
+#include "HTParse.h"
+#include "HTUtils.h"
+#include "WWW.h"
+#include "HTAnchor.h"
+#include "HTFTP.h"
+#include "HTTP.h"
+#include "HTFile.h"
+#include <errno.h>
+#include <stdio.h>
+
+#include "tcp.h"
+#include "HText.h"
+#include "HTNews.h"
+#include "HTGopher.h"
+#include "HTBrowse.h" /* Need global HTClientHost */
+
+#include "HTAccess.h"
+
+#ifdef ERWISE
+#include "Cl.h"
+#endif
+
+#define HT_NO_DATA -9999
+
+PUBLIC int HTDiag = 0; /* Diagnostics: load source as text */
+
+/* Telnet or "rlogin" access
+** -------------------------
+*/
+PRIVATE int remote_session ARGS2(char *, access, char *, host)
+{
+ char * user = host;
+ char * hostname = strchr(host, '@');
+ char * port = strchr(host, ':');
+ char command[256];
+ BOOL rlogin = strcmp(access, "rlogin");
+
+ if (hostname) {
+ *hostname++ = 0; /* Split */
+ } else {
+ hostname = host;
+ user = 0; /* No user specified */
+ }
+ if (port) *port++ = 0; /* Split */
+
+#ifdef unix
+ sprintf(command, "%s%s%s %s %s", access,
+ user ? " -l " : "",
+ user ? user : "",
+ hostname,
+ port ? port : "");
+ if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
+ system(command);
+ return HT_NO_DATA; /* Ok - it was done but no data */
+#define TELNET_DONE
+#endif
+
+#ifdef MULTINET /* VMS varieties */
+ if (!rlogin) { /* telnet */
+ if (user) printf("When you are connected, log in as %s\n", user);
+ sprintf(command, "TELNET %s%s %s",
+ port ? "/PORT=" : "",
+ port ? port : "",
+ hostname);
+ } else {
+ sprintf(command, "RLOGIN%s%s%s%s %s", access,
+ user ? "/USERNAME=" : "",
+ user ? user : "",
+ port ? "/PORT=" : "",
+ port ? port : "",
+ hostname);
+ }
+ if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
+ system(command);
+ return HT_NO_DATA; /* Ok - it was done but no data */
+#define TELNET_DONE
+#endif
+
+#ifdef UCX
+#define SIMPLE_TELNET
+#endif
+#ifdef VM
+#define SIMPLE_TELNET
+#endif
+#ifdef SIMPLE_TELNET
+ if (!rlogin) { /* telnet only */
+ if (user) printf("When you are connected, log in as %s\n", user);
+ sprintf(command, "TELNET %s", /* @@ Bug: port ignored */
+ hostname);
+ if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
+ system(command);
+ return HT_NO_DATA; /* Ok - it was done but no data */
+ }
+#endif
+
+#ifndef TELNET_DONE
+ fprintf(stderr,
+ "Sorry, this browser was compiled without the %s access option.\n",
+ access);
+ fprintf(stderr,
+ "\nTo access the information you must %s to %s", access, hostname);
+ if (port) fprintf(stderr," (port %s)", port);
+ if (user) fprintf(stderr," logging in with username %s", user);
+ fprintf(stderr, ".\n");
+ return -1;
+#endif
+}
+
+/* Open a file descriptor for a document
+** -------------------------------------
+**
+** On entry,
+** addr must point to the fully qualified hypertext reference.
+**
+** On exit,
+** returns <0 Error has occured.
+** >=0 Value of file descriptor or socket to be used
+** to read data.
+** *pFormat Set to the format of the file, if known.
+** (See WWW.h)
+**
+*/
+PRIVATE int HTOpen ARGS3(
+ CONST char *,addr1,
+ HTFormat *,pFormat,
+ HTParentAnchor *,anchor)
+{
+ char * access=0; /* Name of access method */
+ int status;
+ char * gateway;
+ char * gateway_parameter;
+ char * addr = (char *)malloc(strlen(addr1)+1);
+
+ if (addr == NULL) outofmem(__FILE__, "HTOpen");
+ strcpy(addr, addr1); /* Copy to play with */
+
+ access = HTParse(addr, "file:", PARSE_ACCESS);
+
+ gateway_parameter = (char *)malloc(strlen(access)+20);
+ if (gateway_parameter == NULL) outofmem(__FILE__, "HTOpen");
+ strcpy(gateway_parameter, "WWW_");
+ strcat(gateway_parameter, access);
+ strcat(gateway_parameter, "_GATEWAY");
+ gateway = getenv(gateway_parameter);
+ free(gateway_parameter);
+
+ if (gateway) {
+ status = HTLoadHTTP(addr, gateway, anchor, HTDiag);
+#ifndef CURSES
+ if (status<0) fprintf(stderr, /* For simple users */
+ "Cannot connect to information gateway %s\n", gateway);
+#endif
+ } else if (0==strcmp(access, "http")) {
+ status = HTLoadHTTP(addr, 0, anchor, HTDiag);
+#ifndef CURSES
+ if (status<0) fprintf(stderr, /* For simple users */
+ "Cannot connect to information server.\n");
+#endif
+ } else if (0==strcmp(access, "file")) {
+ status = HTOpenFile(addr, pFormat, anchor);
+
+ } else if (0==strcmp(access, "news")) {
+ status = HTLoadNews(addr, anchor, HTDiag);
+ if (status>0) status = HT_LOADED;
+
+ } else if (0==strcmp(access, "gopher")) {
+ status = HTLoadGopher(addr, anchor, HTDiag);
+ if (status>0) status = HT_LOADED;
+
+ } else if (!strcmp(access, "telnet") || /* TELNET */
+ !strcmp(access, "rlogin")) { /* RLOGIN */
+ char * host = HTParse(addr, "", PARSE_HOST);
+ remote_session(access, host);
+ free(host);
+
+ } else if (0==strcmp(access, "wais")) {
+ user_message(
+"HTAccess: For WAIS access set WWW_wais_GATEWAY to gateway address.\n");
+ } else {
+
+ user_message(
+ "HTAccess: name scheme `%s' unknown by this browser version.\n",
+ access);
+ status = -1;
+ }
+ free(access);
+ free(addr);
+ return status;
+}
+
+
+/* Close socket opened for reading a file
+** --------------------------------------
+**
+*/
+#ifdef ERWISE
+PUBLIC int HTClose ARGS1(int,soc)
+#else
+PRIVATE int HTClose ARGS1(int,soc)
+#endif
+{
+ return HTFTP_close_file(soc);
+}
+
+
+/* Load a document
+** ---------------
+**
+** On Entry,
+** anchor is the node_anchor for the document
+** full_address The address of the file to be accessed.
+**
+** On Exit,
+** returns YES Success in opening file
+** NO Failure
+**
+*/
+
+PUBLIC BOOL HTLoadDocument ARGS3(HTParentAnchor *,anchor,
+ CONST char *,full_address,
+ BOOL, filter)
+
+{
+ int new_file_number;
+ HTFormat format;
+ HText * text;
+
+ if (text=(HText *)HTAnchor_document(anchor)) { /* Already loaded */
+#ifdef ERWISE
+ /*
+ * do NOT do this
+ */
+ fprintf(stderr, "HTBrowse: Document already in memory.\n");
+
+ WWWErwiseStatus = CL_ALREADY_LOADED;
+
+ return YES;
+#else
+ if (TRACE) fprintf(stderr, "HTBrowse: Document already in memory.\n");
+ HText_select(text);
+ return YES;
+#endif
+ }
+
+#ifdef CURSES
+ prompt_set("Retrieving document...");
+#endif
+ if (filter) {
+ new_file_number = 0;
+ format = WWW_HTML;
+ } else {
+ new_file_number = HTOpen(full_address, &format, anchor);
+ }
+/* Log the access if necessary
+*/
+ if (logfile) {
+ time_t theTime;
+ time(&theTime);
+ fprintf(logfile, "%24.24s %s %s %s\n",
+ ctime(&theTime),
+ HTClientHost ? HTClientHost : "local",
+ new_file_number<0 ? "FAIL" : "GET",
+ full_address);
+ fflush(logfile); /* Actually update it on disk */
+ if (TRACE) fprintf(stderr, "Log: %24.24s %s %s %s\n",
+ ctime(&theTime),
+ HTClientHost ? HTClientHost : "local",
+ new_file_number<0 ? "FAIL" : "GET",
+ full_address);
+ }
+
+
+ if (new_file_number == HT_LOADED) {
+ if (TRACE) {
+ printf("HTAccess: `%s' has been accessed.\n",
+ full_address);
+ }
+#ifdef ERWISE
+ WWWErwiseStatus = CL_COMPLETED;
+ WWWErwiseConnection->fd = -1;
+#endif
+ return YES;
+ }
+
+ if (new_file_number == HT_NO_DATA) {
+ if (TRACE) {
+ printf("HTAccess: `%s' has been accessed, No data left.\n",
+ full_address);
+ }
+#ifdef ERWISE
+ WWWErwiseStatus = CL_FAILED;
+#endif
+ return NO;
+ }
+
+ if (new_file_number<0) { /* Failure in accessing a file */
+
+#ifdef CURSES
+ user_message("Can't access `%s'", full_address);
+#else
+ printf("\nWWW: Can't access `%s'\n", full_address);
+#endif
+#ifdef ERWISE
+ WWWErwiseStatus = CL_FAILED;
+ return NO;
+#endif
+ if (!HTMainText){
+ exit(2); /* Can't get first page */
+ } else {
+ return NO;
+ }
+ }
+
+ if (TRACE) {
+ printf("WWW: Opened `%s' as fd %d\n",
+ full_address, new_file_number);
+ }
+
+#ifdef ERWISE
+ /*
+ * Do the rest elsewhere (if this connection can be loaded
+ * using non blocking transfer)
+ */
+
+ if(WWWErwiseConnection->function) {
+ WWWErwiseConnection->fd = new_file_number;
+
+ return YES;
+ }
+#endif
+
+ HTParseFormat(HTDiag ? WWW_PLAINTEXT : format, anchor, new_file_number);
+
+ HTClose(new_file_number);
+
+ return YES;
+
+} /* HTLoadDocument */
+
+
+/* Load a document from absolute name
+** ---------------
+**
+** On Entry,
+** relative_name The relative address of the file to be accessed.
+**
+** On Exit,
+** returns YES Success in opening file
+** NO Failure
+**
+**
+*/
+
+PUBLIC BOOL HTLoadAbsolute ARGS2(CONST char *,addr, BOOL, filter)
+{
+ return HTLoadDocument(
+ HTAnchor_parent(HTAnchor_findAddress(addr)),
+ addr, filter);
+}
+
+
+/* Load a document from relative name
+** ---------------
+**
+** On Entry,
+** relative_name The relative address of the file to be accessed.
+**
+** On Exit,
+** returns YES Success in opening file
+** NO Failure
+**
+**
+*/
+
+PUBLIC BOOL HTLoadRelative ARGS1(CONST char *,relative_name)
+{
+ char * full_address = 0;
+ BOOL result;
+ char * mycopy = 0;
+ char * stripped = 0;
+ char * current_address =
+ HTAnchor_address((HTAnchor*)HTMainAnchor);
+
+ StrAllocCopy(mycopy, relative_name);
+
+ stripped = HTStrip(mycopy);
+ full_address = HTParse(stripped,
+ current_address,
+ PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
+ result = HTLoadAbsolute(full_address, NO);
+ free(full_address);
+ free(current_address);
+ return result;
+}
+
+
+/* Load if necessary, and select an anchor
+** --------------------------------------
+**
+** On Entry,
+** destination The child or parenet anchor to be loaded.
+**
+** On Exit,
+** returns YES Success
+** NO Failure
+**
+*/
+
+PUBLIC BOOL HTLoadAnchor ARGS1(HTAnchor *,destination)
+{
+ HTParentAnchor * parent;
+
+ if (!destination) return NO; /* No link */
+
+ parent = HTAnchor_parent(destination);
+
+ if ( /* HTAnchor_document (parent) == NULL) { */ parent != HTMainAnchor) { /* If not already loaded */
+ BOOL result;
+ char * address = HTAnchor_address((HTAnchor*) parent);
+ result = HTLoadDocument(parent, address, NO);
+ free(address);
+ if (!result) return NO;
+ }
+
+ if (destination != (HTAnchor *)parent) /* If child anchor */
+ HText_selectAnchor(HTMainText,
+ (HTChildAnchor*)destination); /* Double display? @@ */
+
+ return YES;
+
+} /* HTLoadAnchor */
+
+
+#ifndef ERWISE
+/* Search
+** ------
+** Performs a keyword search on word given by the user. Adds the keyword to
+** the end of the current address and attempts to open the new address.
+**
+** On Entry,
+** *keywords space-separated keyword list or similar search list
+** HTMainAnchor global must be valid.
+*/
+
+PUBLIC BOOL HTSearch ARGS1(char *,keywords)
+
+{
+ char * p; /* pointer to first non-blank */
+ char * q, *s;
+ char * address = HTAnchor_address((HTAnchor*)HTMainAnchor);
+ BOOL result;
+
+ p = HTStrip(keywords);
+ for (q=p; *q; q++)
+ if (WHITE(*q)) {
+ *q = '+';
+ }
+
+ s=strchr(address, '?'); /* Find old search string */
+ if (s) *s = 0; /* Chop old search off */
+
+ StrAllocCat(address, "?");
+ StrAllocCat(address, p);
+
+ result = HTLoadRelative(address);
+ free(address);
+ return result;
+
+}
+#else /* ERWISE */
+
+/*
+ * Why everything is so hardcoded ????
+ */
+
+PUBLIC char *HTSearchAddress ARGS1(char *,keywords)
+{
+ char * p; /* pointer to first non-blank */
+ char * q, *s;
+ char * address = HTAnchor_address((HTAnchor*)HTMainAnchor);
+ char * current_address;
+ char * mycopy;
+ char * stripped;
+ char * full_address;
+
+
+ p = HTStrip(keywords);
+ for (q=p; *q; q++)
+ if (WHITE(*q)) {
+ *q = '+';
+ }
+
+ s=strchr(address, '?'); /* Find old search string */
+ if (s) *s = 0; /* Chop old search off */
+
+ StrAllocCat(address, "?");
+ StrAllocCat(address, p);
+
+ StrAllocCopy(mycopy, address);
+
+ current_address = HTAnchor_address((HTAnchor*)HTMainAnchor);
+
+ stripped = HTStrip(mycopy);
+
+ full_address = HTParse(stripped,
+ current_address,
+ PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
+
+ free(address);
+
+ return full_address;
+}
+
+#endif /* ERWISE */
+
--- /dev/null
+/* Access Manager HTAccess.h
+** ==============
+*/
+
+#ifndef HTACCESS_H
+#define HTACCESS_H
+
+/* Flag to allow source to be loaded as text
+*/
+extern int HTDiag;
+
+/* Open a file descriptor for a document
+** -------------------------------------
+**
+** On entry,
+** addr must point to the fully qualified hypertext reference.
+**
+** On exit,
+** returns <0 Error has occured.
+** >=0 Value of file descriptor or socket to be used
+** to read data.
+** *pFormat Set to the format of the file, if known.
+** (See WWW.h)
+**
+** No longer public -- only used internally.
+*/
+/* extern int HTOpen PARAMS((CONST char * addr, HTFormat * format)); */
+
+
+/* Close socket opened for reading a file
+** --------------------------------------
+**
+*/
+extern int HTClose PARAMS((int soc));
+
+
+/* Load a document
+** ---------------
+**
+** On Entry,
+** anchor is the node_anchor for the document
+** full_address The address of the file to be accessed.
+**
+** On Exit,
+** returns YES Success in opening file
+** NO Failure
+**
+*/
+
+extern BOOL HTLoadDocument PARAMS((HTParentAnchor * anchor,
+ CONST char * full_address,
+ BOOL filter));
+
+
+
+/* Load a document from relative name
+** ---------------
+**
+** On Entry,
+** relative_name The relative address of the file to be accessed.
+**
+** On Exit,
+** returns YES Success in opening file
+** NO Failure
+**
+**
+*/
+
+extern BOOL HTLoadRelative PARAMS((CONST char * relative_name));
+
+/* Load a document from relative name
+** ---------------
+**
+** On Entry,
+** relative_name The relative address of the file to be accessed.
+**
+** On Exit,
+** returns YES Success in opening file
+** NO Failure
+**
+**
+*/
+
+extern BOOL HTLoadAbsolute PARAMS((CONST char * addr, BOOL filter));
+
+
+/* Load if necessary, and select an anchor
+** --------------------------------------
+**
+** On Entry,
+** destination The child or parenet anchor to be loaded.
+**
+** On Exit,
+** returns YES Success
+** NO Failure
+**
+*/
+
+extern BOOL HTLoadAnchor PARAMS((HTAnchor * destination));
+
+/* Search
+** ------
+** Performs a keyword search on word given by the user. Adds the keyword to
+** the end of the current address and attempts to open the new address.
+**
+** On Entry,
+** *keywords space-separated keyword list or similar search list
+** HTMainAnchor global must be valid.
+*/
+
+extern BOOL HTSearch PARAMS((char * keywords));
+
+
+#endif /* HTACCESS_H */
--- /dev/null
+/* Hypertext "Anchor" Object HTAnchor.c
+** ==========================
+**
+** An anchor represents a region of a hypertext document which is linked to
+** another anchor in the same or a different document.
+**
+** History
+**
+** Nov 1990 Written in Objective-C for the NeXT browser (TBL)
+** 24-Oct-1991 (JFG), written in C, browser-independant
+** 21-Nov-1991 (JFG), first complete version
+**
+** (c) Copyright CERN 1991 - See Copyright.html
+*/
+
+#define HASH_SIZE 101 /* Arbitrary prime. Memory/speed tradeoff */
+
+#include <ctype.h>
+#include "tcp.h"
+#include "HTAnchor.h"
+#include "HTUtils.h"
+#include "HTParse.h"
+
+typedef struct _HyperDoc Hyperdoc;
+#ifdef vms
+struct _HyperDoc {
+ int junk; /* VMS cannot handle pointers to undefined structs */
+};
+#endif
+
+PRIVATE HTList **adult_table=0; /* Point to table of lists of all parents */
+
+/* Creation Methods
+** ================
+**
+** Do not use "new" by itself outside this module. In order to enforce
+** consistency, we insist that you furnish more information about the
+** anchor you are creating : use newWithParent or newWithAddress.
+*/
+
+PRIVATE HTParentAnchor * HTParentAnchor_new
+ NOARGS
+{
+ HTParentAnchor *newAnchor =
+ (HTParentAnchor *) calloc (1, sizeof (HTParentAnchor)); /* zero-filled */
+ newAnchor->parent = newAnchor;
+ return newAnchor;
+}
+
+PRIVATE HTChildAnchor * HTChildAnchor_new
+ NOARGS
+{
+ return (HTChildAnchor *) calloc (1, sizeof (HTChildAnchor)); /* zero-filled */
+}
+
+
+/* Case insensitive string comparison
+** ----------------------------------
+** On entry,
+** s Points to one string, null terminated
+** t points to the other.
+** On exit,
+** returns YES if the strings are equivalent ignoring case
+** NO if they differ in more than their case.
+*/
+
+PRIVATE BOOL equivalent
+ ARGS2 (CONST char *,s, CONST char *,t)
+{
+ if (s && t) { /* Make sure they point to something */
+ for ( ; *s && *t ; s++, t++) {
+ if (TOUPPER(*s) != TOUPPER(*t))
+ return NO;
+ }
+ return TOUPPER(*s) == TOUPPER(*t);
+ } else
+ return s == t; /* Two NULLs are equivalent, aren't they ? */
+}
+
+
+/* Create new or find old sub-anchor
+** ---------------------------------
+**
+** This one is for a new anchor being edited into an existing
+** document. The parent anchor must already exist.
+*/
+
+PRIVATE HTChildAnchor * HTAnchor_findChild
+ ARGS2 (HTParentAnchor *,parent, CONST char *,tag)
+{
+ HTChildAnchor *child;
+ HTList *kids;
+
+ if (! parent) {
+ if (TRACE) printf ("HTAnchor_findChild called with NULL parent.\n");
+ return NULL;
+ }
+ if (kids = parent->children) { /* parent has children : search them */
+ if (tag && *tag) { /* TBL */
+ while (child = HTList_nextObject (kids)) {
+ if (equivalent(child->tag, tag)) { /* Case sensitive 920226 */
+ if (TRACE) printf (
+ "Child anchor %p of parent %p with name `%s' already exists.\n",
+ child, parent, tag);
+ return child;
+ }
+ }
+ } /* end if tag is void */
+ } else /* parent doesn't have any children yet : create family */
+ parent->children = HTList_new ();
+
+ child = HTChildAnchor_new ();
+ if (TRACE) printf("new Anchor %p named `%s' is child of %p\n",
+ child, (int)tag ? tag : (CONST char *)"" , parent); /* int for apollo */
+ HTList_addObject (parent->children, child);
+ child->parent = parent;
+ StrAllocCopy(child->tag, tag);
+ return child;
+}
+
+
+/* Create or find a child anchor with a possible link
+** --------------------------------------------------
+**
+** Create new anchor with a given parent and possibly
+** a name, and possibly a link to a _relatively_ named anchor.
+** (Code originally in ParseHTML.h)
+*/
+PUBLIC HTChildAnchor * HTAnchor_findChildAndLink
+ ARGS4(
+ HTParentAnchor *,parent, /* May not be 0 */
+ CONST char *,tag, /* May be "" or 0 */
+ CONST char *,href, /* May be "" or 0 */
+ HTLinkType *,ltype /* May be 0 */
+ )
+{
+ HTChildAnchor * child = HTAnchor_findChild(parent, tag);
+ if (href && *href) {
+ char * parsed_address;
+ HTAnchor * dest;
+ parsed_address = HTParse(href, HTAnchor_address((HTAnchor *) parent),
+ PARSE_ALL);
+ dest = HTAnchor_findAddress(parsed_address);
+ HTAnchor_link((HTAnchor *) child, dest, ltype);
+ free(parsed_address);
+ }
+ return child;
+}
+
+
+/* Create new or find old named anchor
+** -----------------------------------
+**
+** This one is for a reference which is found in a document, and might
+** not be already loaded.
+** Note: You are not guaranteed a new anchor -- you might get an old one,
+** like with fonts.
+*/
+
+HTAnchor * HTAnchor_findAddress
+ ARGS1 (CONST char *,address)
+{
+ char *tag = HTParse (address, "", PARSE_ANCHOR); /* Anchor tag specified ? */
+
+ /* If the address represents a sub-anchor, we recursively load its parent,
+ then we create a child anchor within that document. */
+ if (*tag) {
+ char *docAddress = HTParse(address, "", PARSE_ACCESS | PARSE_HOST |
+ PARSE_PATH | PARSE_PUNCTUATION);
+ HTParentAnchor * foundParent =
+ (HTParentAnchor *) HTAnchor_findAddress (docAddress);
+ HTChildAnchor * foundAnchor = HTAnchor_findChild (foundParent, tag);
+ free (docAddress);
+ free (tag);
+ return (HTAnchor *) foundAnchor;
+ }
+
+ else { /* If the address has no anchor tag, check whether we have this node */
+ int hash;
+ CONST char *p;
+ HTList * adults;
+ HTList *grownups;
+ HTParentAnchor * foundAnchor;
+
+ free (tag);
+
+ /* Select list from hash table */
+ for(p=address, hash=0; *p; p++) hash = (hash * 3 + *p) % HASH_SIZE;
+ if (!adult_table)
+ adult_table = (HTList**) calloc(HASH_SIZE, sizeof(HTList*));
+ if (!adult_table[hash]) adult_table[hash] = HTList_new();
+ adults = adult_table[hash];
+
+ /* Search list for anchor */
+ grownups = adults;
+ while (foundAnchor = HTList_nextObject (grownups)) {
+ if (equivalent(foundAnchor->address, address)) {
+ if (TRACE) printf("Anchor %p with address `%s' already exists.\n",
+ foundAnchor, address);
+ return (HTAnchor *) foundAnchor;
+ }
+ }
+
+ /* Node not found : create new anchor */
+ foundAnchor = HTParentAnchor_new ();
+ if (TRACE) printf("New anchor %p has hash %d and address `%s'\n",
+ foundAnchor, hash, address);
+ StrAllocCopy(foundAnchor->address, address);
+ HTList_addObject (adults, foundAnchor);
+ return (HTAnchor *) foundAnchor;
+ }
+}
+
+
+/* Delete an anchor and possibly related things (auto garbage collection)
+** --------------------------------------------
+**
+** The anchor is only deleted if the corresponding document is not loaded.
+** All outgoing links from parent and children are deleted, and this anchor
+** is removed from the sources list of all its targets.
+** We also try to delete the targets whose documents are not loaded.
+** If this anchor's source list is empty, we delete it and its children.
+*/
+
+PRIVATE void deleteLinks
+ ARGS1 (HTAnchor *,this)
+{
+ if (! this)
+ return;
+
+ /* Recursively try to delete target anchors */
+ if (this->mainLink.dest) {
+ HTParentAnchor *parent = this->mainLink.dest->parent;
+ HTList_removeObject (parent->sources, this);
+ if (! parent->document) /* Test here to avoid calling overhead */
+ HTAnchor_delete (parent);
+ }
+ if (this->links) { /* Extra destinations */
+ HTLink *target;
+ while (target = HTList_removeLastObject (this->links)) {
+ HTParentAnchor *parent = target->dest->parent;
+ HTList_removeObject (parent->sources, this);
+ if (! parent->document) /* Test here to avoid calling overhead */
+ HTAnchor_delete (parent);
+ }
+ }
+}
+
+PUBLIC BOOL HTAnchor_delete
+ ARGS1 (HTParentAnchor *,this)
+{
+ HTChildAnchor *child;
+
+ /* Don't delete if document is loaded */
+ if (this->document)
+ return NO;
+
+ /* Recursively try to delete target anchors */
+ deleteLinks ((HTAnchor *) this);
+
+ if (! HTList_isEmpty (this->sources)) { /* There are still incoming links */
+ /* Delete all outgoing links from children, if any */
+ HTList *kids = this->children;
+ while (child = HTList_nextObject (kids))
+ deleteLinks ((HTAnchor *) child);
+ return NO; /* Parent not deleted */
+ }
+
+ /* No more incoming links : kill everything */
+ /* First, recursively delete children */
+ while (child = HTList_removeLastObject (this->children)) {
+ deleteLinks ((HTAnchor *) child);
+ free (child->tag);
+ free (child);
+ }
+
+ /* Now kill myself */
+ HTList_delete (this->children);
+ HTList_delete (this->sources);
+ free (this->address);
+ /* Devise a way to clean out the HTFormat if no longer needed (ref count?) */
+ free (this);
+ return YES; /* Parent deleted */
+}
+
+
+/* Move an anchor to the head of the list of its siblings
+** ------------------------------------------------------
+**
+** This is to ensure that an anchor which might have already existed
+** is put in the correct order as we load the document.
+*/
+
+void HTAnchor_makeLastChild
+ ARGS1(HTChildAnchor *,this)
+{
+ if (this->parent != (HTParentAnchor *) this) { /* Make sure it's a child */
+ HTList * siblings = this->parent->children;
+ HTList_removeObject (siblings, this);
+ HTList_addObject (siblings, this);
+ }
+}
+
+/* Data access functions
+** ---------------------
+*/
+
+extern HTParentAnchor * HTAnchor_parent
+ ARGS1 (HTAnchor *,this)
+{
+ return this ? this->parent : NULL;
+}
+
+void HTAnchor_setDocument
+ ARGS2 (HTParentAnchor *,this, HyperDoc *,doc)
+{
+ if (this)
+ this->document = doc;
+}
+
+HyperDoc * HTAnchor_document
+ ARGS1 (HTParentAnchor *,this)
+{
+ return this ? this->document : NULL;
+}
+
+
+/* We don't want code to change an address after anchor creation... yet ?
+void HTAnchor_setAddress
+ ARGS2 (HTAnchor *,this, char *,addr)
+{
+ if (this)
+ StrAllocCopy (this->parent->address, addr);
+}
+*/
+
+char * HTAnchor_address
+ ARGS1 (HTAnchor *,this)
+{
+ char *addr = NULL;
+ if (this) {
+ if (((HTParentAnchor *) this == this->parent) ||
+ !((HTChildAnchor *) this)->tag) { /* it's an adult or no tag */
+ StrAllocCopy (addr, this->parent->address);
+ }
+ else { /* it's a named child */
+ addr = malloc (2 + strlen (this->parent->address)
+ + strlen (((HTChildAnchor *) this)->tag));
+ if (addr == NULL) outofmem(__FILE__, "HTAnchor_address");
+ sprintf (addr, "%s#%s", this->parent->address,
+ ((HTChildAnchor *) this)->tag);
+ }
+ }
+ return addr;
+}
+
+
+
+void HTAnchor_setFormat
+ ARGS2 (HTParentAnchor *,this, HTFormat *,form)
+{
+ if (this)
+ this->format = form;
+}
+
+HTFormat * HTAnchor_format
+ ARGS1 (HTParentAnchor *,this)
+{
+ return this ? this->format : NULL;
+}
+
+
+
+void HTAnchor_setIndex
+ ARGS1 (HTParentAnchor *,this)
+{
+ if (this)
+ this->isIndex = YES;
+}
+
+BOOL HTAnchor_isIndex
+ ARGS1 (HTParentAnchor *,this)
+{
+ return this ? this->isIndex : NO;
+}
+
+
+
+BOOL HTAnchor_hasChildren
+ ARGS1 (HTParentAnchor *,this)
+{
+ return this ? ! HTList_isEmpty(this->children) : NO;
+}
+
+/* Title handling
+*/
+CONST char * HTAnchor_title
+ ARGS1 (HTParentAnchor *,this)
+{
+ return this ? this->title : 0;
+}
+
+void HTAnchor_setTitle
+ ARGS2(HTParentAnchor *,this, CONST char *,title)
+{
+ StrAllocCopy(this->title, title);
+}
+
+void HTAnchor_appendTitle
+ ARGS2(HTParentAnchor *,this, CONST char *,title)
+{
+ StrAllocCat(this->title, title);
+}
+
+/* Link this Anchor to another given one
+** -------------------------------------
+*/
+
+BOOL HTAnchor_link
+ ARGS3(HTAnchor *,source, HTAnchor *,destination, HTLinkType *,type)
+{
+ if (! (source && destination))
+ return NO; /* Can't link to/from non-existing anchor */
+ if (TRACE) printf ("Linking anchor %p to anchor %p\n", source, destination);
+ if (! source->mainLink.dest) {
+ source->mainLink.dest = destination;
+ source->mainLink.type = type;
+ } else {
+ HTLink * newLink = (HTLink *) malloc (sizeof (HTLink));
+ if (newLink == NULL) outofmem(__FILE__, "HTAnchor_link");
+ newLink->dest = destination;
+ newLink->type = type;
+ if (! source->links)
+ source->links = HTList_new ();
+ HTList_addObject (source->links, newLink);
+ }
+ if (!destination->parent->sources)
+ destination->parent->sources = HTList_new ();
+ HTList_addObject (destination->parent->sources, source);
+ return YES; /* Success */
+}
+
+
+/* Manipulation of links
+** ---------------------
+*/
+
+HTAnchor * HTAnchor_followMainLink
+ ARGS1 (HTAnchor *,this)
+{
+ return this->mainLink.dest;
+}
+
+HTAnchor * HTAnchor_followTypedLink
+ ARGS2 (HTAnchor *,this, HTLinkType *,type)
+{
+ if (this->mainLink.type == type)
+ return this->mainLink.dest;
+ if (this->links) {
+ HTList *links = this->links;
+ HTLink *link;
+ while (link = HTList_nextObject (links))
+ if (link->type == type)
+ return link->dest;
+ }
+ return NULL; /* No link of this type */
+}
+
+BOOL HTAnchor_makeMainLink
+ ARGS2 (HTAnchor *,this, HTLink *,movingLink)
+{
+ /* Check that everything's OK */
+ if (! (this && HTList_removeObject (this->links, movingLink)))
+ return NO; /* link not found or NULL anchor */
+ else {
+ /* First push current main link onto top of links list */
+ HTLink *newLink = (HTLink*) malloc (sizeof (HTLink));
+ if (newLink == NULL) outofmem(__FILE__, "HTAnchor_makeMainLink");
+ memcpy (newLink, & this->mainLink, sizeof (HTLink));
+ HTList_addObject (this->links, newLink);
+
+ /* Now make movingLink the new main link, and free it */
+ memcpy (& this->mainLink, movingLink, sizeof (HTLink));
+ free (movingLink);
+ return YES;
+ }
+}
--- /dev/null
+/* Hypertext "Anchor" Object HTAnchor.h
+** ==========================
+**
+** An anchor represents a region of a hypertext document which is linked
+** to another anchor in the same or a different document.
+*/
+
+#ifndef HTANCHOR_H
+#define HTANCHOR_H
+
+/* Version 0 (TBL) written in Objective-C for the NeXT browser */
+/* Version 1 of 24-Oct-1991 (JFG), written in C, browser-independant */
+
+#include "HTList.h"
+#include "HTAtom.h"
+
+#ifdef SHORT_NAMES
+#define HTAnchor_findChild HTAnFiCh
+#define HTAnchor_findChildAndLink HTAnFiLi
+#define HTAnchor_findAddress HTAnFiAd
+#define HTAnchor_delete HTAnDele
+#define HTAnchor_makeLastChild HTAnMaLa
+#define HTAnchor_parent HTAnPare
+#define HTAnchor_setDocument HTAnSeDo
+#define HTAnchor_document HTAnDocu
+#define HTAnchor_setFormat HTAnSeFo
+#define HTAnchor_format HTAnForm
+#define HTAnchor_setIndex HTAnSeIn
+#define HTAnchor_isIndex HTAnIsIn
+#define HTAnchor_address HTAnAddr
+#define HTAnchor_hasChildren HTAnHaCh
+#define HTAnchor_title HTAnTitl
+#define HTAnchor_setTitle HTAnSeTi
+#define HTAnchor_appendTitle HTAnApTi
+#define HTAnchor_link HTAnLink
+#define HTAnchor_followMainLink HTAnFoMa
+#define HTAnchor_followTypedLink HTAnFoTy
+#define HTAnchor_makeMainLink HTAnMaMa
+#endif
+
+/* Main definition of anchor
+** =========================
+*/
+
+typedef struct _HyperDoc HyperDoc; /* Ready for forward references */
+typedef struct _HTAnchor HTAnchor;
+typedef struct _HTParentAnchor HTParentAnchor;
+
+#include "HTFormat.h"
+
+typedef HTAtom HTLinkType;
+
+typedef struct {
+ HTAnchor * dest; /* The anchor to which this leads */
+ HTLinkType * type; /* Semantics of this link */
+} HTLink;
+
+struct _HTAnchor { /* Generic anchor : just links */
+ HTLink mainLink; /* Main (or default) destination of this */
+ HTList * links; /* List of extra links from this, if any */
+ /* We separate the first link from the others to avoid too many small mallocs
+ involved by a list creation. Most anchors only point to one place. */
+ HTParentAnchor * parent; /* Parent of this anchor (self for adults) */
+};
+
+struct _HTParentAnchor {
+ /* Common part from the generic anchor structure */
+ HTLink mainLink; /* Main (or default) destination of this */
+ HTList * links; /* List of extra links from this, if any */
+ HTParentAnchor * parent; /* Parent of this anchor (self) */
+
+ /* ParentAnchor-specific information */
+ HTList * children; /* Subanchors of this, if any */
+ HTList * sources; /* List of anchors pointing to this, if any */
+ HyperDoc * document; /* The document within which this is an anchor */
+ char * address; /* Absolute address of this node */
+ HTFormat * format; /* Pointer to node format descriptor */
+ BOOL isIndex; /* Acceptance of a keyword search */
+ char * title; /* Title of document */
+};
+
+typedef struct {
+ /* Common part from the generic anchor structure */
+ HTLink mainLink; /* Main (or default) destination of this */
+ HTList * links; /* List of extra links from this, if any */
+ HTParentAnchor * parent; /* Parent of this anchor */
+
+ /* ChildAnchor-specific information */
+ char * tag; /* Address of this anchor relative to parent */
+} HTChildAnchor;
+
+
+/* Create new or find old sub-anchor
+** ---------------------------------
+**
+** This one is for a new anchor being edited into an existing
+** document. The parent anchor must already exist.
+*/
+
+extern HTChildAnchor * HTAnchor_findChild
+ PARAMS(
+ (HTParentAnchor *parent,
+ CONST char *tag)
+ );
+
+/* Create or find a child anchor with a possible link
+** --------------------------------------------------
+**
+** Create new anchor with a given parent and possibly
+** a name, and possibly a link to a _relatively_ named anchor.
+** (Code originally in ParseHTML.h)
+*/
+extern HTChildAnchor * HTAnchor_findChildAndLink
+ PARAMS((
+ HTParentAnchor * parent, /* May not be 0 */
+ CONST char * tag, /* May be "" or 0 */
+ CONST char * href, /* May be "" or 0 */
+ HTLinkType * ltype /* May be 0 */
+ ));
+
+
+/* Create new or find old named anchor
+** -----------------------------------
+**
+** This one is for a reference which is found in a document, and might
+** not be already loaded.
+** Note: You are not guaranteed a new anchor -- you might get an old one,
+** like with fonts.
+*/
+
+extern HTAnchor * HTAnchor_findAddress
+ PARAMS(
+ (CONST char * address)
+ );
+
+
+/* Delete an anchor and possibly related things (auto garbage collection)
+** --------------------------------------------
+**
+** The anchor is only deleted if the corresponding document is not loaded.
+** All outgoing links from parent and children are deleted, and this anchor
+** is removed from the sources list of all its targets.
+** We also try to delete the targets whose documents are not loaded.
+** If this anchor's source list is empty, we delete it and its children.
+*/
+
+extern BOOL HTAnchor_delete
+ PARAMS(
+ (HTParentAnchor *this)
+ );
+
+
+/* Move an anchor to the head of the list of its siblings
+** ------------------------------------------------------
+**
+** This is to ensure that an anchor which might have already existed
+** is put in the correct order as we load the document.
+*/
+
+extern void HTAnchor_makeLastChild
+ PARAMS(
+ (HTChildAnchor *this)
+ );
+
+/* Data access functions
+** ---------------------
+*/
+
+extern HTParentAnchor * HTAnchor_parent
+ PARAMS(
+ (HTAnchor *this)
+ );
+
+extern void HTAnchor_setDocument
+ PARAMS(
+ (HTParentAnchor *this, HyperDoc *doc)
+ );
+
+extern HyperDoc * HTAnchor_document
+ PARAMS(
+ (HTParentAnchor *this)
+ );
+/* We don't want code to change an address after anchor creation... yet ?
+extern void HTAnchor_setAddress
+ PARAMS(
+ (HTAnchor *this, char *addr)
+ );
+*/
+
+extern char * HTAnchor_address
+ PARAMS(
+ (HTAnchor *this)
+ );
+
+extern void HTAnchor_setFormat
+ PARAMS(
+ (HTParentAnchor *this, HTFormat *form)
+ );
+
+extern HTFormat * HTAnchor_format
+ PARAMS(
+ (HTParentAnchor *this)
+ );
+
+extern void HTAnchor_setIndex
+ PARAMS(
+ (HTParentAnchor *this)
+ );
+
+extern BOOL HTAnchor_isIndex
+ PARAMS(
+ (HTParentAnchor *this)
+ );
+
+extern BOOL HTAnchor_hasChildren
+ PARAMS(
+ (HTParentAnchor *this)
+ );
+
+/* Title handling
+*/
+extern CONST char * HTAnchor_title
+ PARAMS(
+ (HTParentAnchor *this)
+ );
+
+extern void HTAnchor_setTitle
+ PARAMS(
+ (HTParentAnchor *this, CONST char * title)
+ );
+
+extern void HTAnchor_appendTitle
+ PARAMS(
+ (HTParentAnchor *this, CONST char * title)
+ );
+
+/* Link this Anchor to another given one
+** -------------------------------------
+*/
+
+extern BOOL HTAnchor_link
+ PARAMS(
+ (HTAnchor *source, HTAnchor *destination, HTLinkType *type)
+ );
+
+/* Manipulation of links
+** ---------------------
+*/
+
+extern HTAnchor * HTAnchor_followMainLink
+ PARAMS(
+ (HTAnchor *this)
+ );
+
+extern HTAnchor * HTAnchor_followTypedLink
+ PARAMS(
+ (HTAnchor *this, HTLinkType *type)
+ );
+
+extern BOOL HTAnchor_makeMainLink
+ PARAMS(
+ (HTAnchor *this, HTLink *movingLink)
+ );
+
+#endif /* HTANCHOR_H */
--- /dev/null
+/* Atoms: Names to numbers HTAtom.c
+** =======================
+**
+** Atoms are names which are given representative pointer values
+** so that they can be stored more efficiently, and comparisons
+** for equality done more efficiently.
+**
+** Atoms are kept in a hash table consisting of an array of linked lists.
+**
+** Authors:
+** TBL Tim Berners-Lee, WorldWideWeb project, CERN
+** (c) Copyright CERN 1991 - See Copyright.html
+**
+*/
+#define HASH_SIZE 101 /* Tunable */
+#include "HTUtils.h"
+#include "HTAtom.h"
+
+#ifdef ERWISE
+#include <stdio.h>
+#endif
+
+PRIVATE HTAtom * hash_table[HASH_SIZE];
+PRIVATE BOOL initialised = NO;
+
+#ifdef __STDC__
+PUBLIC HTAtom * HTAtom_for(const char * string)
+#else
+PUBLIC HTAtom * HTAtom_for(string)
+ char * string;
+#endif
+{
+ int hash;
+ CONST char * p;
+ HTAtom * a;
+
+ /* First time around, clear hash table
+ */
+ if (!initialised) {
+ int i;
+ for (i=0; i<HASH_SIZE; i++)
+ hash_table[i] = (HTAtom *) 0;
+ initialised = YES;
+ }
+
+ /* Generate hash function
+ */
+ for(p=string, hash=0; *p; p++) {
+ hash = (hash * 3 + *p) % HASH_SIZE;
+ }
+
+ /* Search for the string in the list
+ */
+ for (a=hash_table[hash]; a; a=a->next) {
+ if (0==strcmp(a->name, string)) {
+ if (TRACE) printf("HTAtom: Old atom %d for `&s'\n", a, string);
+ return a; /* Found: return it */
+ }
+ }
+
+ /* Generate a new entry
+ */
+ a = (HTAtom *)malloc(sizeof(*a));
+ if (a == NULL) outofmem(__FILE__, "HTAtom_for");
+ a->name = (char *)malloc(strlen(string)+1);
+ if (a->name == NULL) outofmem(__FILE__, "HTAtom_for");
+ strcpy(a->name, string);
+ a->next = hash_table[hash]; /* Put onto the head of list */
+ hash_table[hash] = a;
+ if (TRACE) printf("HTAtom: New atom %d for `&s'\n", a, string);
+ return a;
+}
+
+
--- /dev/null
+/* Atoms: Names to numbers HTAtom.h
+** =======================
+**
+** Atoms are names which are given representative pointer values
+** so that they can be stored more efficiently, and compaisons
+** for equality done more efficiently.
+**
+** HTAtom_for(string) returns a representative value such that it
+** will always (within one run of the program) return the same
+** value for the same given string.
+**
+** Authors:
+** TBL Tim Berners-Lee, WorldWideWeb project, CERN
+**
+** (c) Copyright CERN 1991 - See Copyright.html
+**
+*/
+
+#ifndef HTATOM_H
+#define HTATOM_H
+
+typedef struct _HTAtom HTAtom;
+struct _HTAtom {
+ HTAtom * next;
+ char * name;
+}; /* struct _HTAtom */
+
+#ifdef __STDC__
+extern HTAtom * HTAtom_for(const char * string);
+#else
+extern HTAtom * HTAtom_for();
+#endif
+
+#define HTAtom_name(a) ((a)->name)
+
+#endif /* HTATOM_H */
--- /dev/null
+/* Declarations of things available from HTBrowse.c
+** ------------------------------------------------
+**
+** HTBrowse.c, the main program of a line mode browser, leaves various
+** public variables atteh disposal of its submodules.
+*/
+
+#ifndef HTBROWSE_H
+#define HTBROWSE_H
+
+#include "tcp.h"
+
+#ifdef SHORT_NAMES
+#define HTScreenHeight HTScHeig
+#define HTScreenWidth HTScWidt
+#define HTClientHost HTClHost
+#define display_anchors HTDiAnch
+#define interactive HTIntera
+#define reference_mark HTReMark
+#endif
+
+extern int WWW_TraceFlag; /* Off unless -v option given */
+extern int HTScreenWidth; /* By default */
+extern int HTScreenHeight; /* Undefined */
+extern BOOL display_anchors; /* anchor will be shown in text? */
+extern BOOL interactive; /* e.g. shows prompts etc */
+
+
+extern FILE * logfile; /* File to output one-liners to */
+
+extern char * HTClientHost; /* Name or number of telnetting host */
+extern char * reference_mark; /* Format string for [1] &c */
+extern char * end_mark; /* Format string for [End] */
+
+
+#endif /* HTBROWSE_H */
--- /dev/null
+/* Chunk handling: Flexible arrays
+** ===============================
+**
+*/
+
+#include "HTUtils.h"
+#include "HTChunk.h"
+#include <stdio.h>
+/* Create a chunk with a certain allocation unit
+** --------------
+*/
+PUBLIC HTChunk * HTChunkCreate ARGS1 (int,grow)
+{
+ HTChunk * ch = (HTChunk *) malloc(sizeof(HTChunk));
+ if (!ch) return 0;
+ ch->data = 0;
+ ch->growby = grow;
+ ch->size = 0;
+ ch->allocated = 0;
+ return ch;
+}
+
+
+/* Clear a chunk of all data
+** --------------------------
+*/
+PUBLIC void HTChunkClear ARGS1 (HTChunk *,ch)
+{
+ if (ch->data) {
+ free(ch->data);
+ ch->data = 0;
+ }
+ ch->size = 0;
+ ch->allocated = 0;
+}
+
+
+/* Append a character
+** ------------------
+*/
+PUBLIC void HTChunkPutc ARGS2 (HTChunk *,ch, char,c)
+{
+ if (ch->size >= ch->allocated) {
+ ch->allocated = ch->allocated + ch->growby;
+ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
+ : (char *)malloc(ch->allocated);
+ if (!ch->data) outofmem(__FILE__, "HTChunkPutc");
+ }
+ ch->data[ch->size++] = c;
+}
+
+
+/* Ensure a certain size
+** ---------------------
+*/
+PUBLIC void HTChunkEnsure ARGS2 (HTChunk *,ch, int,needed)
+{
+ if (needed <= ch->allocated) return;
+ ch->allocated = needed-1 - ((needed-1) % ch->growby)
+ + ch->growby; /* Round up */
+ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
+ : (char *)malloc(ch->allocated);
+ if (ch->data == NULL) outofmem(__FILE__, "HTChunkEnsure");
+}
+
+
+/* Terminate a chunk
+** -----------------
+*/
+PUBLIC void HTChunkTerminate ARGS1 (HTChunk *,ch)
+{
+ HTChunkPutc(ch, (char)0);
+}
+
+
+/* Append a string
+** ---------------
+*/
+PUBLIC void HTChunkPuts ARGS2 (HTChunk *,ch, CONST char *,s)
+{
+ CONST char * p;
+ for (p=s; *p; p++)
+ HTChunkPutc(ch, *p);
+}
--- /dev/null
+/* Chunk handling: Flexible arrays
+** ===============================
+**
+** This module implements a flexible array. It is a general utility module.
+** A chunk is a structure which may be extended. These routines create
+** and append data to chnuks, automatically reallocating them as necessary.
+**
+*/
+
+
+typedef struct {
+ int size; /* In bytes */
+ int growby; /* Allocation unit in bytes */
+ int allocated; /* Current size of *data */
+ char * data; /* Pointer to malloced area or 0 */
+} HTChunk;
+
+
+#ifdef SHORT_NAMES
+#define HTChunkClear HTChClea
+#define HTChunkPutc HTChPutc
+#define HTChunkPuts HTChPuts
+#define HTChunkCreate HTChCrea
+#define HTChunkTerminate HTChTerm
+#define HTChunkEnsure HtChEnsu
+#endif
+
+
+/* Create new chunk
+**
+** On entry,
+**
+** growby The number of bytes to allocate at a time
+** when the chunk is later extended. Arbitrary but
+** normally a trade-off time vs. memory
+**
+** On exit,
+** returns A chunk pointer to the new chunk,
+*/
+extern HTChunk * HTChunkCreate PARAMS((int growby));
+
+
+/* Clear a chunk
+**
+** On entry,
+** ch A valid chunk pointer made by HTChunkCreate()
+**
+** On exit,
+** *ch The size of the chunk is zero.
+*/
+extern void HTChunkClear PARAMS((HTChunk * ch));
+
+
+/* Ensure a chunk has a certain space in
+**
+** On entry,
+** ch A valid chunk pointer made by HTChunkCreate()
+** s The size required
+**
+** On exit,
+** *ch Has size at least s
+*/
+extern void HTChunkEnsure PARAMS((HTChunk * ch, int s));
+
+
+/* Append a character to a chunk
+**
+** On entry,
+** ch A valid chunk pointer made by HTChunkCreate()
+** c The character to be appended
+** On exit,
+** *ch Is one character bigger
+*/
+
+extern void HTChunkPutc PARAMS((HTChunk * ch, char c));
+
+/* Append a string to a chunk
+**
+** On entry,
+** ch A valid chunk pointer made by HTChunkCreate()
+** s Tpoints to a zero-terminated string to be appended
+** On exit,
+** *ch Is bigger by strlen(s)
+*/
+
+extern void HTChunkPuts PARAMS((HTChunk * ch, const char *s));
+
+
+/* Append a zero character to a chunk
+**
+** On entry,
+** ch A valid chunk pointer made by HTChunkCreate()
+** On exit,
+** *ch Is one character bigger
+*/
+
+extern void HTChunkTerminate PARAMS((HTChunk * ch));
--- /dev/null
+/* File Transfer Protocol (FTP) Client
+** for a WorldWideWeb browser
+** ===================================
+**
+** A cache of control connections is kept.
+**
+** Note: Port allocation
+**
+** It is essential that the port is allocated by the system, rather
+** than chosen in rotation by us (POLL_PORTS), or the following
+** problem occurs.
+**
+** It seems that an attempt by the server to connect to a port which has
+** been used recently by a listen on the same socket, or by another
+** socket this or another process causes a hangup of (almost exactly)
+** one minute. Therefore, we have to use a rotating port number.
+** The problem remains that if the application is run twice in quick
+** succession, it will hang for what remains of a minute.
+**
+** History:
+** 2 May 91 Written TBL, as a part of the WorldWideWeb project.
+** 15 Jan 92 Bug fix: close() was used for NETCLOSE for control soc
+** 10 Feb 92 Retry if cached connection times out or breaks
+**
+** Options:
+** LISTEN We listen, the other guy connects for data.
+** Otherwise, other way round, but problem finding our
+** internet address!
+*/
+
+#define LISTEN /* @@@@ Test */
+
+/*
+BUGS: @@@ Limit connection cache size!
+ Error reporting to user.
+ 400 & 500 errors are acked by user with windows.
+ Use configuration file for user names
+ Prompt user for password
+
+** Note for portablility this version does not use select() and
+** so does not watch the control and data channels at the
+** same time.
+*/
+
+#define REPEAT_PORT /* Give the port number for each file */
+#define REPEAT_LISTEN /* Close each listen socket and open a new one */
+
+/* define POLL_PORTS If allocation does not work, poll ourselves.*/
+#define LISTEN_BACKLOG 2 /* Number of pending connect requests (TCP)*/
+
+#define FIRST_TCP_PORT 1024 /* Region to try for a listening port */
+#define LAST_TCP_PORT 5999
+
+#define LINE_LENGTH 256
+#define COMMAND_LENGTH 256
+
+#include "HTParse.h"
+#include "HTUtils.h"
+#include "tcp.h"
+#include "HTTCP.h"
+#include "HTAnchor.h"
+#include "HText.h"
+#include "HTStyle.h"
+
+#include "HTFTP.h"
+
+#ifndef IPPORT_FTP
+#define IPPORT_FTP 21
+#endif
+
+extern HTStyleSheet * styleSheet;
+PRIVATE HTStyle *h1Style; /* For heading level 1 */
+PRIVATE HTStyle *h2Style; /* For heading level 2 */
+PRIVATE HTStyle *textStyle; /* Text style */
+PRIVATE HTStyle *dirStyle; /* Compact List style */
+
+#ifdef REMOVED_CODE
+extern char *malloc();
+extern void free();
+extern char *strncpy();
+#endif
+
+typedef struct _connection {
+ struct _connection * next; /* Link on list */
+ u_long addr; /* IP address */
+ int socket; /* Socket number for communication */
+} connection;
+
+#ifndef NIL
+#define NIL 0
+#endif
+
+
+/* Module-Wide Variables
+** ---------------------
+*/
+PRIVATE connection * connections =0; /* Linked list of connections */
+PRIVATE char response_text[LINE_LENGTH+1];/* Last response from NewsHost */
+PRIVATE connection * control; /* Current connection */
+PRIVATE int data_soc = -1; /* Socket for data transfer =invalid */
+
+#ifdef POLL_PORTS
+PRIVATE unsigned short port_number = FIRST_TCP_PORT;
+#endif
+
+#ifdef LISTEN
+PRIVATE int master_socket = -1; /* Listening socket = invalid */
+PRIVATE char port_command[255]; /* Command for setting the port */
+PRIVATE fd_set open_sockets; /* Mask of active channels */
+PRIVATE int num_sockets; /* Number of sockets to scan */
+#else
+PRIVATE unsigned short passive_port; /* Port server specified for data */
+#endif
+
+
+#define NEXT_CHAR HTGetChararcter() /* Use function in HTFormat.c */
+
+#define DATA_BUFFER_SIZE 2048
+PRIVATE char data_buffer[DATA_BUFFER_SIZE]; /* Input data buffer */
+PRIVATE char * data_read_pointer;
+PRIVATE char * data_write_pointer;
+#define NEXT_DATA_CHAR next_data_char()
+
+
+/* Procedure: Read a character from the data connection
+** ----------------------------------------------------
+*/
+PRIVATE char next_data_char
+NOARGS
+{
+ int status;
+ if (data_read_pointer >= data_write_pointer) {
+ status = NETREAD(data_soc, data_buffer, DATA_BUFFER_SIZE);
+ /* Get some more data */
+ if (status <= 0) return (char)-1;
+ data_write_pointer = data_buffer + status;
+ data_read_pointer = data_buffer;
+ }
+#ifdef NOT_ASCII
+ {
+ char c = *data_read_pointer++;
+ return FROMASCII(c);
+ }
+#else
+ return *data_read_pointer++;
+#endif
+}
+
+
+/* Close an individual connection
+**
+*/
+#ifdef __STDC__
+PRIVATE int close_connection(connection * con)
+#else
+PRIVATE int close_connection(con)
+ connection *con;
+#endif
+{
+ connection * scan;
+ int status = NETCLOSE(con->socket);
+ if (TRACE) printf("FTP: Closing control socket %d\n", con->socket);
+ if (connections==con) {
+ connections = con->next;
+ return status;
+ }
+ for(scan=connections; scan; scan=scan->next) {
+ if (scan->next == con) {
+ scan->next = con->next; /* Unlink */
+ if (control==con) control = (connection*)0;
+ return status;
+ } /*if */
+ } /* for */
+ return -1; /* very strange -- was not on list. */
+}
+
+
+/* Execute Command and get Response
+** --------------------------------
+**
+** See the state machine illustrated in RFC959, p57. This implements
+** one command/reply sequence. It also interprets lines which are to
+** be continued, which are marked with a "-" immediately after the
+** status code.
+**
+** On entry,
+** con points to the connection which is established.
+** cmd points to a command, or is NIL to just get the response.
+**
+** The command is terminated with the CRLF pair.
+**
+** On exit,
+** returns: The first digit of the reply type,
+** or negative for communication failure.
+*/
+#ifdef __STDC__
+PRIVATE int response(char * cmd)
+#else
+PRIVATE int response(cmd)
+ char * cmd;
+#endif
+{
+ int result; /* Three-digit decimal code */
+ char continuation;
+ int status;
+
+ if (!control) {
+ if(TRACE) printf("FTP: No control connection set up!!\n");
+ return -99;
+ }
+
+ if (cmd) {
+
+ if (TRACE) printf(" Tx: %s", cmd);
+
+#ifdef NOT_ASCII
+ {
+ char * p;
+ for(p=cmd; *p; p++) {
+ *p = TOASCII(*p);
+ }
+ }
+#endif
+ status = NETWRITE(control->socket, cmd, (int)strlen(cmd));
+ if (status<0) {
+ if (TRACE) printf(
+ "FTP: Error %d sending command: closing socket %d\n",
+ status, control->socket);
+ close_connection(control);
+ return status;
+ }
+ }
+
+ do {
+ char *p = response_text;
+ for(;;) {
+ if (((*p++=NEXT_CHAR) == '\n')
+ || (p == &response_text[LINE_LENGTH])) {
+ *p++=0; /* Terminate the string */
+ if (TRACE) printf(" Rx: %s", response_text);
+ sscanf(response_text, "%d%c", &result, &continuation);
+ break;
+ } /* if end of line */
+
+ if (*(p-1) < 0) {
+ if(TRACE) fprintf(stderr, "Error on rx: closing socket %d\n",
+ control->socket);
+ strcpy(response_text, "000 *** TCP read error on response\n");
+ close_connection(control);
+ return -1; /* End of file on response */
+ }
+ } /* Loop over characters */
+
+ } while (continuation == '-');
+
+ if (result==421) {
+ if(TRACE) fprintf(stderr, "FTP: They close so we close socket %d\n",
+ control->socket);
+ close_connection(control);
+ return -1;
+ }
+ return result/100;
+}
+
+
+/* Get a valid connection to the host
+** ----------------------------------
+**
+** On entry,
+** arg points to the name of the host in a hypertext address
+** On exit,
+** returns <0 if error
+** socket number if success
+**
+** This routine takes care of managing timed-out connections, and
+** limiting the number of connections in use at any one time.
+**
+** It ensures that all connections are logged in if they exist.
+** It ensures they have the port number transferred.
+*/
+PRIVATE int get_connection ARGS1 (CONST char *,arg)
+{
+ struct hostent * phost; /* Pointer to host -- See netdb.h */
+ struct sockaddr_in soc_address; /* Binary network address */
+ struct sockaddr_in* sin = &soc_address;
+
+ char * username=0;
+ char * password=0;
+
+ if (!arg) return -1; /* Bad if no name sepcified */
+ if (!*arg) return -1; /* Bad if name had zero length */
+
+/* Set up defaults:
+*/
+ sin->sin_family = AF_INET; /* Family, host order */
+ sin->sin_port = htons(IPPORT_FTP); /* Well Known Number */
+
+ if (TRACE) printf("FTP: Looking for %s\n", arg);
+
+/* Get node name:
+*/
+ {
+ char *p1 = HTParse(arg, "", PARSE_HOST);
+ char *p2 = strchr(p1, '@'); /* user? */
+ char * pw;
+ if (p2) {
+ username = p1;
+ *p2=0; /* terminate */
+ p1 = p2+1; /* point to host */
+ pw = strchr(username, ':');
+ if (pw) {
+ *pw++ = 0;
+ password = pw;
+ }
+ }
+ HTParseInet(sin, p1);
+ if (!username) free(p1);
+ } /* scope of p1 */
+
+
+/* Now we check whether we already have a connection to that port.
+*/
+
+ {
+ connection * scan;
+ for (scan=connections; scan; scan=scan->next) {
+ if (sin->sin_addr.s_addr == scan->addr) {
+ if (TRACE) printf(
+ "FTP: Already have connection for %d.%d.%d.%d.\n",
+ (int)*((unsigned char *)(&scan->addr)+0),
+ (int)*((unsigned char *)(&scan->addr)+1),
+ (int)*((unsigned char *)(&scan->addr)+2),
+ (int)*((unsigned char *)(&scan->addr)+3));
+ if (username) free(username);
+ return scan->socket; /* Good return */
+ } else {
+ if (TRACE) printf(
+ "FTP: Existing connection is %d.%d.%d.%d\n",
+ (int)*((unsigned char *)(&scan->addr)+0),
+ (int)*((unsigned char *)(&scan->addr)+1),
+ (int)*((unsigned char *)(&scan->addr)+2),
+ (int)*((unsigned char *)(&scan->addr)+3));
+ }
+ }
+ }
+
+
+/* Now, let's get a socket set up from the server:
+*/
+ {
+ int status;
+ connection * con = (connection *)malloc(sizeof(*con));
+ if (con == NULL) outofmem(__FILE__, "get_connection");
+ con->addr = sin->sin_addr.s_addr; /* save it */
+ status = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (status<0) {
+ (void) HTInetStatus("socket");
+ free(con);
+ if (username) free(username);
+ return status;
+ }
+ con->socket = status;
+
+ status = connect(con->socket, (struct sockaddr*)&soc_address,
+ sizeof(soc_address));
+ if (status<0){
+ (void) HTInetStatus("connect");
+ if (TRACE) printf(
+ "FTP: Unable to connect to remote host for `%s'.\n",
+ arg);
+ NETCLOSE(con->socket);
+ free(con);
+ if (username) free(username);
+ return status; /* Bad return */
+ }
+
+ if (TRACE) printf("FTP connected, socket %d\n", con->socket);
+ control = con; /* Current control connection */
+ con->next = connections; /* Link onto list of good ones */
+ connections = con;
+ HTInitInput(con->socket);/* Initialise buffering for contron connection */
+
+
+/* Now we log in Look up username, prompt for pw.
+*/
+ {
+ int status = response(NIL); /* Get greeting */
+
+ if (status == 2) { /* Send username */
+ char * command;
+ if (username) {
+ command = (char*)malloc(10+strlen(username)+2+1);
+ if (command == NULL) outofmem(__FILE__, "get_connection");
+ sprintf(command, "USER %s\r\n", username);
+ } else {
+ command = (char*)malloc(25);
+ if (command == NULL) outofmem(__FILE__, "get_connection");
+ sprintf(command, "USER anonymous\r\n");
+ }
+ status = response(command);
+ free(command);
+ }
+ if (status == 3) { /* Send password */
+ char * command;
+ if (password) {
+ command = (char*)malloc(10+strlen(password)+2+1);
+ if (command == NULL) outofmem(__FILE__, "get_connection");
+ sprintf(command, "PASS %s\r\n", password);
+ } else {
+ command = (char*)malloc(10+strlen(HTHostName())+2+1);
+ if (command == NULL) outofmem(__FILE__, "get_connection");
+ sprintf(command,
+ "PASS user@%s\r\n", HTHostName()); /*@@*/
+ }
+ status = response(command);
+ free(command);
+ }
+ if (username) free(username);
+
+ if (status == 3) status = response("ACCT noaccount\r\n");
+
+ if (status !=2) {
+ if (TRACE) printf("FTP: Login fail: %s", response_text);
+ if (control) close_connection(control);
+ return -1; /* Bad return */
+ }
+ if (TRACE) printf("FTP: Logged in.\n");
+ }
+
+/* Now we inform the server of the port number we will listen on
+*/
+#ifndef REPEAT_PORT
+ {
+ int status = response(port_command);
+ if (status !=2) {
+ if (control) close_connection(control);
+ return -status; /* Bad return */
+ }
+ if (TRACE) printf("FTP: Port defined.\n");
+ }
+#endif
+ return con->socket; /* Good return */
+ } /* Scope of con */
+}
+
+
+#ifdef LISTEN
+
+/* Close Master (listening) socket
+** -------------------------------
+**
+**
+*/
+#ifdef __STDC__
+PRIVATE int close_master_socket(void)
+#else
+PRIVATE int close_master_socket()
+#endif
+{
+ int status;
+ FD_CLR(master_socket, &open_sockets);
+ status = NETCLOSE(master_socket);
+ if (TRACE) printf("FTP: Closed master socket %d\n", master_socket);
+ master_socket = -1;
+ if (status<0) return HTInetStatus("close master socket");
+ else return status;
+}
+
+
+/* Open a master socket for listening on
+** -------------------------------------
+**
+** When data is transferred, we open a port, and wait for the server to
+** connect with the data.
+**
+** On entry,
+** master_socket Must be negative if not set up already.
+** On exit,
+** Returns socket number if good
+** less than zero if error.
+** master_socket is socket number if good, else negative.
+** port_number is valid if good.
+*/
+#ifdef __STDC__
+PRIVATE int get_listen_socket(void)
+#else
+PRIVATE int get_listen_socket()
+#endif
+{
+ struct sockaddr_in soc_address; /* Binary network address */
+ struct sockaddr_in* sin = &soc_address;
+ int new_socket; /* Will be master_socket */
+
+
+ FD_ZERO(&open_sockets); /* Clear our record of open sockets */
+ num_sockets = 0;
+
+#ifndef REPEAT_LISTEN
+ if (master_socket>=0) return master_socket; /* Done already */
+#endif
+
+/* Create internet socket
+*/
+ new_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (new_socket<0)
+ return HTInetStatus("socket for master socket");
+
+ if (TRACE) printf("FTP: Opened master socket number %d\n", new_socket);
+
+/* Search for a free port.
+*/
+ sin->sin_family = AF_INET; /* Family = internet, host order */
+ sin->sin_addr.s_addr = INADDR_ANY; /* Any peer address */
+#ifdef POLL_PORTS
+ {
+ unsigned short old_port_number = port_number;
+ for(port_number=old_port_number+1;;port_number++){
+ int status;
+ if (port_number > LAST_TCP_PORT)
+ port_number = FIRST_TCP_PORT;
+ if (port_number == old_port_number) {
+ return HTInetStatus("bind");
+ }
+ soc_address.sin_port = htons(port_number);
+ if ((status=bind(new_socket,
+ (struct sockaddr*)&soc_address,
+ /* Cast to generic sockaddr */
+ sizeof(soc_address))) == 0)
+ break;
+ if (TRACE) printf(
+ "TCP bind attempt to port %d yields %d, errno=%d\n",
+ port_number, status, errno);
+ } /* for */
+ }
+#else
+ {
+ int status;
+ int address_length = sizeof(soc_address);
+ status = getsockname(control->socket,
+ (struct sockaddr *)&soc_address,
+ &address_length);
+ if (status<0) return HTInetStatus("getsockname");
+ CTRACE(tfp, "FTP: This host is %s\n",
+ HTInetString(sin));
+
+ soc_address.sin_port = 0; /* Unspecified: please allocate */
+ status=bind(new_socket,
+ (struct sockaddr*)&soc_address,
+ /* Cast to generic sockaddr */
+ sizeof(soc_address));
+ if (status<0) return HTInetStatus("bind");
+
+ address_length = sizeof(soc_address);
+ status = getsockname(new_socket,
+ (struct sockaddr*)&soc_address,
+ &address_length);
+ if (status<0) return HTInetStatus("getsockname");
+ }
+#endif
+
+ CTRACE(tfp, "FTP: bound to port %d on %s\n",
+ (unsigned int)ntohs(sin->sin_port),
+ HTInetString(sin));
+
+#ifdef REPEAT_LISTEN
+ if (master_socket>=0)
+ (void) close_master_socket();
+#endif
+
+ master_socket = new_socket;
+
+/* Now we must find out who we are to tell the other guy
+*/
+ (void)HTHostName(); /* Make address valid - doesn't work*/
+ sprintf(port_command, "PORT %d,%d,%d,%d,%d,%d\r\n",
+ (int)*((unsigned char *)(&sin->sin_addr)+0),
+ (int)*((unsigned char *)(&sin->sin_addr)+1),
+ (int)*((unsigned char *)(&sin->sin_addr)+2),
+ (int)*((unsigned char *)(&sin->sin_addr)+3),
+ (int)*((unsigned char *)(&sin->sin_port)+0),
+ (int)*((unsigned char *)(&sin->sin_port)+1));
+
+
+/* Inform TCP that we will accept connections
+*/
+ if (listen(master_socket, 1)<0) {
+ master_socket = -1;
+ return HTInetStatus("listen");
+ }
+ CTRACE(tfp, "TCP: Master socket(), bind() and listen() all OK\n");
+ FD_SET(master_socket, &open_sockets);
+ if ((master_socket+1) > num_sockets) num_sockets=master_socket+1;
+
+ return master_socket; /* Good */
+
+} /* get_listen_socket */
+#endif
+
+
+/* Get Styles from stylesheet
+** --------------------------
+*/
+PRIVATE void get_styles NOARGS
+{
+ if (!h1Style) h1Style = HTStyleNamed(styleSheet, "Heading1");
+ if (!h2Style) h2Style = HTStyleNamed(styleSheet, "Heading2");
+ if (!textStyle) textStyle = HTStyleNamed(styleSheet, "Example");
+ if (!dirStyle) dirStyle = HTStyleNamed(styleSheet, "Dir");
+}
+
+
+/* Read a directory into an hypertext object from the data socket
+** --------------------------------------------------------------
+**
+** On entry,
+** anchor Parent anchor to link the HText to
+** address Address of the directory
+** On exit,
+** returns HT_LOADED if OK
+** <0 if error.
+*/
+PRIVATE int read_directory
+ARGS2 (
+ HTParentAnchor *, parent,
+ CONST char *, address
+)
+{
+ HText * HT = HText_new (parent);
+ char *filename = HTParse(address, "", PARSE_PATH + PARSE_PUNCTUATION);
+ HTChildAnchor * child; /* corresponds to an entry of the directory */
+ char c = 0;
+#define LASTPATH_LENGTH 150 /* @@@@ Horrible limit on the entry size */
+ char lastpath[LASTPATH_LENGTH + 1];
+ char *p, *entry;
+
+ HText_beginAppend (HT);
+ get_styles();
+
+ HTAnchor_setTitle (parent, "FTP Directory of ");
+ HTAnchor_appendTitle (parent, address + 5); /* +5 gets rid of "file:" */
+ HText_setStyle (HT, h1Style);
+ HText_appendText (HT, filename);
+
+ HText_setStyle (HT, dirStyle);
+ data_read_pointer = data_write_pointer = data_buffer;
+
+ if (*filename == 0) /* Empty filename : use root */
+ strcpy (lastpath, "/");
+ else {
+ p = filename + strlen (filename) - 2;
+ while (p >= filename && *p != '/')
+ p--;
+ strcpy (lastpath, p + 1); /* relative path */
+ }
+ free (filename);
+ entry = lastpath + strlen (lastpath);
+ if (*(entry-1) != '/')
+ *entry++ = '/'; /* ready to append entries */
+
+ if (strlen (lastpath) > 1) { /* Current file is not the FTP root */
+ strcpy (entry, "..");
+ child = HTAnchor_findChildAndLink (parent, 0, lastpath, 0);
+ HText_beginAnchor (HT, child);
+ HText_appendText (HT, "Parent Directory");
+ HText_endAnchor (HT);
+ HText_appendCharacter (HT, '\t');
+ }
+ for (;;) {
+ p = entry;
+ while (p - lastpath < LASTPATH_LENGTH) {
+ c = NEXT_DATA_CHAR;
+ if (c == '\r') {
+ c = NEXT_DATA_CHAR;
+ if (c != '\n') {
+ if (TRACE)
+ printf ("Warning: No newline but %d after carriage return.\n", c);
+ break;
+ }
+ }
+ if (c == '\n' || c == (char) EOF)
+ break;
+ *p++ = c;
+ }
+ if (c == (char) EOF && p == entry)
+ break;
+ *p = 0;
+ child = HTAnchor_findChildAndLink (parent, 0, lastpath, 0);
+ HText_beginAnchor (HT, child);
+ HText_appendText (HT, entry);
+ HText_endAnchor (HT);
+ HText_appendCharacter (HT, '\t');
+ }
+
+ HText_appendParagraph (HT);
+ HText_endAppend (HT);
+ return response(NIL) == 2 ? HT_LOADED : -1;
+}
+
+
+#ifndef ERWISE
+/* Retrieve File from Server
+** -------------------------
+**
+** On entry,
+** name WWW address of a file: document, including hostname
+** On exit,
+** returns Socket number for file if good.
+** <0 if bad.
+*/
+PUBLIC int HTFTP_open_file_read
+ARGS2 (
+ CONST char *, name,
+ HTParentAnchor *, anchor
+)
+{
+ BOOL isDirectory = NO;
+ int status;
+ int retry; /* How many times tried? */
+
+ for (retry=0; retry<2; retry++) { /* For timed out/broken connections */
+
+ status = get_connection(name);
+ if (status<0) return status;
+
+#ifdef LISTEN
+ status = get_listen_socket();
+ if (status<0) return status;
+
+#ifdef REPEAT_PORT
+/* Inform the server of the port number we will listen on
+*/
+ {
+ status = response(port_command);
+ if (status !=2) { /* Could have timed out */
+ if (status<0) continue; /* try again - net error*/
+ return -status; /* bad reply */
+ }
+ if (TRACE) printf("FTP: Port defined.\n");
+ }
+#endif
+#else /* Use PASV */
+/* Tell the server to be passive
+*/
+ {
+ char *p;
+ int reply, h0, h1, h2, h3, p0, p1; /* Parts of reply */
+ status = response("PASV\r\n");
+ if (status !=2) {
+ if (status<0) continue; /* retry or Bad return */
+ return -status; /* bad reply */
+ }
+ for(p=response_text; *p; p++)
+ if ((*p<'0')||(*p>'9')) *p = ' '; /* Keep only digits */
+ status = sscanf(response_text, "%d%d%d%d%d%d%d",
+ &reply, &h0, &h1, &h2, &h3, &p0, &p1);
+ if (status<5) {
+ if (TRACE) printf("FTP: PASV reply has no inet address!\n");
+ return -99;
+ }
+ passive_port = (p0<<8) + p1;
+ if (TRACE) printf("FTP: Server is listening on port %d\n",
+ passive_port);
+ }
+
+/* Open connection for data:
+*/
+ {
+ struct sockaddr_in soc_address;
+ int status = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (status<0) {
+ (void) HTInetStatus("socket for data socket");
+ return status;
+ }
+ data_soc = status;
+
+ soc_address.sin_addr.s_addr = control->addr;
+ soc_address.sin_port = htons(passive_port);
+ soc_address.sin_family = AF_INET; /* Family, host order */
+ if (TRACE) printf(
+ "FTP: Data remote address is port %d, inet %d.%d.%d.%d\n",
+ (unsigned int)ntohs(soc_address.sin_port),
+ (int)*((unsigned char *)(&soc_address.sin_addr)+0),
+ (int)*((unsigned char *)(&soc_address.sin_addr)+1),
+ (int)*((unsigned char *)(&soc_address.sin_addr)+2),
+ (int)*((unsigned char *)(&soc_address.sin_addr)+3));
+
+ status = connect(data_soc, (struct sockaddr*)&soc_address,
+ sizeof(soc_address));
+ if (status<0){
+ (void) HTInetStatus("connect for data");
+ NETCLOSE(data_soc);
+ return status; /* Bad return */
+ }
+
+ if (TRACE) printf("FTP data connected, socket %d\n", data_soc);
+ }
+#endif /* use PASV */
+ status = 0;
+ break; /* No more retries */
+
+ } /* for retries */
+ if (status<0) return status; /* Failed with this code */
+
+/* Ask for the file:
+*/
+ {
+ char *filename = HTParse(name, "", PARSE_PATH + PARSE_PUNCTUATION);
+ char command[LINE_LENGTH+1];
+ if (!*filename) StrAllocCopy(filename, "/");
+ sprintf(command, "RETR %s\r\n", filename);
+ status = response(command);
+ if (status != 1) { /* Failed : try to CWD to it */
+ sprintf(command, "CWD %s\r\n", filename);
+ status = response(command);
+ if (status == 2) { /* Successed : let's NAME LIST it */
+ isDirectory = YES;
+ sprintf(command, "NLST\r\n");
+ status = response (command);
+ }
+ }
+ free(filename);
+ if (status != 1) return -status; /* Action not started */
+ }
+
+#ifdef LISTEN
+/* Wait for the connection
+*/
+ {
+ struct sockaddr_in soc_address;
+ int soc_addrlen=sizeof(soc_address);
+ status = accept(master_socket,
+ (struct sockaddr *)&soc_address,
+ &soc_addrlen);
+ if (status<0)
+ return HTInetStatus("accept");
+ CTRACE(tfp, "TCP: Accepted new socket %d\n", status);
+ data_soc = status;
+ }
+#else
+/* @@ */
+#endif
+ if (isDirectory)
+ return read_directory (anchor, name);
+ /* returns HT_LOADED or error */
+ else
+ return data_soc;
+
+} /* open_file_read */
+#endif /* ERWISE */
+
+/* Close socket opened for reading a file, and get final message
+** -------------------------------------------------------------
+**
+*/
+PUBLIC int HTFTP_close_file
+ARGS1 (int,soc)
+{
+ int status;
+
+ if (soc!=data_soc) {
+ if (TRACE) printf("HTFTP: close socket %d: (not FTP data socket).\n",
+ soc);
+ return NETCLOSE(soc);
+ }
+ status = NETCLOSE(data_soc);
+ if (TRACE) printf("FTP: Closing data socket %d\n", data_soc);
+ if (status<0) (void) HTInetStatus("close"); /* Comment only */
+ data_soc = -1; /* invalidate it */
+
+ status = response(NIL);
+ if (status!=2) return -status;
+
+ return status; /* Good */
+}
+
+
+/*___________________________________________________________________________
+*/
+/* Test program only
+** -----------------
+**
+** Compiling this with -DTEST produces a test program. Unix only
+**
+** Syntax:
+** test <file or option> ...
+**
+** options: -v Verbose: Turn trace on at this point
+*/
+#ifdef TEST
+
+PUBLIC int WWW_TraceFlag;
+
+#ifdef __STDC__
+int main(int argc, char*argv[])
+#else
+int main(argc, argv)
+ int argc;
+ char *argv[];
+#endif
+{
+
+ int arg; /* Argument number */
+ int status;
+ connection * con;
+ WWW_TraceFlag = (0==strcmp(argv[1], "-v")); /* diagnostics ? */
+
+#ifdef SUPRESS
+ status = get_listen_socket();
+ if (TRACE) printf("get_listen_socket returns %d\n\n", status);
+ if (status<0) exit(status);
+
+ status = get_connection(argv[1]); /* test double use */
+ if (TRACE) printf("get_connection(`%s') returned %d\n\n", argv[1], status);
+ if (status<0) exit(status);
+#endif
+
+ for(arg=1; arg<argc; arg++) { /* For each argument */
+ if (0==strcmp(argv[arg], "-v")) {
+ WWW_TraceFlag = 1; /* -v => Trace on */
+
+ } else { /* Filename: */
+
+ status = HTTP_open_file_read(argv[arg]);
+ if (TRACE) printf("open_file_read returned %d\n\n", status);
+ if (status<0) exit(status);
+
+ /* Copy the file to std out:
+ */
+ {
+ char buffer[INPUT_BUFFER_SIZE];
+ for(;;) {
+ int status = NETREAD(data_soc, buffer, INPUT_BUFFER_SIZE);
+ if (status<=0) {
+ if (status<0) (void) HTInetStatus("read");
+ break;
+ }
+ status = write(1, buffer, status);
+ if (status<0) {
+ printf("Write failure!\n");
+ break;
+ }
+ }
+ }
+
+ status = HTTP_close_file(data_soc);
+ if (TRACE) printf("Close_file returned %d\n\n", status);
+
+ } /* if */
+ } /* for */
+ status = response("QUIT\r\n"); /* Be good */
+ if (TRACE) printf("Quit returned %d\n", status);
+
+ while(connections) close_connection(connections);
+
+ close_master_socket();
+
+} /* main */
+#endif /* TEST */
+
--- /dev/null
+/* FTP access functions HTFTP.h
+** ====================
+*/
+
+/* Retrieve File from Server
+** -------------------------
+**
+** On exit,
+** returns Socket number for file if good.
+** <0 if bad.
+*/
+extern int HTFTP_open_file_read
+PARAMS
+((
+ CONST char * name,
+ HTParentAnchor * anchor
+));
+
+/* Close socket opened for reading a file, and get final message
+** -------------------------------------------------------------
+**
+*/
+extern int HTFTP_close_file
+PARAMS ((int soc));
+
+
+/* Return Host Name
+** ----------------
+*/
+extern CONST char * HTHostName
+NOPARAMS;
--- /dev/null
+/* File Access HTFile.c
+** ===========
+**
+** This is unix-specific code in general, with some VMS bits.
+** These are routines for file access used by WWW browsers.
+**
+** History:
+** Feb 91 Written Tim Berners-Lee CERN/CN
+** Apr 91 vms-vms access included using DECnet syntax
+**
+** Bugs:
+** Cannot access VMS files from a unix machine. How can we know that the
+** target machine runs VMS?
+*/
+
+#define INFINITY 512 /* file name length @@ FIXME */
+
+
+
+#ifdef unix /* if this is to compile on a UNIX machine */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+#include "HText.h"
+#define GOT_READ_DIR 1 /* if directory reading functions are available */
+#endif
+
+#include "HTUtils.h"
+#include "HTFile.h"
+
+#include "WWW.h"
+#include "HTParse.h"
+#include "tcp.h"
+#include "HTTCP.h"
+#include "HTFTP.h"
+#include "HTAnchor.h"
+
+PRIVATE char *HTMountRoot = "/Net/"; /* Where to find mounts */
+#ifdef vms
+PRIVATE char *HTCacheRoot = "/WWW$SCRATCH/"; /* Where to cache things */
+#else
+PRIVATE char *HTCacheRoot = "/tmp/W3_Cache_"; /* Where to cache things */
+#endif
+
+/* PRIVATE char *HTSaveRoot = "$(HOME)/WWW/";*/ /* Where to save things */
+
+#ifdef vms
+/* Convert unix-style name into VMS name
+** -------------------------------------
+**
+** Bug: Returns pointer to static -- non-reentrant
+*/
+PRIVATE char * vms_name(CONST char * nn, CONST char * fn)
+{
+
+/* We try converting the filename into Files-11 syntax. That is, we assume
+** first that the file is, like us, on a VMS node. We try remote
+** (or local) DECnet access. Files-11, VMS, VAX and DECnet
+** are trademarks of Digital Equipment Corporation.
+** The node is assumed to be local if the hostname WITHOUT DOMAIN
+** matches the local one. @@@
+*/
+ static char vmsname[INFINITY]; /* returned */
+ char * filename = (char*)malloc(strlen(fn)+1);
+ char * nodename = (char*)malloc(strlen(nn)+2+1); /* Copies to hack */
+ char *second; /* 2nd slash */
+ char *last; /* last slash */
+
+ char * hostname = HTHostName();
+
+ strcpy(filename, fn);
+ strcpy(nodename, ""); /* On same node? Yes if node names match */
+ {
+ char *p, *q;
+ for (p=hostname, q=nn; *p && *p!='.' && *q && *q!='.'; p++, q++){
+ if (TOUPPER(*p)!=TOUPPER(*q)) {
+ strcpy(nodename, nn);
+ q = strchr(nodename, '.'); /* Mismatch */
+ if (q) *q=0; /* Chop domain */
+ strcat(nodename, "::"); /* Try decnet anyway */
+ break;
+ }
+ }
+ }
+
+ second = strchr(filename+1, '/'); /* 2nd slash */
+ last = strrchr(filename, '/'); /* last slash */
+
+ if (!second) { /* Only one slash */
+ sprintf(vmsname, "%s%s", nodename, filename);
+ } else if(second==last) { /* Exactly two slashes */
+ *second = 0; /* Split filename from disk */
+ sprintf(vmsname, "%s%s:%s", nodename, filename+1, second+1);
+ *second = '/'; /* restore */
+ } else { /* More than two slashes */
+ char * p;
+ *second = 0; /* Split disk from directories */
+ *last = 0; /* Split dir from filename */
+ sprintf(vmsname, "%s%s:[%s]%s",
+ nodename, filename+1, second+1, last+1);
+ *second = *last = '/'; /* restore filename */
+ for (p=strchr(vmsname, '['); *p!=']'; p++)
+ if (*p=='/') *p='.'; /* Convert dir sep. to dots */
+ }
+ free(nodename);
+ free(filename);
+ return vmsname;
+}
+
+
+#endif /* vms */
+
+/* Make the cache file name for a W3 document
+** ------------------------------------------
+** Make up a suitable name for saving the node in
+**
+** E.g. /tmp/WWW_Cache_news/1234@cernvax.cern.ch
+** /tmp/WWW_Cache_http/crnvmc/FIND/xx.xxx.xx
+**
+** On exit,
+** returns a malloc'ed string which must be freed by the caller.
+*/
+PUBLIC char * HTCacheFileName ARGS1(CONST char *,name)
+{
+ char * access = HTParse(name, "", PARSE_ACCESS);
+ char * host = HTParse(name, "", PARSE_HOST);
+ char * path = HTParse(name, "", PARSE_PATH+PARSE_PUNCTUATION);
+
+ char * result;
+ result = (char *)malloc(
+ strlen(HTCacheRoot)+strlen(access)
+ +strlen(host)+strlen(path)+6+1);
+ if (result == NULL) outofmem(__FILE__, "HTCacheFileName");
+ sprintf(result, "%s/WWW/%s/%s%s", HTCacheRoot, access, host, path);
+ free(path);
+ free(access);
+ free(host);
+ return result;
+}
+
+/* Open a file for write, creating the path
+** ----------------------------------------
+*/
+#ifdef NOT_IMPLEMENTED
+PRIVATE int HTCreatePath ARGS1(CONST char *,path)
+{
+ return -1;
+}
+#endif
+
+/* Convert filenames between local and WWW formats
+** -----------------------------------------------
+** Make up a suitable name for saving the node in
+**
+** E.g. $(HOME)/WWW/news/1234@cernvax.cern.ch
+** $(HOME)/WWW/http/crnvmc/FIND/xx.xxx.xx
+**
+** On exit,
+** returns a malloc'ed string which must be freed by the caller.
+*/
+PUBLIC char * HTLocalName ARGS1(CONST char *,name)
+{
+ char * access = HTParse(name, "", PARSE_ACCESS);
+ char * host = HTParse(name, "", PARSE_HOST);
+ char * path = HTParse(name, "", PARSE_PATH+PARSE_PUNCTUATION);
+
+ if (0==strcmp(access, "file")) {
+ free(access);
+ if ((0==strcmp(host, HTHostName())) || !*host) {
+ free(host);
+ if (TRACE) printf("Node `%s' means path `%s'\n", name, path);
+ return(path);
+ } else {
+ char * result = (char *)malloc(
+ strlen("/Net/")+strlen(host)+strlen(path)+1);
+ if (result == NULL) outofmem(__FILE__, "HTLocalName");
+ sprintf(result, "%s%s%s", "/Net/", host, path);
+ free(host);
+ free(path);
+ if (TRACE) printf("Node `%s' means file `%s'\n", name, result);
+ return result;
+ }
+ } else { /* other access */
+ char * result;
+ CONST char * home = (CONST char*)getenv("HOME");
+ if (!home) home = "/tmp";
+ result = (char *)malloc(
+ strlen(home)+strlen(access)+strlen(host)+strlen(path)+6+1);
+ if (result == NULL) outofmem(__FILE__, "HTLocalName");
+ sprintf(result, "%s/WWW/%s/%s%s", home, access, host, path);
+ free(path);
+ free(access);
+ free(host);
+ return result;
+ }
+}
+
+
+/* Make a WWW name from a full local path name
+**
+** Bugs:
+** At present, only the names of two network root nodes are hand-coded
+** in and valid for the NeXT only. This should be configurable in
+** the general case.
+*/
+
+PUBLIC char * WWW_nameOfFile ARGS1 (CONST char *,name)
+{
+ char * result;
+#ifdef NeXT
+ if (0==strncmp("/private/Net/", name, 13)) {
+ result = (char *)malloc(7+strlen(name+13)+1);
+ if (result == NULL) outofmem(__FILE__, "WWW_nameOfFile");
+ sprintf(result, "file://%s", name+13);
+ } else
+#endif
+ if (0==strncmp(HTMountRoot, name, 5)) {
+ result = (char *)malloc(7+strlen(name+5)+1);
+ if (result == NULL) outofmem(__FILE__, "WWW_nameOfFile");
+ sprintf(result, "file://%s", name+5);
+ } else {
+ result = (char *)malloc(7+strlen(HTHostName())+strlen(name)+1);
+ if (result == NULL) outofmem(__FILE__, "WWW_nameOfFile");
+ sprintf(result, "file://%s%s", HTHostName(), name);
+ }
+ if (TRACE) printf("File `%s'\n\tmeans node `%s'\n", name, result);
+ return result;
+}
+
+
+/* Determine file format from file name
+** ------------------------------------
+**
+** Note: This function is also in the server file HTRetrieve.c
+** If it gets complicated, it should be shared.
+**
+*/
+
+PUBLIC HTFormat HTFileFormat ARGS1 (CONST char *,filename)
+{
+ CONST char * extension;
+ for (extension=filename+strlen(filename);
+ (extension>filename) &&
+ (*extension != '.') &&
+ (*extension!='/');
+ extension--) /* search */ ;
+
+ if (*extension == '.') {
+ return 0==strcmp(".html", extension) ? WWW_HTML
+ : 0==strcmp(".rtf", extension) ? WWW_RICHTEXT
+ : 0==strcmp(".txt", extension) ? WWW_PLAINTEXT
+ : WWW_PLAINTEXT; /* Unrecognised, try plain text */
+ } else {
+ return WWW_PLAINTEXT;
+ }
+}
+
+
+/* Determine write access to a file
+// --------------------------------
+//
+// On exit,
+// return value YES if file can be accessed and can be written to.
+//
+// Bugs:
+// 1. No code for non-unix systems.
+// 2. Isn't there a quicker way?
+*/
+
+#ifdef vms
+#define NO_GROUPS
+#endif
+#ifdef NO_UNIX_IO
+#define NO_GROUPS
+#endif
+#ifdef PCNFS
+#define NO_GROUPS
+#endif
+
+PUBLIC BOOL HTEditable ARGS1 (CONST char *,filename)
+{
+#ifdef NO_GROUPS
+ return NO; /* Safe answer till we find the correct algorithm */
+#else
+ int groups[NGROUPS];
+ uid_t myUid;
+ int ngroups; /* The number of groups */
+ struct stat fileStatus;
+ int i;
+
+ if (stat(filename, &fileStatus)) /* Get details of filename */
+ return NO; /* Can't even access file! */
+
+ ngroups = getgroups(NGROUPS, groups); /* Groups to which I belong */
+ myUid = geteuid(); /* Get my user identifier */
+
+ if (TRACE) {
+ int i;
+ printf("File mode is 0%o, uid=%d, gid=%d. My uid=%d, %d groups (",
+ fileStatus.st_mode, fileStatus.st_uid, fileStatus.st_gid,
+ myUid, ngroups);
+ for (i=0; i<ngroups; i++) printf(" %d", groups[i]);
+ printf(")\n");
+ }
+
+ if (fileStatus.st_mode & 0002) /* I can write anyway? */
+ return YES;
+
+ if ((fileStatus.st_mode & 0200) /* I can write my own file? */
+ && (fileStatus.st_uid == myUid))
+ return YES;
+
+ if (fileStatus.st_mode & 0020) /* Group I am in can write? */
+ {
+ for (i=0; i<ngroups; i++) {
+ if (groups[i] == fileStatus.st_gid)
+ return YES;
+ }
+ }
+ if (TRACE) printf("\tFile is not editable.\n");
+ return NO; /* If no excuse, can't do */
+#endif
+}
+
+
+/* Open a file descriptor for a document
+** -------------------------------------
+**
+** On entry,
+** addr must point to the fully qualified hypertext reference.
+**
+** On exit,
+** returns <0 Error has occured.
+** >=0 Value of file descriptor or socket to be used
+** to read data.
+** *pFormat Set to the format of the file, if known.
+** (See WWW.h)
+**
+*/
+int HTOpenFile
+ARGS3
+(
+ CONST char *,addr,
+ HTFormat *,pFormat,
+ HTParentAnchor *,anchor
+)
+{
+ char * filename;
+ int fd = -1; /* Unix file descriptor number = INVALID */
+ char * nodename = 0;
+ char * newname=0; /* Simplified name of file */
+
+/* Reduce the filename to a basic form (hopefully unique!)
+*/
+ StrAllocCopy(newname, addr);
+ filename=HTParse(newname, "", PARSE_PATH|PARSE_PUNCTUATION);
+ nodename=HTParse(newname, "", PARSE_HOST);
+ free(newname);
+
+ *pFormat = HTFileFormat(filename);
+
+
+#ifdef vms
+/* Assume that the file is remote vms or ultrix if no domain name @@ */
+ if (!strchr(nodename, '.')) {
+ char * vmsname = vms_name(nodename, filename);
+ fd = open(vmsname, O_RDONLY, 0);
+
+/* If the file wasn't VMS syntax, then perhaps it is ultrix
+*/
+ if (fd<0) {
+ char ultrixname[INFINITY];
+ if (TRACE) fprintf(stderr, "HTFile: Can't open as %s\n", vmsname);
+ sprintf(ultrixname, "%s::\"%s\"", nodename, filename);
+ fd = open(ultrixname, O_RDONLY, 0);
+ if (fd<0) {
+ if (TRACE) fprintf(stderr,
+ "HTFile: Can't open as %s\n", ultrixname);
+ }
+ }
+ }
+#else
+
+/* For unix, we try to translate the name into the name of a transparently
+** mounted file.
+*/
+#ifndef NO_UNIX_IO
+ {
+ char * localname = HTLocalName(addr);
+
+
+#ifdef GOT_READ_DIR
+/*
+** Check to see if the 'localname' is in fact a directory. If it is
+** create a new hypertext object containing a list of files and
+** subdirectories contained in the directory. All of these are links
+** to the directories or files listed.
+** NB This assumes the existance of a type 'struct direct', which will
+** hold the directory entry, and a type 'DIR' which is used to point to
+** the current directory being read.
+*/
+
+ struct stat dir_info;
+
+ if (stat(localname,&dir_info) == -1) { /* get file information */
+ /* if can't read file information */
+ if (TRACE) fprintf(stderr, "HTFile: can't stat %s\n", localname);
+
+ } else { /* Stat was OK */
+
+
+ if (((dir_info.st_mode) & S_IFMT) == S_IFDIR) {
+ /* if localname is a directory */
+ HTChildAnchor * child;
+ HText * HT;
+ extern HTStyleSheet * styleSheet;
+ static HTStyle * DirectoryStyle = 0;
+ static HTStyle * H1Style = 0;
+ DIR *dp;
+ struct direct * dirbuf;
+
+ char * tmpfilename = NULL;
+ char * shortfilename = NULL;
+ struct stat *file_info = malloc(sizeof(struct stat));
+
+ if (TRACE)
+ fprintf(stderr,"%s is a directory\n",localname);
+
+ if (!H1Style)
+ H1Style = HTStyleNamed(styleSheet, "Heading1");
+
+ if (!DirectoryStyle)
+ DirectoryStyle = HTStyleNamed(styleSheet, "Dir");
+
+ HTAnchor_setTitle(anchor, filename);
+
+ HT = HText_new(anchor);
+ HText_beginAppend(HT);
+
+ HText_setStyle(HT,H1Style);
+ shortfilename=strrchr(localname,'/');
+ /* put the last part of the path in shortfilename */
+ shortfilename++; /* get rid of leading '/' */
+ if (*shortfilename=='\0')
+ shortfilename--;
+
+ HText_appendText(HT,shortfilename);
+ HText_setStyle(HT,DirectoryStyle);
+
+ dp = opendir(localname);
+ if (dp) {
+ /* if the directory file is readable */
+ while (dirbuf = readdir(dp)) {
+ /* while there are directory entries to be read */
+ if (dirbuf->d_ino == 0)
+ /* if the entry is not being used, skip it */
+ continue;
+
+ if (!strcmp(dirbuf->d_name,"."))
+ continue; /* skip the entry for this directory */
+
+ if (strcmp(dirbuf->d_name,".."))
+ /* if the current entry is parent directory */
+ if ((*(dirbuf->d_name)=='.') ||
+ (*(dirbuf->d_name)==','))
+ continue; /* skip those files whose name begins
+ with '.' or ',' */
+
+ StrAllocCopy(tmpfilename,localname);
+ if (strcmp(localname,"/"))
+ /* if filename is not root directory */
+ StrAllocCat(tmpfilename,"/");
+ else
+ if (!strcmp(dirbuf->d_name,".."))
+ continue;
+ /* if root directory and current entry is parent
+ directory, skip the current entry */
+
+ StrAllocCat(tmpfilename,dirbuf->d_name);
+ /* append the current entry's filename to the path */
+ HTSimplify(tmpfilename);
+
+ child = HTAnchor_findChildAndLink(
+ anchor, 0, tmpfilename, 0);
+ HText_beginAnchor(HT, child);
+ stat(tmpfilename,file_info);
+
+ if (strcmp(dirbuf->d_name,"..")) {
+/* if the current entry is not the parent directory then use the file name */
+ HText_appendText(HT,dirbuf->d_name);
+ if (((file_info->st_mode) & S_IFMT) == S_IFDIR)
+ HText_appendCharacter(HT, '/');
+ }
+ else {
+ /* use name of parent directory */
+ char * endbit = strrchr(tmpfilename, '/');
+ HText_appendText(HT,"Up to ");
+ HText_appendText(HT, endbit?endbit+1:tmpfilename);
+ }
+ HText_endAnchor(HT);
+
+ HText_appendCharacter(HT, '\t');
+ } /* end while directory entries left to read */
+
+ closedir(dp);
+ free(tmpfilename);
+
+ } else { /* Directory is not readable */
+ if (TRACE)
+ fprintf(stderr,"HTFile.c: directory %s unreadable\n",
+ localname);
+ HText_appendText(HT,
+ "Sorry, can't read the contents of this directory - probably read protected\n");
+
+ } /* end if directory not readable */
+
+ HText_endAppend(HT);
+
+ free(file_info);
+ free(filename);
+ free(localname);
+ return HT_LOADED; /* fd not valid, but document loaded anyway */
+
+ } /* end if localname is directory */
+
+ } /* end if file stat worked */
+
+/* End of directory reading section
+*/
+#endif
+
+ fd = open(localname, O_RDONLY, 0);
+ if(TRACE) printf ("HTAccess: Opening `%s' gives %d\n",
+ localname, fd);
+ free(localname);
+ }
+#endif
+#endif
+
+/* Now, as transparently mounted access has failed, we try FTP.
+*/
+ if (fd<0)
+ if (strcmp(nodename, HTHostName())!=0) {
+ free(filename);
+ return HTFTP_open_file_read(addr, anchor);
+ }
+
+/* All attempts have failed if fd<0.
+*/
+ if (fd<0) printf("Can't open `%s', errno=%d\n", filename, errno);
+ free(filename);
+ return fd;
+
+}
--- /dev/null
+/* File Access HTFile.h
+** ===========
+**
+** These are routines for file access used by WWW browsers.
+**
+*/
+
+#include "HTFormat.h"
+
+/* Convert filenames between local and WWW formats
+** -----------------------------------------------
+** Make up a suitable name for saving the node in
+**
+** E.g. $(HOME)/WWW/news/1234@cernvax.cern.ch
+** $(HOME)/WWW/http/crnvmc/FIND/xx.xxx.xx
+*/
+#ifdef __STDC__
+extern char * HTLocalName(const char * name);
+#else
+extern char * HTLocalName();
+#endif
+
+/* Make a WWW name from a full local path name
+**
+*/
+extern char * WWW_nameOfFile PARAMS((const char * name));
+
+
+/* Generate the name of a cache file
+*/
+
+extern char * HTCacheFileName PARAMS((CONST char * name));
+
+
+/* Determine file format from file name
+** ------------------------------------
+*/
+
+#ifdef __STDC__
+extern int HTFileFormat(const char * filename);
+#else
+extern int HTFileFormat();
+#endif
+
+
+/* Determine write access to a file
+// --------------------------------
+//
+// On exit,
+// return value YES if file can be accessed and can be written to.
+//
+// Isn't there a quicker way?
+*/
+
+#ifdef __STDC__
+extern BOOL HTEditable(const char * filename);
+#else
+extern BOOL HTEditable();
+#endif
+
+
+/* Open a file descriptor for a document
+** -------------------------------------
+**
+** On entry,
+** addr must point to the fully qualified hypertext reference.
+**
+** On exit,
+** returns <0 Error has occured.
+** >=0 Value of file descriptor or socket to be used
+** to read data.
+** *pFormat Set to the format of the file, if known.
+** (See WWW.h)
+**
+*/
+extern int HTOpenFile
+PARAMS
+((
+ const char * addr,
+ HTFormat * pFormat,
+ HTParentAnchor * anchor
+));
+
--- /dev/null
+/* The portable font concept (!?*)
+*/
+
+/* Line mode browser version:
+*/
+
+typedef int HTFont; /* For now */
+
+#define HT_NON_BREAK_SPACE ((char)1) /* For now */
+
+#define HT_FONT 0
+#define HT_CAPITALS 1
+#define HT_BOLD 2
+#define HT_UNDERLINE 4
+#define HT_INVERSE 8
+#define HT_DOUBLE 0x10
+
+#define HT_BLACK 0
+#define HT_WHITE 1
--- /dev/null
+/* Manage different file formats HTFormat.c
+** =============================
+**
+** Bugs:
+** Not reentrant.
+**
+** Assumes the incoming stream is ASCII, rather than a local file
+** format, and so ALWAYS converts from ASCII on non-ASCII machines.
+** Therefore, non-ASCII machines can't read local files.
+*/
+
+#include "HTUtils.h"
+#include "tcp.h"
+#include "HTFormat.h"
+
+#include "HTML.h"
+#include "HText.h"
+#include "HTStyle.h"
+
+extern HTStyleSheet * styleSheet;
+
+/* File buffering
+** --------------
+**
+** The input file is read using the macro which can read from
+** a socket or a file.
+** The input buffer size, if large will give greater efficiency and
+** release the server faster, and if small will save space on PCs etc.
+*/
+#define INPUT_BUFFER_SIZE 4096 /* Tradeoff */
+PRIVATE char input_buffer[INPUT_BUFFER_SIZE];
+PRIVATE char * input_pointer;
+PRIVATE char * input_limit;
+PRIVATE int input_file_number;
+
+
+/* Set up the buffering
+**
+** These routines are public because they are in fact needed by
+** many parsers, and on PCs and Macs we should not duplicate
+** the static buffer area.
+*/
+PUBLIC void HTInitInput ARGS1 (int,file_number)
+{
+ input_file_number = file_number;
+ input_pointer = input_limit = input_buffer;
+}
+
+
+PUBLIC char HTGetChararcter NOARGS
+{
+ char ch;
+ do {
+ if (input_pointer >= input_limit) {
+#ifdef ERWISE
+ int status = cl_read_data(
+ input_file_number, input_buffer, INPUT_BUFFER_SIZE);
+#else
+ int status = NETREAD(
+ input_file_number, input_buffer, INPUT_BUFFER_SIZE);
+#endif
+ if (status <= 0) {
+ if (status == 0) return (char)EOF;
+ if (TRACE) fprintf(stderr,
+ "HTFormat: File read error %d\n", status);
+ return (char)EOF; /* -1 is returned by UCX at end of HTTP link */
+ }
+ input_pointer = input_buffer;
+ input_limit = input_buffer + status;
+ }
+ ch = *input_pointer++;
+ } while (ch == (char) 13); /* Ignore ASCII carriage return */
+
+ return FROMASCII(ch);
+}
+
+
+/* Parse a file given format and file number
+** ------------
+*/
+PUBLIC void HTParseFormat ARGS3(
+ HTFormat,format,
+ HTParentAnchor *,anchor,
+ int,file_number)
+{
+/* Parse the file
+*/
+#ifdef CURSES
+ long bytecount = 0;
+#endif
+ HTInitInput(file_number);
+
+ switch (format) {
+
+ case WWW_HTML: /* Parse HTML */
+ {
+ HTML_begin(anchor);
+ SGML_begin(&HTML_dtd);
+ for(;;) {
+ char character;
+ character = HTGetChararcter();
+ if (character == (char)EOF) break;
+#ifdef CURSES
+ if (++bytecount % 1024 == 0) prompt_count(bytecount / 1024);
+#endif
+
+ SGML_character(&HTML_dtd, character);
+ }
+ SGML_end(&HTML_dtd);
+ }
+ break;
+
+ default : /* unknown format -- Parse plain text */
+ {
+ HText * text = HText_new(anchor);
+ HText_setStyle(text, HTStyleNamed(styleSheet, "Example"));
+ HText_beginAppend(text);
+ for(;;) {
+ char character;
+ character = HTGetChararcter();
+ if (character == (char)EOF) break;
+#ifdef CURSES
+ if (++bytecount % 1024 == 0) prompt_count(bytecount / 1024);
+#endif
+ HText_appendCharacter(text, character);
+ }
+ HText_endAppend(text);
+ }
+ break;
+
+ } /* end of switch (format) */
+
+}
--- /dev/null
+/* Manage different file formats HTFormat.c
+** =============================
+**
+*/
+#ifndef HTFORMAT_H
+#define HTFORMAT_H
+
+#include "HTUtils.h"
+
+typedef int HTFormat;
+ /* Can take the following values: */
+#define WWW_INVALID (-1)
+#define WWW_SOURCE 0 /* Whatever it was */
+#define WWW_PLAINTEXT 1 /* plain ISO latin (ASCII) */
+#define WWW_POSTSCRIPT 2 /* Postscript - encapsulated? */
+#define WWW_RICHTEXT 3 /* Microsoft RTF transfer format */
+#define WWW_HTML 4 /* WWW HyperText Markup Language */
+#define WWW_BINARY 5 /* Otherwise Unknown binary format */
+
+#include "HTAnchor.h"
+
+
+/* Clear input buffer and set file number
+*/
+extern void HTInitInput PARAMS((int file_number));
+
+/* Get next character from buffer
+*/
+extern char HTGetChararcter NOPARAMS;
+
+
+/* Parse a file given its format
+*/
+extern void HTParseFormat PARAMS((
+ HTFormat format,
+ HTParentAnchor *anchor,
+ int file_number));
+
+#endif
--- /dev/null
+/* GOPHER ACCESS HTGopher.c
+** =============
+**
+** History:
+** 26 Sep 90 Adapted from other accesses (News, HTTP) TBL
+** 29 Nov 91 Downgraded to C, for portable implementation.
+*/
+
+#define GOPHER_PORT 70 /* See protocol spec */
+#define BIG 1024 /* Bug */
+#define LINE_LENGTH 256 /* Bug */
+
+/* Gopher entity types:
+*/
+#define GOPHER_TEXT '0'
+#define GOPHER_MENU '1'
+#define GOPHER_CSO '2'
+#define GOPHER_ERROR '3'
+#define GOPHER_MACBINHEX '4'
+#define GOPHER_PCBINHEX '5'
+#define GOPHER_UUENCODED '6'
+#define GOPHER_INDEX '7'
+#define GOPHER_TELNET '8'
+#define GOPHER_HTML 'h' /* HTML */
+#define GOPHER_DUPLICATE '+'
+#define GOPHER_WWW 'w' /* W3 address */
+
+#include <ctype.h>
+#include "HTUtils.h" /* Coding convention macros */
+#include "tcp.h"
+
+#include "HTGopher.h"
+
+#include "HText.h"
+#include "HTParse.h"
+#include "HTFormat.h"
+#include "HTTCP.h"
+
+#ifdef NeXTStep
+#include <appkit/defaults.h>
+#define GOPHER_PROGRESS(foo)
+#else
+#define GOPHER_PROGRESS(foo) printf("%s\n", (foo))
+#endif
+
+extern HTStyleSheet * styleSheet;
+
+#define NEXT_CHAR HTGetChararcter()
+
+
+
+/* Module-wide variables
+*/
+PRIVATE int s; /* Socket for GopherHost */
+PRIVATE HText * HT; /* the new hypertext */
+PRIVATE HTParentAnchor *node_anchor; /* Its anchor */
+PRIVATE int diagnostic; /* level: 0=none 2=source */
+
+PRIVATE HTStyle *addressStyle; /* For address etc */
+PRIVATE HTStyle *heading1Style; /* For heading level 1 */
+PRIVATE HTStyle *textStyle; /* Text style */
+
+
+/* Matrix of allowed characters in filenames
+** -----------------------------------------
+*/
+
+PRIVATE BOOL acceptable[256];
+PRIVATE BOOL acceptable_inited = NO;
+
+PRIVATE void init_acceptable NOARGS
+{
+ unsigned int i;
+ char * good =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./-_$";
+ for(i=0; i<256; i++) acceptable[i] = NO;
+ for(;*good; good++) acceptable[(unsigned int)*good] = YES;
+ acceptable_inited = YES;
+}
+
+PRIVATE CONST char hex[17] = "0123456789abcdef";
+
+/* Decdoe one hex character
+*/
+
+PRIVATE char from_hex ARGS1(char, c)
+{
+ return (c>='0')&&(c<='9') ? c-'0'
+ : (c>='A')&&(c<='F') ? c-'A'+10
+ : (c>='a')&&(c<='f') ? c-'a'+10
+ : 0;
+}
+
+
+
+/* Get Styles from stylesheet
+** --------------------------
+*/
+PRIVATE void get_styles NOARGS
+{
+ if (!heading1Style) heading1Style = HTStyleNamed(styleSheet, "Heading1");
+ if (!addressStyle) addressStyle = HTStyleNamed(styleSheet, "Address");
+ if (!textStyle) textStyle = HTStyleNamed(styleSheet, "Example");
+}
+
+
+/* Paste in an Anchor
+** ------------------
+**
+** The title of the destination is set, as there is no way
+** of knowing what the title is when we arrive.
+**
+** On entry,
+** HT is in append mode.
+** text points to the text to be put into the file, 0 terminated.
+** addr points to the hypertext refernce address 0 terminated.
+*/
+PRIVATE void write_anchor ARGS2(CONST char *,text, CONST char *,addr)
+{
+ HTChildAnchor *anchor;
+ HTParentAnchor *dest;
+
+ HText_beginAnchor(HT,
+ anchor = HTAnchor_findChildAndLink(node_anchor, "", addr, 0));
+ dest = HTAnchor_parent(
+ HTAnchor_followMainLink((HTAnchor *)anchor));
+
+ if (!HTAnchor_title(dest)) HTAnchor_setTitle(dest, text);
+
+ HText_appendText(HT, text);
+ HText_endAnchor(HT);
+}
+
+
+/* Parse a Gopher Menu document
+** ============================
+**
+*/
+
+PRIVATE void parse_menu ARGS2 (
+ CONST char *, arg,
+ HTParentAnchor *,anAnchor)
+{
+ char gtype;
+ char ch;
+ char line[BIG];
+ char address[BIG];
+ char *name, *selector; /* Gopher menu fields */
+ char *host;
+ char *port;
+ char *p = line;
+
+
+#define TAB '\t'
+#define HEX_ESCAPE '%'
+
+ if (!HTAnchor_title(anAnchor))
+ HTAnchor_setTitle(anAnchor, arg);/* Tell user something's happening */
+
+ node_anchor = anAnchor;
+ HT = HText_new(anAnchor);
+
+ HText_beginAppend(HT);
+ HText_appendText(HT, "Select one of:\n");
+
+ while ((ch=NEXT_CHAR) != (char)EOF) {
+
+ if (ch != '\n') {
+ *p = ch; /* Put character in line */
+ if (p< &line[BIG-1]) p++;
+
+ } else {
+ *p++ = 0; /* Terminate line */
+ p = line; /* Scan it to parse it */
+ port = 0; /* Flag "not parsed" */
+ if (TRACE) fprintf(stderr, "HTGopher: Menu item: %s\n", line);
+ gtype = *p++;
+
+ /* Break on line with a dot by itself */
+ if ((gtype=='.') && ((*p=='\r') || (*p==0))) break;
+
+ if (gtype && *p) {
+ name = p;
+ selector = strchr(name, TAB);
+ if (selector) {
+ *selector++ = 0; /* Terminate name */
+ host = strchr(selector, TAB);
+ if (host) {
+ *host++ = 0; /* Terminate selector */
+ port = strchr(host, TAB);
+ if (port) {
+ char *junk;
+ port[0] = ':'; /* delimit host a la W3 */
+ junk = strchr(port, TAB);
+ if (junk) *junk++ = 0; /* Chop port */
+ if ((port[1]=='0') && (!port[2]))
+ port[0] = 0; /* 0 means none */
+ } /* no port */
+ } /* host ok */
+ } /* selector ok */
+ } /* gtype and name ok */
+
+ if (gtype == GOPHER_WWW) { /* Gopher pointer to W3 */
+ write_anchor(name, selector);
+ HText_appendParagraph(HT);
+
+ } else if (port) { /* Other types need port */
+ if (gtype == GOPHER_TELNET) {
+ if (*selector) sprintf(address, "telnet://%s@%s/",
+ selector, host);
+ else sprintf(address, "telnet://%s/", host);
+
+ } else { /* If parsed ok */
+ char *q;
+ char *p;
+ sprintf(address, "//%s/%c", host, gtype);
+ q = address+ strlen(address);
+ for(p=selector; *p; p++) { /* Encode selector string */
+ if (acceptable[*p]) *q++ = *p;
+ else {
+ *q++ = HEX_ESCAPE; /* Means hex coming */
+ *q++ = hex[(*p) >> 4];
+ *q++ = hex[(*p) & 15];
+ }
+ }
+ *q++ = 0; /* terminate address */
+ }
+ write_anchor(name, address);
+ HText_appendParagraph(HT);
+ } else { /* parse error */
+ if (TRACE) fprintf(stderr,
+ "HTGopher: Bad menu item.\n");
+ HText_appendText(HT, line);
+ HText_appendParagraph(HT);
+ } /* parse error */
+
+ p = line; /* Start again at beginning of line */
+
+ } /* if end of line */
+
+ } /* Loop over characters */
+
+ HText_endAppend(HT);
+ return;
+}
+
+/* Display a Gopher Index document
+** -------------------------------
+*/
+
+PRIVATE void display_index ARGS2 (
+ CONST char *, arg,
+ HTParentAnchor *,anAnchor)
+{
+ node_anchor = anAnchor;
+ HT = HText_new(anAnchor);
+ HText_beginAppend(HT);
+ HText_setStyle(HT, heading1Style);
+ HText_appendText(HT, arg);
+ HText_setStyle(HT, textStyle);
+ HText_appendText(HT, "\nThis is a searchable index.\n");
+
+ if (!HTAnchor_title(anAnchor))
+ HTAnchor_setTitle(anAnchor, arg);/* Tell user something's happening */
+
+ HText_endAppend(HT);
+ return;
+}
+
+
+/* Load by name HTLoadGopher
+** ============
+**
+** Bug: No decoding of strange data types as yet.
+**
+*/
+PUBLIC int HTLoadGopher ARGS3(
+ CONST char *,arg,
+ HTParentAnchor *,anAnchor,
+ int,diag)
+{
+ char *command; /* The whole command */
+ int status; /* tcp return */
+ char gtype; /* Gopher Node type */
+ char * selector; /* Selector string */
+
+ struct sockaddr_in soc_address; /* Binary network address */
+ struct sockaddr_in* sin = &soc_address;
+
+ diagnostic = diag; /* set global flag */
+
+ if (!acceptable_inited) init_acceptable();
+
+ if (!arg) return -3; /* Bad if no name sepcified */
+ if (!*arg) return -2; /* Bad if name had zero length */
+
+ if (TRACE) printf("HTGopher: Looking for %s\n", arg);
+ get_styles();
+
+
+/* Set up defaults:
+*/
+ sin->sin_family = AF_INET; /* Family, host order */
+ sin->sin_port = htons(GOPHER_PORT); /* Default: new port, */
+
+ if (TRACE) printf("HTTPAccess: Looking for %s\n", arg);
+
+/* Get node name and optional port number:
+*/
+ {
+ char *p1 = HTParse(arg, "", PARSE_HOST);
+ HTParseInet(sin, p1);
+ free(p1);
+ }
+
+/* Get entity type, and selector string.
+*/
+ {
+ char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION);
+ gtype = '1'; /* Default = menu */
+ selector = p1;
+ if ((*selector++=='/') && (*selector)) { /* Skip first slash */
+ gtype = *selector++; /* Pick up gtype */
+ }
+ if (gtype == GOPHER_INDEX) {
+ HTAnchor_setIndex(anAnchor); /* Search is allowed */
+ selector = strchr(selector, '?'); /* Look for search string */
+ if (!selector || !*selector) { /* No search required */
+ display_index(arg, anAnchor); /* Display "cover page" */
+ return 1; /* Local function only */
+ }
+ command = malloc(strlen(selector)+ 2 + 1);
+ if (command == NULL) outofmem(__FILE__, "HTLoadGopher");
+ strcpy(command, selector);
+
+ } else { /* Not index */
+ char * p = selector;
+ char * q = command = malloc(strlen(selector)+2+1);
+ if (command == NULL) outofmem(__FILE__, "HTLoadGopher");
+ while (*p) { /* Decode hex */
+ if (*p == HEX_ESCAPE) {
+ char c;
+ unsigned int b;
+ p++;
+ c = *p++;
+ b = from_hex(c);
+ c = *p++;
+ if (!c) break; /* Odd number of chars! */
+ *q++ = (b<<4) + from_hex(c);
+ } else {
+ *q++ = *p++; /* Record */
+ }
+ }
+ *q++ = 0; /* Terminate command */
+ }
+ free(p1);
+ }
+
+ strcat(command, "\r\n"); /* Include CR for telnet compat. */
+
+
+/* Set up a socket to the server for the data:
+*/
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ status = connect(s, (struct sockaddr*)&soc_address, sizeof(soc_address));
+ if (status<0){
+ if (TRACE) printf("HTTPAccess: Unable to connect to remote host for `%s'.\n",
+ arg);
+ free(command);
+ return HTInetStatus("connect");
+ }
+
+ HTInitInput(s); /* Set up input buffereing */
+
+ if (TRACE) printf("HTGopher: Connected, writing command `%s' to socket %d\n", command, s);
+
+#ifdef NOT_ASCII
+ {
+ char * p;
+ for(p = command; *p; p++) {
+ *p = TOASCII(*p);
+ }
+ }
+#endif
+
+ status = NETWRITE(s, command, (int)strlen(command));
+ free(command);
+ if (status<0){
+ if (TRACE) printf("HTGopher: Unable to send command.\n");
+ return HTInetStatus("send");
+ }
+
+/* Now read the data from the socket:
+*/
+ if (diagnostic==2) gtype = GOPHER_TEXT; /* Read as plain text anyway */
+
+ switch (gtype) {
+
+ case GOPHER_HTML :
+ HTParseFormat(WWW_HTML, anAnchor, s);
+ return 1;
+
+ case GOPHER_MENU :
+ case GOPHER_INDEX :
+ parse_menu(arg, anAnchor);
+ return 1;
+
+ case GOPHER_TEXT :
+ default: /* @@ parse as plain text */
+ HTParseFormat(WWW_PLAINTEXT, anAnchor, s);
+ return 1;
+ } /* switch(gtype) */
+ /*NOTREACHED*/
+}
+
--- /dev/null
+/* GOPHER ACCESS HTGopher.h
+** =============
+**
+** History:
+** 8 Jan 92 Adapted from HTTP TBL
+*/
+
+#ifndef HTGOPHER_H
+#define HTGOPHER_H
+
+#include "HTAnchor.h"
+extern int HTLoadGopher PARAMS((const char *arg,
+ HTParentAnchor * anAnchor,
+ int diag));
+
+#endif /* HTGOPHER_H */
--- /dev/null
+#include "HTHistory.h"
+
+#include "tcp.h" /* for standard io */
+
+static HTList * history; /* List of visited anchors */
+
+
+/* Navigation
+** ==========
+*/
+
+/* Record the jump to an anchor
+** ----------------------------
+*/
+
+void HTHistory_record
+ ARGS1 (HTAnchor *,destination)
+{
+ if (destination) {
+ if (! history)
+ history = HTList_new();
+ HTList_addObject (history, destination);
+ }
+}
+
+/* Go back in history (find the last visited node)
+** ------------------
+*/
+
+HTAnchor * HTHistory_backtrack
+ NOARGS /* FIXME: Should we add a `sticky' option ? */
+{
+ if (HTHistory_canBacktrack())
+ HTList_removeLastObject (history);
+ return HTList_lastObject (history); /* is Home if can't backtrack */
+}
+
+BOOL HTHistory_canBacktrack
+ NOARGS
+{
+ return (HTList_objectAt (history, 1) != NULL);
+}
+
+/* Browse through references in the same parent node
+** -------------------------------------------------
+**
+** Take the n-th child's link after or before the one we took to get here.
+** Positive offset means go towards most recently added children.
+*/
+
+HTAnchor * HTHistory_moveBy
+ ARGS1 (int,offset)
+{
+ HTAnchor * last = HTList_objectAt (history, 1);
+ if (! last)
+ return NULL; /* No last visited node */
+ if (last != (HTAnchor *) last->parent) { /* Was a child */
+ HTList * kids = last->parent->children;
+ int i = HTList_indexOf (kids, last);
+ HTAnchor * nextOne = HTList_objectAt (kids, i - offset);
+ if (nextOne) {
+ HTAnchor * destination = HTAnchor_followMainLink (nextOne);
+ if (destination) {
+ HTList_removeLastObject (history);
+ HTList_removeLastObject (history);
+ HTList_addObject (history, nextOne);
+ HTList_addObject (history, destination);
+ }
+ return destination;
+ } else {
+ if (TRACE) printf(
+ "HTHistory_moveBy: offset by %+d goes out of list %p.\n",
+ offset, kids);
+ return NULL;
+ }
+ } else { /* Was a parent */
+ return NULL; /* FIXME we could possibly follow the next link... */
+ }
+}
+
+BOOL HTHistory_canMoveBy
+ ARGS1 (int,offset)
+{
+ HTAnchor * last = HTList_objectAt (history, 1);
+ if (! last)
+ return NO; /* No last visited node */
+ if (last != (HTAnchor *) last->parent) { /* Was a child */
+ HTList * kids = last->parent->children;
+ int i = HTList_indexOf (kids, last);
+ return (HTList_objectAt (kids, i - offset) != NULL);
+ } else { /* Was a parent */
+ return NO; /* FIXME we could possibly follow the next link... */
+ }
+}
+
+
+/* Retrieval
+** =========
+*/
+
+/* Read numbered visited anchor (1 is the oldest)
+** ----------------------------
+*/
+
+HTAnchor * HTHistory_read
+ ARGS1 (int,number)
+{
+ return HTList_objectAt (history, HTList_count (history) - number);
+}
+
+
+/* Recall numbered visited anchor (1 is the oldest)
+** ------------------------------
+** This reads the anchor and stores it again in the list, except if last.
+*/
+
+HTAnchor * HTHistory_recall
+ ARGS1 (int,number)
+{
+ HTAnchor * destination =
+ HTList_objectAt (history, HTList_count (history) - number);
+ if (destination && destination != HTList_lastObject (history))
+ HTList_addObject (history, destination);
+ return destination;
+}
+
+/* Number of Anchors stored
+** ------------------------
+**
+** This is needed in order to check the validity of certain commands
+** for menus, etc.
+(not needed for now. Use canBacktrack, etc.)
+int HTHistory_count
+ NOARGS
+{
+ return HTList_count (history);
+}
+*/
+
+/* Change last history entry
+** -------------------------
+**
+** Sometimes we load a node by one anchor but leave by a different
+** one, and it is the one we left from which we want to remember.
+*/
+
+void HTHistory_leavingFrom
+ ARGS1 (HTAnchor *,anchor)
+{
+ if (HTList_removeLastObject (history))
+ HTList_addObject (history, anchor);
+ else
+ if (TRACE) fprintf(stderr, "HTHistory_leavingFrom: empty history !\n");
+}
--- /dev/null
+#ifndef HTHISTORY_H
+#define HTHISTORY_H
+
+#include "HTAnchor.h"
+
+#ifdef SHORT_NAMES
+#define HTHistory_record HTHiReco
+#define HTHistory_backtrack HTHiBack
+#define HTHistory_canBacktrack HTHiCaBa
+#define HTHistory_moveBy HTHiMoBy
+#define HTHistory_canMoveBy HTHiCaMo
+#define HTHistory_read HTHiRead
+#define HTHistory_recall HTHiReca
+#define HTHistory_count HTHiCoun
+#define HTHistory_leavingFrom HTHiLeFr
+#endif
+
+/* Navigation
+** ==========
+*/
+
+/* Record the jump to an anchor
+** ----------------------------
+*/
+
+extern void HTHistory_record
+ PARAMS(
+ (HTAnchor * destination)
+ );
+
+/* Go back in history (find the last visited node)
+** ------------------
+*/
+
+extern HTAnchor * HTHistory_backtrack
+ NOPARAMS; /* FIXME: Should we add a `sticky' option ? */
+
+extern BOOL HTHistory_canBacktrack
+ NOPARAMS;
+
+/* Browse through references in the same parent node
+** -------------------------------------------------
+**
+** Take the n-th child's link after or before the one we took to get here.
+** Positive offset means go towards most recently added children.
+*/
+
+extern HTAnchor * HTHistory_moveBy
+ PARAMS(
+ (int offset)
+ );
+
+extern BOOL HTHistory_canMoveBy
+ PARAMS(
+ (int offset)
+ );
+
+#define HTHistory_next (HTHistory_moveBy (+1))
+#define HTHistory_canNext (HTHistory_canMoveBy (+1))
+#define HTHistory_previous (HTHistory_moveBy (-1))
+#define HTHistory_canPrevious (HTHistory_canMoveBy (-1))
+
+
+/* Retrieval
+** =========
+*/
+
+/* Read numbered visited anchor (1 is the oldest)
+** ----------------------------
+*/
+
+extern HTAnchor * HTHistory_read
+ PARAMS(
+ (int number)
+ );
+
+/* Recall numbered visited anchor (1 is the oldest)
+** ------------------------------
+** This reads the anchor and stores it again in the list, except if last.
+*/
+
+extern HTAnchor * HTHistory_recall
+ PARAMS(
+ (int number)
+ );
+
+/* Number of Anchors stored
+** ------------------------
+**
+** This is needed in order to check the validity of certain commands
+** for menus, etc.
+(not needed for now. Use canBacktrack, etc.)
+extern int HTHistory_count NOPARAMS;
+*/
+
+/* Change last history entry
+** -------------------------
+**
+** Sometimes we load a node by one anchor but leave by a different
+** one, and it is the one we left from which we want to remember.
+*/
+extern void HTHistory_leavingFrom
+ PARAMS(
+ (HTAnchor * anchor)
+ );
+
+#endif /* HTHISTORY_H */
--- /dev/null
+/* A small List class HTList.c
+** ==================
+**
+** A list is represented as a sequence of linked nodes of type HTList.
+** The first node is a header which contains no object.
+** New nodes are inserted between the header and the rest of the list.
+*/
+
+#include "HTList.h"
+
+#ifdef ERWISE
+#include <stdio.h>
+#endif
+
+HTList * HTList_new NOARGS
+{
+ HTList *newList = (HTList *)malloc (sizeof (HTList));
+ if (newList == NULL) outofmem(__FILE__, "HTList_new");
+ newList->object = NULL;
+ newList->next = NULL;
+ return newList;
+}
+
+void HTList_delete ARGS1(HTList *,this)
+{
+ HTList *current;
+ while (current = this) {
+ this = this->next;
+ free (current);
+ }
+}
+
+void HTList_addObject ARGS2(HTList *,this, void *,newObject)
+{
+ if (this) {
+ HTList *newNode = (HTList *)malloc (sizeof (HTList));
+ if (newNode == NULL) outofmem(__FILE__, "HTList_addObject");
+ newNode->object = newObject;
+ newNode->next = this->next;
+ this->next = newNode;
+ }
+ else
+ if (TRACE) printf ("HTList: Trying to add object %p to a nonexisting list\n",
+ newObject);
+}
+
+BOOL HTList_removeObject ARGS2(HTList *,this, void *,oldObject)
+{
+ if (this) {
+ HTList *previous;
+ while (this->next) {
+ previous = this;
+ this = this->next;
+ if (this->object == oldObject) {
+ previous->next = this->next;
+ free (this);
+ return YES; /* Success */
+ }
+ }
+ }
+ return NO; /* object not found or NULL list */
+}
+
+void * HTList_removeLastObject ARGS1 (HTList *,this)
+{
+ if (this && this->next) {
+ HTList *lastNode = this->next;
+ void * lastObject = lastNode->object;
+ this->next = lastNode->next;
+ free (lastNode);
+ return lastObject;
+ } else /* Empty list */
+ return NULL;
+}
+
+void * HTList_removeFirstObject ARGS1 (HTList *,this)
+{
+ if (this && this->next) {
+ HTList * prevNode;
+ void *firstObject;
+ while (this->next) {
+ prevNode = this;
+ this = this->next;
+ }
+ firstObject = this->object;
+ prevNode->next = NULL;
+ free (this);
+ return firstObject;
+ } else /* Empty list */
+ return NULL;
+}
+
+int HTList_count ARGS1 (HTList *,this)
+{
+ int count = 0;
+ if (this)
+ while (this = this->next)
+ count++;
+ return count;
+}
+
+int HTList_indexOf ARGS2(HTList *,this, void *,object)
+{
+ if (this) {
+ int position = 0;
+ while (this = this->next) {
+ if (this->object == object)
+ return position;
+ position++;
+ }
+ }
+ return -1; /* Object not in the list */
+}
+
+void * HTList_objectAt ARGS2 (HTList *,this, int,position)
+{
+ if (position < 0)
+ return NULL;
+ if (this) {
+ while (this = this->next) {
+ if (position == 0)
+ return this->object;
+ position--;
+ }
+ }
+ return NULL; /* Reached the end of the list */
+}
--- /dev/null
+/* List object
+**
+** The list object is a generic container for storing collections
+** of things in order.
+*/
+#ifndef HTLIST_H
+#define HTLIST_H
+
+#include "HTUtils.h" /* for BOOL type and PARAMS and ARGS*/
+
+typedef struct _HTList HTList;
+
+struct _HTList {
+ void * object;
+ HTList * next;
+};
+
+#ifdef SHORT_NAMES
+#define HTList_new HTLiNew
+#define HTList_delete HTLiDele
+#define HTList_addObject HTLiAdOb
+#define HTList_removeObject HTLiReOb
+#define HTList_removeLastObject HTLiReLa
+#define HTList_removeFirstObject HTLiReFi
+#define HTList_count HTLiCoun
+#define HTList_indexOf HTLiInOf
+#define HTList_objectAt HTLiObAt
+#endif
+
+extern HTList * HTList_new NOPARAMS;
+extern void HTList_delete PARAMS((HTList *this));
+extern void HTList_addObject PARAMS((HTList *this, void *newObject));
+extern BOOL HTList_removeObject PARAMS((HTList *this, void *oldObject));
+extern void * HTList_removeLastObject PARAMS((HTList *this));
+extern void * HTList_removeFirstObject PARAMS((HTList *this));
+#define HTList_isEmpty(this) (this ? this->next == NULL : YES)
+extern int HTList_count PARAMS((HTList *this));
+extern int HTList_indexOf PARAMS((HTList *this, void *object));
+#define HTList_lastObject(this) \
+ (this && this->next ? this->next->object : NULL)
+extern void * HTList_objectAt PARAMS((HTList *this, int position));
+
+/* Fast macro to traverse the list. Call it first with copy of list header :
+ it returns the first object and increments the passed list pointer.
+ Call it with the same variable until it returns NULL. */
+#define HTList_nextObject(this) \
+ (this && (this = this->next) ? this->object : NULL)
+
+#endif /* HTLIST_H */
--- /dev/null
+/* HTML Parser
+** ===========
+*/
+#include <ctype.h>
+#include <stdio.h>
+
+#include "HTUtils.h"
+#include "SGML.h"
+#include "HTAtom.h"
+#include "HTChunk.h"
+#include "HText.h"
+#include "HTStyle.h"
+#include "HTML.h"
+
+
+/* SPECIAL HTML CODE
+** =================
+*/
+
+extern HTStyleSheet * styleSheet; /* Application-wide */
+
+PRIVATE HTParentAnchor * node_anchor;
+PRIVATE HText * text;
+
+PRIVATE HTStyle * glossary_style;
+PRIVATE HTStyle * list_compact_style;
+PRIVATE HTStyle * glossary_compact_style;
+
+PRIVATE HTChunk title = { 0, 128, 0, 0 }; /* Grow by 128 */
+
+
+/* Forward declarations of routines for DTD
+*/
+PRIVATE void no_change PARAMS((HTTag * t, HTElement * e));
+PRIVATE void begin_litteral PARAMS((HTTag * t, HTElement * e));
+PRIVATE void begin_element PARAMS((HTTag * t, HTElement * e));
+PRIVATE void end_element PARAMS((HTTag * t, HTElement * e));
+PRIVATE void begin_document PARAMS((HTTag * t, HTElement * e));
+PRIVATE void end_document PARAMS((HTTag * t, HTElement * e));
+PRIVATE void begin_anchor PARAMS((HTTag * t, HTElement * e));
+PRIVATE void end_anchor PARAMS((HTTag * t, HTElement * e));
+PRIVATE void begin_list PARAMS((HTTag * t, HTElement * e));
+PRIVATE void list_element PARAMS((HTTag * t, HTElement * e));
+PRIVATE void end_list PARAMS((HTTag * t, HTElement * e));
+PRIVATE void begin_glossary PARAMS((HTTag * t, HTElement * e));
+PRIVATE void end_glossary PARAMS((HTTag * t, HTElement * e));
+
+PRIVATE int got_styles = 0;
+PRIVATE void get_styles NOPARAMS;
+
+PRIVATE BOOL style_change;
+PRIVATE HTStyle * new_style;
+PRIVATE HTStyle * old_style;
+PRIVATE BOOL in_word; /* Have just had a non-white character */
+
+/* Style buffering avoids dummy paragraph begin/ends.
+*/
+#define UPDATE_STYLE if (style_change) { \
+ HText_setStyle(text, new_style); \
+ old_style = new_style; \
+ style_change = NO; }
+
+PRIVATE void change_style ARGS1(HTStyle *,style)
+{
+ if (new_style!=style) {
+ style_change = YES /* was old_style == new_style */ ;
+ new_style = style;
+ }
+}
+
+
+/* TITLE
+*/
+
+/* Accumulate a character of title
+*/
+#ifdef __STDC__
+static void accumulate_string(char c)
+#else
+static void accumulate_string(c)
+ char c;
+#endif
+{
+ HTChunkPutc(&title, c);
+}
+
+
+/* Clear the title
+*/
+PRIVATE void clear_string ARGS2(HTTag *,t, HTElement *,e)
+{
+ HTChunkClear(&title);
+}
+
+PRIVATE void set_title ARGS2(HTTag *,t, HTElement *,e)
+{
+ HTChunkTerminate(&title);
+ HTAnchor_setTitle(node_anchor, title.data);
+}
+
+/* Character handling
+*/
+PRIVATE void set_index ARGS2(HTTag *,t, HTElement *,e)
+{
+ HTAnchor_setIndex(node_anchor);
+}
+
+PRIVATE void pass_character ARGS1(char, c)
+{
+ if (style_change) {
+ if ((c=='\n') || (c==' ')) return; /* Ignore it */
+ UPDATE_STYLE;
+ }
+ if (c=='\n') {
+ if (in_word) {
+ HText_appendCharacter(text, ' ');
+ in_word = NO;
+ }
+ } else {
+ HText_appendCharacter(text, c);
+ in_word = YES;
+ }
+}
+
+PRIVATE void litteral_text ARGS1(char, c)
+{
+/* We guarrantee that the style is up-to-date in begin_litteral
+*/
+ HText_appendCharacter(text, c); /* @@@@@ */
+}
+
+PRIVATE void ignore_text ARGS1(char, c)
+{
+ /* Do nothing */
+}
+
+PRIVATE void set_next_id ARGS2(HTTag *,t, HTElement *,e)
+{
+ /* @@@@@ Bad SGML anyway */
+}
+
+PRIVATE void new_paragraph ARGS2(HTTag *,t, HTElement *,e)
+{
+ UPDATE_STYLE;
+ HText_appendParagraph(text);
+ in_word = NO;
+}
+
+PRIVATE void term ARGS2(HTTag *,t, HTElement *,e)
+{
+ if (!style_change) {
+ HText_appendParagraph(text);
+ in_word = NO;
+ }
+}
+
+PRIVATE void definition ARGS2(HTTag *,t, HTElement *,e)
+{
+ UPDATE_STYLE;
+ pass_character('\t'); /* Just tab out one stop */
+ in_word = NO;
+}
+
+/* Our Static DTD for HTML
+** -----------------------
+*/
+
+static entity entities[] = {
+ { "lt", "<" },
+ { "gt", ">" },
+ { "amp", "&" },
+ { "bullet" , "\267" }, /* @@@ NeXT only */
+ { 0, 0 } /* Terminate list */
+};
+
+static attr no_attr[] = {{ 0, 0 , 0}};
+
+static attr a_attr[] = { /* Anchor attributes */
+#define A_ID 0
+ { "NAME", 0, 0 }, /* Should be ID */
+#define A_TYPE 1
+ { "TYPE", 0, 0 },
+#define A_HREF 2
+ { "HREF", 0, 0 },
+ { 0, 0 , 0} /* Terminate list */
+};
+static attr list_attr[] = {
+#define LIST_COMPACT 0
+ { "COMPACT", 0, 0 },
+ { 0, 0, 0 } /* Terminate list */
+};
+
+static attr glossary_attr[] = {
+#define GLOSSARY_COMPACT 0
+ { "COMPACT", 0, 0 },
+ { 0, 0, 0 } /* Terminate list */
+};
+
+static HTTag default_tag =
+ { "DOCUMENT", no_attr , 0, 0, begin_document, pass_character, end_document };
+/* NAME ATTR STYLE LITERAL? ON_BEGIN ON__CHARACTER ON_END
+*/
+static HTTag tags[] = {
+#define TITLE_TAG 0
+ { "TITLE", no_attr, 0, 0, clear_string, accumulate_string, set_title },
+#define ISINDEX_TAG 1
+ { "ISINDEX", no_attr, 0, 0, set_index, 0 , 0 },
+#define NEXTID_TAG 2
+ { "NEXTID", no_attr, 0, 0, set_next_id, 0, 0 },
+#define ADDRESS_TAG 3
+ { "ADDRESS" , no_attr, 0, 0, begin_element, pass_character, end_element },
+#define H1_TAG 4
+ { "H1" , no_attr, 0, 0, begin_element, pass_character, end_element },
+ { "H2" , no_attr, 0, 0, begin_element, pass_character, end_element },
+ { "H3" , no_attr, 0, 0, begin_element, pass_character, end_element },
+ { "H4" , no_attr, 0, 0, begin_element, pass_character, end_element },
+ { "H5" , no_attr, 0, 0, begin_element, pass_character, end_element },
+ { "H6" , no_attr, 0, 0, begin_element, pass_character, end_element },
+ { "H7" , no_attr, 0, 0, begin_element, pass_character, end_element },
+#define UL_TAG 11
+ { "UL" , list_attr, 0, 0, begin_list, pass_character, end_list },
+#define OL_TAG 12
+ { "OL" , list_attr, 0, 0, begin_list, pass_character, end_list },
+#define MENU_TAG 13
+ { "MENU" , list_attr, 0, 0, begin_list, pass_character, end_list },
+#define DIR_TAG 14
+ { "DIR" , list_attr, 0, 0, begin_list, pass_character, end_list },
+#define LI_TAG 15
+ { "LI" , no_attr, 0, 0, list_element, pass_character, 0 },
+#define DL_TAG 16
+ { "DL" , list_attr, 0, 0, begin_glossary, pass_character, end_glossary },
+ { "DT" , no_attr, 0, 0, term, pass_character, 0 },
+ { "DD" , no_attr, 0, 0, definition, pass_character, 0 },
+ { "A" , a_attr, 0, 0, begin_anchor, pass_character, end_anchor },
+#define P_TAG 20
+ { "P" , no_attr, 0, 0, new_paragraph, pass_character, 0 },
+#define XMP_TAG 21
+ { "XMP" , no_attr, 0, YES, begin_litteral, litteral_text, end_element },
+#define LISTING_TAG 22
+ { "LISTING" , no_attr, 0, YES,begin_litteral, litteral_text, end_element },
+#define PLAINTEXT_TAG 23
+ { "PLAINTEXT", no_attr, 0, YES, begin_litteral, litteral_text, end_element },
+#define COMMENT_TAG 24
+ { "COMMENT", no_attr, 0, YES, no_change, ignore_text, no_change },
+ { 0, 0, 0, 0, 0, 0 , 0} /* Terminate list */
+};
+
+PUBLIC SGML_dtd HTML_dtd = { tags, &default_tag, entities };
+
+
+/* Flattening the style structure
+** ------------------------------
+**
+On the NeXT, and on any read-only browser, it is simpler for the text to have
+a sequence of styles, rather than a nested tree of styles. In this
+case we have to flatten the structure as it arrives from SGML tags into
+a sequence of styles.
+*/
+
+/* Anchor handling
+** ---------------
+*/
+PRIVATE void begin_anchor ARGS2(HTTag *,t, HTElement *,e)
+{
+ HTChildAnchor * source = HTAnchor_findChildAndLink(
+ node_anchor, /* parent */
+ a_attr[A_ID].present ? a_attr[A_ID].value : 0, /* Tag */
+ a_attr[A_HREF].present ? a_attr[A_HREF].value : 0, /* Addresss */
+ a_attr[A_TYPE].present ?
+ (HTLinkType*)HTAtom_for(a_attr[A_TYPE].value)
+ : 0);
+
+ UPDATE_STYLE;
+ HText_beginAnchor(text, source);
+}
+
+PRIVATE void end_anchor ARGS2(HTTag *, t,
+ HTElement *, e)
+{
+ UPDATE_STYLE;
+ HText_endAnchor(text);
+}
+
+
+/* General SGML Element Handling
+** -----------------------------
+*/
+PRIVATE void begin_element ARGS2(HTTag *,t, HTElement *,e)
+{
+ change_style((HTStyle*)(t->style));
+}
+PRIVATE void no_change ARGS2(HTTag *,t, HTElement *,e)
+{
+ /* Do nothing */;
+}
+PRIVATE void begin_litteral ARGS2(HTTag *,t, HTElement *,e)
+{
+ change_style(t->style);
+ UPDATE_STYLE;
+}
+PRIVATE void end_element ARGS2(HTTag *,t, HTElement *,e)
+{
+ if (e) change_style(e->tag->style);
+}
+
+/* Lists
+*/
+PRIVATE void begin_list ARGS2(HTTag *,t, HTElement *,e)
+{
+ change_style(list_attr[LIST_COMPACT].present
+ ? list_compact_style
+ : (HTStyle*)(t->style));
+ in_word = NO;
+}
+
+PRIVATE void end_list ARGS2(HTTag *,t, HTElement *,e)
+{
+ change_style(e->tag->style);
+ in_word = NO;
+}
+
+PRIVATE void list_element ARGS2(HTTag *,t, HTElement *,e)
+{
+ if (e->tag != &tags[DIR_TAG])
+ HText_appendParagraph(text);
+ else
+ HText_appendCharacter(text, '\t'); /* Tab @@ nl for UL? */
+ in_word = NO;
+}
+
+
+PRIVATE void begin_glossary ARGS2(HTTag *,t, HTElement *,e)
+{
+ change_style(glossary_attr[GLOSSARY_COMPACT].present
+ ? glossary_compact_style
+ : glossary_style);
+ in_word = NO;
+}
+
+PRIVATE void end_glossary ARGS2(HTTag *,t, HTElement *,e)
+{
+ change_style(e->tag->style);
+ in_word = NO;
+}
+
+
+/* Begin and End document
+** ----------------------
+*/
+PUBLIC void HTML_begin ARGS1(HTParentAnchor *,anchor)
+{
+ node_anchor = anchor;
+}
+
+PRIVATE void begin_document ARGS2(HTTag *, t, HTElement *, e)
+{
+ if (!got_styles) get_styles();
+ text = HText_new(node_anchor);
+ HText_beginAppend(text);
+ HText_setStyle(text, default_tag.style);
+ old_style = 0;
+ style_change = NO;
+ in_word = NO;
+}
+
+PRIVATE void end_document ARGS2(HTTag *, t, HTElement *, e)
+{
+ HText_endAppend(text);
+
+}
+
+/* Get Styles from style sheet
+** ---------------------------
+*/
+PRIVATE void get_styles NOARGS
+{
+ got_styles = YES;
+
+ tags[P_TAG].style =
+ default_tag.style = HTStyleNamed(styleSheet, "Normal");
+ tags[H1_TAG].style = HTStyleNamed(styleSheet, "Heading1");
+ tags[H1_TAG+1].style = HTStyleNamed(styleSheet, "Heading2");
+ tags[H1_TAG+2].style = HTStyleNamed(styleSheet, "Heading3");
+ tags[H1_TAG+3].style = HTStyleNamed(styleSheet, "Heading4");
+ tags[H1_TAG+4].style = HTStyleNamed(styleSheet, "Heading5");
+ tags[H1_TAG+5].style = HTStyleNamed(styleSheet, "Heading6");
+ tags[H1_TAG+6].style = HTStyleNamed(styleSheet, "Heading7");
+ tags[DL_TAG].style = HTStyleNamed(styleSheet, "Glossary");
+ tags[UL_TAG].style = HTStyleNamed(styleSheet, "List");
+ tags[OL_TAG].style = HTStyleNamed(styleSheet, "List");
+ tags[MENU_TAG].style = HTStyleNamed(styleSheet, "Menu");
+ list_compact_style =
+ tags[DIR_TAG].style = HTStyleNamed(styleSheet, "Dir");
+ glossary_style = HTStyleNamed(styleSheet, "Glossary");
+ glossary_compact_style = HTStyleNamed(styleSheet, "GlossaryCompact");
+ tags[ADDRESS_TAG].style= HTStyleNamed(styleSheet, "Address");
+ tags[PLAINTEXT_TAG].style =
+ tags[XMP_TAG].style = HTStyleNamed(styleSheet, "Example");
+ tags[LISTING_TAG].style = HTStyleNamed(styleSheet, "Listing");
+}
+
+
+/* Parse an HTML file
+** ------------------
+**
+** This version takes a pointer to the routine to call
+** to get each character.
+*/
+BOOL HTML_Parse
+#ifdef __STDC__
+ (HTParentAnchor * anchor, char (*next_char)() )
+#else
+ (anchor, next_char)
+ HTParentAnchor * anchor;
+ char (*next_char)();
+#endif
+{
+ HTML_begin(anchor);
+ SGML_begin(&HTML_dtd);
+ for(;;) {
+ char character;
+ character = (*next_char)();
+ if (character == (char)EOF) break;
+
+ SGML_character(&HTML_dtd, character);
+ }
+ SGML_end(&HTML_dtd);
+ return YES;
+}
--- /dev/null
+/* The HTML Parser HTML.h
+** ---------------
+*/
+
+#ifndef HTML_H
+#define HTML_H
+
+#include "HTUtils.h"
+#include "HTAnchor.h"
+#include "SGML.h"
+
+extern SGML_dtd HTML_dtd; /* The DTD */
+extern void HTML_begin PARAMS((HTParentAnchor * anchor));
+extern BOOL HTML_Parse PARAMS((
+ HTParentAnchor * anchor,
+ char (*next_char)() ));
+#endif
--- /dev/null
+/* NEWS ACCESS HTNews.c
+** ===========
+**
+** History:
+** 26 Sep 90 Written TBL
+** 29 Nov 91 Downgraded to C, for portable implementation.
+*/
+
+#define NEWS_PORT 119 /* See rfc977 */
+#define APPEND /* Use append methods */
+#define MAX_CHUNK 40 /* Largest number of articles in one window */
+#define CHUNK_SIZE 20 /* Number of articles for quick display */
+
+#ifndef DEFAULT_NEWS_HOST
+#define DEFAULT_NEWS_HOST "news"
+#endif
+#ifndef SERVER_FILE
+#define SERVER_FILE "/usr/local/lib/rn/server"
+#endif
+
+#include <ctype.h>
+#include "HTUtils.h" /* Coding convention macros */
+#include "tcp.h"
+
+#include "HTNews.h"
+
+#include "HText.h"
+#include "HTParse.h"
+#include "HTFormat.h"
+
+#ifdef NeXTStep
+#include <appkit/defaults.h>
+#define NEWS_PROGRESS(foo)
+#else
+#define NEWS_PROGRESS(foo) fprintf(stderr, "%s\n", (foo))
+#endif
+
+extern HTStyleSheet * styleSheet;
+
+#define NEXT_CHAR HTGetChararcter()
+#define LINE_LENGTH 512 /* Maximum length of line of ARTICLE etc */
+#define GROUP_NAME_LENGTH 256 /* Maximum length of group name */
+
+
+/* Module-wide variables
+*/
+PRIVATE char * NewsHost;
+PRIVATE struct sockaddr_in soc_address; /* Binary network address */
+PRIVATE int s; /* Socket for NewsHost */
+PRIVATE char response_text[LINE_LENGTH+1]; /* Last response */
+PRIVATE HText * HT; /* the new hypertext */
+PRIVATE HTParentAnchor *node_anchor; /* Its anchor */
+PRIVATE int diagnostic; /* level: 0=none 2=source */
+
+PRIVATE HTStyle *addressStyle; /* For address etc */
+PRIVATE HTStyle *heading1Style; /* For heading level 1 */
+PRIVATE HTStyle *textStyle; /* Text style */
+
+
+/* Initialisation for this module
+** ------------------------------
+**
+** Except on the NeXT, we pick up the NewsHost name from
+**
+** 1. Environment variable NNTPSERVER
+** 2. File SERVER_FILE
+** 3. Compilation time macro DEFAULT_NEWS_HOST
+** 4. Default to "news"
+**
+** On the NeXT, we pick up the NewsHost name from, in order:
+**
+** 1. WorldWideWeb default "NewsHost"
+** 2. Global default "NewsHost"
+** 3. News default "NewsHost"
+** 4. Compilation time macro DEFAULT_NEWS_HOST
+** 5. Defualt to "news"
+*/
+PRIVATE BOOL initialized = NO;
+PRIVATE BOOL initialize NOARGS
+{
+ CONST struct hostent *phost; /* Pointer to host - See netdb.h */
+ struct sockaddr_in* sin = &soc_address;
+
+
+/* Set up defaults:
+*/
+ sin->sin_family = AF_INET; /* Family = internet, host order */
+ sin->sin_port = htons(NEWS_PORT); /* Default: new port, */
+
+/* Get name of Host
+*/
+#ifdef NeXTStep
+ if ((NewsHost = NXGetDefaultValue("WorldWideWeb","NewsHost"))==0)
+ if ((NewsHost = NXGetDefaultValue("News","NewsHost")) == 0)
+ NewsHost = "cernvax.cern.ch";
+#else
+ if (getenv("NNTPSERVER")) {
+ StrAllocCopy(NewsHost, (char *)getenv("NNTPSERVER"));
+ if (TRACE) fprintf(stderr, "HTNews: NNTPSERVER defined as `%s'\n",
+ NewsHost);
+ } else {
+ char server_name[256];
+ FILE* fp = fopen(SERVER_FILE, "r");
+ if (fp) {
+ if (fscanf(fp, "%s", server_name)==1) {
+ StrAllocCopy(NewsHost, server_name);
+ if (TRACE) fprintf(stderr,
+ "HTNews: File %s defines news host as `%s'\n",
+ SERVER_FILE, NewsHost);
+ }
+ fclose(fp);
+ }
+ }
+ if (!NewsHost) NewsHost = DEFAULT_NEWS_HOST;
+#endif
+
+ if (*NewsHost>='0' && *NewsHost<='9') { /* Numeric node address: */
+ sin->sin_addr.s_addr = inet_addr((char *)NewsHost); /* See arpa/inet.h */
+
+ } else { /* Alphanumeric node name: */
+ phost=gethostbyname((char*)NewsHost); /* See netdb.h */
+ if (!phost) {
+#ifdef NeXTStep
+ NXRunAlertPanel(NULL, "Can't find internet node name `%s'.",
+ NULL,NULL,NULL,
+ NewsHost);
+#else
+ fprintf(stderr,
+ "HTNews: Can't find internet node name `%s'.\n",NewsHost);
+#endif
+ CTRACE(tfp,
+ "HTNews: Can't find internet node name `%s'.\n",NewsHost);
+ return NO; /* Fail */
+ }
+ memcpy(&sin->sin_addr, phost->h_addr, phost->h_length);
+ }
+
+ if (TRACE) printf(
+ "HTNews: Parsed address as port %4x, inet %d.%d.%d.%d\n",
+ (unsigned int)ntohs(sin->sin_port),
+ (int)*((unsigned char *)(&sin->sin_addr)+0),
+ (int)*((unsigned char *)(&sin->sin_addr)+1),
+ (int)*((unsigned char *)(&sin->sin_addr)+2),
+ (int)*((unsigned char *)(&sin->sin_addr)+3));
+
+ s = -1; /* Disconnected */
+
+ return YES;
+}
+
+
+
+/* Get Styles from stylesheet
+** --------------------------
+*/
+PRIVATE void get_styles NOARGS
+{
+ if (!heading1Style) heading1Style = HTStyleNamed(styleSheet, "Heading1");
+ if (!addressStyle) addressStyle = HTStyleNamed(styleSheet, "Address");
+ if (!textStyle) textStyle = HTStyleNamed(styleSheet, "Example");
+}
+
+
+/* Send NNTP Command line to remote host & Check Response
+** ------------------------------------------------------
+**
+** On entry,
+** command points to the command to be sent, including CRLF, or is null
+** pointer if no command to be sent.
+** On exit,
+** Negative status indicates transmission error, socket closed.
+** Positive status is an NNTP status.
+*/
+
+
+PRIVATE int response ARGS1(CONST char *,command)
+{
+ int result;
+ char * p = response_text;
+ if (command) {
+ int status = NETWRITE(s, command, (int)strlen(command));
+ if (status<0){
+ if (TRACE) fprintf(stderr,
+ "HTNews: Unable to send `%s'. Disconnecting.\n");
+ NETCLOSE(s);
+ s = -1;
+ return status;
+ } /* if bad status */
+ if (TRACE) printf("NNTP command sent: %s", command);
+ } /* if command to be sent */
+
+ for(;;) {
+ if (((*p++=NEXT_CHAR) == '\n') || (p == &response_text[LINE_LENGTH])) {
+ *p++=0; /* Terminate the string */
+ if (TRACE) printf("NNTP Response: %s\n", response_text);
+ sscanf(response_text, "%d", &result);
+ return result;
+ } /* if end of line */
+
+ if (*(p-1) < 0) {
+ if (TRACE) fprintf(stderr,
+ "HTNews: EOF on read, closing socket %d\n", s);
+ NETCLOSE(s); /* End of file, close socket */
+ return s = -1; /* End of file on response */
+ }
+ } /* Loop over characters */
+}
+
+
+/* Case insensitive string comparisons
+** -----------------------------------
+**
+** On entry,
+** template must be already un upper case.
+** unknown may be in upper or lower or mixed case to match.
+*/
+PRIVATE BOOL match ARGS2 (CONST char *,unknown, CONST char *,template)
+{
+ CONST char * u = unknown;
+ CONST char * t = template;
+ for (;*u && *t && (TOUPPER(*u)==*t); u++, t++) /* Find mismatch or end */ ;
+ return (BOOL)(*t==0); /* OK if end of template */
+}
+
+/* Find Author's name in mail address
+** ----------------------------------
+**
+** On exit,
+** THE EMAIL ADDRESS IS CORRUPTED
+**
+** For example, returns "Tim Berners-Lee" if given any of
+** " Tim Berners-Lee <tim@online.cern.ch> "
+** or " tim@online.cern.ch ( Tim Berners-Lee ) "
+*/
+PRIVATE char * author_name ARGS1 (char *,email)
+{
+ char *s, *e;
+
+ if ((s=strchr(email,'(')) && (e=strchr(email, ')')))
+ if (e>s) {
+ *e=0; /* Chop off everything after the ')' */
+ return HTStrip(s+1); /* Remove leading and trailing spaces */
+ }
+
+ if ((s=strchr(email,'<')) && (e=strchr(email, '>')))
+ if (e>s) {
+ strcpy(s, e+1); /* Remove <...> */
+ return HTStrip(email); /* Remove leading and trailing spaces */
+ }
+
+ return HTStrip(email); /* Default to the whole thing */
+
+}
+
+
+/* Paste in an Anchor
+** ------------------
+**
+**
+** On entry,
+** HT has a selection of zero length at the end.
+** text points to the text to be put into the file, 0 terminated.
+** addr points to the hypertext refernce address,
+** terminated by white space, comma, NULL or '>'
+*/
+PRIVATE void write_anchor ARGS2(CONST char *,text, CONST char *,addr)
+{
+ char href[LINE_LENGTH+1];
+
+ {
+ CONST char * p;
+ strcpy(href,"news:");
+ for(p=addr; *p && (*p!='>') && !WHITE(*p) && (*p!=','); p++);
+ strncat(href, addr, p-addr); /* Make complete hypertext reference */
+ }
+
+ HText_beginAnchor(HT,
+ HTAnchor_findChildAndLink(node_anchor, "", href, 0));
+ HText_appendText(HT, text);
+ HText_endAnchor(HT);
+}
+
+
+/* Write list of anchors
+** ---------------------
+**
+** We take a pointer to a list of objects, and write out each,
+** generating an anchor for each.
+**
+** On entry,
+** HT has a selection of zero length at the end.
+** text points to a comma or space separated list of addresses.
+** On exit,
+** *text is NOT any more chopped up into substrings.
+*/
+PRIVATE void write_anchors ARGS1 (char *,text)
+{
+ char * start = text;
+ char * end;
+ char c;
+ for (;;) {
+ for(;*start && (WHITE(*start)); start++); /* Find start */
+ if (!*start) return; /* (Done) */
+ for(end=start; *end && (*end!=' ') && (*end!=','); end++);/* Find end */
+ if (*end) end++; /* Include comma or space but not NULL */
+ c = *end;
+ *end = 0;
+ write_anchor(start, start);
+ *end = c;
+ start = end; /* Point to next one */
+ }
+}
+
+/* Abort the connection abort_socket
+** --------------------
+*/
+PRIVATE void abort_socket NOARGS
+{
+ if (TRACE) fprintf(stderr,
+ "HTNews: EOF on read, closing socket %d\n", s);
+ NETCLOSE(s); /* End of file, close socket */
+ HText_appendText(HT, "Network Error: connection lost");
+ HText_appendParagraph(HT);
+ s = -1; /* End of file on response */
+ return;
+}
+
+/* Read in an Article read_article
+** ------------------
+**
+**
+** Note the termination condition of a single dot on a line by itself.
+** RFC 977 specifies that the line "folding" of RFC850 is not used, so we
+** do not handle it here.
+**
+** On entry,
+** s Global socket number is OK
+** HT Global hypertext object is ready for appending text
+*/
+PRIVATE void read_article NOARGS
+{
+
+ char line[LINE_LENGTH+1];
+ char *references=NULL; /* Hrefs for other articles */
+ char *newsgroups=NULL; /* Newsgroups list */
+ char *p = line;
+ BOOL done = NO;
+
+/* Read in the HEADer of the article:
+**
+** The header fields are either ignored, or formatted and put into the
+** Text.
+*/
+ if (!diagnostic) {
+ HText_setStyle(HT, addressStyle);
+ while(!done){
+ char ch = *p++ = NEXT_CHAR;
+ if (ch==(char)EOF) {
+ abort_socket(); /* End of file, close socket */
+ return; /* End of file on response */
+ }
+ if ((ch == '\n') || (p == &line[LINE_LENGTH])) {
+ *--p=0; /* Terminate the string */
+ if (TRACE) printf("H %s\n", line);
+
+ if (line[0]=='.') {
+ if (line[1]<' ') { /* End of article? */
+ done = YES;
+ break;
+ }
+
+ } else if (line[0]<' ') {
+ break; /* End of Header? */
+ } else if (match(line, "SUBJECT:")) {
+ HTAnchor_setTitle(node_anchor, line+8);
+ HText_setStyle(HT, heading1Style);
+ HText_appendText(HT, line+8);
+ HText_setStyle(HT, addressStyle);
+ } else if (match(line, "DATE:")
+ || match(line, "FROM:")
+ || match(line, "ORGANIZATION:")) {
+ strcat(line, "\n");
+ HText_appendText(HT, strchr(line,':')+1);
+ } else if (match(line, "NEWSGROUPS:")) {
+ StrAllocCopy(newsgroups, HTStrip(strchr(line,':')+1));
+
+ } else if (match(line, "REFERENCES:")) {
+ StrAllocCopy(references, HTStrip(strchr(line,':')+1));
+
+ } /* end if match */
+ p = line; /* Restart at beginning */
+ } /* if end of line */
+ } /* Loop over characters */
+
+ HText_appendCharacter(HT, '\n');
+ HText_setStyle(HT, textStyle);
+ if (newsgroups) {
+ HText_appendText(HT, "\nNewsgroups: ");
+ write_anchors(newsgroups);
+ free(newsgroups);
+ }
+
+ if (references) {
+ HText_appendText(HT, "\nReferences: ");
+ write_anchors(references);
+ free(references);
+ }
+
+ HText_appendText(HT, "\n\n\n");
+
+ } else { /* diagnostic */
+ HText_setStyle(HT, textStyle);
+ }
+
+/* Read in the BODY of the Article:
+*/
+ p = line;
+ while(!done){
+ char ch = *p++ = NEXT_CHAR;
+ if (ch==(char)EOF) {
+ abort_socket(); /* End of file, close socket */
+ return; /* End of file on response */
+ }
+ if ((ch == '\n') || (p == &line[LINE_LENGTH])) {
+ *p++=0; /* Terminate the string */
+ if (TRACE) printf("B %s", line);
+ if (line[0]=='.') {
+ if (line[1]<' ') { /* End of article? */
+ done = YES;
+ break;
+ } else { /* Line starts with dot */
+ HText_appendText(HT, &line[1]); /* Ignore first dot */
+ }
+ } else {
+
+/* Normal lines are scanned for buried references to other articles.
+** Unfortunately, it will pick up mail addresses as well!
+*/
+ char *l = line;
+ char * p;
+ while (p=strchr(l, '<')) {
+ char *q = strchr(p,'>');
+ char *at = strchr(p, '@');
+ if (q && at && at<q) {
+ char c = q[1];
+ q[1] = 0; /* chop up */
+ *p = 0;
+ HText_appendText(HT, l);
+ *p = '<'; /* again */
+ *q = 0;
+ HText_beginAnchor(HT,
+ HTAnchor_findChildAndLink(
+ node_anchor, "", p+1, 0));
+ *q = '>'; /* again */
+ HText_appendText(HT, p);
+ HText_endAnchor(HT);
+ q[1] = c; /* again */
+ l=q+1;
+ } else break; /* line has unmatched <> */
+ }
+ HText_appendText(HT, l); /* Last bit of the line */
+ } /* if not dot */
+ p = line; /* Restart at beginning */
+ } /* if end of line */
+ } /* Loop over characters */
+}
+
+
+/* Read in a List of Newsgroups
+** ----------------------------
+*/
+/*
+** Note the termination condition of a single dot on a line by itself.
+** RFC 977 specifies that the line "folding" of RFC850 is not used, so we
+** do not handle it here.
+*/
+PRIVATE void read_list NOARGS
+{
+
+ char line[LINE_LENGTH+1];
+ char *p;
+ BOOL done = NO;
+
+/* Read in the HEADer of the article:
+**
+** The header fields are either ignored, or formatted and put into the
+** Text.
+*/
+ HText_appendText(HT, "\nNewsgroups:\n\n"); /* Should be haeding style */
+ p = line;
+ while(!done){
+ char ch = *p++ = NEXT_CHAR;
+ if (ch==(char)EOF) {
+ abort_socket(); /* End of file, close socket */
+ return; /* End of file on response */
+ }
+ if ((ch == '\n') || (p == &line[LINE_LENGTH])) {
+ *p++=0; /* Terminate the string */
+ if (TRACE) printf("B %s", line);
+ if (line[0]=='.') {
+ if (line[1]<' ') { /* End of article? */
+ done = YES;
+ break;
+ } else { /* Line starts with dot */
+ HText_appendText(HT, &line[1]);
+ }
+ } else {
+
+/* Normal lines are scanned for references to newsgroups.
+*/
+ char group[LINE_LENGTH];
+ int first, last;
+ char postable;
+ if (sscanf(line, "%s %d %d %c", group, &first, &last, &postable)==4)
+ write_anchor(line, group);
+ else
+ HText_appendText(HT, line);
+ } /* if not dot */
+ p = line; /* Restart at beginning */
+ } /* if end of line */
+ } /* Loop over characters */
+}
+
+
+/* Read in a Newsgroup
+** -------------------
+** Unfortunately, we have to ask for each article one by one if we
+** want more than one field.
+**
+*/
+PRIVATE void read_group ARGS3(
+ CONST char *,groupName,
+ int,first_required,
+ int,last_required
+)
+{
+ char line[LINE_LENGTH+1];
+ char author[LINE_LENGTH+1];
+ char subject[LINE_LENGTH+1];
+ char *p;
+ BOOL done;
+
+ char buffer[LINE_LENGTH];
+ char *reference=0; /* Href for article */
+ int art; /* Article number WITHIN GROUP */
+ int status, count, first, last; /* Response fields */
+ /* count is only an upper limit */
+
+ sscanf(response_text, " %d %d %d %d", &status, &count, &first, &last);
+ if(TRACE) printf("Newsgroup status=%d, count=%d, (%d-%d) required:(%d-%d)\n",
+ status, count, first, last, first_required, last_required);
+ if (last==0) {
+ HText_appendText(HT, "\nNo articles in this group.\n");
+ return;
+ }
+
+#define FAST_THRESHOLD 100 /* Above this, read IDs fast */
+#define CHOP_THRESHOLD 50 /* Above this, chop off the rest */
+
+ if (first_required<first) first_required = first; /* clip */
+ if ((last_required==0) || (last_required > last)) last_required = last;
+
+ if (last_required<=first_required) {
+ HText_appendText(HT, "\nNo articles in this range.\n");
+ return;
+ }
+
+ if (last_required-first_required+1 > MAX_CHUNK) { /* Trim this block */
+ first_required = last_required-CHUNK_SIZE+1;
+ }
+ if (TRACE) printf (
+ " Chunk will be (%d-%d)\n", first_required, last_required);
+
+/* Link to earlier articles
+*/
+ if (first_required>first) {
+ int before; /* Start of one before */
+ if (first_required-MAX_CHUNK <= first) before = first;
+ else before = first_required-CHUNK_SIZE;
+ sprintf(buffer, "%s/%d-%d", groupName, before, first_required-1);
+ if (TRACE) printf(" Block before is %s\n", buffer);
+ HText_appendText(HT, " (");
+ HText_beginAnchor(HT,
+ HTAnchor_findChildAndLink(node_anchor, "", buffer, 0));
+ HText_appendText(HT, "Earlier articles");
+ HText_endAnchor(HT);
+ HText_appendText(HT, "...)\n");
+ }
+
+ done = NO;
+
+/*#define USE_XHDR*/
+#ifdef USE_XHDR
+ if (count>FAST_THRESHOLD) {
+ sprintf(buffer,
+ "\nThere are about %d articles currently available in %s, IDs as follows:\n\n",
+ count, groupName);
+ HText_appendText(HT, buffer);
+ sprintf(buffer, "XHDR Message-ID %d-%d\n", first, last);
+ status = response(buffer);
+ if (status==221) {
+
+ p = line;
+ while(!done){
+ char ch = *p++ = NEXT_CHAR;
+ if (ch==(char)EOF) {
+ abort_socket(); /* End of file, close socket */
+ return; /* End of file on response */
+ }
+ if ((ch == '\n') || (p == &line[LINE_LENGTH])) {
+ *p++=0; /* Terminate the string */
+ if (TRACE) printf("X %s", line);
+ if (line[0]=='.') {
+ if (line[1]<' ') { /* End of article? */
+ done = YES;
+ break;
+ } else { /* Line starts with dot */
+ /* Ignore strange line */
+ }
+ } else {
+
+ /* Normal lines are scanned for references to articles.
+ */
+ char * space = strchr(line, ' ');
+ if (space++)
+ write_anchor(space, space);
+ } /* if not dot */
+ p = line; /* Restart at beginning */
+ } /* if end of line */
+ } /* Loop over characters */
+
+ /* leaving loop with "done" set */
+ } /* Good status */
+ };
+#endif
+
+/* Read newsgroup using individual fields:
+*/
+ if (!done) {
+ if (first==first_required && last==last_required)
+ HText_appendText(HT, "\nAll available articles in ");
+ else HText_appendText(HT, "\nArticles in ");
+ HText_appendText(HT, groupName);
+ HText_appendText(HT, "\n\n");
+ for(art=first_required; art<=last_required; art++) {
+
+/*#define OVERLAP*/
+#ifdef OVERLAP
+/* With this code we try to keep the server running flat out by queuing just
+** one extra command ahead of time. We assume (1) that the server won't abort
+** if it get input during output, and (2) that TCP buffering is enough for the
+** two commands. Both these assumptions seem very reasonable. However, we HAVE
+** had a hangup with a loaded server.
+*/
+ if (art==first_required) {
+ if (art==last_required) {
+ sprintf(buffer, "HEAD %d\n", art); /* Only one */
+ status = response(buffer);
+ } else { /* First of many */
+ sprintf(buffer, "HEAD %d\nHEAD %d\n", art, art+1);
+ status = response(buffer);
+ }
+ } else if (art==last_required) { /* Last of many */
+ status = response(NULL);
+ } else { /* Middle of many */
+ sprintf(buffer, "HEAD %d\n", art+1);
+ status = response(buffer);
+ }
+
+#else /* NOT OVERLAP */
+ sprintf(buffer, "HEAD %d\n", art);
+ status = response(buffer);
+#endif /* NOT OVERLAP */
+
+ if (status == 221) { /* Head follows - parse it:*/
+
+ p = line; /* Write pointer */
+ done = NO;
+ while(!done){
+ char ch = *p++ = NEXT_CHAR;
+ if (ch==(char)EOF) {
+ abort_socket(); /* End of file, close socket */
+ return; /* End of file on response */
+ }
+ if ((ch == '\n')
+ || (p == &line[LINE_LENGTH]) ) {
+
+ *--p=0; /* Terminate & chop LF*/
+ p = line; /* Restart at beginning */
+ if (TRACE) printf("G %s\n", line);
+ switch(line[0]) {
+
+ case '.':
+ done = (line[1]<' '); /* End of article? */
+ break;
+
+ case 'S':
+ case 's':
+ if (match(line, "SUBJECT:"))
+ strcpy(subject, line+9);/* Save subject */
+ break;
+
+ case 'M':
+ case 'm':
+ if (match(line, "MESSAGE-ID:")) {
+ char * addr = HTStrip(line+11) +1; /* Chop < */
+ addr[strlen(addr)-1]=0; /* Chop > */
+ StrAllocCopy(reference, addr);
+ }
+ break;
+
+ case 'f':
+ case 'F':
+ if (match(line, "FROM:")) {
+ char * p;
+ strcpy(author,
+ author_name(strchr(line,':')+1));
+ p = author + strlen(author) - 1;
+ if (*p=='\n') *p = 0; /* Chop off newline */
+ }
+ break;
+
+ } /* end switch on first character */
+ } /* if end of line */
+ } /* Loop over characters */
+
+ sprintf(buffer, "\"%s\" - %s", subject, author);
+ if (reference) {
+ write_anchor(buffer, reference);
+ free(reference);
+ reference=0;
+ } else {
+ HText_appendText(HT, buffer);
+ }
+ HText_appendParagraph(HT);
+
+
+/* Change the title bar to indicate progress!
+*/
+ if (art%10 == 0) {
+ sprintf(buffer, "Reading newsgroup %s, Article %d (of %d-%d) ...",
+ groupName, art, first, last);
+ HTAnchor_setTitle(node_anchor, buffer);
+ }
+
+ } /* If good response */
+ } /* Loop over article */
+ } /* If read headers */
+
+/* Link to later articles
+*/
+ if (last_required<last) {
+ int after; /* End of article after */
+ after = last_required+CHUNK_SIZE;
+ if (after==last) sprintf(buffer, "news:%s", groupName); /* original group */
+ else sprintf(buffer, "news:%s/%d-%d", groupName, last_required+1, after);
+ if (TRACE) printf(" Block after is %s\n", buffer);
+ HText_appendText(HT, "(");
+ HText_beginAnchor(HT, HTAnchor_findChildAndLink(
+ node_anchor, "", buffer, 0));
+ HText_appendText(HT, "Later articles");
+ HText_endAnchor(HT);
+ HText_appendText(HT, "...)\n");
+ }
+
+/* Set window title
+*/
+ sprintf(buffer, "Newsgroup %s, Articles %d-%d",
+ groupName, first_required, last_required);
+ HTAnchor_setTitle(node_anchor, buffer);
+
+}
+
+
+/* Load by name HTLoadNews
+** ============
+*/
+PUBLIC int HTLoadNews ARGS3(
+ CONST char *,arg,
+ HTParentAnchor *,anAnchor,
+ int,diag)
+{
+ char command[257]; /* The whole command */
+ char groupName[GROUP_NAME_LENGTH]; /* Just the group name */
+ int status; /* tcp return */
+ int retries; /* A count of how hard we have tried */
+ BOOL group_wanted; /* Flag: group was asked for, not article */
+ BOOL list_wanted; /* Flag: group was asked for, not article */
+ int first, last; /* First and last articles asked for */
+
+ diagnostic = diag; /* set global flag */
+
+ if (TRACE) printf("HTNews: Looking for %s\n", arg);
+ get_styles();
+
+ if (!initialized) initialized = initialize();
+ if (!initialized) return -1; /* FAIL */
+
+ {
+ char * p1;
+
+/* We will ask for the document, omitting the host name & anchor.
+**
+** Syntax of address is
+** xxx@yyy Article
+** <xxx@yyy> Same article
+** xxxxx News group (no "@")
+*/
+ group_wanted = (strchr(arg, '@')==0) && (strchr(arg, '*')==0);
+ list_wanted = (strchr(arg, '@')==0) && (strchr(arg, '*')!=0);
+
+ p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION);
+ if (list_wanted) {
+ strcpy(command, "LIST ");
+ } else if (group_wanted) {
+ char * slash = strchr(p1, '/');
+ strcpy(command, "GROUP ");
+ first = 0;
+ last = 0;
+ if (slash) {
+ *slash = 0;
+ strcpy(groupName, p1);
+ *slash = '/';
+ (void) sscanf(slash+1, "%d-%d", &first, &last);
+ } else {
+ strcpy(groupName, p1);
+ }
+ strcat(command, groupName);
+ } else {
+ strcpy(command, "ARTICLE ");
+ if (strchr(p1, '<')==0) strcat(command,"<");
+ strcat(command, p1);
+ if (strchr(p1, '>')==0) strcat(command,">");
+ }
+ free(p1);
+
+ strcat(command, "\r\n"); /* CR LF, as in rfc 977 */
+
+ } /* scope of p1 */
+
+ if (!*arg) return NO; /* Ignore if no name */
+
+
+/* Make a hypertext object with an anchor list.
+*/
+ node_anchor = anAnchor;
+ HT = HText_new(anAnchor);
+ HText_beginAppend(HT);
+
+/* Now, let's get a stream setup up from the NewsHost:
+*/
+ for(retries=0;retries<2; retries++){
+
+ if (s<0) {
+ HTAnchor_setTitle(node_anchor, "Connecting to NewsHost ...");/* Tell user */
+ NEWS_PROGRESS("Connecting to NewsHost ...");
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ status = connect(s, (struct sockaddr*)&soc_address, sizeof(soc_address));
+ if (status<0){
+ char message[256];
+ NETCLOSE(s);
+ s = -1;
+ if (TRACE) printf("HTNews: Unable to connect to news host.\n");
+/* if (retries<=1) continue; WHY TRY AGAIN ? */
+#ifdef NeXTStep
+ NXRunAlertPanel(NULL,
+ "Could not access newshost %s.",
+ NULL,NULL,NULL,
+ NewsHost);
+#else
+ fprintf(stderr, "Could not access newshost %s\n",
+ NewsHost);
+#endif
+ sprintf(message,
+"\nCould not access %s.\n\n (Check default WorldWideWeb NewsHost ?)\n",
+ NewsHost);
+ HText_beginAppend(HT);
+ HText_appendText(HT, message);
+ HText_endAppend(HT);
+ return YES;
+ } else {
+ if (TRACE) printf("HTNews: Connected to news host %s.\n",
+ NewsHost);
+ HTInitInput(s); /* set up buffering */
+ if ((response(NULL) / 100) !=2) {
+ NETCLOSE(s);
+ s = -1;
+#ifdef NeXTStep
+ NXRunAlertPanel("News access",
+ "Could not retrieve information:\n %s.",
+ NULL,NULL,NULL,
+ response_text);
+#endif
+ HTAnchor_setTitle(node_anchor, "News host response");
+ HText_beginAppend(HT);
+ HText_appendText(HT,
+ "Sorry, could not retrieve information: ");
+ HText_appendText(HT, response_text);
+ HText_endAppend(HT);
+ return YES;
+ }
+ }
+ } /* If needed opening */
+
+ HTAnchor_setTitle(node_anchor, arg);/* Tell user something's happening */
+ status = response(command);
+ if (status<0) break;
+ if ((status/ 100) !=2) {
+/* NXRunAlertPanel("News access", response_text,
+ NULL,NULL,NULL);
+*/
+ HText_beginAppend(HT);
+ HText_appendText(HT, response_text);
+ HText_endAppend(HT);
+ NETCLOSE(s);
+ s = -1;
+/* return HT; -- no:the message might be "Timeout-disconnected" left over */
+ continue; /* Try again */
+ }
+
+/* Load a group, article, etc
+*/
+ HText_beginAppend(HT);
+
+ if (list_wanted) read_list();
+ else if (group_wanted) read_group(groupName, first, last);
+ else read_article();
+
+ HText_endAppend(HT);
+ return YES;
+
+ } /* Retry loop */
+
+ HText_beginAppend(HT);
+ HText_appendText(HT, "Sorry, could not load requested news.\n");
+ HText_endAppend(HT);
+
+/* NXRunAlertPanel(NULL, "Sorry, could not load `%s'.",
+ NULL,NULL,NULL, arg);No -- message earlier wil have covered it */
+
+ return YES;
+}
+
--- /dev/null
+/* NEWS ACCESS HTNews.h
+** ===========
+**
+** History:
+** 26 Sep 90 Written TBL
+** 29 Nov 91 Downgraded to C, for portable implementation.
+*/
+
+#ifndef HTNEWS_H
+#define HTNEWS_H
+
+#include "HTAnchor.h"
+extern int HTLoadNews PARAMS((const char *arg,
+ HTParentAnchor * anAnchor,
+ int diag));
+
+#endif /* HTNEWS_H */
--- /dev/null
+/* Parse HyperText Document Address HTParse.c
+** ================================
+*/
+
+#include "HTUtils.h"
+#include "HTParse.h"
+#include "tcp.h"
+
+struct struct_parts {
+ char * access;
+ char * host;
+ char * absolute;
+ char * relative;
+/* char * search; no - treated as part of path */
+ char * anchor;
+};
+
+
+/* Strip white space off a string
+** ------------------------------
+**
+** On exit,
+** Return value points to first non-white character, or to 0 if none.
+** All trailing white space is OVERWRITTEN with zero.
+*/
+
+#ifdef __STDC__
+char * HTStrip(char * s)
+#else
+char * HTStrip(s)
+ char *s;
+#endif
+{
+#define SPACE(c) ((c==' ')||(c=='\t')||(c=='\n'))
+ char * p=s;
+ for(p=s;*p;p++); /* Find end of string */
+ for(p--;p>=s;p--) {
+ if(SPACE(*p)) *p=0; /* Zap trailing blanks */
+ else break;
+ }
+ while(SPACE(*s))s++; /* Strip leading blanks */
+ return s;
+}
+
+
+/* Scan a filename for its consituents
+** -----------------------------------
+**
+** On entry,
+** name points to a document name which may be incomplete.
+** On exit,
+** absolute or relative may be nonzero (but not both).
+** host, anchor and access may be nonzero if they were specified.
+** Any which are nonzero point to zero terminated strings.
+*/
+#ifdef __STDC__
+PRIVATE void scan(char * name, struct struct_parts *parts)
+#else
+PRIVATE void scan(name, parts)
+ char * name;
+ struct struct_parts *parts;
+#endif
+{
+ char * after_access;
+ char * p;
+ int length = strlen(name);
+
+ parts->access = 0;
+ parts->host = 0;
+ parts->absolute = 0;
+ parts->relative = 0;
+ parts->anchor = 0;
+
+ after_access = name;
+ for(p=name; *p; p++) {
+ if (*p==':') {
+ *p = 0;
+ parts->access = name; /* Access name has been specified */
+ after_access = p+1;
+ }
+ if (*p=='/') break;
+ if (*p=='#') break;
+ }
+
+ for(p=name+length-1; p>=name; p--) {
+ if (*p =='#') {
+ parts->anchor=p+1;
+ *p=0; /* terminate the rest */
+ }
+ }
+ p = after_access;
+ if (*p=='/'){
+ if (p[1]=='/') {
+ parts->host = p+2; /* host has been specified */
+ *p=0; /* Terminate access */
+ p=strchr(parts->host,'/'); /* look for end of host name if any */
+ if(p) {
+ *p=0; /* Terminate host */
+ parts->absolute = p+1; /* Root has been found */
+ }
+ } else {
+ parts->absolute = p+1; /* Root found but no host */
+ }
+ } else {
+ parts->relative = (*after_access) ? after_access : 0; /* zero for "" */
+ }
+#ifdef NOT_DEFINED /* search is just treated as part of path */
+ {
+ char *p = relative ? relative : absolute;
+ if (p) {
+ char * q = strchr(p, '?'); /* Any search string? */
+ if (q) {
+ *q = 0; /* If so, chop that off. */
+ parts->search = q+1;
+ }
+ }
+ }
+#endif
+} /*scan */
+
+
+/* Parse a Name relative to another name
+** -------------------------------------
+**
+** This returns those parts of a name which are given (and requested)
+** substituting bits from the related name where necessary.
+**
+** On entry,
+** aName A filename given
+** relatedName A name relative to which aName is to be parsed
+** wanted A mask for the bits which are wanted.
+**
+** On exit,
+** returns A pointer to a malloc'd string which MUST BE FREED
+*/
+#ifdef __STDC__
+char * HTParse(const char * aName, const char * relatedName, int wanted)
+#else
+char * HTParse(aName, relatedName, wanted)
+ char * aName;
+ char * relatedName;
+ int wanted;
+#endif
+
+{
+ char * result = 0;
+ char * return_value = 0;
+ int len;
+ char * name = 0;
+ char * rel = 0;
+ char * p;
+ struct struct_parts given, related;
+
+ /* Make working copies of input strings to cut up:
+ */
+ len = strlen(aName)+strlen(relatedName)+10;
+ result=(char *)malloc(len); /* Lots of space: more than enough */
+ if (result == NULL) outofmem(__FILE__, "HTParse");
+
+ StrAllocCopy(name, aName);
+ StrAllocCopy(rel, relatedName);
+
+ scan(name, &given);
+ scan(rel, &related);
+ result[0]=0; /* Clear string */
+ if (wanted & PARSE_ACCESS)
+ if (given.access|| related.access) {
+ strcat(result, given.access ? given.access : related.access);
+ if(wanted & PARSE_PUNCTUATION) strcat(result, ":");
+ }
+
+ if (given.access && related.access) /* If different, inherit nothing. */
+ if (strcmp(given.access, related.access)!=0) {
+ related.host=0;
+ related.absolute=0;
+ related.relative=0;
+ related.anchor=0;
+ }
+
+ if (wanted & PARSE_HOST)
+ if(given.host || related.host) {
+ if(wanted & PARSE_PUNCTUATION) strcat(result, "//");
+ strcat(result, given.host ? given.host : related.host);
+ }
+
+ if (given.host && related.host) /* If different hosts, inherit no path. */
+ if (strcmp(given.host, related.host)!=0) {
+ related.absolute=0;
+ related.relative=0;
+ related.anchor=0;
+ }
+
+ if (wanted & PARSE_PATH) {
+ if(given.absolute) { /* All is given */
+ if(wanted & PARSE_PUNCTUATION) strcat(result, "/");
+ strcat(result, given.absolute);
+ } else if(related.absolute) { /* Adopt path not name */
+ strcat(result, "/");
+ strcat(result, related.absolute);
+ if (given.relative) {
+ p = strchr(result, '?'); /* Search part? */
+ if (!p) p=result+strlen(result)-1;
+ for (; *p!='/'; p--); /* last / */
+ p[1]=0; /* Remove filename */
+ strcat(result, given.relative); /* Add given one */
+ HTSimplify (result);
+ }
+ } else if(given.relative) {
+ strcat(result, given.relative); /* what we've got */
+ } else if(related.relative) {
+ strcat(result, related.relative);
+ } else { /* No inheritance */
+ strcat(result, "/");
+ }
+ }
+
+ if (wanted & PARSE_ANCHOR)
+ if(given.anchor || related.anchor) {
+ if(wanted & PARSE_PUNCTUATION) strcat(result, "#");
+ strcat(result, given.anchor ? given.anchor : related.anchor);
+ }
+ free(rel);
+ free(name);
+
+ StrAllocCopy(return_value, result);
+ free(result);
+ return return_value; /* exactly the right length */
+}
+
+/* Simplify a filename
+// -------------------
+//
+// A unix-style file is allowed to contain the seqeunce xxx/../ which may be
+// replaced by "" , and the seqeunce "/./" which may be replaced by "/".
+// Simplification helps us recognize duplicate filenames.
+//
+// Thus, /etc/junk/../fred becomes /etc/fred
+// /etc/junk/./fred becomes /etc/junk/fred
+*/
+#ifdef __STDC__
+void HTSimplify(char * filename)
+#else
+void HTSimplify(filename)
+ char * filename;
+#endif
+
+{
+ char * p;
+ char * q;
+ for(p=filename+2; *p; p++) {
+ if (*p=='/') {
+ if ((p[1]=='.') && (p[2]=='.') && (p[3]=='/' || !p[3] )) {
+ for (q=p-1; (q>filename) && (*q!='/'); q--); /* prev slash */
+ if (*q=='/') {
+ strcpy(q, p+3); /* Remove /xxx/.. */
+ if (!*filename) strcpy(filename, "/");
+ p = q-1; /* Start again with prev slash */
+ } else { /* xxx/.. error? */
+ strcpy(filename, p[3] ? p+4 : p+3); /* rm xxx/../ */
+ p = filename; /* Start again */
+ }
+ } else if ((p[1]=='.') && (p[2]=='/' || !p[2])) {
+ strcpy(p, p+2); /* Remove a slash and a dot */
+ }
+ }
+ }
+}
+
+
+/* Make Relative Name
+** ------------------
+**
+** This function creates and returns a string which gives an expression of
+** one address as related to another. Where there is no relation, an absolute
+** address is retured.
+**
+** On entry,
+** Both names must be absolute, fully qualified names of nodes
+** (no anchor bits)
+**
+** On exit,
+** The return result points to a newly allocated name which, if
+** parsed by HTParse relative to relatedName, will yield aName.
+** The caller is responsible for freeing the resulting name later.
+**
+*/
+#ifdef __STDC__
+char * HTRelative(const char * aName, const char *relatedName)
+#else
+char * HTRelative(aName, relatedName)
+ char * aName;
+ char * relatedName;
+#endif
+{
+ char * result = 0;
+ CONST char *p = aName;
+ CONST char *q = relatedName;
+ CONST char * after_access = 0;
+ CONST char * path = 0;
+ CONST char * last_slash = 0;
+ int slashes = 0;
+
+ for(;*p; p++, q++) { /* Find extent of match */
+ if (*p!=*q) break;
+ if (*p==':') after_access = p+1;
+ if (*p=='/') {
+ last_slash = p;
+ slashes++;
+ if (slashes==3) path=p;
+ }
+ }
+
+ /* q, p point to the first non-matching character or zero */
+
+ if (!after_access) { /* Different access */
+ StrAllocCopy(result, aName);
+ } else if (slashes<3){ /* Different nodes */
+ StrAllocCopy(result, after_access);
+ } else if (slashes==3){ /* Same node, different path */
+ StrAllocCopy(result, path);
+ } else { /* Some path in common */
+ int levels= 0;
+ for(; *q && (*q!='#'); q++) if (*q=='/') levels++;
+ result = (char *)malloc(3*levels + strlen(last_slash) + 1);
+ if (result == NULL) outofmem(__FILE__, "HTRelative");
+ result[0]=0;
+ for(;levels; levels--)strcat(result, "../");
+ strcat(result, last_slash+1);
+ }
+ if (TRACE) printf("HT: `%s' expressed relative to\n `%s' is\n `%s'.",
+ aName, relatedName, result);
+ return result;
+}
--- /dev/null
+/* Parse HyperText Document Address HTParse.h
+** ================================
+*/
+/* These are flag bits which may be ORed together to form a number to give
+** the 'wanted' argument to HTParse.
+*/
+#define PARSE_ACCESS 16
+#define PARSE_HOST 8
+#define PARSE_PATH 4
+#define PARSE_ANCHOR 2
+#define PARSE_PUNCTUATION 1
+#define PARSE_ALL 31
+
+/* Parse a Name relative to another name
+** -------------------------------------
+**
+** This returns those parts of a name which are given (and requested)
+** substituting bits from the related name where necessary.
+**
+** On entry,
+** aName A filename given
+** relatedName A name relative to ehich aName is to be parsed
+** wanted A mask for the bits which are wanted.
+**
+** On exit,
+** returns A pointer to a malloc'd string which MUST BE FREED
+*/
+#ifdef __STDC__
+extern char * HTParse(const char * aName, const char * relatedName, int wanted);
+#else
+extern char * HTParse();
+#endif
+
+/* Strip white space off a string
+** ------------------------------
+**
+** On exit,
+** Return value points to first non-white character, or to 0 if none.
+** All trailing white space is OVERWRITTEN with zero.
+*/
+#ifdef __STDC__
+extern char * HTStrip(char * s);
+#else
+extern char * HTStrip();
+#endif
+
+/* Simplify a filename
+** -------------------
+**
+** A unix-style file is allowed to contain the seqeunce xxx/../ which
+** may be replaced by "" , and the seqeunce "/./" which may be replaced
+** by "/".
+** Simplification helps us recognize duplicate filenames. It doesn't deal
+** with soft links, though.
+** The new (shorter) filename overwrites the old.
+**
+** Thus, /etc/junk/../fred becomes /etc/fred
+** /etc/junk/./fred becomes /etc/junk/fred
+*/
+#ifdef __STDC__
+extern void HTSimplify(char * filename);
+#else
+extern void HTSimplify();
+#endif
+
+/* Make Relative Name
+** ------------------
+**
+** This function creates and returns a string which gives an expression of
+** one address as related to another. Where there is no relation, an
+** absolute address is retured.
+**
+** On entry,
+** Both names must be absolute, fully qualified names of nodes
+** (no anchor bits)
+**
+** On exit,
+** The return result points to a newly allocated name which, if parsed
+** by HTParse relative to relatedName, will yield aName. The caller is
+** responsible for freeing the resulting name later.
+**
+*/
+#ifdef __STDC__
+extern char * HTRelative(const char * aName, const char *relatedName);
+#else
+extern char * HTRelative();
+#endif
--- /dev/null
+/* Case-independent string comparison HTString.c
+**
+** Original version came with listserv implementation.
+** Version TBL Oct 91 replaces one which modified the strings.
+** 02-Dec-91 (JFG) Added stralloccopy and stralloccat
+** 23 Jan 92 (TBL) Changed strallocc* to 8 char HTSAC* for VM and suchlike
+*/
+#include <ctype.h>
+#include "HTUtils.h"
+#include "tcp.h"
+
+#ifndef VM /* VM has these already it seems */
+
+/* Strings of any length
+** ---------------------
+*/
+PUBLIC int strcasecomp ARGS2 (CONST char*,a, CONST char *,b)
+{
+ CONST char *p =a;
+ CONST char *q =b;
+ for(p=a, q=b; *p && *q; p++, q++) {
+ int diff = TOLOWER(*p) - TOLOWER(*q);
+ if (diff) return diff;
+ }
+ if (*p) return 1; /* p was longer than q */
+ if (*q) return -1; /* p was shorter than q */
+ return 0; /* Exact match */
+}
+
+
+/* With count limit
+** ----------------
+*/
+PUBLIC int strncasecomp ARGS3(CONST char*,a, CONST char *,b, int,n)
+{
+ CONST char *p =a;
+ CONST char *q =b;
+
+ for(p=a, q=b;; p++, q++) {
+ int diff;
+ if (p == a+n) return 0; /* Match up to n characters */
+ if (!(*p && *q)) return *p - *q;
+ diff = TOLOWER(*p) - TOLOWER(*q);
+ if (diff) return diff;
+ }
+ /*NOTREACHED*/
+}
+#endif
+
+/* Allocate a new copy of a string, and returns it
+*/
+PUBLIC char * HTSACopy
+ ARGS2 (char **,dest, CONST char *,src)
+{
+ if (*dest) free(*dest);
+ if (! src)
+ *dest = NULL;
+ else {
+ *dest = (char *) malloc (strlen(src) + 1);
+ if (*dest == NULL) outofmem(__FILE__, "HTSACopy");
+ strcpy (*dest, src);
+ }
+ return *dest;
+}
+
+PUBLIC char * HTSACat
+ ARGS2 (char **,dest, CONST char *,src)
+{
+ if (src && *src) {
+ if (*dest) {
+ int length = strlen (*dest);
+ *dest = (char *) realloc (*dest, length + strlen(src) + 1);
+ if (*dest == NULL) outofmem(__FILE__, "HTSACat");
+ strcpy (*dest + length, src);
+ } else {
+ *dest = (char *) malloc (strlen(src) + 1);
+ if (*dest == NULL) outofmem(__FILE__, "HTSACat");
+ strcpy (*dest, src);
+ }
+ }
+ return *dest;
+}
--- /dev/null
+/* Case-independent string comparison HTString.h
+** and allocations with copies
+*/
+#ifndef HTSTRING_H
+#define HTSTRING_H
+
+#include "HTUtils.h"
+
+extern int strcasecomp PARAMS((CONST char *a, CONST char *b));
+extern int strncasecomp PARAMS((CONST char *a, CONST char *b, int n));
+
+extern char * HTSACopy PARAMS ((char **dest, CONST char *src));
+extern char * HTSACat PARAMS ((char **dest, CONST char *src));
+
+/* Enable the old macro-like calling methods */
+#define StrAllocCopy(dest, src) HTSACopy (&(dest), src)
+#define StrAllocCat(dest, src) HTSACat (&(dest), src)
+
+#endif
--- /dev/null
+/* Style Implementation for Hypertext HTStyle.c
+** ==================================
+**
+** Styles allow the translation between a logical property
+** of a piece of text and its physical representation.
+**
+** A StyleSheet is a collection of styles, defining the
+** translation necessary to
+** represent a document. It is a linked list of styles.
+*/
+#include "HTStyle.h"
+#include "HTUtils.h"
+
+/* Create a new style
+*/
+PUBLIC HTStyle* HTStyleNew NOARGS
+{
+ HTStyle * self = (HTStyle *)malloc(sizeof(*self));
+ memset(self, 0, sizeof(*self));
+ self->font = HT_FONT;
+ self->color = HT_BLACK;
+ return self;
+}
+
+/* Create a new style with a name
+*/
+PUBLIC HTStyle* HTStyleNewNamed ARGS1 (CONST char *,name)
+{
+ HTStyle * self = HTStyleNew();
+ StrAllocCopy(self->name, name);
+ return self;
+}
+
+
+/* Free a style
+*/
+PUBLIC HTStyle * HTStyleFree ARGS1 (HTStyle *,self)
+{
+ if (self->name) free(self->name);
+ if (self->SGMLTag) free(self->SGMLTag);
+ free(self);
+ return 0;
+}
+
+
+#ifdef SUPPRESS /* Only on the NeXT */
+/* Read a style from a stream (without its name)
+** --------------------------
+**
+** Reads a style with paragraph information from a stream.
+** The style name is not read or written by these routines.
+*/
+#define NONE_STRING "(None)"
+#define HTStream NXStream
+
+HTStyle * HTStyleRead (HTStyle * style, HTStream * stream)
+{
+ char myTag[STYLE_NAME_LENGTH];
+ char fontName[STYLE_NAME_LENGTH];
+ NXTextStyle *p;
+ int tab;
+ int gotpara; /* flag: have we got a paragraph definition? */
+
+ NXScanf(stream, "%s%s%f%d",
+ myTag,
+ fontName,
+ &style->fontSize,
+ &gotpara);
+ if (gotpara) {
+ if (!style->paragraph) {
+ style->paragraph = malloc(sizeof(*(style->paragraph)));
+ style->paragraph->tabs = 0;
+ }
+ p = style->paragraph;
+ NXScanf(stream, "%f%f%f%f%hd%f%f%hd",
+ &p->indent1st,
+ &p->indent2nd,
+ &p->lineHt,
+ &p->descentLine,
+ &p->alignment,
+ &style->spaceBefore,
+ &style->spaceAfter,
+ &p->numTabs);
+ if (p->tabs) free(p->tabs);
+ p->tabs = malloc(p->numTabs * sizeof(p->tabs[0]));
+ for (tab=0; tab < p->numTabs; tab++) {
+ NXScanf(stream, "%hd%f",
+ &p->tabs[tab].kind,
+ &p->tabs[tab].x);
+ }
+ } else { /* No paragraph */
+ if (style->paragraph) {
+ free(style->paragraph);
+ style->paragraph = 0;
+ }
+ } /* if no paragraph */
+ StrAllocCopy(style->SGMLTag, myTag);
+ if (strcmp(fontName, NONE_STRING)==0)
+ style->font = 0;
+ else
+ style->font = [Font newFont:fontName size:style->fontSize];
+ return 0;
+
+}
+
+
+/* Write a style to a stream in a compatible way
+*/
+HTStyle * HTStyleWrite (HTStyle * style, NXStream * stream)
+{
+ int tab;
+ NXTextStyle *p = style->paragraph;
+ NXPrintf(stream, "%s %s %f %d\n",
+ style->SGMLTag,
+ style->font ? [style->font name] : NONE_STRING,
+ style->fontSize,
+ p!=0);
+
+ if (p) {
+ NXPrintf(stream, "\t%f %f %f %f %d %f %f\t%d\n",
+ p->indent1st,
+ p->indent2nd,
+ p->lineHt,
+ p->descentLine,
+ p->alignment,
+ style->spaceBefore,
+ style->spaceAfter,
+ p->numTabs);
+
+ for (tab=0; tab < p->numTabs; tab++)
+ NXPrintf(stream, "\t%d %f\n",
+ p->tabs[tab].kind,
+ p->tabs[tab].x);
+ }
+ return style;
+}
+
+
+/* Write a style to stdout for diagnostics
+*/
+HTStyle * HTStyleDump (HTStyle * style)
+{
+ int tab;
+ NXTextStyle *p = style->paragraph;
+ printf("Style %d `%s' SGML:%s. Font %s %.1f point.\n",
+ style,
+ style->name,
+ style->SGMLTag,
+ [style->font name],
+ style->fontSize);
+ if (p) {
+ printf(
+ "\tIndents: first=%.0f others=%.0f, Height=%.1f Desc=%.1f\n"
+ "\tAlign=%d, %d tabs. (%.0f before, %.0f after)\n",
+ p->indent1st,
+ p->indent2nd,
+ p->lineHt,
+ p->descentLine,
+ p->alignment,
+ p->numTabs,
+ style->spaceBefore,
+ style->spaceAfter);
+
+ for (tab=0; tab < p->numTabs; tab++) {
+ printf("\t\tTab kind=%d at %.0f\n",
+ p->tabs[tab].kind,
+ p->tabs[tab].x);
+ }
+ printf("\n");
+ } /* if paragraph */
+ return style;
+}
+#endif
+
+
+/* StyleSheet Functions
+** ====================
+*/
+
+/* Searching for styles:
+*/
+HTStyle * HTStyleNamed ARGS2 (HTStyleSheet *,self, CONST char *,name)
+{
+ HTStyle * scan;
+ for (scan=self->styles; scan; scan=scan->next)
+ if (0==strcmp(scan->name, name)) return scan;
+ if (TRACE) printf("StyleSheet: No style named `%s'\n", name);
+ return 0;
+}
+
+#ifdef NEXT_SUPRESS /* Not in general common code */
+
+HTStyle * HTStyleMatching (HTStyleSheet * self, HTStyle *style)
+{
+ HTStyle * scan;
+ for (scan=self->styles; scan; scan=scan->next)
+ if (scan->paragraph == para) return scan;
+ return 0;
+}
+
+/* Find the style which best fits a given run
+** ------------------------------------------
+**
+** This heuristic is used for guessing the style for a run of
+** text which has been pasted in. In order, we try:
+**
+** A style whose paragraph structure is actually used by the run.
+** A style matching in font
+** A style matching in paragraph style exactly
+** A style matching in paragraph to a degree
+*/
+
+HTStyle * HTStyleForRun (HTStyleSheet *self, NXRun *run)
+{
+ HTStyle * scan;
+ HTStyle * best = 0;
+ int bestMatch = 0;
+ NXTextStyle * rp = run->paraStyle;
+ for (scan=self->styles; scan; scan=scan->next)
+ if (scan->paragraph == run->paraStyle) return scan; /* Exact */
+
+ for (scan=self->styles; scan; scan=scan->next){
+ NXTextStyle * sp = scan->paragraph;
+ if (sp) {
+ int match = 0;
+ if (sp->indent1st == rp->indent1st) match = match+1;
+ if (sp->indent2nd == rp->indent2nd) match = match+2;
+ if (sp->lineHt == rp->lineHt) match = match+1;
+ if (sp->numTabs == rp->numTabs) match = match+1;
+ if (sp->alignment == rp->alignment) match = match+3;
+ if (scan->font == run->font) match = match+10;
+ if (match>bestMatch) {
+ best=scan;
+ bestMatch=match;
+ }
+ }
+ }
+ if (TRACE) printf("HTStyleForRun: Best match for style is %d out of 18\n",
+ bestMatch);
+ return best;
+}
+#endif
+
+
+/* Add a style to a sheet
+** ----------------------
+*/
+HTStyleSheet * HTStyleSheetAddStyle ARGS2
+ (HTStyleSheet *,self, HTStyle *,style)
+{
+ style->next = 0; /* The style will go on the end */
+ if (!self->styles) {
+ self->styles = style;
+ } else {
+ HTStyle * scan;
+ for(scan=self->styles; scan->next; scan=scan->next); /* Find end */
+ scan->next=style;
+ }
+ return self;
+}
+
+
+/* Remove the given object from a style sheet if it exists
+*/
+HTStyleSheet * HTStyleSheetRemoveStyle ARGS2
+ (HTStyleSheet *,self, HTStyle *,style)
+{
+ if (self->styles = style) {
+ self->styles = style->next;
+ return self;
+ } else {
+ HTStyle * scan;
+ for(scan = self->styles; scan; scan = scan->next) {
+ if (scan->next = style) {
+ scan->next = style->next;
+ return self;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Create new style sheet
+*/
+
+HTStyleSheet * HTStyleSheetNew NOARGS
+{
+ HTStyleSheet * self = (HTStyleSheet *)malloc(sizeof(*self));
+
+ memset((void*)self, 0, sizeof(*self)); /* ANSI */
+/* Harbison c ref man says (char*)self
+ but k&r ansii and abc books and Think_C say (void*) */
+
+/* bzero(self, sizeof(*self)); */ /* BSD */
+ return self;
+}
+
+
+/* Free off a style sheet pointer
+*/
+HTStyleSheet * HTStyleSheetFree ARGS1 (HTStyleSheet *,self)
+{
+ HTStyle * style;
+ while((style=self->styles)!=0) {
+ self->styles = style->next;
+ HTStyleFree(style);
+ }
+ free(self);
+ return 0;
+}
+
+
+/* Read a stylesheet from a typed stream
+** -------------------------------------
+**
+** Reads a style sheet from a stream. If new styles have the same names
+** as existing styles, they replace the old ones without changing the ids.
+*/
+
+#ifdef NEXT_SUPRESS /* Only on the NeXT */
+HTStyleSheet * HTStyleSheetRead(HTStyleSheet * self, NXStream * stream)
+{
+ int numStyles;
+ int i;
+ HTStyle * style;
+ char styleName[80];
+ NXScanf(stream, " %d ", &numStyles);
+ if (TRACE) printf("Stylesheet: Reading %d styles\n", numStyles);
+ for (i=0; i<numStyles; i++) {
+ NXScanf(stream, "%s", styleName);
+ style = HTStyleNamed(self, styleName);
+ if (!style) {
+ style = HTStyleNewNamed(styleName);
+ (void) HTStyleSheetAddStyle(self, style);
+ }
+ (void) HTStyleRead(style, stream);
+ if (TRACE) HTStyleDump(style);
+ }
+ return self;
+}
+
+/* Write a stylesheet to a typed stream
+** ------------------------------------
+**
+** Writes a style sheet to a stream.
+*/
+
+HTStyleSheet * HTStyleSheetWrite(HTStyleSheet * self, NXStream * stream)
+{
+ int numStyles = 0;
+ HTStyle * style;
+
+ for(style=self->styles; style; style=style->next) numStyles++;
+ NXPrintf(stream, "%d\n", numStyles);
+
+ if (TRACE) printf("StyleSheet: Writing %d styles\n", numStyles);
+ for (style=self->styles; style; style=style->next) {
+ NXPrintf(stream, "%s ", style->name);
+ (void) HTStyleWrite(style, stream);
+ }
+ return self;
+}
+#endif
--- /dev/null
+/* Style Definition for Hypertext HTStyle.h
+** ==============================
+**
+** Styles allow the translation between a logical property of a piece of
+** text and its physical representation.
+**
+** A StyleSheet is a collection of styles, defining the
+** translation necessary to represent a document.
+** It is a linked list of styles.
+*/
+#ifndef HTStyle_H
+#define HTStyle_H
+
+#include "HTUtils.h"
+#include "HTAnchor.h"
+#include "HTFont.h"
+
+#ifdef SHORT_NAMES
+#define HTStyleNew HTStNew
+#define HTStyleFree HTStFree
+#define HTStyleRead HTStRead
+#define HTStyleWrite HTStWrite
+#define HTStyleSheetNew HTStShNe
+#define HTStyleSheetFree HTStShFr
+#define HTStyleNamed HTStName
+#define HTStyleForParagraph HTStFoPa
+#define HTStyleMatching HTStMatc
+#define HTStyleForRun HTStFoRu
+#define HTStyleSheetAddStyle HTStShAd
+#define HTStyleSheetRemoveStyle HTStShRm
+#define HTStyleSheetRead HTStShRe
+#define HTStyleSheetWrite HTStShWr
+#endif
+
+#ifdef NeXT_suppressed
+#include <appkit/appkit.h>
+typedef NXCoord HTCoord;
+#define HTParagraphStyle NXTextStyle
+#define HTCoord NXCoord
+typedef struct _color {
+ float grey;
+ int RGBColor;
+} HTColor;
+#else
+
+typedef float HTCoord;
+
+typedef struct _HTParagraphStyle {
+ HTCoord left_indent; /* @@@@ junk! etc etc*/
+} HTParagraphStyle;
+
+typedef int HTColor; /* Sorry about the US spelling! */
+
+#endif
+
+
+
+#define STYLE_NAME_LENGTH 80 /* @@@@@@@@@@@ */
+
+typedef struct {
+ short kind; /* only NX_LEFTTAB implemented*/
+ HTCoord position; /* x coordinate for stop */
+} HTTabStop;
+
+
+/* The Style Structure
+** -------------------
+*/
+
+typedef struct _HTStyle {
+
+/* Style management information
+*/
+ struct _HTStyle *next; /* Link for putting into stylesheet */
+ char * name; /* Style name */
+ char * SGMLTag; /* Tag name to start */
+
+
+/* Character attributes (a la NXRun)
+*/
+ HTFont font; /* Font id */
+ HTCoord fontSize; /* The size of font, not independent */
+ HTColor color; /* text gray of current run */
+ int superscript; /* superscript (-sub) in points */
+
+ HTAnchor *anchor; /* Anchor id if any, else zero */
+
+/* Paragraph Attribtes (a la NXTextStyle)
+*/
+ HTCoord indent1st; /* how far first line in paragraph is
+ * indented */
+ HTCoord leftIndent; /* how far second line is indented */
+ HTCoord rightIndent; /* (Missing from NeXT version */
+ short alignment; /* quad justification */
+ HTCoord lineHt; /* line height */
+ HTCoord descentLine; /* descender bottom from baseline */
+ HTTabStop *tabs; /* array of tab stops, 0 terminated */
+
+ BOOL wordWrap; /* Yes means wrap at space not char */
+ BOOL freeFormat; /* Yes means \n is just white space */
+ HTCoord spaceBefore; /* Omissions from NXTextStyle */
+ HTCoord spaceAfter;
+ int paraFlags; /* Paragraph flags, bits as follows: */
+
+#define PARA_KEEP 1 /* Do not break page within this paragraph */
+#define PARA_WITH_NEXT 2 /* Do not break page after this paragraph */
+
+#define HT_JUSTIFY 0 /* For alignment */
+#define HT_LEFT 1
+#define HT_RIGHT 2
+#define HT_CENTER 3
+
+} HTStyle;
+
+
+/* Style functions:
+*/
+extern HTStyle * HTStyleNew NOPARAMS;
+extern HTStyle* HTStyleNewNamed PARAMS ((CONST char * name));
+extern HTStyle * HTStyleFree PARAMS((HTStyle * self));
+#ifdef SUPRESS
+extern HTStyle * HTStyleRead PARAMS((HTStyle * self, HTStream * stream));
+extern HTStyle * HTStyleWrite PARAMS((HTStyle * self, HTStream * stream));
+#endif
+/* Style Sheet
+** -----------
+*/
+typedef struct _HTStyleSheet {
+ char * name;
+ HTStyle * styles;
+} HTStyleSheet;
+
+
+/* Stylesheet functions:
+*/
+extern HTStyleSheet * HTStyleSheetNew NOPARAMS;
+extern HTStyleSheet * HTStyleSheetFree PARAMS((HTStyleSheet * self));
+extern HTStyle * HTStyleNamed PARAMS((HTStyleSheet * self, CONST char * name));
+extern HTStyle * HTStyleForParagraph PARAMS((HTStyleSheet * self,
+ HTParagraphStyle * paraStyle));
+extern HTStyle * HTStyleMatching PARAMS((HTStyleSheet *self, HTStyle * style));
+/* extern HTStyle * HTStyleForRun PARAMS((HTStyleSheet *self, NXRun * run)); */
+extern HTStyleSheet * HTStyleSheetAddStyle PARAMS((HTStyleSheet * self,
+ HTStyle * style));
+extern HTStyleSheet * HTStyleSheetRemoveStyle PARAMS((HTStyleSheet * self,
+ HTStyle * style));
+#ifdef SUPPRESS
+extern HTStyleSheet * HTStyleSheetRead PARAMS((HTStyleSheet * self,
+ HTStream * stream));
+extern HTStyleSheet * HTStyleSheetWrite PARAMS((HTStyleSheet * self,
+ HTStream * stream));
+#endif
+#define CLEAR_POINTER ((void *)-1) /* Pointer value means "clear me" */
+#endif /* HTStyle_H */
--- /dev/null
+/* Generic Communication Code HTTCP.c
+** ==========================
+**
+** This code is in common between client and server sides.
+**
+** 16 Jan 92 Fix strtol() undefined on CMU Mach. - TBL
+*/
+
+
+#include "HTUtils.h"
+#include "tcp.h" /* Defines SHORT_NAMES if necessary */
+#ifdef SHORT_NAMES
+#define HTInetStatus HTInStat
+#define HTInetString HTInStri
+#define HTParseInet HTPaInet
+#endif
+
+/* Module-Wide variables
+*/
+
+PRIVATE char *hostname=0; /* The name of this host */
+
+
+/* PUBLIC VARIABLES
+*/
+
+/* PUBLIC struct sockaddr_in HTHostAddress; */ /* The internet address of the host */
+ /* Valid after call to HTHostName() */
+
+/* Encode INET status (as in sys/errno.h) inet_status()
+** ------------------
+**
+** On entry,
+** where gives a description of what caused the error
+** global errno gives the error number in the unix way.
+**
+** On return,
+** returns a negative status in the unix way.
+*/
+#ifndef PCNFS
+#ifdef vms
+extern int uerrno; /* Deposit of error info (as perr errno.h) */
+extern int vmserrno; /* Deposit of VMS error info */
+extern volatile noshare int errno; /* noshare to avoid PSECT conflict */
+#else
+#ifndef errno
+extern int errno;
+#endif
+#endif
+
+#ifndef VM
+#ifndef vms
+#ifndef NeXT
+#ifndef THINK_C
+extern char *sys_errlist[]; /* see man perror on cernvax */
+extern int sys_nerr;
+#endif /* think c */
+#endif /* NeXT */
+#endif /* vms */
+#endif /* VM */
+#endif /* PCNFS */
+
+/* Report Internet Error
+** ---------------------
+*/
+#ifdef __STDC__
+PUBLIC int HTInetStatus(char *where)
+#else
+PUBLIC int HTInetStatus(where)
+ char *where;
+#endif
+{
+ CTRACE(tfp, "TCP: Error %d in `errno' after call to %s() failed.\n\t%s\n",
+ errno, where,
+#ifdef VM
+ "(Error number not translated)"); /* What Is the VM equiv? */
+#define ER_NO_TRANS_DONE
+#endif
+#ifdef vms
+ "(Error number not translated)");
+#define ER_NO_TRANS_DONE
+#endif
+#ifdef NeXT
+ strerror(errno));
+#define ER_NO_TRANS_DONE
+#endif
+#ifdef THINK_C
+ strerror(errno));
+#define ER_NO_TRANS_DONE
+#endif
+
+#ifndef ER_NO_TRANS_DONE
+ errno < sys_nerr ? sys_errlist[errno] : "Unknown error" );
+#endif
+
+
+#ifdef vms
+ CTRACE(tfp, " Unix error number (uerrno) = %ld dec\n", uerrno);
+ CTRACE(tfp, " VMS error (vmserrno) = %lx hex\n", vmserrno);
+#endif
+ return -errno;
+}
+
+
+/* Parse a cardinal value parse_cardinal()
+** ----------------------
+**
+** On entry,
+** *pp points to first character to be interpreted, terminated by
+** non 0:9 character.
+** *pstatus points to status already valid
+** maxvalue gives the largest allowable value.
+**
+** On exit,
+** *pp points to first unread character
+** *pstatus points to status updated iff bad
+*/
+#ifdef __STDC__
+PUBLIC unsigned int HTCardinal(int *pstatus,
+ char **pp,
+ unsigned int max_value)
+#else
+PUBLIC unsigned int HTCardinal(pstatus, pp, max_value)
+ int *pstatus;
+ char **pp;
+ unsigned int max_value;
+#endif
+{
+ int n;
+ if ( (**pp<'0') || (**pp>'9')) { /* Null string is error */
+ *pstatus = -3; /* No number where one expeceted */
+ return 0;
+ }
+
+ n=0;
+ while ((**pp>='0') && (**pp<='9')) n = n*10 + *((*pp)++) - '0';
+
+ if (n>max_value) {
+ *pstatus = -4; /* Cardinal outside range */
+ return 0;
+ }
+
+ return n;
+}
+
+
+/* Produce a string for an inernet address
+** ---------------------------------------
+**
+** On exit,
+** returns a pointer to a static string which must be copied if
+** it is to be kept.
+*/
+#ifdef __STDC__
+PUBLIC const char * HTInetString(struct sockaddr_in* sin)
+#else
+PUBLIC char * HTInetString(sin)
+ struct sockaddr_in *sin;
+#endif
+{
+ static char string[16];
+ sprintf(string, "%d.%d.%d.%d",
+ (int)*((unsigned char *)(&sin->sin_addr)+0),
+ (int)*((unsigned char *)(&sin->sin_addr)+1),
+ (int)*((unsigned char *)(&sin->sin_addr)+2),
+ (int)*((unsigned char *)(&sin->sin_addr)+3));
+ return string;
+}
+
+
+/* Parse an internet node address and port
+** ---------------------------------------
+**
+** On entry,
+** str points to a string with a node name or number,
+** with optional trailing colon and port number.
+** sin points to the binary internet address field.
+**
+** On exit,
+** *sin is filled in. If no port is specified in str, that
+** field is left unchanged in *sin.
+*/
+#ifdef __STDC__
+PUBLIC int HTParseInet(struct sockaddr_in* sin, const char *str)
+#else
+PUBLIC int HTParseInet(sin, str)
+ struct sockaddr_in *sin;
+ char *str;
+#endif
+{
+ char *port;
+ char host[256];
+ struct hostent *phost; /* Pointer to host - See netdb.h */
+ strcpy(host, str); /* Take a copy we can mutilate */
+
+
+
+/* Parse port number if present
+*/
+ if (port=strchr(host, ':')) {
+ *port++ = 0; /* Chop off port */
+ if (port[0]>='0' && port[0]<='9') {
+#ifdef unix
+ sin->sin_port = htons(atol(port));
+#else
+ sin->sin_port = htons(strtol(port, (char**)0 , 10));
+#endif
+ } else {
+#ifdef SUPPRESS /* 1. crashes!?!. 2. Not recommended */
+ struct servent * serv = getservbyname(port, (char*)0);
+ if (serv) sin->sin_port = serv->s_port;
+ else if (TRACE) printf("TCP: Unknown service %s\n", port);
+#endif
+ }
+ }
+
+/* Parse host number if present
+*/
+ if (*host>='0' && *host<='9') { /* Numeric node address: */
+ sin->sin_addr.s_addr = inet_addr(host); /* See arpa/inet.h */
+
+ } else { /* Alphanumeric node name: */
+#ifdef MVS /* Oustanding problem with crsh in MVS gethostbyname */
+ if(TRACE)printf("HTTCP: Calling gethostbyname(%s)\n", host);
+#endif
+ phost=gethostbyname(host); /* See netdb.h */
+#ifdef MVS
+ if(TRACE)printf("HTTCP: gethostbyname() returned %d\n", phost);
+#endif
+ if (!phost) {
+ if (TRACE) printf(
+ "HTTPAccess: Can't find internet node name `%s'.\n",host);
+ return -1; /* Fail? */
+ }
+ memcpy(&sin->sin_addr, phost->h_addr, phost->h_length);
+ }
+
+ if (TRACE) printf(
+ "TCP: Parsed address as port %d, IP address %d.%d.%d.%d\n",
+ (unsigned int)ntohs(sin->sin_port),
+ (int)*((unsigned char *)(&sin->sin_addr)+0),
+ (int)*((unsigned char *)(&sin->sin_addr)+1),
+ (int)*((unsigned char *)(&sin->sin_addr)+2),
+ (int)*((unsigned char *)(&sin->sin_addr)+3));
+
+ return 0; /* OK */
+}
+
+
+
+/* Derive the name of the host on which we are
+** -------------------------------------------
+**
+*/
+#ifdef __STDC__
+PRIVATE void get_host_details(void)
+#else
+PRIVATE void get_host_details()
+#endif
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64 /* Arbitrary limit */
+#endif
+
+{
+ char name[MAXHOSTNAMELEN+1]; /* The name of this host */
+#ifdef NEED_HOST_ADDRESS /* no -- needs name server! */
+ struct hostent * phost; /* Pointer to host -- See netdb.h */
+#endif
+ int namelength = sizeof(name);
+
+ if (hostname) return; /* Already done */
+ gethostname(name, namelength); /* Without domain */
+ CTRACE(tfp, "TCP: Local host name is %s\n", name);
+ StrAllocCopy(hostname, name);
+
+#ifdef NEED_HOST_ADDRESS /* no -- needs name server! */
+ phost=gethostbyname(name); /* See netdb.h */
+ if (!phost) {
+ if (TRACE) printf(
+ "TCP: Can't find my own internet node address for `%s'!!\n",
+ name);
+ return; /* Fail! */
+ }
+ StrAllocCopy(hostname, phost->h_name);
+ memcpy(&HTHostAddress, &phost->h_addr, phost->h_length);
+ if (TRACE) printf(" Name server says that is `%s' = %s\n",
+ hostname, HTInetString(&HTHostAddress));
+#endif
+}
+
+#ifdef __STDC__
+PUBLIC const char * HTHostName(void)
+#else
+PUBLIC char * HTHostName()
+#endif
+{
+ get_host_details();
+ return hostname;
+}
+
--- /dev/null
+/* Generic Communication Code HTTCP.h
+** ==========================
+**
+*/
+#include "tcp.h"
+
+#ifdef SHORT_NAMES
+#define HTInetStatus HTInStat
+#define HTInetString HTInStri
+#define HTParseInet HTPaInet
+#endif
+
+
+/* Produce a string for an internet address
+** ---------------------------------------
+**
+** On exit,
+** returns a pointer to a static string which must be copied if
+** it is to be kept.
+*/
+#ifdef __STDC__
+extern const char * HTInetString(struct sockaddr_in* sin);
+#else
+extern char * HTInetString();
+#endif
+
+
+/* Encode INET status (as in sys/errno.h) inet_status()
+** ------------------
+**
+** On entry,
+** where gives a description of what caused the error
+** global errno gives the error number in the unix way.
+**
+** On return,
+** returns a negative status in the unix way.
+*/
+#ifdef __STDC__
+extern int HTInetStatus(char *where);
+#else
+extern int HTInetStatus();
+#endif
+
+/* Publicly accesible variables
+*/
+/* extern struct sockaddr_in HTHostAddress; */
+ /* The internet address of the host */
+ /* Valid after call to HTHostName() */
+
+
+/* Parse a cardinal value parse_cardinal()
+** ----------------------
+**
+** On entry,
+** *pp points to first character to be interpreted, terminated by
+** non 0:9 character.
+** *pstatus points to status already valid
+** maxvalue gives the largest allowable value.
+**
+** On exit,
+** *pp points to first unread character
+** *pstatus points to status updated iff bad
+*/
+#ifdef __STDC__
+extern unsigned int HTCardinal(int *pstatus,
+ char **pp,
+ unsigned int max_value);
+#else
+extern unsigned int HTCardinal();
+#endif
+
+/* Parse an internet node address and port
+** ---------------------------------------
+**
+** On entry,
+** str points to a string with a node name or number,
+** with optional trailing colon and port number.
+** sin points to the binary internet address field.
+**
+** On exit,
+** *sin is filled in. If no port is specified in str, that
+** field is left unchanged in *sin.
+*/
+#ifdef __STDC__
+extern int HTParseInet(struct sockaddr_in* sin, const char *str);
+#else
+extern int HTParseInet();
+#endif
+
+/* Get Name of This Machine
+** ------------------------
+**
+*/
+#ifdef __STDC__
+extern const char * HTHostName(void);
+#else
+extern char * HTHostName();
+#endif
--- /dev/null
+/* HyperText Tranfer Protocol - Client implementation HTTP.c
+** ==========================
+*/
+
+/* Module parameters:
+** -----------------
+**
+** These may be undefined and redefined by syspec.h
+*/
+#include "HTParse.h"
+#include "HTUtils.h"
+#include "tcp.h"
+#include "HTTCP.h"
+#include "HTFormat.h"
+
+
+#ifndef ERWISE
+/* Load Dcoument from HTTP Server HTLoadHTTP()
+** ==============================
+**
+** Given a hypertext address, this routine loads a document.
+**
+**
+** On entry,
+** arg is the hypertext reference of the article to be loaded.
+** gate is nill if no gateway, else the gateway address.
+**
+** On exit,
+** returns >=0 If no error, a good socket number
+** <0 Error.
+**
+** The socket must be closed by the caller after the document has been
+** read.
+**
+*/
+PUBLIC int HTLoadHTTP ARGS4 (CONST char *, arg,
+ CONST char *, gate,
+ HTAnchor *, anAnchor,
+ int, diag)
+{
+ int s; /* Socket number for returned data */
+ char *command; /* The whole command */
+ int status; /* tcp return */
+
+ struct sockaddr_in soc_address; /* Binary network address */
+ struct sockaddr_in* sin = &soc_address;
+
+ if (!arg) return -3; /* Bad if no name sepcified */
+ if (!*arg) return -2; /* Bad if name had zero length */
+
+/* Set up defaults:
+*/
+ sin->sin_family = AF_INET; /* Family, host order */
+ sin->sin_port = htons(TCP_PORT); /* Default: new port, */
+
+ if (TRACE) {
+ if (gate) fprintf(stderr,
+ "HTTPAccess: Using gateway %s for %s\n", gate, arg);
+ else fprintf(stderr, "HTTPAccess: Direct access for %s\n", arg);
+ }
+
+/* Get node name and optional port number:
+*/
+ {
+ char *p1 = HTParse(gate ? gate : arg, "", PARSE_HOST);
+ HTParseInet(sin, p1);
+ free(p1);
+ }
+
+
+/* Now, let's get a socket set up from the server for the sgml data:
+*/
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ status = connect(s, (struct sockaddr*)&soc_address, sizeof(soc_address));
+ if (status<0){
+ if (TRACE) printf(
+ "HTTP: Unable to connect to remote host for `%s'.\n",
+ arg);
+ free(command);
+ return HTInetStatus("connect");
+ }
+
+ if (TRACE) printf("HTTP connected, socket %d\n", s);
+
+/* Ask that node for the document,
+** omitting the host name & anchor if not gatewayed.
+*/
+ if (gate) {
+ command = malloc(4 + strlen(arg)+ 2 + 1);
+ if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
+ strcpy(command, "GET ");
+ strcat(command, arg);
+ } else { /* not gatewayed */
+ char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION);
+ command = malloc(4 + strlen(p1)+ 2 + 1);
+ if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
+ strcpy(command, "GET ");
+ strcat(command, p1);
+ free(p1);
+ }
+ strcat(command, "\r\n"); /* Include CR for telnet compat. */
+
+
+ if (TRACE) printf("HTTP writing command `%s' to socket %d\n", command, s);
+
+#ifdef NOT_ASCII
+ {
+ char * p;
+ for(p = command; *p; p++) {
+ *p = TOASCII(*p);
+ }
+ }
+#endif
+
+ status = NETWRITE(s, command, (int)strlen(command));
+ free(command);
+ if (status<0){
+ if (TRACE) printf("HTTPAccess: Unable to send command.\n");
+ return HTInetStatus("send");
+ }
+
+/* Now load the date
+*/
+ HTParseFormat(diag ? WWW_PLAINTEXT : WWW_HTML,
+ (HTParentAnchor *) anAnchor, s);
+
+ if (TRACE) printf("HTTP: close socket %d.\n", s);
+ status = NETCLOSE(s);
+
+ return HT_LOADED; /* Good return */
+}
+#endif /* ERWISE */
--- /dev/null
+/* HyperText Tranfer Protocol HTTP.h
+** ==========================
+*/
+
+#ifndef HTTP_H
+#define HTTP_H
+
+#include "HTAnchor.h"
+
+/* Open Socket for reading from HTTP Server HTTP_get()
+** ========================================
+**
+** Given a hypertext address, this routine opens a socket to the server,
+** sends the "get" command to ask for the node, and then returns the
+** socket to the caller. The socket must later be closed by the caller.
+**
+** On entry,
+** arg is the hypertext reference of the article to be loaded.
+** On exit,
+** returns >=0 If no error, a good socket number
+** <0 Error.
+**
+*/
+#ifdef __STDC__
+extern int HTTP_Get(const char * arg);
+#else
+extern int HTTP_Get();
+#endif
+
+/* Load Document using HTTP
+** ------------------------
+*/
+
+extern int HTLoadHTTP PARAMS((CONST char *arg,
+ CONST char * gateway,
+ HTParentAnchor * anAnchor,
+ int diag));
+
+#endif /* HTTP_H */
--- /dev/null
+/* Macros for general use HTUtils.h
+**
+** See also: the system dependent file "tcp.h"
+*/
+
+/* extern void *malloc(size_t size); */
+
+#ifndef HTUTILS_H
+#define HTUTILS_H
+
+#ifdef SHORT_NAMES
+#define WWW_TraceFlag HTTrFlag
+#endif
+
+/* Debug message control.
+*/
+#ifdef DEBUG
+
+#ifndef STDIO_H
+#include <stdio.h>
+#define STDIO_H
+#endif
+
+#define TRACE (WWW_TraceFlag)
+#define PROGRESS(str) printf(str)
+extern int WWW_TraceFlag;
+#else
+#define TRACE 0
+#define PROGRESS(str) /* nothing for now */
+#endif
+#define CTRACE if(TRACE)fprintf
+#define tfp stdout
+
+/* Standard C library for malloc() etc
+*/
+#ifdef vax
+#ifdef unix
+#define ultrix /* Assume vax+unix=ultrix */
+#endif
+#endif
+
+#ifndef VMS
+#ifndef ultrix
+#ifdef NeXT
+#include <libc.h> /* NeXT */
+#endif
+#ifndef MACH /* Vincent.Cate@furmint.nectar.cs.cmu.edu */
+#include <stdlib.h> /* ANSI */
+#endif
+#else
+#include <malloc.h> /* ultrix */
+#include <memory.h>
+#include <stdio.h>
+#endif
+
+#else /* VMS */
+#include <stdio.h>
+#include <ctype.h>
+#endif
+
+#define PUBLIC /* Accessible outside this module */
+#define PRIVATE static /* Accessible only within this module */
+
+#ifdef __STDC__
+#define CONST const /* "const" only exists in STDC */
+#define NOPARAMS (void)
+#define PARAMS(parameter_list) parameter_list
+#define NOARGS (void)
+#define ARGS1(t,a) \
+ (t a)
+#define ARGS2(t,a,u,b) \
+ (t a, u b)
+#define ARGS3(t,a,u,b,v,c) \
+ (t a, u b, v c)
+#define ARGS4(t,a,u,b,v,c,w,d) \
+ (t a, u b, v c, w d)
+#define ARGS5(t,a,u,b,v,c,w,d,x,e) \
+ (t a, u b, v c, w d, x e)
+#define ARGS6(t,a,u,b,v,c,w,d,x,e,y,f) \
+ (t a, u b, v c, w d, x e, y f)
+#define ARGS7(t,a,u,b,v,c,w,d,x,e,y,f,z,g) \
+ (t a, u b, v c, w d, x e, y f, z g)
+#define ARGS8(t,a,u,b,v,c,w,d,x,e,y,f,z,g,s,h) \
+ (t a, u b, v c, w d, x e, y f, z g, s h)
+#define ARGS9(t,a,u,b,v,c,w,d,x,e,y,f,z,g,s,h,r,i) \
+ (t a, u b, v c, w d, x e, y f, z g, s h, r i)
+
+#else /* not ANSI */
+
+#define CONST
+#define NOPARAMS ()
+#define PARAMS(parameter_list) ()
+#define NOARGS ()
+#define ARGS1(t,a) (a) \
+ t a;
+#define ARGS2(t,a,u,b) (a,b) \
+ t a; u b;
+#define ARGS3(t,a,u,b,v,c) (a,b,c) \
+ t a; u b; v c;
+#define ARGS4(t,a,u,b,v,c,w,d) (a,b,c,d) \
+ t a; u b; v c; w d;
+#define ARGS5(t,a,u,b,v,c,w,d,x,e) (a,b,c,d,e) \
+ t a; u b; v c; w d; x e;
+#define ARGS6(t,a,u,b,v,c,w,d,x,e,y,f) (a,b,c,d,e,f) \
+ t a; u b; v c; w d; x e; y f;
+#define ARGS7(t,a,u,b,v,c,w,d,x,e,y,f,z,g) (a,b,c,d,e,f,g) \
+ t a; u b; v c; w d; x e; y f; z g;
+#define ARGS8(t,a,u,b,v,c,w,d,x,e,y,f,z,g,s,h) (a,b,c,d,e,f,g,h) \
+ t a; u b; v c; w d; x e; y f; z g; s h;
+#define ARGS9(t,a,u,b,v,c,w,d,x,e,y,f,z,g,s,h,r,i) (a,b,c,d,e,f,g,h,i) \
+ t a; u b; v c; w d; x e; y f; z g; s h; r i;
+
+#endif /* __STDC__ (ANSI) */
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+
+/* Note: GOOD and BAD are already defined (differently) on RS6000 aix */
+/* #define GOOD(status) ((status)&1) VMS style status: test bit 0 */
+/* #define BAD(status) (!GOOD(status)) Bit 0 set if OK, otherwise clear */
+
+#ifndef BOOLEAN_DEFINED
+typedef char BOOLEAN; /* Logical value */
+#ifndef CURSES
+#ifndef TRUE
+#define TRUE (BOOLEAN)1
+#define FALSE (BOOLEAN)0
+#endif
+#endif
+#define BOOLEAN_DEFINED
+#endif
+
+#ifndef BOOL
+#define BOOL BOOLEAN
+#endif
+#ifndef YES
+#define YES (BOOLEAN)1
+#define NO (BOOLEAN)0
+#endif
+
+#define TCP_PORT 2784 /* 80 Allocated by Jon Postel/ISI 24-Jan-92 */
+
+/* Is character c white space? */
+
+#ifndef NOT_ASCII
+#define WHITE(c) (((unsigned char)(c))<=' ') /* Assumes ASCII but faster */
+#else
+#define WHITE(c) ( ((c)==' ') || ((c)=='\t') || ((c)=='\n') || ((c)=='\r') )
+#endif
+
+#define HT_LOADED (29999) /* Instead of a socket */
+
+#include "HTString.h" /* String utilities */
+
+#ifndef ERWISE_UI
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#else
+#include <varargs.h>
+#endif /* ERWISE */
+
+#ifdef CURSES
+/* htbrowse.c; */
+#include <curses.h>
+
+extern WINDOW *w_top, *w_text, *w_prompt;
+extern void user_message PARAMS((const char *fmt, ...));
+extern void prompt_set PARAMS((CONST char * msg));
+extern void prompt_count PARAMS((long kb));
+#else
+#define user_message printf
+#endif
+
+/* Out Of Memory checking for malloc() return:
+*/
+#ifndef __FILE__
+#define __FILE__ ""
+#define __LINE__ ""
+#endif
+
+#define outofmem(file, func) \
+ { fprintf(stderr, "%s %s: out of memory.\nProgram aborted.\n", file, func); \
+ exit(1);}
+/* extern void outofmem PARAMS((const char *fname, const char *func)); */
+
+
+extern void msg_init PARAMS((int height));
+extern void msg_printf PARAMS((int y, const char *fmt, ...));
+extern void msg_exit PARAMS((int wait_for_key));
+
+#endif /* HTUTILS_H */
+
--- /dev/null
+/* HyperText Object HText.h
+** ================
+** This is the C intreface to the Objective-C HyperText class.
+*/
+
+#ifndef HTEXT_H
+#define HTEXT_H
+#include "HTAnchor.h"
+#include "HTStyle.h"
+
+#ifdef SHORT_NAMES
+#define HTMainText HTMaText
+#define HTMainAnchor HtMaAnch
+#define HText_new HTHTNew
+#define HText_free HTHTFree
+#define HText_beginAppend HTHTBeAp
+#define HText_endAppend HTHTEnAp
+#define HText_setStyle HTHTSeSt
+#define HText_appendCharacter HTHTApCh
+#define HText_appendText HTHTApTe
+#define HText_appendParagraph HTHTApPa
+#define HText_beginAnchor HTHTBeAn
+#define HText_endAnchor HTHTEnAn
+#define HText_dump HTHTDump
+#define HText_nodeAnchor HTHTNoAn
+#define HText_select HTHTSele
+#define HText_selectAnchor HTHTSeAn
+#define HText_applyStyle HTHTApSt
+#define HText_updateStyle HTHTUpSt
+#define HText_selectionStyle HTHTStyl
+#define HText_replaceSel HTHTRepl
+#define HText_applyToSimilar HTHTApTo
+#define HText_selectUnstyled HTHTSeUn
+#define HText_unlinkSelection HTHTUnSe
+#define HText_linkSelTo HTHTLiSe
+#define HText_referenceSelected HTHTRefS
+#endif
+
+#ifndef THINK_C
+typedef struct _HText HText;
+#else
+class CHyperText; /* Part of the Mac browser */
+typedef CHyperText HText
+#endif
+
+extern HText * HTMainText; /* Pointer to current main text */
+extern HTParentAnchor * HTMainAnchor; /* Pointer to current text's anchor */
+
+/* Creation and deletion
+**
+** Create hypertext object HText_new
+*/
+ extern HText * HText_new PARAMS((HTParentAnchor * anchor));
+
+/* Free hypertext object HText_free
+*/
+extern void HText_free PARAMS((HText * me));
+
+
+/* Object Building methods
+** -----------------------
+**
+** These are used by a parser to build the text in an object
+** HText_beginAppend must be called, then any combination of other
+** append calls, then HText_endAppend. This allows optimised
+** handling using buffers and caches which are flushed at the end.
+*/
+extern void HText_beginAppend PARAMS((HText * text));
+
+extern void HText_endAppend PARAMS((HText * text));
+
+/* Set the style for future text
+*/
+extern void HText_setStyle PARAMS((HText * text, HTStyle * style));
+
+/* Add one character
+*/
+extern void HText_appendCharacter PARAMS((HText * text, char ch));
+
+/* Add a zero-terminated string
+*/
+extern void HText_appendText PARAMS((HText * text, CONST char * str));
+
+/* New Paragraph
+*/
+extern void HText_appendParagraph PARAMS((HText * text));
+
+/* Start/end sensitive text
+**
+** The anchor object is created and passed to HText_beginAnchor.
+** The senstive text is added to the text object, and then HText_endAnchor
+** is called. Anchors may not be nested.
+*/
+
+extern void HText_beginAnchor PARAMS((HText * text, HTChildAnchor * anc));
+extern void HText_endAnchor PARAMS((HText * text));
+
+
+/* Dump diagnostics to stderr
+*/
+extern void HText_dump PARAMS((HText * me));
+
+/* Return the anchor associated with this node
+*/
+extern HTParentAnchor * HText_nodeAnchor PARAMS((HText * me));
+
+
+/* Browsing functions
+** ------------------
+*/
+
+/* Bring to front and highlight it
+*/
+
+extern BOOL HText_select PARAMS((HText * text));
+extern BOOL HText_selectAnchor PARAMS((HText * text, HTChildAnchor* anchor));
+
+/* Editing functions
+** -----------------
+**
+** These are called from the application. There are many more functions
+** not included here from the orginal text object. These functions
+** NEED NOT BE IMPLEMENTED in a browser which cannot edit.
+*/
+
+/* Style handling:
+*/
+/* Apply this style to the selection
+*/
+extern void HText_applyStyle PARAMS((HText * me, HTStyle *style));
+
+/* Update all text with changed style.
+*/
+extern void HText_updateStyle PARAMS((HText * me, HTStyle *style));
+
+/* Return style of selection
+*/
+extern HTStyle * HText_selectionStyle PARAMS((
+ HText * me,
+ HTStyleSheet* sheet));
+
+/* Paste in styled text
+*/
+extern void HText_replaceSel PARAMS((HText * me,
+ CONST char *aString,
+ HTStyle* aStyle));
+
+/* Apply this style to the selection and all similarly formatted text
+** (style recovery only)
+*/
+extern void HTextApplyToSimilar PARAMS((HText * me, HTStyle *style));
+
+/* Select the first unstyled run.
+** (style recovery only)
+*/
+extern void HTextSelectUnstyled PARAMS((HText * me, HTStyleSheet *sheet));
+
+
+/* Anchor handling:
+*/
+extern void HText_unlinkSelection PARAMS((HText * me));
+extern HTAnchor * HText_referenceSelected PARAMS((HText * me));
+extern HTAnchor * HText_linkSelTo PARAMS((HText * me, HTAnchor* anchor));
+
+
+#endif /* HTEXT_H */
--- /dev/null
+#
+#
+#
+ OBJS = HTAccess.o HTFTP.o HTHistory.o HTParse.o HTTP.o \
+ HTAnchor.o HTFile.o HTList.o HTString.o SGML.o \
+ HTAtom.o HTFormat.o HTML.o HTStyle.o HTChunk.o \
+ HTGopher.o HTNews.o HTTCP.o
+
+ SRCS = HTAccess.c HTFTP.c HTHistory.c HTParse.c HTTP.c \
+ HTAnchor.c HTFile.c HTList.c HTString.c SGML.c \
+ HTAtom.c HTFormat.c HTML.c HTStyle.c HTChunk.c \
+ HTGopher.c HTNews.c HTTCP.c
+
+ DEFINES = -DERWISE -I.. -I. -I../../HText
+
+
+NormalLibraryTarget(WWW, $(OBJS))
+
+DependTarget()
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a11091>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../../.
+ CURRENT_DIR = ./Cl/WWWLibrary
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+ OBJS = HTAccess.o HTFTP.o HTHistory.o HTParse.o HTTP.o \
+ HTAnchor.o HTFile.o HTList.o HTString.o SGML.o \
+ HTAtom.o HTFormat.o HTML.o HTStyle.o HTChunk.o \
+ HTGopher.o HTNews.o HTTCP.o
+
+ SRCS = HTAccess.c HTFTP.c HTHistory.c HTParse.c HTTP.c \
+ HTAnchor.c HTFile.c HTList.c HTString.c SGML.c \
+ HTAtom.c HTFormat.c HTML.c HTStyle.c HTChunk.c \
+ HTGopher.c HTNews.c HTTCP.c
+
+ DEFINES = -DERWISE -I.. -I. -I../../HText
+
+all:: libWWW.a
+
+libWWW.a: $(OBJS)
+ $(RM) $@
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+depend::
+ $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a10847>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../../.
+ CURRENT_DIR = ./Cl/WWWLibrary
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+ OBJS = HTAccess.o HTFTP.o HTHistory.o HTParse.o HTTP.o \
+ HTAnchor.o HTFile.o HTList.o HTString.o SGML.o \
+ HTAtom.o HTFormat.o HTML.o HTStyle.o HTChunk.o \
+ HTGopher.o HTNews.o HTTCP.o
+
+ SRCS = HTAccess.c HTFTP.c HTHistory.c HTParse.c HTTP.c \
+ HTAnchor.c HTFile.c HTList.c HTString.c SGML.c \
+ HTAtom.c HTFormat.c HTML.c HTStyle.c HTChunk.c \
+ HTGopher.c HTNews.c HTTCP.c
+
+ DEFINES = -DERWISE -I..
+
+all:: libWWW.a
+
+libWWW.a: $(OBJS)
+ $(RM) $@
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+depend::
+ $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+Copyright WorldWideWeb project CERN 1990, 1991 -- See Copyright.html
+____________________________________________________________________
+
+
+
+This is the common code shared by various WWW products.
+See other /Implementation/ directories for the specific parts.
+
+TBL
--- /dev/null
+/* General SGML Parser code SGML.c
+** ========================
+*/
+#include <ctype.h>
+#include <stdio.h>
+#include "HTUtils.h"
+#include "HTChunk.h"
+#include "SGML.h"
+
+#include "tcp.h" /* For TOUPPER ! */
+
+static void (*contents_treatment) PARAMS((char c));
+static HTTag *current_tag;
+static attr *current_attribute;
+static HTChunk *string =0;
+static HTElement *element_stack;
+
+/* Handle Attribute
+** ----------------
+*/
+PUBLIC CONST char * SGML_default = "";
+
+#ifdef __STDC__
+PRIVATE void handle_attribute_name(const char * s)
+#else
+PRIVATE void handle_attribute_name(s)
+ char *s;
+#endif
+{
+ for( current_attribute = current_tag->attributes;
+ current_attribute->name;
+ current_attribute++) {
+ if (0==strcasecomp(current_attribute->name, s))
+ break;
+ }
+ if (!current_attribute->name) {
+ if (TRACE)
+ fprintf(stderr, "SGML: Unknown attribute %s for tag %s\n",
+ s, current_tag->name);
+ current_attribute = 0; /* Invalid */
+ return;
+ }
+ current_attribute->present = YES;
+ if (current_attribute->value) {
+ free(current_attribute->value);
+ current_attribute->value = 0;
+ }
+}
+
+/* Handle attribute value
+** ----------------------
+*/
+#ifdef __STDC__
+PRIVATE void handle_attribute_value(const char * s)
+#else
+PRIVATE void handle_attribute_value(s)
+ char *s;
+#endif
+{
+ if (current_attribute) {
+ StrAllocCopy(current_attribute->value, s);
+ } else {
+ if (TRACE) fprintf(stderr, "SGML: Attribute value %s ignored\n", s);
+ }
+ current_attribute = 0; /* can't have two assignments! */
+}
+
+/* Handle entity
+** -------------
+**
+** On entry,
+** s contains the entity name zero terminated
+** Bugs:
+** If the entity name is unknown, the terminator is treated as
+** a printable non-special character in all cases, even if it is '<'
+*/
+#ifdef __STDC__
+PRIVATE void handle_entity(const char * s, entity * entities, char term)
+#else
+PRIVATE void handle_entity(s,entities, term)
+ char * s;
+ entity * entities;
+ char term;
+#endif
+{
+ entity * e;
+ for(e = entities; e->name; e++) {
+ if (0==strcmp(e->name, s)) {
+ char * p;
+ for (p=e->representation; *p; p++) {
+ (*contents_treatment)(*p);
+ }
+ return; /* Good */
+ }
+ }
+ /* If entity string not found, display as text */
+ if (TRACE)
+ fprintf(stderr, "SGML: Unknown entity %s\n", s);
+ (*contents_treatment)('&');
+ {
+ CONST char *p;
+ for (p=s; *p; p++) {
+ (*contents_treatment)(*p);
+ }
+ }
+ (*contents_treatment)(term);
+}
+
+/* End element
+*/
+#ifdef __STDC__
+PRIVATE void end_element(HTTag * old_tag)
+#else
+PRIVATE void end_element(old_tag)
+ HTTag * old_tag;
+#endif
+{
+ if (TRACE) fprintf(stderr, "SGML: End </%s>\n", old_tag->name);
+ if (!old_tag->end) {
+ if (TRACE) fprintf(stderr,"SGML: Illegal end tag </%s> found.\n",
+ old_tag->name);
+ return;
+ }
+ while (element_stack) {/* Loop is error path only */
+ HTElement * N = element_stack;
+ HTTag * t = element_stack->tag;
+
+ if (old_tag != t) { /* Mismatch: syntax error */
+ if (element_stack->next) { /* This is not the last level */
+ if (TRACE) fprintf(stderr,
+ "SGML: Found </%s> when expecting </%s>. </%s> assumed.\n",
+ old_tag->name, t->name, t->name);
+ } else { /* last level */
+ if (TRACE) fprintf(stderr,
+ "SGML: Found </%s> when expecting </%s>. </%s> Ignored.\n",
+ old_tag->name, t->name, old_tag->name);
+ return; /* Ignore */
+ }
+ }
+
+ element_stack = N->next; /* Remove from stack */
+ free(N);
+ (t->end)(t, element_stack); /* Assume tag end */
+ if (element_stack) /* not end of document */
+ contents_treatment = element_stack->tag->treat;
+ if (old_tag == t) return; /* Correct sequence */
+
+ /* Syntax error path only */
+
+ }
+ fprintf(stderr,
+ "SGML: Extra end tag </%s> found and ignored.\n", old_tag->name);
+}
+
+
+/* Start a element
+*/
+#ifdef __STDC__
+PRIVATE void start_element(HTTag * new_tag)
+#else
+PRIVATE void start_element(new_tag)
+ HTTag * new_tag;
+#endif
+{
+ if (TRACE) fprintf(stderr, "SGML: Start <%s>\n", new_tag->name);
+ (*new_tag->begin)(new_tag, element_stack);
+ if (new_tag->end) { /* i.e. tag not empty */
+ HTElement * N = (HTElement *)malloc(sizeof(HTElement));
+ if (N == NULL) outofmem(__FILE__, "start_element");
+ N->next = element_stack;
+ N->tag = new_tag;
+ element_stack = N;
+ contents_treatment = new_tag->treat;
+ }
+}
+
+
+
+/* SGML Engine
+** -----------
+**
+** On entry,
+** dtd->tags represents the DTD, along with
+** dtd->entities
+**
+** default_tag represents the initial and final actions,
+** and the character processing, for data outside
+** any tags. May not be empty.
+*/
+
+PRIVATE enum sgml_state { S_text, S_litteral, S_tag, S_tag_gap,
+ S_attr, S_attr_gap, S_equals, S_value,
+ S_quoted, S_end, S_entity, S_junk_tag} state;
+
+PUBLIC void SGML_begin ARGS1(SGML_dtd *,dtd)
+{
+ if (!string) string = HTChunkCreate(128); /* Grow by this much */
+
+ state = S_text;
+ start_element(dtd->default_tag); /* Start document */
+}
+
+PUBLIC void SGML_end ARGS1(SGML_dtd *,dtd)
+{
+ end_element(dtd->default_tag); /* End document */
+}
+
+PUBLIC void SGML_character ARGS2(SGML_dtd *,dtd, char,c)
+
+{
+ switch(state) {
+ case S_text:
+ if (c=='&' && !(element_stack &&
+ element_stack->tag &&
+ element_stack->tag->litteral)) {
+ string->size = 0;
+ state = S_entity;
+
+ } else if (c=='<') {
+ string->size = 0;
+ state = (element_stack &&
+ element_stack->tag &&
+ element_stack->tag->litteral) ?
+ S_litteral : S_tag;
+ } else (*contents_treatment)(c);
+ break;
+
+/* In litteral mode, waits only for specific end tag!
+*/
+ case S_litteral :
+ HTChunkPutc(string, c);
+ if ( TOUPPER(c) != ((string->size ==1) ? '/'
+ : element_stack->tag->name[string->size-2])) {
+ int i;
+
+ /* If complete match, end litteral */
+ if ((c=='>') && (!element_stack->tag->name[string->size-2])) {
+ end_element(element_stack->tag);
+ string->size = 0;
+ current_attribute = (attr *) 0;
+ state = S_text;
+ break;
+ } /* If Mismatch: recover string. */
+ (*contents_treatment)('<');
+ for (i=0; i<string->size; i++) /* recover */
+ (*contents_treatment)(string->data[i]);
+ state = S_text;
+ }
+
+ break;
+
+/* Handle Entities
+*/
+ case S_entity:
+ if (isalnum(c))
+ HTChunkPutc(string, c);
+ else {
+ HTChunkTerminate(string);
+ handle_entity(string->data, dtd->entities, c);
+ state = S_text;
+ }
+ break;
+
+/* Tag
+*/
+ case S_tag: /* new tag */
+ if (isalnum(c))
+ HTChunkPutc(string, c);
+ else { /* End of tag name */
+ attr * a;
+ if (c=='/') {
+ if (TRACE) if (string->size!=0)
+ fprintf(stderr,"SGML: `<%s/' found!\n", string->data);
+ state = S_end;
+ break;
+ }
+ HTChunkTerminate(string) ;
+ for(current_tag = dtd->tags; current_tag->name; current_tag++) {
+ if (0==strcasecomp(current_tag->name, string->data)) {
+ break;
+ }
+ }
+ if (!current_tag->name) {
+ if(TRACE) fprintf(stderr, "Unknown tag %s\n",
+ string->data);
+ state = (c=='>') ? S_text : S_junk_tag;
+ break;
+ }
+
+ for (a = current_tag->attributes; a->name; a++ ) {
+ a->present = NO;
+ }
+ string->size = 0;
+ current_attribute = (attr *) 0;
+
+ if (c=='>') {
+ if (current_tag->name) start_element(current_tag);
+ state = S_text;
+ } else {
+ state = S_tag_gap;
+ }
+ }
+ break;
+
+
+ case S_tag_gap: /* Expecting attribute or > */
+ if (WHITE(c)) break; /* Gap between attributes */
+ if (c=='>') { /* End of tag */
+ if (current_tag->name) start_element(current_tag);
+ state = S_text;
+ break;
+ }
+ HTChunkPutc(string, c);
+ state = S_attr; /* Get attribute */
+ break;
+
+ /* accumulating value */
+ case S_attr:
+ if (WHITE(c) || (c=='>') || (c=='=')) { /* End of word */
+ HTChunkTerminate(string) ;
+ handle_attribute_name(string->data);
+ string->size = 0;
+ if (c=='>') { /* End of tag */
+ if (current_tag->name) start_element(current_tag);
+ state = S_text;
+ break;
+ }
+ state = (c=='=' ? S_equals: S_attr_gap);
+ } else {
+ HTChunkPutc(string, c);
+ }
+ break;
+
+ case S_attr_gap: /* Expecting attribute or = or > */
+ if (WHITE(c)) break; /* Gap after attribute */
+ if (c=='>') { /* End of tag */
+ if (current_tag->name) start_element(current_tag);
+ state = S_text;
+ break;
+ } else if (c=='=') {
+ state = S_equals;
+ break;
+ }
+ HTChunkPutc(string, c);
+ state = S_attr; /* Get next attribute */
+ break;
+
+ case S_equals: /* After attr = */
+ if (WHITE(c)) break; /* Before attribute value */
+ if (c=='>') { /* End of tag */
+ fprintf(stderr, "SGML: found = but no value\n");
+ if (current_tag->name) start_element(current_tag);
+ state = S_text;
+ break;
+
+ } else if (c=='"') {
+ state = S_quoted;
+ break;
+ }
+ HTChunkPutc(string, c);
+ state = S_value;
+ break;
+
+ case S_value:
+ if (WHITE(c) || (c=='>')) { /* End of word */
+ HTChunkTerminate(string) ;
+ handle_attribute_value(string->data);
+ string->size = 0;
+ if (c=='>') { /* End of tag */
+ if (current_tag->name) start_element(current_tag);
+ state = S_text;
+ break;
+ }
+ else state = S_tag_gap;
+ } else {
+ HTChunkPutc(string, c);
+ }
+ break;
+
+ case S_quoted: /* Quoted attribute value */
+ if (c=='"') { /* End of attribute value */
+ HTChunkTerminate(string) ;
+ handle_attribute_value(string->data);
+ string->size = 0;
+ state = S_tag_gap;
+ } else {
+ HTChunkPutc(string, c);
+ }
+ break;
+
+ case S_end: /* </ */
+ if (isalnum(c))
+ HTChunkPutc(string, c);
+ else { /* End of end tag name */
+ HTChunkTerminate(string) ;
+ if (c!='>') {
+ if (TRACE) fprintf(stderr,"SGML: `</%s%c' found!\n",
+ string->data, c);
+ state = S_junk_tag;
+ break;
+ }
+ for(current_tag = dtd->tags; current_tag->name; current_tag++) {
+ if (0==strcasecomp(current_tag->name, string->data)) {
+ end_element(current_tag);
+ break;
+ }
+ }
+ if (!current_tag->name) {
+ if(TRACE) fprintf(stderr,
+ "Unknown end tag </%s>\n", string->data);
+ }
+ string->size = 0;
+ current_attribute = (attr *) 0;
+ state = S_text;
+ }
+ break;
+
+
+ case S_junk_tag:
+ if (c=='>') {
+ state = S_text;
+ }
+
+ } /* switch on state */
+
+}
--- /dev/null
+/* SGML Parser definitions SGML.h
+** =======================
+**
+** The SGML parser is a state machine. It is called for every character
+** of the input stream. The DTD data structure contains pointers
+** to functions which are called to implement the actual effect of the
+** text read. When these functions are called, the attribute structures
+** pointed to by the DTD are valid, and the function is passed
+** a pointer to the curent tag structure, and an
+** "element stack" which represents the state of nesting within SGML
+** elements.
+*/
+/* (c) Copyright CERN 1991 - See Copyright.html
+*/
+
+#ifndef SGML_H
+#define SGML_H
+
+typedef struct {
+ char * name; /* The (constant) name of the attribute */
+ BOOL present; /* Was attribute specified for this tag? */
+ char * value; /* Malloced. Valid only if present is YES. */
+} attr;
+
+
+/* A tag structure describes an SGML element.
+** -----------------------------------------
+**
+** If the tag has an end tag, then treat and end must be non-zero.
+** If the tag does not, they must be zero.
+**
+** name is the string which comes after the tag opener "<".
+**
+** attributes points to a zero-terminated array
+** of attribute structures filled in by the parser.
+**
+** style is a pointer left for use by oter modules (typically
+** for storing the style used with this element)
+**
+** litteral determines how the SGML engine parses the charaters
+** within the element. If set, tag openers are ignored
+** except for that which opens a matching closing tag.
+**
+** begin is called when the tag has been parsed, and the
+** attribute values set. The element pointer points
+** to the top of the new element stack.
+**
+** treat is a pointer to a function which is called for
+** each text character within the element.
+**
+** end is called when the end tag has been parsed.
+** The element pointer points to the top of the
+** new element stack.
+*/
+typedef struct _tag HTTag;
+typedef struct _HTElement HTElement;
+struct _tag{
+ char * name; /* The name of the tag */
+ attr * attributes; /* The list of acceptable attributes */
+ void * style; /* Not used by the SGML engine */
+ BOOL litteral; /* End only on end tag @@ */
+ void (*begin) PARAMS((HTTag * t, HTElement * e)); /* Action on begin tag */
+ void (*treat) PARAMS((char c)); /* Action when character is parsed */
+ void (*end) PARAMS((HTTag * t, HTElement * e)); /* Action on </tag> or 0 if empty */
+};
+
+/* Stack of previous tags:
+**
+** This allows us to return down the stack reselcting styles.
+** As we return, attribute values will be garbage in general.
+*/
+struct _HTElement {
+ HTElement * next; /* Previously nested element or 0 */
+ HTTag * tag; /* The tag at this level */
+ void * info; /* Free to be used by caller only */
+};
+
+
+typedef struct _entity {
+ char * name;
+ char * representation;
+} entity;
+
+typedef struct {
+ HTTag * tags;
+ HTTag * default_tag;
+ entity * entities;
+} SGML_dtd;
+
+
+/* Initialise the SGML parser
+**
+** On entry,
+** dtd must point to a DTD structure as defined above
+** On exit,
+** The default tag starter has been processed.
+*/
+
+extern void SGML_begin PARAMS((SGML_dtd * dtd));
+
+
+/* Crank the SGML parser
+**
+** On entry,
+** dtd must point to a DTD structure as defined above.
+** SGML_begin must have been called on it.
+**
+** c is the next character of the input stream
+*/
+
+extern void SGML_character PARAMS((SGML_dtd * dtd, char c));
+
+
+/* Finish the SGML parser
+**
+** On entry,
+** dtd must point to a DTD structure as defined above
+** SGML_begin must have been called on it.
+** On exit,
+** The document will be completed.
+** SGML_begin must be called again before any
+** more parsing is done.
+*/
+
+extern void SGML_end PARAMS((SGML_dtd * dtd));
+
+
+
+#endif /* SGML_H */
--- /dev/null
+/* Include file for WorldWideWeb project-wide definitions
+*/
+
+/* Formats:
+*/
+
+#ifndef WWW_H
+#define WWW_H
+
+/* Bit fields describing the capabilities for a node:
+*/
+#define WWW_READ 1
+#define WWW_WRITE 2
+#define WWW_LINK_TO_NODE 4
+#define WWW_LINK_TO_PART 8
+#define WWW_LINK_FROM_NODE 16
+#define WWW_LINK_FROM_PART 32
+#define WWW_DO_ANYTHING 63
+
+#endif /* WWW_H */
--- /dev/null
+/* System-system differences for TCP include files and macros tcp.h
+** ===========================================================
+**
+**
+** This file includes for each system, the files necessary for
+** network and file I/O
+**
+** Authors
+** TBL Tim Berners-Lee, W3 project, CERN, <timbl@info.cern.ch>
+** EvA Eelco van Asperen <evas@cs.few.eur.nl>
+**
+** History:
+** 22 Feb 91 Written (TBL) as part of the WWW project.
+** 16 Jan 92 PC code from EvA
+*/
+#ifndef TCP_H
+#define TCP_H
+
+#define NETCLOSE close /* Routine to close a TCP-IP socket */
+#define NETREAD read /* Routine to read from a TCP-IP socket */
+#define NETWRITE write /* Routine to write to a TCP-IP socket */
+
+
+/* Macintosh - Think-C
+** -------------------
+**
+** Think-C is one development environment on the Mac.
+**
+** We recommend that you compile with 4-byte ints to be compatible
+** with MPW C. We used Tom Milligan's s_socket library which was
+** written for 4 byte int, and the MacTCP library assumes 4-byte int.
+*/
+#ifdef THINK_C
+#define DEBUG /* Can't put it on the CC command line */
+#define NO_UNIX_IO /* getuid() missing */
+#define NO_GETPID /* getpid() does not exist */
+#define NO_GETWD /* getwd() does not exist */
+
+#undef NETCLOSE /* Routine to close a TCP-IP socket */
+#undef NETREAD /* Routine to read from a TCP-IP socket */
+#undef NETWRITE /* Routine to write to a TCP-IP socket */
+#define NETCLOSE s_close /* Routine to close a TCP-IP socket */
+#define NETREAD s_read /* Routine to read from a TCP-IP socket */
+#define NETWRITE s_write /* Routine to write to a TCP-IP socket */
+
+#define bind s_bind /* Funny names presumably to prevent clashes */
+#define connect s_connect
+#define accept s_accept
+#define listen s_listen
+#define socket s_socket
+#define getsockname s_getsockname
+
+/* The function prototype checking is better than the include files
+*/
+
+extern s_close(int s);
+extern s_read(int s, char *buffer, int buflen);
+extern s_write(int s, const char *buffer, int buflen);
+
+extern bind(int s, struct sockaddr *name, int namelen);
+extern accept(int s, struct sockaddr *addr, int *addrlen);
+extern listen(int s, int qlen);
+extern connect(int s, struct sockaddr *addr, int addrlen);
+
+extern s_socket(int domain, int type, int protocol);
+extern s_getsockname(int s, struct sockaddr *name, int *namelen);
+extern struct hostent *gethostent(const char * name);
+extern unsigned long inet_addr(const char * name);
+
+#endif
+
+
+/* On the NeXT, there's a little package of include files.
+*/
+#ifdef NeXT
+#include <libc.h> /* NeXT has all this packaged up */
+#define ntohs(x) (x)
+#define htons(x) (x)
+#include <sys/errno.h> /* Get ECONNRESET etc */
+#define SELECT /* Is supported ok */
+#define INCLUDES_DONE
+
+#else /* Not NeXT */
+#ifndef STDIO_H
+#include <stdio.h>
+#define STDIO_H
+#endif
+
+
+/* On the IBM RS-6000, AIX is almost Unix.
+** But AIX must be defined in the makefile.
+*/
+#ifdef AIX
+#define unix
+#endif
+
+/* MVS is compiled as for VM. MVS has no unix-style I/O
+** The command line compile options seem to come across in
+** lower case.
+**
+** See aslo lots of VM stuff lower down.
+*/
+#ifdef mvs
+#define MVS
+#endif
+
+#ifdef MVS
+#define VM
+#endif
+
+#ifdef NEWLIB
+#pragma linkage(newlib,OS) /* Enables recursive NEWLIB */
+#endif
+
+/* VM doesn't have a built-in predefined token, so we cheat: */
+#ifdef __STDIO__
+#define VM
+#else
+#include <string.h> /* For bzero etc - not NeXT or VM */
+#endif
+#define SELECT /* Handle >1 channel if we can. */
+#endif /* Not NeXT */
+
+
+/* Under VMS, there are many versions of TCP-IP. Define one if you
+** do not use Digital's UCX product:
+**
+** UCX DEC's "Ultrix connection" (default)
+** WIN_TCP From Wollongong, now GEC software.
+** MULTINET From SRI, now from TGV Inv.
+**
+** The second two do not interfere with the unix i/o library, and so they
+** need special calls to read, write and close sockets. In these cases the
+** socket number is a VMS channel number, so we make the HORRIBLE
+** assumption that a channel number will be greater than 10 but a
+** unix file descriptor less than 10.
+*/
+#ifdef vms
+#ifdef WIN_TCP
+#undef NETREAD
+#undef NETWRITE
+#undef NETCLOSE
+#define NETREAD(s,b,l) ((s)>10 ? netread((s),(b),(l)) : read((s),(b),(l)))
+#define NETWRITE(s,b,l) ((s)>10 ? netwrite((s),(b),(l)) : write((s),(b),(l)))
+#define NETCLOSE(s) ((s)>10 ? netclose(s) : close(s))
+#endif
+
+#ifdef MULTINET
+#undef NETCLOSE
+#undef NETREAD
+#undef NETWRITE
+#define NETREAD(s,b,l) ((s)>10 ? socket_read((s),(b),(l)) : read((s),(b),(l)))
+#define NETWRITE(s,b,l) ((s)>10 ? socket_write((s),(b),(l)) : \
+ write((s),(b),(l)))
+#define NETCLOSE(s) ((s)>10 ? socket_close(s) : close(s))
+#endif
+
+/* Certainly this works for UCX and Multinet; not tried for Wollongong
+*/
+#ifdef MULTINET
+#include "multinet_root:[multinet.include.sys]types.h"
+#include "multinet_root:[multinet.include]errno.h"
+#include "multinet_root:[multinet.include.sys]time.h"
+#else
+#include types
+#include errno
+#include time
+#endif
+#include string
+#ifndef STDIO_H
+#include stdio
+#define STDIO_H
+#endif
+
+#include file
+#include unixio
+
+#define INCLUDES_DONE
+
+#ifdef MULTINET /* Include from standard Multinet directories */
+#include "multinet_root:[multinet.include.sys]socket.h"
+#ifdef __TIME_LOADED /* defined by sys$library:time.h */
+#define __TIME /* to avoid double definitions in next file */
+#endif
+#include "multinet_root:[multinet.include.netinet]in.h"
+#include "multinet_root:[multinet.include.arpa]inet.h"
+#include "multinet_root:[multinet.include]netdb.h"
+#else
+#include socket
+#include in
+#include inet
+#include netdb
+#endif
+#define TCP_INCLUDES_DONE
+
+#endif /* vms */
+
+
+/* IBM VM/CMS or MVS
+** -----------------
+**
+** Note: All files must have lines <= 80 characters
+** All include file names must have 8 chars max (+".h")
+**
+** Under VM, compile with "DEF=VM"
+**
+** Under MVS, compile with "NOMAR DEF(MVS)" to get rid of 72 char margin
+** System include files TCPIP and COMMMAC neeed line number removal(!)
+*/
+
+#ifdef VM /* or MVS -- see above. */
+#define NOT_ASCII /* char type is not ASCII */
+#define NO_UNIX_IO /* Unix I/O routines are not supported */
+#define NO_GETPID /* getpid() does not exist */
+#define NO_GETWD /* getwd() does not exist */
+#ifndef SHORT_NAMES
+#define SHORT_NAMES /* 8 character uniqueness for globals */
+#endif
+#include <manifest.h>
+#include <bsdtypes.h>
+#include <stdefs.h>
+#include <socket.h>
+#include <in.h>
+#include <inet.h>
+#include <netdb.h>
+#include <errno.h> /* independent */
+extern char asciitoebcdic[], ebcdictoascii[];
+#define TOASCII(c) (c=='\n' ? 10 : ebcdictoascii[c])
+#define FROMASCII(c) (c== 10 ? '\n' : asciitoebcdic[c])
+#include <bsdtime.h>
+#include <time.h>
+#include <string.h>
+#define INCLUDES_DONE
+#define TCP_INCLUDES_DONE
+#endif
+
+
+/* IBM-PC running MS-DOS with SunNFS for TCP/IP
+** ---------------------
+**
+** This code thanks to Eelco van Asperen <evas@cs.few.eur.nl>
+*/
+
+#ifdef PCNFS
+#include <sys/types.h>
+#include <string.h>
+#ifndef STDIO_H
+#include <stdio.h>
+#define STDIO_H
+#endif
+
+#include <errno.h> /* independent */
+#include <sys/time.h> /* independent */
+#include <sys/stat.h>
+#include <fcntl.h> /* In place of sys/param and sys/file */
+#define INCLUDES_DONE
+
+#define FD_SET(fd,pmask) (*(unsigned*)(pmask)) |= (1<<(fd))
+#define FD_CLR(fd,pmask) (*(unsigned*)(pmask)) &= ~(1<<(fd))
+#define FD_ZERO(pmask) (*(unsigned*)(pmask))=0
+#define FD_ISSET(fd,pmask) (*(unsigned*)(pmask) & (1<<(fd)))
+#endif
+
+
+/* Regular BSD unix versions: (default)
+** -------------------------
+*/
+
+#ifndef INCLUDES_DONE
+#include <sys/types.h>
+/* #include <streams/streams.h> not ultrix */
+#include <string.h>
+#ifndef STDIO_H
+#include <stdio.h>
+#define STDIO_H
+#endif
+
+#include <errno.h> /* independent */
+#include <sys/time.h> /* independent */
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/file.h> /* For open() etc */
+#define INCLUDES_DONE
+#endif /* Normal includes */
+
+
+/* Default include files for TCP
+*/
+#ifndef TCP_INCLUDES_DONE
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h> /* Must be after netinet/in.h */
+#include <netdb.h>
+#endif /* TCP includes */
+
+
+/* Default macros for manipulating masks for select()
+*/
+#ifndef FD_SET
+typedef unsigned int fd_set;
+#define FD_SET(fd,pmask) (*(pmask)) |= (1<<(fd))
+#define FD_CLR(fd,pmask) (*(pmask)) &= ~(1<<(fd))
+#define FD_ZERO(pmask) (*(pmask))=0
+#define FD_ISSET(fd,pmask) (*(pmask) & (1<<(fd)))
+#endif
+
+
+/* Default macros for converting characters
+**
+*/
+#ifndef TOASCII
+#define TOASCII(c) (c)
+#define FROMASCII(c) (c)
+#endif
+
+#ifndef TOLOWER
+#ifdef pyr /* Pyramid can't uppercase non-alpha */
+#define TOLOWER(c) (isupper(c) ? tolower(c) : (c))
+#define TOUPPER(c) (islower(c) ? toupper(c) : (c))
+#else
+#define TOLOWER(c) tolower(c)
+#define TOUPPER(c) toupper(c)
+#endif /* pyr */
+#endif /* ndef TOUPPER */
+
+#endif /* TCP_H */
--- /dev/null
+/* A real style sheet for the Character Grid browser
+**
+** The dimensions are all in characters!
+*/
+
+#include "HTStyle.h"
+
+/* Template:
+** link to next, name, tag, tagtype,
+** font, size, colour, superscript, anchor id,
+** indents: 1st, left, right, lineheight, descent, tabs,
+** word wrap, free format, space: before, after, flags.
+*/
+
+PRIVATE HTStyle HTStyleNormal =
+{0, "Normal", "P",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 3, 3, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 1, 0};
+
+PRIVATE HTStyle HTStyleList =
+{&HTStyleNormal, "List", "UL",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 7, 10, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 1, 0};
+
+PRIVATE HTStyle HTStyleListCompact =
+{
+ &HTStyleList, "ListCompact", "ULC",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 1, 4, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 0, 0, 0
+};
+PRIVATE HTTabStop tabs_16[] =
+{
+ {0, 16},
+ {0, 32},
+ {0, 48},
+ {0, 64},
+ {0, 80},
+ {0, 96},
+ {0, 112}
+};
+
+PRIVATE HTStyle HTStyleColumns16 =
+{
+ &HTStyleListCompact, "Columns16", "ULC",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 1, 4, 0, HT_LEFT, 1, 0, tabs_16,
+ YES, YES, 0, 0, 0
+};
+
+PRIVATE HTStyle HTStyleGlossary =
+{
+ &HTStyleColumns16, "Glossary", "DL",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 2, 25, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 1, 0
+};
+PRIVATE HTStyle HTStyleGlossaryCompact =
+{
+ &HTStyleGlossary, "GlossaryCompact", "DLC",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 0, 24, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 0, 0, 0
+};
+PRIVATE HTStyle HTStyleExample =
+{&HTStyleGlossaryCompact, "Example", "XMP",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 0, 0, 0, HT_LEFT, 1, 0, 0,
+ NO, NO, 1, 1, 0};
+
+PRIVATE HTStyle HTStyleListing =
+{&HTStyleExample, "Listing", "LISTING",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 0, 0, 0, HT_LEFT, 1, 0, 0,
+ NO, NO, 1, 1, 0};
+
+PRIVATE HTStyle HTStyleAddress =
+{&HTStyleListing, "Address", "ADDRESS",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 0, 0, 0, HT_RIGHT, 1, 0, 0,
+ NO, NO, 1, 1, 0};
+
+PRIVATE HTStyle HTStyleHeading1 =
+{&HTStyleAddress, "Heading1", "H1",
+ HT_FONT + HT_CAPITALS + HT_BOLD, 1.0, HT_BLACK, 0, 0,
+ 0, 0, 0, HT_CENTER, 1, 0, 0,
+ YES, YES, 1, 1, 0};
+
+PRIVATE HTStyle HTStyleHeading2 =
+{&HTStyleHeading1, "Heading2", "H2",
+ HT_FONT + HT_BOLD, 1.0, HT_BLACK, 0, 0,
+ 0, 0, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 1, 0};
+
+PRIVATE HTStyle HTStyleHeading3 =
+{&HTStyleHeading2, "Heading3", "H3",
+ HT_FONT + HT_CAPITALS, 1.0, HT_BLACK, 0, 0,
+ 2, 2, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 0, 0};
+
+PRIVATE HTStyle HTStyleHeading4 =
+{&HTStyleHeading3, "Heading4", "H4",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 4, 4, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 0, 0};
+
+PRIVATE HTStyle HTStyleHeading5 =
+{&HTStyleHeading4, "Heading5", "H5",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 6, 6, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 0, 0};
+
+PRIVATE HTStyle HTStyleHeading6 =
+{&HTStyleHeading5, "Heading6", "H6",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 8, 8, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 0, 0};
+
+PRIVATE HTStyle HTStyleHeading7 =
+{&HTStyleHeading6, "Heading7", "H7",
+ HT_FONT, 1.0, HT_BLACK, 0, 0,
+ 10, 10, 0, HT_LEFT, 1, 0, 0,
+ YES, YES, 1, 0, 0};
+
+/* Style sheet points to the last in the list:
+*/
+PRIVATE HTStyleSheet sheet =
+{"default.style", &HTStyleHeading7}; /* sheet */
+
+PUBLIC HTStyleSheet *styleSheet = &sheet;
--- /dev/null
+/*
+ * HText.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Wed Feb 26 15:59:04 1992 tvr
+ * Last modified: Mon Apr 27 00:41:22 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+
+#include "HTStyle.h"
+#include "HText.h"
+
+
+/*
+ * This file interacts with WWWLibrary and builds one hypertext page.
+ * For every hypertext object on this page will be set
+ * - data, length
+ * - anchor information
+ * - style
+ * Empty object will be generated for paragraph endings, newlines and
+ * tabulators.
+ */
+
+
+/*
+ * Debug module (temporary)
+ */
+
+#define HT_DEBUG(a) /*printf a*/
+
+
+/*
+ * Local prototype
+ */
+
+void new_htext_object ();
+void make_paragraph_object ();
+void HText_setStyle ();
+
+
+/*
+ * Local text (temporary)
+ */
+
+struct HText *HtLocalText;
+
+
+/*
+ * When constructing data, save it first here. Then malloc needed space
+ * and copy it
+ */
+
+char localdata[HTEXT_MAX_OBJECT_SIZE];
+
+
+/*
+ * Set same anchor information to all objects belonging to same
+ * anchor.
+ */
+
+HTChildAnchor *local_anchor = 0;
+
+/*
+ * Default style
+ */
+extern HTStyleSheet *styleSheet;
+
+
+/*
+ * This file has functions that WWWLibrary uses to construct an hypertext
+ * object.
+ */
+
+/* Creation Method
+** ---------------
+*/
+struct HText *
+HText_new (anchor)
+ HTParentAnchor *anchor;
+{
+ struct HText *self;
+
+ /*
+ * Create hypertext object.
+ */
+
+ self = (struct HText *) malloc (sizeof (struct HText));
+
+ if (!self)
+ return self;
+
+ HTAnchor_setDocument (anchor, (HyperDoc *) self);
+
+ /*
+ * Initialize object.
+ */
+
+ memset (self, 0, sizeof (struct HText));
+
+ /*
+ * Set some WWWLibrary stuff ...
+ */
+ self->node_anchor = anchor;
+
+ /*
+ * Setup hashing code
+ */
+
+ HtLocalText = self;
+
+ return self;
+}
+
+
+/* Free Entire Text
+** ----------------
+*/
+void
+HText_free (self)
+ struct HText *self;
+{
+ struct HTextObject *p, *p2;
+ struct HTextAnchor *a, *a2;
+
+ if (!self)
+ return;
+
+ p = self->first;
+
+ /*
+ * Set some WWWLibrary stuff ...
+ */
+ if (self->node_anchor)
+ HTAnchor_setDocument (self->node_anchor, (HyperDoc *) 0);
+
+
+ /*
+ * Free all data allocated on this file.
+ */
+ while (p)
+ {
+ p2 = p;
+ p = p->next;
+
+ /*
+ * Avoid loop if something goes wrong
+ */
+ p2->next = p2->prev = NULL;
+
+ if (p2->data)
+ free (p2->data);
+
+ free (p2);
+
+ }
+
+ a = self->anchorlist;
+
+ while (a)
+ {
+ a2 = a;
+ a = a->next;
+
+ free (a2);
+ }
+
+ free (self);
+}
+
+/*
+ * Get default style
+ */
+HTStyle *
+ht_get_default_style ()
+{
+ HTStyle *p = styleSheet->styles;
+
+ while (p && p->next)
+ {
+ if (!strcmp (p->SGMLTag, "XMP"))
+ return p;
+ p = p->next;
+ }
+
+ /*
+ * Return last if xmp not found
+ */
+ return p;
+}
+
+
+
+/* Object Building methods
+** -----------------------
+**
+** These are used by a parser to build the text in an object
+*/
+void
+HText_beginAppend (text)
+ struct HText *text;
+{
+ /*
+ * Set object to accept text
+ */
+
+ new_htext_object (text);
+
+ if (!text->first)
+ {
+ HT_DEBUG ((stderr, "htext begin append failed?\n"));
+ }
+
+ /*
+ * Set default style. Some pages cause no setStyle.
+ */
+ HText_setStyle (text, ht_get_default_style ());
+}
+
+
+/* New paragraph in current style
+** ------------------------------
+** See also: setStyle.
+*/
+
+void
+HText_appendParagraph (text)
+ struct HText *text;
+{
+ HT_DEBUG (("\nHText_appendParagraph\n"));
+
+ /*
+ * Create paragraph object
+ */
+
+ make_paragraph_object (text, HTEXT_PARAGRAPH);
+}
+
+
+
+
+/* Append a character to the text object
+** -------------------------------------
+*/
+void
+HText_appendCharacter (text, ch)
+ struct HText *text;
+ char ch;
+{
+ struct HTextObject *p;
+ int l;
+ static char lastchar = 0;
+
+ HT_DEBUG (("%c", ch));
+
+ /*
+ * safety
+ */
+
+ if (!text)
+ return;
+
+ /*
+ * Parse special characters
+ */
+ if (ch == '\n')
+ {
+
+ make_paragraph_object (text, HTEXT_NEWLINE);
+
+ return;
+
+ }
+
+ if (ch == '\t')
+ {
+
+ make_paragraph_object (text, HTEXT_TAB);
+
+ return;
+
+ }
+
+ /*
+ * Append space(s) at the end of objects
+ */
+ if (lastchar == ' ' && ch != ' ')
+ {
+
+ new_htext_object (text);
+
+ /*
+ * Don't loose this character
+ */
+ lastchar = ch;
+
+ HText_appendCharacter (text, ch);
+
+ return;
+ }
+
+ lastchar = ch;
+
+ p = text->last;
+
+ /*
+ * If local buffer is full, make continued hypertext object.
+ * This should not happen (is extreamely rare).
+ */
+
+ if (p->length >= HTEXT_MAX_OBJECT_SIZE)
+ {
+
+ p->paragraph = HTEXT_CONTINUE;
+
+ new_htext_object (text);
+
+ HText_appendCharacter (p, ch);
+
+ /* return */
+
+ }
+ else
+ {
+
+ localdata[p->length++] = ch;
+ }
+}
+
+
+HTextAnchor_t *
+htext_new_anchor ()
+{
+ HTextAnchor_t *p;
+
+ p = (HTextAnchor_t *) malloc (sizeof (HTextAnchor_t));
+
+ if (!p)
+ {
+ HT_DEBUG (("cannot malloc on htext_new_anchor(). tough.\n"));
+
+ exit (-1);
+ }
+
+ memset (p, 0, sizeof (HTextAnchor_t));
+
+ return p;
+}
+
+
+/* Anchor handling
+** ---------------
+*/
+/* Start an anchor field
+*/
+void
+HText_beginAnchor (text, anc)
+ struct HText *text;
+ HTChildAnchor *anc;
+{
+ HT_DEBUG (("\nHText_beginAnchor [%s]\n", anc->tag));
+
+ /*
+ * Set up anchor
+ */
+
+ if (!anc)
+ return;
+
+ if (HTAnchor_followMainLink ((HTAnchor *) anc))
+ {
+ /*
+ * Anchor is to be shown on the screen
+ */
+ new_htext_object (text);
+
+ local_anchor = anc;
+ }
+ /*
+ * Anchor is HREF anchor only
+ */
+ if (!text->anchorlist)
+ {
+
+ text->anchorlist = htext_new_anchor ();
+
+ text->anchorlist->object = text->last;
+
+ text->anchorlist->anchor = anc;
+
+ }
+ else
+ {
+
+ HTextAnchor_t *p = text->anchorlist;
+
+ for (; p->next; p = p->next) ;
+
+ p->next = htext_new_anchor ();
+
+ p->next->anchor = anc;
+
+ p->next->object = text->last;
+ }
+}
+
+
+
+/*
+ * End anchor creation
+ */
+
+void
+HText_endAnchor (text)
+ struct HText *text;
+{
+ HT_DEBUG (("\nHText_endAnchor\n"));
+
+ /*
+ * Create this anchor an object and create new
+ */
+
+ new_htext_object (text);
+
+ local_anchor = NULL;
+
+}
+
+
+
+void
+HText_appendText (text, str)
+ struct HText *text;
+ char *str;
+{
+ register char *p;
+
+ HT_DEBUG (("HText_appendText by characters\n"));
+
+ /*
+ * Append characters (or better, words)
+ */
+
+ for (p = str; *p; p++)
+ HText_appendCharacter (text, *p);
+
+}
+
+/*
+ * End text appending
+ */
+
+void
+HText_endAppend (text)
+ struct HText *text;
+{
+ HT_DEBUG (("HText_endAppend"));
+
+ new_htext_object (text);
+}
+
+
+void
+HText_setStyle (text, style)
+ struct HText *text;
+ HTStyle *style;
+{
+ HT_DEBUG (("HText_setStyle %s\n", style->name));
+
+ if (!style)
+ {
+ HT_DEBUG (("HText bug on HText_setStyle ... not changing style\n"));
+ return;
+ }
+
+ /*
+ * Begin style
+ */
+ new_htext_object (text);
+
+ /*
+ * If many headers in a row, append paragraph
+ */
+ if (text->last->style == style)
+ {
+ HText_appendParagraph (text);
+ }
+
+ text->last->style = style;
+}
+
+
+
+BOOL
+HText_select (text)
+ struct HText *text;
+{
+ HT_DEBUG (("\nHText_select ??????\n"));
+ /*
+ * Do what ???
+ */
+
+ HtLocalText = text;
+}
+
+
+
+BOOL
+HText_selectAnchor (text, anchor)
+ struct HText *text;
+ struct HTChildAnchor *anchor;
+{
+ HT_DEBUG (("\nHText_selectAnchor\n"));
+
+ /*
+ * Something stupid ?
+ */
+}
+
+
+
+/*
+ * Allocate new object. Set up modes from previous. Set up data -area.
+ */
+
+struct HTextObject *
+malloc_ht_object (prev)
+ struct HTextObject *prev;
+{
+ struct HTextObject *p;
+
+ /*
+ * New object
+ */
+
+ p = (struct HTextObject *) malloc (sizeof (struct HTextObject));
+
+ if (!p)
+ {
+ HT_DEBUG (("cannot malloc hypertextobject\n"));
+ exit (-1);
+ }
+
+ if (prev)
+ {
+
+ memcpy (p, prev, sizeof (struct HTextObject));
+
+ p->data = 0;
+
+ p->length = 0;
+
+ p->anchor = 0;
+
+ p->paragraph = 0;
+
+ }
+ else
+ {
+
+ memset (p, 0, sizeof (struct HTextObject));
+
+ }
+
+
+ return p;
+}
+
+
+
+
+/*
+ * Create new hypertext object.
+ */
+
+void
+new_htext_object (text)
+ struct HText *text;
+{
+ struct HTextObject *p;
+
+ /*
+ * First object ?
+ */
+ if (text->first == 0)
+ {
+ text->first = text->last = malloc_ht_object (NULL);
+
+ return;
+ }
+
+ /*
+ * Temporary assignment
+ */
+
+ p = text->last;
+
+ /*
+ * Strip all null objects exept paragraph marks
+ */
+ if ((p->length == 0) && !(p->paragraph))
+ return;
+
+ /*
+ * Check paragraph objects
+ */
+ if (p->paragraph && (p->paragraph != HTEXT_CONTINUE) && p->length)
+ {
+ HT_DEBUG (("non null paragraph object ?\n"));
+ exit (-1);
+ }
+
+ /*
+ * If constructing object, malloc and copy local data
+ */
+
+ if (p->length)
+ {
+
+ p->data = (char *) malloc (p->length + 1);
+
+ if (!p->data)
+ {
+ HT_DEBUG (("cannot malloc data on new_htext_object()\n"));
+ exit (-1);
+ }
+
+ memcpy (p->data, localdata, p->length);
+
+ p->data[p->length] = 0;
+ }
+
+ /*
+ * Set anchorinformation to object
+ */
+
+ p->anchor = local_anchor;
+
+ /*
+ * Create new object
+ */
+
+ p = malloc_ht_object (text->last);
+
+ /*
+ * Set it last
+ */
+
+ p->prev = text->last;
+
+ text->last->next = p;
+
+ text->last = p;
+}
+
+
+
+/*
+ * Make empty object only stating paragraph, tab or newline
+ */
+
+void
+make_paragraph_object (text, type)
+ struct HText *text;
+ int type;
+{
+ new_htext_object (text);
+
+ text->last->paragraph = type;
+
+ new_htext_object (text);
+
+}
+
+
+/*
+ * Malloc and copy data
+ */
+char *
+ht_memdup (data, len)
+ char *data;
+ int len;
+{
+ char *p;
+
+ p = (char *) malloc (len);
+
+ if (!p)
+ return 0;
+
+ memcpy (p, data, len);
+
+ return p;
+}
+
+
+/*
+ * Duplicate object information of this hypertext-page
+ */
+
+HText_t *
+HtDuplicate (text)
+ HText_t *text;
+{
+ HText_t *newtext;
+ HTextObject_t *o, *p;
+ HTextObject_t *p_old = 0;
+
+ newtext = (HText_t *) malloc (sizeof (*newtext));
+
+ if (!newtext)
+ return 0;
+
+ memset (newtext, 0, sizeof (*newtext));
+
+ o = text->first;
+
+ /*
+ * Allocate new htext -page info
+ */
+ if (o)
+ {
+ p = newtext->first = (HTextObject_t *) malloc (sizeof (*p));
+
+ if (!p)
+ {
+
+ free (newtext);
+
+ return 0;
+ }
+ }
+
+ while (o)
+ {
+ memset (p, 0, sizeof (*p));
+
+ p->paragraph = o->paragraph;
+
+ p->length = o->length;
+
+ p->style = o->style;
+
+ p->data = (char *) ht_memdup (o->data, o->length);
+
+ if (!p->data)
+ {
+
+ goto free_allocated_error;
+ }
+
+ p->prev = p_old;
+
+ if (o->next)
+ {
+
+ p_old = p;
+
+ p = (HTextObject_t *) malloc (sizeof (*p));
+
+ if (!p)
+ {
+
+ goto free_allocated_error;
+ }
+
+ p_old->next = p;
+ }
+
+ o = o->next;
+ }
+
+ newtext->last = p;
+
+ return newtext;
+
+free_allocated_error:
+
+ o = newtext->first;
+
+ while (o)
+ {
+
+ if (o->data)
+ free (o->data);
+
+ free (o);
+ }
+
+ free (newtext);
+
+ return 0;
+}
--- /dev/null
+/*
+ * HText.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Wed Feb 26 15:57:03 1992 tvr
+ * Last modified: Mon Apr 27 23:55:47 1992 tvr
+ *
+ */
+
+
+/*
+ * Maximum Htext object data size
+ */
+
+#define HTEXT_MAX_OBJECT_SIZE 1024
+
+/*
+ * Region changes on hypertext
+ */
+#define HTEXT_PARAGRAPH 1
+#define HTEXT_TAB 2
+#define HTEXT_NEWLINE 3
+#define HTEXT_CONTINUE 4
+
+
+/*
+ * Hypertext object structure.
+ */
+
+typedef struct HTextObject
+{
+ /*
+ * Pointers to next and previous objects
+ */
+
+ struct HTextObject *prev;
+ struct HTextObject *next;
+
+ /*
+ * All Hypertext specific fields here
+ */
+
+ /*
+ * If object is an anchor, have anchordata here
+ */
+ HTChildAnchor *anchor;
+
+ /*
+ * Style of this object.
+ */
+ HTStyle *style;
+
+ /*
+ * what data on this object
+ */
+ char *data;
+
+ /*
+ * How many bytes data
+ */
+ int length;
+
+ /*
+ * Marks paragraph change at the end of this object
+ */
+ int paragraph;
+
+ /*
+ * All Xl specific data here
+ */
+
+ /*
+ * Position of an object on a virtual screen. These will be set when
+ * object is being positioned.
+ */
+ long x;
+ long y;
+
+ /*
+ * Size of an object. These are calculated once (as these does
+ * not change).
+ */
+ long width;
+ long height;
+
+ /*
+ * Xl specific data of this object
+ */
+ struct XlObjectData *xl_data;
+} HTextObject_t;
+
+
+/*
+ * Hypertext structure of a page
+ */
+
+typedef struct HText
+{
+ /*
+ * First and last hypertext objects
+ */
+
+ struct HTextObject *first;
+ struct HTextObject *last;
+
+ /*
+ * Node anchor of this page
+ */
+ HTParentAnchor *node_anchor;
+
+ /*
+ * Xl specific global data for a page
+ */
+ struct XlGlobalData *xl_global;
+
+ /*
+ * HREF pointer list
+ */
+ struct HTextAnchor *anchorlist;
+
+ /*
+ * Cursor object of this page
+ */
+ struct HTextObject *cursor;
+
+} HText_t;
+
+
+/*
+ * HREF pointer list on a page
+ */
+typedef struct HTextAnchor
+{
+ /*
+ * Pointer to next
+ */
+ struct HTextAnchor *next;
+
+ /*
+ * Anchor data
+ */
+ HTChildAnchor *anchor;
+
+ /*
+ * To which hypertextobject is this connected to
+ */
+ struct HTextObject *object;
+} HTextAnchor_t;
+
+
+
+/*
+ * Prototype
+ */
+
+HText_t *HtDuplicate (HText_t * text);
--- /dev/null
+#
+#
+#
+
+ OBJS = DefaultStyles.o HText.o dummy.o
+ SRCS = DefaultStyles.c HText.c dummy.c
+
+ DEFINES = -I../Cl/WWWLibrary
+
+NormalLibraryTarget(Ht, $(OBJS))
+
+DependTarget()
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a10867>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../.
+ CURRENT_DIR = ./HText
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+
+ OBJS = DefaultStyles.o HText.o dummy.o
+ SRCS = DefaultStyles.c HText.c dummy.c
+
+ DEFINES = -I../Cl/WWWLibrary
+
+all:: libHt.a
+
+libHt.a: $(OBJS)
+ $(RM) $@
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+depend::
+ $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+/*
+ * dummy.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Wed Feb 26 16:30:17 1992 tvr
+ * Last modified: Wed Feb 26 23:12:57 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include "HTStyle.h"
+#include "HText.h"
+
+/*
+ * something needed here to compile, but not to HText ..
+ */
+
+FILE *logfile = NULL;
+
+char *HTClientHost = NULL;
+
+struct HText *HTMainText = NULL;
+
+struct HTParentAnchor *HTMainAnchor = NULL;
--- /dev/null
+#
+#
+#
+
+#define PassCDebugFlags 'CC=$(CC)' 'CDEBUGFLAGS=$(CDEBUGFLAGS)'
+#define IHaveSubdirs
+
+all::
+
+world::
+ make ${MFLAGS} mastermakefiles
+ make ${MFLAGS} depend
+ make ${MFLAGS} all
+
+ SUBDIRS = Cl HText Xl Ui erwise
+
+MakeSubdirs($(SUBDIRS))
+
+DependSubdirs($(SUBDIRS))
+
+install::
+ $(MAKE) $(MFLAGS) install
+
+/**/# rebuild the makefiles at the master source tree
+mastermakefiles::
+ -$(MV) Makefile Makefile.bak
+ $(MAKE) -f Makefile.bak Makefile
+ $(MAKE) Makefiles
+
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a07565>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = .
+ CURRENT_DIR = .
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+
+all::
+
+world::
+ make ${MFLAGS} mastermakefiles
+ make ${MFLAGS} depend
+ make ${MFLAGS} all
+
+ SUBDIRS = Cl HText Xl Ui erwise
+
+all::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "making" all "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) 'CC=$(CC)' 'CDEBUGFLAGS=$(CDEBUGFLAGS)' all); \
+ done
+
+depend::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "depending" "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) depend); \
+ done
+
+install::
+ $(MAKE) $(MFLAGS) install
+
+# rebuild the makefiles at the master source tree
+mastermakefiles::
+ -$(MV) Makefile Makefile.bak
+ $(MAKE) -f Makefile.bak Makefile
+ $(MAKE) Makefiles
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# rules for building in SUBDIRS - do not edit
+
+install::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "installing" "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) DESTDIR='$(DESTDIR)' install); \
+ done
+
+install.man::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "installing man pages" "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) DESTDIR='$(DESTDIR)' install.man); \
+ done
+
+clean::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "cleaning" "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) RM_CMD='$(RM_CMD)' clean); \
+ done
+
+tags::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo "tagging" "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) TAGS='$(TAGS)' tags); \
+ done
+
+Makefiles::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ echo "making Makefiles in $(CURRENT_DIR)/$$i..."; \
+ case "$$i" in \
+ ./?*/?*/?*/?*) newtop=../../../../ sub=subsubsubsub;; \
+ ./?*/?*/?*) newtop=../../../ sub=subsubsub;; \
+ ./?*/?*) newtop=../../ sub=subsub;; \
+ ./?*) newtop=../ sub=sub;; \
+ */?*/?*/?*) newtop=../../../../ sub=subsubsubsub;; \
+ */?*/?*) newtop=../../../ sub=subsubsub;; \
+ */?*) newtop=../../ sub=subsub;; \
+ *) newtop=../ sub=sub;; \
+ esac; \
+ case "$(TOP)" in \
+ /?*) newtop= upprefix= ;; \
+ *) upprefix=../ ;; \
+ esac; \
+ $(MAKE) $${sub}dirMakefiles UPPREFIX=$$upprefix NEWTOP=$$newtop \
+ MAKEFILE_SUBDIR=$$i NEW_CURRENT_DIR=$(CURRENT_DIR)/$$i;\
+ done
+
+subdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+subsubdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+subsubsubdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+subsubsubsubdirMakefiles:
+ $(RM) $(MAKEFILE_SUBDIR)/Makefile.bak
+ -@if [ -f $(MAKEFILE_SUBDIR)/Makefile ]; then set -x; \
+ $(MV) $(MAKEFILE_SUBDIR)/Makefile $(MAKEFILE_SUBDIR)/Makefile.bak; \
+ else exit 0; fi
+ cd $(MAKEFILE_SUBDIR); $(IMAKE_CMD) -DTOPDIR=$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(UPPREFIX)$(TOP) -DCURDIR=$(NEW_CURRENT_DIR); \
+ $(MAKE) $(MFLAGS) Makefiles
+
+includes::
+ @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
+ for i in $(SUBDIRS) ;\
+ do \
+ (cd $$i ; echo including "in $(CURRENT_DIR)/$$i..."; \
+ $(MAKE) $(MFLAGS) includes); \
+ done
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+#
+#
+#
+
+ OBJS = UiInit.o UiSelectionBox.o UiPage.o UiMisc.o \
+ UiSearch.o UiPageSettings.o UiList.o UiInfo.o \
+ UiControlPanel.o UiDefaults.o UiUtil.o UiPrint.o \
+ UiConnections.o UiFileSelection.o UiRecall.o
+
+ SRCS = UiInit.c UiSelectionBox.c UiPage.c UiMisc.c \
+ UiSearch.c UiPageSettings.c UiList.c UiInfo.c \
+ UiControlPanel.c UiDefaults.c UiUtil.c UiPrint.c \
+ UiConnections.c UiFileSelection.c UiRecall.c
+
+ XLDIR = ../Xl
+ HTDIR = ../HText
+ WWWDIR = ../Cl/WWWLibrary
+ MOTIF_HDRS = -I/p/motif/include
+ ERWISE_HDRS = -I$(XLDIR) -I$(HTDIR) -I$(WWWDIR)
+ DEFINES = $(ERWISE_HDRS) $(MOTIF_HDRS) -DERWISE_UI
+
+NormalLibraryTarget(Ui, $(OBJS))
+
+DependTarget()
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a10907>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../.
+ CURRENT_DIR = ./Ui
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+
+ OBJS = UiInit.o UiSelectionBox.o UiPage.o UiMisc.o \
+ UiSearch.o UiPageSettings.o UiList.o UiInfo.o \
+ UiControlPanel.o UiDefaults.o UiUtil.o UiPrint.o \
+ UiConnections.o UiFileSelection.o UiRecall.o
+
+ SRCS = UiInit.c UiSelectionBox.c UiPage.c UiMisc.c \
+ UiSearch.c UiPageSettings.c UiList.c UiInfo.c \
+ UiControlPanel.c UiDefaults.c UiUtil.c UiPrint.c \
+ UiConnections.c UiFileSelection.c UiRecall.c
+
+ XLDIR = ../Xl
+ HTDIR = ../HText
+ WWWDIR = ../Cl/WWWLibrary
+ MOTIF_HDRS = -I/p/motif/include
+ ERWISE_HDRS = -I$(XLDIR) -I$(HTDIR) -I$(WWWDIR)
+ DEFINES = $(ERWISE_HDRS) $(MOTIF_HDRS) -DERWISE_UI
+
+all:: libUi.a
+
+libUi.a: $(OBJS)
+ $(RM) $@
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+depend::
+ $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+head 1.1;
+access
+ kny
+ kss
+ kts
+ tvr;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.1
+date 92.02.09.16.41.46; author kny; state Exp;
+branches;
+next 1.0;
+
+1.0
+date 92.01.22.13.51.39; author kny; state Exp;
+branches;
+next ;
+
+
+desc
+@Demo-program for Ui-library.
+@
+
+
+1.1
+log
+@Added demogetpage-callback, cleaned up some things.
+@
+text
+@static char *rcsid = "$Id: uidemo.c,v 1.0 1992/01/22 13:51:39 kny Exp kny $";
+
+#include <stdio.h>
+#include "Ui.h"
+
+
+void demoquit(void);
+void demoinfo(void);
+void demoopen(void);
+void demohelp(void);
+void demogetpage(char *nodename);
+
+
+void main(argc, argv)
+int argc;
+char *argv[];
+{
+ if (UiInitialize(argc, argv) != UI_OK)
+ {
+ fprintf(stderr, "Error initializing Ui-toolkit\n");
+ exit(-1);
+ }
+
+ UiAttachCallback("Quit", demoquit);
+ UiAttachCallback("Info", demoinfo);
+ UiAttachCallback("Open", demoopen);
+ UiAttachCallback("Help", demohelp);
+
+ UiMainLoop();
+}
+
+
+void demoquit()
+{
+ printf("Quit me harder\n");
+
+ exit(0);
+}
+
+
+void demoinfo()
+{
+ printf("WWW-X-Client-Demo V0.000001ALPHA (C) Copyright OHT-Erwise\n");
+}
+
+
+void demoopen()
+{
+ UiDisplaySelectionBox(demogetpage);
+}
+
+
+void demohelp()
+{
+ printf("Help my ass\n");
+}
+
+
+void demogetpage(nodename)
+char *nodename;
+{
+ void *hypetext = (void *) NULL;
+
+ printf("Retrieving page %s\n", nodename);
+ UiDisplayPage(nodename, hypetext);
+}
+@
+
+
+1.0
+log
+@Initial revision
+@
+text
+@d1 1
+a1 1
+static char *rcsid = "$Id$";
+d7 5
+a11 4
+void demoquit(void *parameter);
+void demoinfo(void *parameter);
+void demoopen(void *parameter);
+void demohelp(void *parameter);
+d24 4
+a27 4
+ UiAttachCallback("Quit", demoquit, (void *) "harder");
+ UiAttachCallback("Info", demoinfo, (void *) NULL);
+ UiAttachCallback("Open", demoopen, (void *) NULL);
+ UiAttachCallback("Help", demohelp, (void *) NULL);
+d33 1
+a33 2
+void demoquit(parameter)
+void *parameter;
+d35 1
+a35 1
+ printf("Quit me %s\n", (char *) parameter);
+d41 1
+a41 2
+void demoinfo(parameter)
+void *parameter;
+d47 1
+a47 2
+void demoopen(parameter)
+void *parameter;
+d49 1
+a49 1
+ UiDisplaySelectionBox(NULL);
+d53 1
+a53 2
+void demohelp(parameter)
+void *parameter;
+d56 10
+@
--- /dev/null
+/* $Id: Ui.h,v 1.3 1992/04/28 00:34:53 kny Exp kny $ */
+
+
+#define UI_OK 0
+#define UI_ERROR 1
+#define UI_NOTFOUND 2
+
+#define UI_NONE 0
+#define UI_SHIFT 1
+#define UI_CTRL 4
+
+
+/*
+ * Config defines
+ */
+#define C_GLOBALSETTINGS "GlobalSettings"
+
+#define C_TOPMARGIN "topmargin"
+#define C_BOTTOMMARGIN "bottommargin"
+#define C_LEFTMARGIN "leftmargin"
+#define C_RIGHTMARGIN "rightmargin"
+#define C_WIDTH "width"
+#define C_HEIGHT "height"
+#define C_ONEPAGEMODE "onepagemode"
+#define C_FIXEDWIDTHMODE "fixedwidthmode"
+#define C_FIXEDWIDTH "fixedwidth"
+#define C_DOUBLECLICKTIME "doubleclicktime"
+
+#define C_SEARCH "search"
+#define C_CONTROLPANEL "controlpanel"
+#define C_LIST "list"
+#define C_RECALL "recall"
+#define C_PAGESETTINGS "pagesettings"
+
+#define C_DEFAULTS "Defaults"
+#define C_DEFAULTSTABLE "defaultstable"
+
+
+typedef enum {
+ uiVTint,
+ uiVTdouble,
+ uiVTstring
+} uiVarType_t;
+
+
+extern int UiInitialize(int argc, char *argv[],
+ void *(*configpf) (void *table, char *item),
+ void *(*configsetpf) (void *table, char *item,
+ void *value));
+extern void UiMainLoop(void);
+
+extern int UiDisplaySelectionBox(void (*callback) (char *filename));
+
+extern int UiDisplayPage(char *address, HText_t * prevhtext, HText_t * htext,
+ HTextObject_t * htextobject, char *title);
+extern int UiDeletePage(char *address, HText_t * htext);
+extern int UiSetCursor(char *address, HText_t * htext,
+ HTextObject_t * htextobject);
+
+extern int UiDisplaySearchDialog(int type);
+
+extern int UiDisplayPageSettingsDialog(int type);
+
+extern int UiDisplayListDialog(char **listitems, char **addresses, int nitems,
+ void (*callback) (char *topaddress,
+ char *address,
+ char *parentaddress));
+
+extern int UiDisplayRecallDialog(char **listitems, int nitems,
+ void (*callback) (char *topaddress,
+ char *address,
+ char *parentaddress));
+
+extern int UiAttachCallback(char *actionname,
+ void (*callback) (char *address,
+ HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter),
+ void *parameter);
+extern int UiBindKey(char *keyname, int modifier,
+ void (*callback) (char *address,
+ HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter),
+ void *parameter);
+extern int UiBindVariable(char *varname, void *variable, uiVarType_t type);
+extern int UiUpdateVariable(char *varname);
+extern void UiGetNextAction(void (*helponactioncb) (char *actionstring));
+extern int UiAddTimeOut(int timeout, void (*callback) (void *data),
+ void *data);
+extern void UiDeleteTimeOut(int timoutid);
+extern int UiAddInputFD(int fd, void (*callback) (void *data), void *data);
+extern void UiDeleteInputFD(int inputid);
+extern void UiAddStringToCutBuffer(char *data);
+void UiDisplayPopup(void (*callback) (char *address, char *topaddress,
+ char *parentaddress),
+ char *topaddress, char **items, int nitems);
+
+extern void UiShowInfo(void);
+
+extern int UiDisplayControlPanel(void);
+
+extern int UiDisplayFileSelection(void (*callback) (char *topaddress,
+ HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter));
--- /dev/null
+static char *rcsid = "$Id$";
+
+#include "UiIncludes.h"
+
+static Widget uicreateconnectionsform();
+static Widget uicreateconnectionslabel(Widget formwdg);
+static Widget uicreateconnectionskill(Widget formwdg);
+static Widget uicreateconnectionsclose(Widget formwdg);
+static Widget uicreateconnectionsseparator(Widget formwdg, Widget bottomwdg);
+static Widget
+ uicreateconnectionslist(Widget formwdg, Widget topwdg,
+ Widget bottomwdg);
+static void uiconnectionsfreeprevious(void);
+static void uiconnectionssetitems(char **listitems, void **connections,
+ int nitems);
+static void uiconnectionskillcb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+static void uiconnectionsclosecb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+
+
+static int uiconnectionsdisplayed = FALSE;
+static char **uilistitems;
+static void **uiconnections;
+static int uinitems;
+static void (*uiconnectionscallback) (void *connection);
+
+
+int UiDisplayConnectionsDialog(listitems, connections, nitems, callback)
+char **listitems;
+void **connections;
+int nitems;
+void (*callback) (void *connection);
+{
+ uiConnectionsGfx_t *connectionsgfx = &uiTopLevel.ConnectionsGfx;
+
+ uiconnectionsfreeprevious();
+
+ uiconnectionsdisplayed = TRUE;
+ uilistitems = listitems;
+ uiconnections = connections;
+ uinitems = nitems;
+ uiconnectionscallback = callback;
+
+ if (connectionsgfx->FormWdg) {
+ XtMapWidget(XtParent(connectionsgfx->FormWdg));
+ uiconnectionssetitems(listitems, connections, nitems);
+
+ return UI_OK;
+ }
+ connectionsgfx->FormWdg = uicreateconnectionsform();
+ connectionsgfx->LabelWdg =
+ uicreateconnectionslabel(connectionsgfx->FormWdg);
+ connectionsgfx->KillWdg =
+ uicreateconnectionskill(connectionsgfx->FormWdg);
+ connectionsgfx->CloseWdg =
+ uicreateconnectionsclose(connectionsgfx->FormWdg);
+ connectionsgfx->SeparatorWdg =
+ uicreateconnectionsseparator(connectionsgfx->FormWdg,
+ connectionsgfx->KillWdg);
+ connectionsgfx->ListWdg =
+ uicreateconnectionslist(connectionsgfx->FormWdg,
+ connectionsgfx->LabelWdg,
+ connectionsgfx->SeparatorWdg);
+
+ uiconnectionssetitems(listitems, connections, nitems);
+
+ XtManageChild(connectionsgfx->FormWdg);
+ XtRealizeWidget(XtParent(connectionsgfx->FormWdg));
+
+ return UI_OK;
+}
+
+
+int UiConnectionsDialogDisplayed()
+{
+ return uiconnectionsdisplayed;
+}
+
+
+void uiConnectionsUpdateDialog()
+{
+ if (!uiPageInfo.CurrentPage && uiTopLevel.ConnectionsGfx.FormWdg) {
+ uiconnectionsfreeprevious();
+ uiconnectionssetitems((char **) NULL, (void **) NULL, 0);
+ XtUnmapWidget(XtParent(uiTopLevel.ConnectionsGfx.FormWdg));
+ }
+}
+
+
+static Widget
+ uicreateconnectionsform()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("Connections",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_CONNECTIONS_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "ConnectionsDialog",
+ args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreateconnectionslabel(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ Widget labelwdg;
+
+ labelstr = XmStringCreateSimple("Open connections");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_CONNECTIONS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "ConnectionsLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ return labelwdg;
+}
+
+
+static Widget
+ uicreateconnectionskill(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget killwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 40,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_CONNECTIONS_WDG_OFFSET, NULL);
+ killwdg = XmCreatePushButtonGadget(formwdg, "Kill", args, nargs);
+ XtAddCallback(killwdg, XmNactivateCallback,
+ (XtCallbackProc) uiconnectionskillcb, (caddr_t) NULL);
+ XtManageChild(killwdg);
+
+ return killwdg;
+}
+
+
+static Widget
+ uicreateconnectionsclose(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget closewdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 60,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_CONNECTIONS_WDG_OFFSET, NULL);
+ closewdg = XmCreatePushButtonGadget(formwdg, "Close", args, nargs);
+ XtAddCallback(closewdg, XmNactivateCallback,
+ (XtCallbackProc) uiconnectionsclosecb, (caddr_t) NULL);
+ XtManageChild(closewdg);
+
+ return closewdg;
+}
+
+
+static Widget
+ uicreateconnectionsseparator(formwdg, bottomwdg)
+Widget formwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_CONNECTIONS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(formwdg, "ConnectionsSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ return separatorwdg;
+}
+
+
+static Widget
+ uicreateconnectionslist(formwdg, topwdg, bottomwdg)
+Widget formwdg;
+Widget topwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget listwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNvisibleItemCount, 15,
+ XmNwidth, 300,
+ XmNselectionPolicy, XmSINGLE_SELECT,
+ XmNlistSizePolicy, XmCONSTANT,
+ XmNscrollBarDisplayPolicy, XmSTATIC,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_CONNECTIONS_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_CONNECTIONS_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_CONNECTIONS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_CONNECTIONS_WDG_OFFSET, NULL);
+ listwdg = XmCreateScrolledList(formwdg, "ConnectionsList", args, nargs);
+ XtManageChild(listwdg);
+ XtAddCallback(listwdg, XmNdefaultActionCallback,
+ (XtCallbackProc) uiconnectionskillcb, (caddr_t) NULL);
+
+ return listwdg;
+}
+
+
+void uiconnectionsfreeprevious()
+{
+ if (uinitems)
+ uiFree(uilistitems);
+}
+
+
+static void uiconnectionssetitems(listitems, connections, nitems)
+char **listitems;
+void **connections;
+int nitems;
+{
+ Widget listwdg = uiTopLevel.ConnectionsGfx.ListWdg;
+ int i;
+ XmString *tmpstr = uiMalloc(nitems * sizeof(XmString));
+
+ XmListDeleteAllItems(listwdg);
+ if (nitems) {
+ for (i = 0; i < nitems; i++)
+ tmpstr[i] = XmStringCreateSimple(listitems[i]);
+
+ XmListAddItems(listwdg, tmpstr, nitems, 0);
+ for (i = 0; i < nitems; i++)
+ XmStringFree(tmpstr[i]);
+ uiFree((void *) tmpstr);
+ }
+}
+
+
+
+
+static void uiconnectionskillcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ Widget connectionswdg = uiTopLevel.ConnectionsGfx.ListWdg;
+ int *poslist;
+ int poscount;
+ char *parentaddress;
+
+ if (uinitems)
+ if (XmListGetSelectedPos(connectionswdg, &poslist, &poscount)) {
+ uiDefineCursor(uiBusyCursor);
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) ("Kill connection");
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else
+ (*uiconnectionscallback) (uiconnections[poslist[0] - 1]);
+
+ uiUndefineCursor();
+
+ XtFree(poslist);
+ }
+}
+
+
+static void uiconnectionsclosecb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.ConnectionsGfx.FormWdg));
+ uiconnectionsdisplayed = FALSE;
+}
--- /dev/null
+static char *rcsid = "$Id$";
+
+#include "UiIncludes.h"
+
+static Widget uicreatecpform();
+static Widget
+ uicreatecpbutton(Widget parentwdg, char *name, char *actionname,
+ int leftpos, int rightpos);
+static Widget uicreatecpclosebutton(Widget parentwdg);
+static Widget uicreatecplabel(Widget parentwdg, Widget rightwdg);
+static Widget uicreatecplist(Widget parentwdg, Widget bottomwdg,
+ Widget topwdg);
+static void uicpclosecb(char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+static void uicpclickcb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+
+
+uiTopLevel_t uiTopLevel;
+
+
+int UiDisplayControlPanel()
+{
+ ArgList args;
+ Cardinal nargs;
+ uiTopLevelGfx_t *topgfx = &uiTopLevel.TopGfx;
+ uiControlPanelGfx_t *controlpanelgfx = &uiTopLevel.ControlPanelGfx;
+
+ if (controlpanelgfx->FormWdg) {
+ XtMapWidget(XtParent(controlpanelgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(controlpanelgfx->FormWdg),
+ uiTopLevel.GlobalSettings.ControlPanelPlacement);
+
+ return UI_OK;
+ }
+ args = uiVaSetArgs(&nargs,
+ XmNwidth, 280,
+ XmNheight, 180,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ controlpanelgfx->FormWdg = uicreatecpform();
+ controlpanelgfx->SearchWdg = uicreatecpbutton(controlpanelgfx->FormWdg,
+ "Search", "Search", 0, 25);
+ controlpanelgfx->HomeWdg = uicreatecpbutton(controlpanelgfx->FormWdg,
+ "Home", "Home", 25, 50);
+ controlpanelgfx->RecallWdg = uicreatecpbutton(controlpanelgfx->FormWdg,
+ "Recall", "Recall", 50, 75);
+ controlpanelgfx->CloseWdg = uicreatecpbutton(controlpanelgfx->FormWdg,
+ "Close\nhierarchy",
+ "Close hierarchy", 75, 100);
+ controlpanelgfx->DialogCloseWdg =
+ uicreatecpclosebutton(controlpanelgfx->FormWdg);
+ controlpanelgfx->LabelWdg =
+ uicreatecplabel(controlpanelgfx->FormWdg,
+ controlpanelgfx->DialogCloseWdg);
+ controlpanelgfx->ListWdg = uicreatecplist(controlpanelgfx->FormWdg,
+ controlpanelgfx->SearchWdg,
+ controlpanelgfx->DialogCloseWdg);
+ XtManageChild(controlpanelgfx->FormWdg);
+ XtRealizeWidget(XtParent(controlpanelgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(controlpanelgfx->FormWdg),
+ uiTopLevel.GlobalSettings.ControlPanelPlacement);
+
+ return UI_OK;
+}
+
+
+void uiControlPanelUpdateDialog()
+{
+ if (uiTopLevel.ControlPanelGfx.FormWdg) {
+ if (uiPageInfo.CurrentPage) {
+ } else
+ XtUnmapWidget(XtParent(uiTopLevel.ControlPanelGfx.FormWdg));
+ }
+}
+
+
+static Widget
+ uicreatecpform()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("ControlPanel",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_CONTROL_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "ControlPanel", args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreatecpbutton(parentwdg, name, actionname, leftpos, rightpos)
+Widget parentwdg;
+char *name;
+char *actionname;
+int leftpos;
+int rightpos;
+{
+ Widget tmpwdg;
+ uiActionData_t *actiondata = uiMalloc(sizeof(*actiondata));
+
+ tmpwdg = XmCreatePushButtonGadget(parentwdg, name,
+ (ArgList) NULL, 0);
+ XtVaSetValues(tmpwdg,
+ XmNheight, 65,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, leftpos,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, rightpos, NULL);
+ actiondata->ActionName = actionname;
+ actiondata->Page = uiPageInfo.CurrentPage;
+ XtAddCallback(tmpwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) actiondata);
+ XtManageChild(tmpwdg);
+
+ return tmpwdg;
+}
+
+
+static Widget
+ uicreatecpclosebutton(parentwdg)
+Widget parentwdg;
+{
+ Widget tmpwdg;
+ static uiActionData_t actiondata;
+
+ tmpwdg = XmCreatePushButtonGadget(parentwdg, "Close", (ArgList) NULL, 0);
+ XtVaSetValues(tmpwdg,
+ XmNwidth, 70,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_CP_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_CP_WDG_OFFSET, NULL);
+ actiondata.ActionName = "CpClose";
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(tmpwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) & actiondata);
+ UiAttachCallback("CpClose", uicpclosecb, "CpClose");
+
+ XtManageChild(tmpwdg);
+
+ return tmpwdg;
+}
+
+
+static Widget
+ uicreatecplabel(parentwdg, rightwdg)
+Widget parentwdg;
+Widget rightwdg;
+{
+ Widget tmpwdg;
+
+ tmpwdg = XmCreateLabelGadget(parentwdg, "ControlPanelLabel",
+ (ArgList) NULL, 0);
+ XtVaSetValues(tmpwdg,
+ XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNbottomWidget, rightwdg,
+ XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNtopWidget, rightwdg,
+ XmNrightAttachment, XmATTACH_WIDGET,
+ XmNrightWidget, rightwdg,
+ XmNrightOffset, UI_CP_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_CP_WDG_OFFSET, NULL);
+
+ XtManageChild(tmpwdg);
+
+ return tmpwdg;
+}
+
+
+static Widget
+ uicreatecplist(formwdg, topwdg, bottomwdg)
+Widget formwdg;
+Widget topwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget listwdg;
+ uiHierarchy_t *hierarchy = uiTopLevel.Hierarchies;
+ XmString dummystr;
+
+ args = uiVaSetArgs(&nargs,
+ XmNvisibleItemCount, 5,
+ XmNselectionPolicy, XmSINGLE_SELECT,
+ XmNlistSizePolicy, XmCONSTANT,
+ XmNscrollBarDisplayPolicy, XmSTATIC,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_CP_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_CP_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_CP_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_CP_WDG_OFFSET, NULL);
+ listwdg = XmCreateScrolledList(formwdg, "CpList", args, nargs);
+ XtManageChild(listwdg);
+
+ while (hierarchy) {
+ dummystr = XmStringCreateSimple(hierarchy->Address);
+ XmListAddItem(listwdg, dummystr, 0);
+ XmStringFree(dummystr);
+ hierarchy = hierarchy->Next;
+ }
+
+ return listwdg;
+}
+
+
+static void uicpclickcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ char *selection;
+
+ XmStringGetLtoR(calldata->item, XmSTRING_DEFAULT_CHARSET, &selection);
+}
+
+
+static void uicpclosecb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.ControlPanelGfx.FormWdg));
+}
--- /dev/null
+static char *rcsid = "$Id$";
+
+#include "UiIncludes.h"
+
+static void uibinddefaultsvariables(void);
+static void uiupdatedefaultsvariables(void);
+static Widget uicreatedefaultsformdialog();
+static Widget uicreatedefaultslabel(Widget parent, Widget bottomwdg);
+static Widget
+ uicreatedefaultsitem(char *name, Widget parent,
+ Widget bottomwdg);
+static Widget uicreatedefaultsclose(Widget parent);
+static void uidefaultsclosecb(char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+
+
+int UiDisplayDefaultsDialog()
+{
+ uiDefaultsGfx_t *defaultsgfx = &uiTopLevel.DefaultsGfx;
+
+ uibinddefaultsvariables();
+
+ if (defaultsgfx->FormWdg) {
+ XtMapWidget(XtParent(defaultsgfx->FormWdg));
+
+ uiupdatedefaultsvariables();
+
+ return UI_OK;
+ }
+ defaultsgfx->FormWdg = uicreatedefaultsformdialog();
+ defaultsgfx->CloseWdg = uicreatedefaultsclose(defaultsgfx->FormWdg);
+ defaultsgfx->PageSettings = uicreatedefaultsitem("Page Settings window",
+ defaultsgfx->FormWdg,
+ defaultsgfx->CloseWdg);
+ defaultsgfx->RecallWindow =
+ uicreatedefaultsitem("Recall window",
+ defaultsgfx->FormWdg,
+ defaultsgfx->PageSettings);
+ defaultsgfx->ListWindow = uicreatedefaultsitem("List window",
+ defaultsgfx->FormWdg,
+ defaultsgfx->RecallWindow);
+ defaultsgfx->ControlPanel = uicreatedefaultsitem("Control panel",
+ defaultsgfx->FormWdg,
+ defaultsgfx->ListWindow);
+ defaultsgfx->SearchWindow =
+ uicreatedefaultsitem("Search window", defaultsgfx->FormWdg,
+ defaultsgfx->ControlPanel);
+ defaultsgfx->LabelWdg = uicreatedefaultslabel(defaultsgfx->FormWdg,
+ defaultsgfx->SearchWindow);
+
+ XtManageChild(defaultsgfx->FormWdg);
+ XtRealizeWidget(XtParent(defaultsgfx->FormWdg));
+
+ uiupdatedefaultsvariables();
+
+ return UI_OK;
+}
+
+
+void uiDefaultsUpdateDialog()
+{
+ if (uiTopLevel.DefaultsGfx.FormWdg) {
+ if (uiPageInfo.CurrentPage) {
+ uibinddefaultsvariables();
+ uiupdatedefaultsvariables();
+ } else
+ XtUnmapWidget(XtParent(uiTopLevel.DefaultsGfx.FormWdg));
+ }
+}
+
+
+static void uibinddefaultsvariables()
+{
+ UiBindVariable("Page Settings window",
+ (void *) &uiTopLevel.GlobalSettings.PageSettingsPlacement,
+ uiVTint);
+ UiBindVariable("Recall window",
+ (void *) &uiTopLevel.GlobalSettings.RecallPlacement,
+ uiVTint);
+ UiBindVariable("List window",
+ (void *) &uiTopLevel.GlobalSettings.ListPlacement,
+ uiVTint);
+ UiBindVariable("Control panel",
+ (void *) &uiTopLevel.GlobalSettings.ControlPanelPlacement,
+ uiVTint);
+ UiBindVariable("Search window",
+ (void *) &uiTopLevel.GlobalSettings.SearchPlacement,
+ uiVTint);
+}
+
+
+static void uiupdatedefaultsvariables()
+{
+ UiUpdateVariable("Page Settings window");
+ UiUpdateVariable("Recall window");
+ UiUpdateVariable("List window");
+ UiUpdateVariable("Control panel");
+ UiUpdateVariable("Search window");
+}
+
+
+static Widget
+ uicreatedefaultsformdialog()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("Defaults",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_DEFAULTS_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "Defaults", args, nargs);
+
+ return formwdg;
+}
+
+static Widget
+ uicreatedefaultslabel(parent, bottomwdg)
+Widget parent;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget labelwdg;
+ XmString labelstr;
+
+ labelstr = XmStringCreateSimple("Follow pointer");
+
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_DEFAULTS_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_DEFAULTS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(parent, "DEFAULTSLabel", args, nargs);
+ XtManageChild(labelwdg);
+
+ return labelwdg;
+}
+
+
+static Widget
+ uicreatedefaultsitem(name, parent, bottomwdg)
+char *name;
+Widget parent;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget togglewdg;
+ static uiActionData_t actiondata;
+
+ args = uiVaSetArgs(&nargs,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_DEFAULTS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ formwdg = XmCreateForm(parent, name, args, nargs);
+ XtManageChild(formwdg);
+
+ togglewdg = XmCreateToggleButtonGadget(formwdg, name,
+ (ArgList) NULL, 0);
+ XtVaSetValues(togglewdg,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_DEFAULTS_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_DEFAULTS_WDG_OFFSET, NULL);
+ XtAddCallback(togglewdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) name);
+ /* Ignore */
+ (void) uiAddWidgetInfo(name, togglewdg, uiWTcheckbutton);
+ XtManageChild(togglewdg);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreatedefaultsclose(parent)
+Widget parent;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+ Widget tmpwdg;
+ static uiActionData_t actiondata;
+
+ tmpwdg = XmCreatePushButtonGadget(parent, "Close", (ArgList) NULL, 0);
+ XtVaSetValues(tmpwdg,
+ XmNwidth, 70,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_DEFAULTS_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_DEFAULTS_WDG_OFFSET, NULL);
+ actiondata.ActionName = "DefaultsClose";
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(tmpwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) & actiondata);
+ UiAttachCallback("DefaultsClose", uidefaultsclosecb,
+ "DefaultsGfx.FormWdg");
+
+ XtManageChild(tmpwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, tmpwdg,
+ XmNbottomOffset, UI_DEFAULTS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(parent, "DefaultsSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ return separatorwdg;
+}
+
+
+static void setplacementvalue(uiconfigsetfp, table, item, placementvalue)
+void *(*uiconfigsetfp) (void *table, char *item, void *value);
+void *table;
+char *item;
+int placementvalue;
+{
+ if (placementvalue)
+ uiconfigsetfp(table, item, "Mouse");
+ else
+ uiconfigsetfp(table, item, "Fixed");
+}
+
+
+static void uidefaultsclosecb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ uiGlobalSettings_t *gs = &uiTopLevel.GlobalSettings;
+ void *table;
+
+ table = uiConfigPF((void *) NULL, C_GLOBALSETTINGS);
+ setplacementvalue(uiConfigSetPF, table, C_SEARCH, gs->SearchPlacement);
+ setplacementvalue(uiConfigSetPF, table, C_CONTROLPANEL, gs->ControlPanelPlacement);
+ setplacementvalue(uiConfigSetPF, table, C_LIST, gs->ListPlacement);
+ setplacementvalue(uiConfigSetPF, table, C_RECALL, gs->RecallPlacement);
+ setplacementvalue(uiConfigSetPF, table, C_PAGESETTINGS, gs->PageSettingsPlacement);
+
+ XtUnmapWidget(XtParent(uiTopLevel.DefaultsGfx.FormWdg));
+}
--- /dev/null
+/* $Id: UiDefs.h,v 1.2 1992/04/05 11:44:09 kss Exp kny $ */
+
+
+#define UI_INVALID (-1)
+
+#define UI_SEARCH_WDG_OFFSET 10
+#define UI_PAGESETTINGS_WDG_OFFSET 10
+#define UI_LIST_WDG_OFFSET 10
+#define UI_INFO_WDG_OFFSET 10
+#define UI_CP_WDG_OFFSET 10
+#define UI_DEFAULTS_WDG_OFFSET 10
+#define UI_PRINT_WDG_OFFSET 10
+#define UI_CONNECTIONS_WDG_OFFSET 10
+
+#define UI_LEFT 0
+#define UI_RIGHT 1
+#define UI_UP 2
+#define UI_DOWN 3
+
+#define UI_HSCROLLBAR "HScrollBar"
+#define UI_VSCROLLBAR "VScrollBar"
+
+#define UI_ERWISE_TITLE "Erwise"
+#define UI_SEARCH_TITLE "Text search"
+#define UI_LIST_TITLE "List of tags"
+#define UI_PRINT_TITLE "Print"
+#define UI_SETTINGS_TITLE "Page settings"
+#define UI_RECALL_TITLE "Browsed documents"
+#define UI_CONTROL_TITLE "Control panel"
+#define UI_CONNECTIONS_TITLE "Open connections"
+#define UI_DEFAULTS_TITLE "Defaults"
+
+#define ui_VALID(x) ((x) != (-1))
+#define ui_INVALID(x) ((x) == (-1))
+
+#define ui_HELPMENU(x) (!strcmp(x, "Help"))
+#define ui_TOGGLE(x) ((x)[-1] == '*')
--- /dev/null
+static char *rcsid = "$Id$";
+
+#include "UiIncludes.h"
+
+
+static Widget uicreatefsformdialog();
+static Widget
+ uicreatefsfsbox(Widget formwdg,
+ void (*callback) (char *topaddress,
+ HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter));
+static void uifileselectionokcb(Widget wdg, caddr_t callback,
+ XmPushButtonCallbackStruct * calldata);
+static void uifileselectioncancelcb(Widget wdg, caddr_t ignored,
+ XmPushButtonCallbackStruct * calldata);
+static void uifileselectionclickcb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+
+
+uiTopLevel_t uiTopLevel;
+
+
+int UiDisplayFileSelection(callback)
+void (*callback) (char *topaddress, HText_t * htext, HTextObject_t * htextobject,
+ void *parameter);
+{
+ uiFileSelectionGfx_t *fsgfx = &uiTopLevel.FSGfx;
+
+ if (fsgfx->FormWdg) {
+ XtMapWidget(XtParent(fsgfx->FormWdg));
+
+ return UI_OK;
+ }
+ fsgfx->FormWdg = uicreatefsformdialog();
+ fsgfx->FSBoxWdg = uicreatefsfsbox(fsgfx->FormWdg, callback);
+
+ XtManageChild(fsgfx->FormWdg);
+ XtRealizeWidget(XtParent(fsgfx->FormWdg));
+
+ return UI_OK;
+}
+
+
+static Widget
+ uicreatefsformdialog()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("FileSelection",
+ topLevelShellWidgetClass,
+ NULL, 0);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "FileSelection",
+ args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreatefsfsbox(formwdg, callback)
+Widget formwdg;
+void (*callback) (char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget fsboxwdg, textwdg, okwdg, cancelwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, 1,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, 1,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, 1,
+ XmNbottomOffset, 1,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ fsboxwdg = XmCreateFileSelectionBox(formwdg, "FSBox",
+ args, nargs);
+ XtUnmanageChild(XmFileSelectionBoxGetChild(fsboxwdg,
+ XmDIALOG_HELP_BUTTON));
+
+ textwdg = XmFileSelectionBoxGetChild(fsboxwdg, XmDIALOG_TEXT);
+ XmTextSetString(textwdg, "");
+
+ okwdg = XmFileSelectionBoxGetChild(fsboxwdg, XmDIALOG_OK_BUTTON);
+ XtAddCallback(okwdg, XmNactivateCallback, uifileselectionokcb,
+ (caddr_t) callback);
+
+ cancelwdg = XmFileSelectionBoxGetChild(fsboxwdg, XmDIALOG_CANCEL_BUTTON);
+ XtAddCallback(cancelwdg, XmNactivateCallback, uifileselectioncancelcb,
+ (caddr_t) NULL);
+ XtManageChild(fsboxwdg);
+
+ return fsboxwdg;
+}
+
+
+static void uifileselectionokcb(wdg, callback, calldata)
+Widget wdg;
+caddr_t callback;
+XmPushButtonCallbackStruct *calldata;
+{
+ Widget textwdg;
+ char *selection;
+
+ textwdg = XmFileSelectionBoxGetChild(uiTopLevel.FSGfx.FSBoxWdg,
+ XmDIALOG_TEXT);
+ selection = XmTextGetString(textwdg);
+ XtUnmapWidget(XtParent(uiTopLevel.FSGfx.FormWdg));
+ (*(void (*) (char *, HText_t *, HTextObject_t *, void *)) callback)
+ (uiPageInfo.CurrentPage->Hierarchy->Address,
+ uiPageInfo.CurrentPage->HText, uiPageInfo.CurrentPage->HTextObject,
+ (void *) selection);
+
+ XtFree(selection);
+}
+
+
+static void uifileselectioncancelcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmPushButtonCallbackStruct *calldata;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.FSGfx.FormWdg));
+}
+
+
+static void uifileselectionclickcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ Widget textwdg;
+ char *selection;
+
+ XmStringGetLtoR(calldata->item, XmSTRING_DEFAULT_CHARSET, &selection);
+ textwdg = XmFileSelectionBoxGetChild(uiTopLevel.FSGfx.FSBoxWdg,
+ XmDIALOG_TEXT);
+ XmTextSetString(textwdg, selection);
+ XtFree(selection);
+}
--- /dev/null
+/* $Id: UiIncludes.h,v 1.3 1992/03/26 18:13:50 kny Exp kny $ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <varargs.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include <Xm/Xm.h>
+#include <Xm/ArrowBG.h>
+#include <Xm/CascadeBG.h>
+#include <Xm/DrawingA.h>
+#include <Xm/FileSB.h>
+#include <Xm/Form.h>
+#include <Xm/Frame.h>
+#include <Xm/LabelG.h>
+#include <Xm/List.h>
+#include <Xm/MenuShell.h>
+#include <Xm/MessageB.h>
+#include <Xm/PushBG.h>
+#include <Xm/RowColumn.h>
+#include <Xm/ScrollBar.h>
+#include <Xm/ScrolledW.h>
+#include <Xm/SeparatoG.h>
+#include <Xm/Text.h>
+#include <Xm/ToggleBG.h>
+
+#include "HTAnchor.h"
+#include "HTStyle.h"
+#include "HText.h"
+
+#include "Xl.h"
+#include "Ui.h"
+#include "UiDefs.h"
+#include "UiTypes.h"
+#include "UiProtos.h"
--- /dev/null
+static char *rcsid = "$Id: UiInfo.c,v 1.1 1992/03/26 18:13:50 kny Exp kny $";
+
+
+#include "UiIncludes.h"
+
+#define logo_width 90
+#define logo_height 90
+static char logo_bits[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0xd8, 0xcf, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0xc0, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x7f, 0x00, 0x2e, 0x0f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd8, 0x4f, 0x01, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xe7, 0xa0, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x31, 0x00, 0xc4, 0xef, 0xff, 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe0, 0x00, 0x00, 0x84, 0xef, 0xff, 0x0f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x00, 0x00, 0x0c, 0xce, 0xff, 0x3f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x1f, 0x00, 0x00, 0xf4, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,
+ 0x00, 0x80, 0x13, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00,
+ 0x00, 0xe0, 0x09, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
+ 0x00, 0xe0, 0x00, 0x00, 0x00, 0xfa, 0xed, 0xff, 0xff, 0x1f, 0x00, 0x00,
+ 0x00, 0x38, 0x00, 0x00, 0x80, 0x3f, 0x9c, 0xff, 0xff, 0x3f, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x00, 0x80, 0x5f, 0x62, 0xff, 0xff, 0x7f, 0x00, 0x00,
+ 0x00, 0x0c, 0x00, 0x00, 0x80, 0x1f, 0x40, 0xf6, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0xaf, 0x36, 0xe8, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0xfa, 0x0f, 0x14, 0xfd, 0xff, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x03, 0x00,
+ 0x80, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x3f, 0x0c, 0xfc, 0xff, 0x07, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xfd, 0xff, 0xff, 0x07, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0xf2, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0f, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xef, 0x1f, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xef, 0x9f, 0x1f, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x38, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x38, 0x00,
+ 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x71, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x61, 0x00,
+ 0x5a, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0x61, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xc0, 0x00,
+ 0x41, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xc0, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x80, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0x07, 0xff, 0x81, 0x80, 0x08, 0x08, 0x02, 0xff, 0xc1, 0xff, 0x00,
+ 0xff, 0x8f, 0xff, 0xc3, 0xc1, 0x1d, 0x1c, 0x87, 0xff, 0xe3, 0xff, 0x01,
+ 0xff, 0x87, 0xff, 0xc7, 0xc1, 0x1d, 0x1c, 0xc7, 0xff, 0xe1, 0xff, 0x00,
+ 0x07, 0x80, 0x03, 0x87, 0x83, 0x0f, 0x0e, 0xc7, 0x01, 0xe0, 0x00, 0x00,
+ 0x07, 0x80, 0x03, 0x87, 0x83, 0x0f, 0x0e, 0xc7, 0x01, 0xe0, 0x00, 0x00,
+ 0x07, 0x80, 0x03, 0x87, 0x83, 0x0f, 0x0e, 0xc7, 0x01, 0xe0, 0x00, 0x00,
+ 0x07, 0x80, 0x03, 0x07, 0x07, 0x07, 0x07, 0xc7, 0x01, 0xe0, 0x00, 0x00,
+ 0x7f, 0x80, 0xff, 0x07, 0x07, 0x07, 0x07, 0xc7, 0xff, 0xe0, 0x1f, 0x00,
+ 0xff, 0x80, 0xff, 0x03, 0x07, 0x07, 0x07, 0x87, 0xff, 0xe1, 0x1f, 0x00,
+ 0x7f, 0x80, 0xff, 0x01, 0x8e, 0x8f, 0x03, 0x07, 0xff, 0xe3, 0x1f, 0x00,
+ 0x07, 0x80, 0xc3, 0x01, 0x8e, 0x8f, 0x03, 0x07, 0x80, 0xe3, 0x00, 0x00,
+ 0x07, 0x80, 0xc3, 0x01, 0x8e, 0x8f, 0x03, 0x07, 0x80, 0xe3, 0x00, 0x00,
+ 0x07, 0x80, 0x83, 0x03, 0xdc, 0xdd, 0x01, 0x07, 0x80, 0xe3, 0x00, 0x00,
+ 0x07, 0x80, 0x83, 0x03, 0xdc, 0xdd, 0x01, 0x07, 0x80, 0xe3, 0x00, 0x00,
+ 0xff, 0x87, 0x03, 0x07, 0xf8, 0xf8, 0x00, 0x87, 0xff, 0xe3, 0xff, 0x00,
+ 0xff, 0x8f, 0x03, 0x07, 0xf8, 0xf8, 0x00, 0xc7, 0xff, 0xe1, 0xff, 0x01,
+ 0xfe, 0x07, 0x01, 0x02, 0x70, 0x70, 0x00, 0x82, 0xff, 0xc0, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfd, 0xff, 0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x03, 0x00, 0x01,
+ 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x41, 0x00, 0x01,
+ 0xfa, 0xff, 0x01, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x23, 0x00, 0x01,
+ 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x31, 0x80, 0x00,
+ 0xf2, 0xff, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x39, 0x80, 0x00,
+ 0xf4, 0xff, 0x03, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0x3c, 0x80, 0x00,
+ 0xe4, 0xff, 0x03, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x3f, 0x1c, 0x40, 0x00,
+ 0xe4, 0xff, 0x01, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x1f, 0x0c, 0x40, 0x00,
+ 0xe8, 0xff, 0x03, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x0e, 0x40, 0x00,
+ 0xc8, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x06, 0x20, 0x00,
+ 0xc8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x0f, 0x06, 0x20, 0x00,
+ 0xd0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x07, 0x00, 0x10, 0x00,
+ 0x90, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x07, 0x00, 0x10, 0x00,
+ 0xa0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x08, 0x00,
+ 0x20, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x08, 0x00,
+ 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x04, 0x00,
+ 0x80, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x04, 0x00,
+ 0x80, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x09, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x88, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xa0, 0x7f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xc0, 0x03, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xdc, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+
+Widget uicreateinfoform();
+Widget uicreateinfook(Widget parent);
+void uicreateinfolabels(Widget parent, Widget bottomwdg);
+static void uiinfookcb(char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+
+
+int UiDisplayInfo()
+{
+ uiInfoGfx_t *infogfx = &uiTopLevel.InfoGfx;
+
+ if (infogfx->FormWdg) {
+ XtMapWidget(XtParent(infogfx->FormWdg));
+
+ return UI_OK;
+ }
+ infogfx->FormWdg = uicreateinfoform();
+ infogfx->OkWdg = uicreateinfook(infogfx->FormWdg);
+ uicreateinfolabels(infogfx->FormWdg, infogfx->OkWdg);
+
+ XtManageChild(infogfx->FormWdg);
+ XtRealizeWidget(XtParent(infogfx->FormWdg));
+
+ return UI_OK;
+}
+
+
+static Widget
+ uicreateinfoform()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("Info",
+ topLevelShellWidgetClass,
+ NULL, 0);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "InfoDialog",
+ args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreateinfook(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget okwdg;
+ static uiActionData_t actiondata;
+
+ args = uiVaSetArgs(&nargs,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_INFO_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_INFO_WDG_OFFSET, NULL);
+ okwdg = XmCreatePushButtonGadget(formwdg, " Ok ", args, nargs);
+ actiondata.ActionName = "InfoOk";
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(okwdg, XmNactivateCallback, uiinfookcb, (caddr_t) NULL);
+ XtManageChild(okwdg);
+
+ return okwdg;
+}
+
+
+void uicreateinfolabels(formwdg, bottomwdg)
+Widget formwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ Pixmap logo_pixmap;
+ Widget wdg;
+ Display *dpy;
+ Widget label1wdg;
+ Widget label2wdg;
+ Widget label3wdg;
+
+ wdg = uiTopLevel.TopGfx.TopWdg;
+ dpy = XtDisplay(wdg);
+
+ logo_pixmap =
+ XCreatePixmapFromBitmapData(dpy, XtWindow(wdg), logo_bits,
+ logo_height, logo_width,
+ BlackPixel(dpy, DefaultScreen(dpy)),
+ uiGetArg(wdg, XmNbackground),
+ DefaultDepth(dpy, DefaultScreen(dpy)));
+
+ if (logo_pixmap == NULL) {
+ printf("Pixmap creation failed\n");
+ exit(1);
+ }
+ args = uiVaSetArgs(&nargs,
+ XmNlabelType, XmPIXMAP,
+ XmNlabelPixmap, logo_pixmap,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_INFO_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_INFO_WDG_OFFSET, NULL);
+ label1wdg = XmCreateLabelGadget(formwdg, "InfoLabel1", args, nargs);
+ XtManageChild(label1wdg);
+
+ labelstr = XmStringCreateLtoR("WorldWideWeb \n browser \n for the X Window System \n \n Version 1.0 Alpha", XmSTRING_DEFAULT_CHARSET);
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_INFO_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, label1wdg,
+ XmNrightOffset, UI_INFO_WDG_OFFSET, NULL);
+ label2wdg = XmCreateLabelGadget(formwdg, "InfoLabel2", args, nargs);
+ XtManageChild(label2wdg);
+ XmStringFree(labelstr);
+
+ labelstr = XmStringCreateLtoR("Authors: \n Kim Nyberg, Teemu Rantanen, \n Kati Suominen, Kari Syd{nmaanlakka\n\nE-mail: erwise@cs.hut.fi", XmSTRING_DEFAULT_CHARSET);
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, label1wdg,
+ XmNtopOffset, UI_INFO_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_INFO_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_INFO_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_INFO_WDG_OFFSET, NULL);
+ label3wdg = XmCreateLabelGadget(formwdg, "InfoLabel3", args, nargs);
+ XtManageChild(label3wdg);
+ XmStringFree(labelstr);
+}
+
+
+static void uiinfookcb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.InfoGfx.FormWdg));
+}
--- /dev/null
+static char *rcsid = "$Id: UiInit.c,v 1.3 1992/03/26 18:13:50 kny Exp kny $";
+
+#include "UiIncludes.h"
+
+
+static void uisetupdefaults(int argc, char *argv[],
+ void *(*configpf) (void *table, char *item));
+static Widget uicreatebutton(Widget parentwdg, char *name, int leftpos,
+ int rightpos);
+
+static void uitopactivatecb(Widget wdg, caddr_t actionname,
+ XmPushButtonCallbackStruct * calldata);
+
+
+uiTopLevel_t uiTopLevel;
+Cursor uiBusyCursor, uiArrowCursor;
+void *(*uiConfigPF) (void *table, char *item);
+void *(*uiConfigSetPF) (void *table, char *item, void *value);
+
+
+int UiInitialize(argc, argv, configpf, configsetpf)
+int argc;
+char *argv[];
+void *(*configpf) (void *table, char *item);
+void *(*configsetpf) (void *table, char *item, void *value);
+{
+ uiTopLevelGfx_t *topgfx = &uiTopLevel.TopGfx;
+
+ uiConfigPF = configpf;
+ uiConfigSetPF = configsetpf;
+
+ topgfx->TopWdg = XtInitialize(argv[0], "Erwise", NULL, 0, &argc, argv);
+ topgfx->FormWdg = XmCreateForm(topgfx->TopWdg, "Form",
+ (ArgList) NULL, 0);
+ XtVaSetValues(topgfx->FormWdg,
+ XmNwidth, 280,
+ XmNheight, 70, NULL);
+ topgfx->InfoWdg = uicreatebutton(topgfx->FormWdg, "Info", 0, 25);
+ topgfx->OpenWdg = uicreatebutton(topgfx->FormWdg, "Open", 25, 50);
+ topgfx->QuitWdg = uicreatebutton(topgfx->FormWdg, "Quit", 50, 75);
+ topgfx->HelpWdg = uicreatebutton(topgfx->FormWdg, "Help", 75, 100);
+
+ XtManageChild(topgfx->FormWdg);
+ XtRealizeWidget(topgfx->TopWdg);
+
+ XlSetupResources(configpf);
+
+ uisetupdefaults(argc, argv, configpf);
+
+ uiBusyCursor = XCreateFontCursor(XtDisplay(topgfx->TopWdg), XC_watch);
+ uiArrowCursor = XCreateFontCursor(XtDisplay(topgfx->TopWdg),
+ XC_right_ptr);
+
+ return UI_OK;
+}
+
+
+void UiMainLoop()
+{
+ XtMainLoop();
+}
+
+
+int PlaceValue(value)
+char *value;
+{
+ if (value && !strncasecmp(value, "mouse", strlen("mouse")))
+ return TRUE;
+ return FALSE;
+}
+
+
+static void uisetupdefaults(argc, argv, configpf)
+int argc;
+char *argv[];
+void *(*configpf) (void *table, char *item);
+{
+ uiGlobalSettings_t *gs = &uiTopLevel.GlobalSettings;
+ void *table;
+
+ if (table = configpf((void *) NULL, C_GLOBALSETTINGS)) {
+ gs->TopMargin = atoi((char *) configpf(table, C_TOPMARGIN));
+ gs->BottomMargin = atoi((char *) configpf(table, C_BOTTOMMARGIN));
+ gs->LeftMargin = atoi((char *) configpf(table, C_LEFTMARGIN));
+ gs->RightMargin = atoi((char *) configpf(table, C_RIGHTMARGIN));
+ gs->UseFixed = TruthValue((char *) configpf(table, C_FIXEDWIDTHMODE));
+ gs->FixedWidth = atoi((char *) configpf(table, C_FIXEDWIDTH));
+ gs->OnePageMode = TruthValue((char *) configpf(table, C_ONEPAGEMODE));
+ gs->Width = atoi((char *) configpf(table, C_WIDTH));
+ gs->Height = atoi((char *) configpf(table, C_HEIGHT));
+ gs->DoubleClickTime =
+ (Time) atoi((char *) configpf(table, C_DOUBLECLICKTIME));
+ gs->SearchPlacement = PlaceValue((char *) configpf(table, C_SEARCH));
+ gs->ControlPanelPlacement =
+ PlaceValue((char *) configpf(table, C_CONTROLPANEL));
+ gs->ListPlacement =
+ PlaceValue((char *) configpf(table, C_LIST));
+ gs->RecallPlacement =
+ PlaceValue((char *) configpf(table, C_RECALL));
+ gs->PageSettingsPlacement =
+ PlaceValue((char *) configpf(table, C_PAGESETTINGS));
+ } else
+ uiDisplayWarning("failed to get configurations for global settings");
+
+ if (table = configpf((void *) NULL, C_DEFAULTS))
+ uiSelectionArray = (char **) configpf(table, C_DEFAULTSTABLE);
+ else
+ uiDisplayWarning("failed to get configurations for selection");
+
+ uiPageAttachCallbacks();
+ uiPageDefineKeys();
+}
+
+
+static Widget
+ uicreatebutton(parentwdg, name, leftpos, rightpos)
+Widget parentwdg;
+char *name;
+int leftpos;
+int rightpos;
+{
+ Widget tmpwdg;
+
+ tmpwdg = XmCreatePushButtonGadget(parentwdg, name,
+ (ArgList) NULL, 0);
+ XtVaSetValues(tmpwdg,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, leftpos,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, rightpos, NULL);
+ XtAddCallback(tmpwdg, XmNactivateCallback, uitopactivatecb,
+ (caddr_t) name);
+ XtManageChild(tmpwdg);
+
+ return tmpwdg;
+}
+
+
+static void uitopactivatecb(wdg, actionname, calldata)
+Widget wdg;
+caddr_t actionname;
+XmPushButtonCallbackStruct *calldata;
+{
+ uiAction_t *tmpaction;
+
+ if (tmpaction = uiFindAction((char *) actionname))
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) (actionname);
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else
+ (*tmpaction->Callback) ((char *) NULL, (HText_t *) NULL,
+ (HTextObject_t *) NULL,
+ tmpaction->Parameter);
+}
--- /dev/null
+static char *rcsid = "$Id: UiList.c,v 1.1 1992/03/26 18:13:50 kny Exp kny $";
+
+
+#include "UiIncludes.h"
+
+
+static void uilistfreeprevious(void);
+static void uilistsetitems(char **listitems, int nitems);
+
+static Widget uicreatelistform(void);
+static Widget uicreatelistlabel(Widget parent);
+static Widget uicreatelistopen(Widget parent);
+static Widget uicreatelistclose(Widget parent);
+static Widget uicreatelistseparator(Widget parent, Widget bottomwdg);
+static Widget uicreatelistlist(Widget parent, Widget topwdg, Widget bottomwdg);
+static void uilistopencb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+static void uilistclosecb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+
+
+static uiPage_t *uilistpage = (uiPage_t *) NULL;
+static char **uilistitems;
+static char **uiaddresses;
+static int uinitems;
+static void (*uilistcallback) (char *topaddress, char *address,
+ char *parentaddress);
+
+
+int UiDisplayListDialog(listitems, addresses, nitems, callback)
+char **listitems;
+char **addresses;
+int nitems;
+void (*callback) (char *topaddress, char *address, char *parentaddress);
+{
+ uiListGfx_t *listgfx = &uiTopLevel.ListGfx;
+
+ uilistfreeprevious();
+
+ uilistpage = uiPageInfo.CurrentPage;
+ uilistitems = listitems;
+ uiaddresses = addresses;
+ uinitems = nitems;
+ uilistcallback = callback;
+
+ if (listgfx->FormWdg) {
+ XtMapWidget(XtParent(listgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(listgfx->FormWdg),
+ uiTopLevel.GlobalSettings.ListPlacement);
+
+ uilistsetitems(listitems, nitems);
+
+ return UI_OK;
+ }
+ listgfx->FormWdg = uicreatelistform();
+ listgfx->LabelWdg = uicreatelistlabel(listgfx->FormWdg);
+ listgfx->OpenWdg = uicreatelistopen(listgfx->FormWdg);
+ listgfx->CloseWdg = uicreatelistclose(listgfx->FormWdg);
+ listgfx->SeparatorWdg = uicreatelistseparator(listgfx->FormWdg,
+ listgfx->OpenWdg);
+ listgfx->ListWdg = uicreatelistlist(listgfx->FormWdg, listgfx->LabelWdg,
+ listgfx->SeparatorWdg);
+
+ uilistsetitems(listitems, nitems);
+
+ XtManageChild(listgfx->FormWdg);
+ XtRealizeWidget(XtParent(listgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(listgfx->FormWdg),
+ uiTopLevel.GlobalSettings.ListPlacement);
+
+ return UI_OK;
+}
+
+
+void uiListUpdateDialog(page)
+uiPage_t *page;
+{
+ if (uiTopLevel.ListGfx.FormWdg && (page == uilistpage)) {
+ uilistfreeprevious();
+ uilistsetitems((char **) NULL, 0);
+ uilistpage = (uiPage_t *) NULL;
+ XtUnmapWidget(XtParent(uiTopLevel.ListGfx.FormWdg));
+ }
+}
+
+
+static Widget
+ uicreatelistform()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("List",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_LIST_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "ListDialog", args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreatelistlabel(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ Widget labelwdg;
+
+ labelstr = XmStringCreateSimple("List of references");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "ListLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ return labelwdg;
+}
+
+
+static Widget
+ uicreatelistopen(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget openwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 40,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET, NULL);
+ openwdg = XmCreatePushButtonGadget(formwdg, "Open", args, nargs);
+ XtAddCallback(openwdg, XmNactivateCallback,
+ (XtCallbackProc) uilistopencb, (caddr_t) NULL);
+ XtManageChild(openwdg);
+
+ return openwdg;
+}
+
+
+static Widget
+ uicreatelistclose(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget closewdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 60,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET, NULL);
+ closewdg = XmCreatePushButtonGadget(formwdg, "Close", args, nargs);
+ XtAddCallback(closewdg, XmNactivateCallback,
+ (XtCallbackProc) uilistclosecb, (caddr_t) NULL);
+ XtManageChild(closewdg);
+
+ return closewdg;
+}
+
+
+static Widget
+ uicreatelistseparator(formwdg, bottomwdg)
+Widget formwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(formwdg, "ListSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ return separatorwdg;
+}
+
+
+static Widget
+ uicreatelistlist(formwdg, topwdg, bottomwdg)
+Widget formwdg;
+Widget topwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget listwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNvisibleItemCount, 15,
+ XmNwidth, 300,
+ XmNselectionPolicy, XmSINGLE_SELECT,
+ XmNlistSizePolicy, XmCONSTANT,
+ XmNscrollBarDisplayPolicy, XmSTATIC,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_LIST_WDG_OFFSET, NULL);
+ listwdg = XmCreateScrolledList(formwdg, "ListList", args, nargs);
+ XtManageChild(listwdg);
+ XtAddCallback(listwdg, XmNdefaultActionCallback,
+ (XtCallbackProc) uilistopencb, (caddr_t) NULL);
+
+ return listwdg;
+}
+
+
+void uilistfreeprevious()
+{
+ if (uilistpage && uinitems) {
+ uiFree((void *) uiaddresses);
+
+ while (uinitems--)
+ uiFree(uilistitems[uinitems]);
+
+ uiFree(uilistitems);
+ }
+}
+
+
+static void uilistsetitems(listitems, nitems)
+char **listitems;
+int nitems;
+{
+ Widget listwdg = uiTopLevel.ListGfx.ListWdg;
+ int i;
+ XmString *tmpstr = uiMalloc(nitems * sizeof(XmString));
+
+ XmListDeleteAllItems(listwdg);
+ if (nitems) {
+ for (i = 0; i < nitems; i++)
+ tmpstr[i] = XmStringCreateSimple(listitems[i]);
+
+ XmListAddItems(listwdg, tmpstr, nitems, 0);
+ for (i = 0; i < nitems; i++)
+ XmStringFree(tmpstr[i]);
+ uiFree((void *) tmpstr);
+ }
+}
+
+
+static void uilistopencb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ Widget listwdg = uiTopLevel.ListGfx.ListWdg;
+ int *poslist;
+ int poscount;
+ char *parentaddress;
+
+ if (uinitems)
+ if (XmListGetSelectedPos(listwdg, &poslist, &poscount)) {
+ uiDefineCursor(uiBusyCursor);
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) ("Get page");
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else {
+ parentaddress =
+ HTAnchor_address((HTAnchor *)
+ uilistpage->HText->node_anchor);
+ (*uilistcallback) (uiaddresses[poslist[0] - 1],
+ uilistpage->Hierarchy->Address,
+ parentaddress);
+ }
+
+ uiUndefineCursor();
+
+ XtFree(poslist);
+ }
+}
+
+
+static void uilistclosecb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.ListGfx.FormWdg));
+}
--- /dev/null
+static char *rcsid = "$Id: UiMisc.c,v 1.3 1992/03/26 18:13:50 kny Exp kny $";
+
+#include "UiIncludes.h"
+
+
+static void uitimeouthandler(XtPointer data, XtIntervalId * id);
+static void uifdinputhandler(XtPointer data, int *fd, XtInputId * id);
+static void uipopupcb(Widget wdg, char *address,
+ XmAnyCallbackStruct * calldata);
+
+
+void (*uiHelpOnActionCB) (char *actionstring) =
+ (
+ void (*) (char *actionstring)) NULL;
+
+static void (*uitimeoutcallback) (void *data);
+static void (*uifdinputcallback) (void *data);
+
+static XtInputId uiinputid;
+static void (*uipopupcallback) (char *address, char *topaddress,
+ char *parentaddress);
+static char *uipopuptopaddress;
+
+
+int UiAttachCallback(actionname, callback, parameter)
+char *actionname;
+void (*callback) (char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+void *parameter;
+{
+ uiAction_t *tmpaction;
+
+ if (!(tmpaction = uiFindAction(actionname))) {
+ tmpaction = uiTopLevel.Actions;
+ if (!tmpaction)
+ tmpaction =
+ uiTopLevel.Actions =
+ (uiAction_t *) uiMalloc(sizeof(*tmpaction));
+ else {
+ while (tmpaction->Next)
+ tmpaction = tmpaction->Next;
+ tmpaction =
+ tmpaction->Next = (uiAction_t *) uiMalloc(sizeof(*tmpaction));
+ }
+ tmpaction->Name = strdup(actionname);
+ tmpaction->Next = (uiAction_t *) NULL;
+ }
+ tmpaction->Callback = callback;
+ tmpaction->Parameter = parameter;
+
+ return UI_OK;
+}
+
+
+int UiBindKey(keyname, modifier, callback, parameter)
+char *keyname;
+int modifier;
+void (*callback) (char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+void *parameter;
+{
+ uiKey_t *tmpkey;
+
+ if (!(tmpkey = uiFindKey(keyname, modifier))) {
+ tmpkey = uiTopLevel.Keys;
+ if (!tmpkey)
+ tmpkey =
+ uiTopLevel.Keys =
+ (uiKey_t *) uiMalloc(sizeof(*tmpkey));
+ else {
+ while (tmpkey->Next)
+ tmpkey = tmpkey->Next;
+ tmpkey =
+ tmpkey->Next = (uiKey_t *) uiMalloc(sizeof(*tmpkey));
+ }
+ tmpkey->Name = strdup(keyname);
+ tmpkey->Next = (uiKey_t *) NULL;
+ }
+ tmpkey->Modifier = modifier;
+ tmpkey->Callback = callback;
+ tmpkey->Parameter = parameter;
+
+ return UI_OK;
+}
+
+
+int UiBindVariable(varname, variable, type)
+char *varname;
+void *variable;
+uiVarType_t type;
+{
+ uiVariable_t *tmpvar;
+
+ if (!(tmpvar = uiFindVariable(varname))) {
+ tmpvar = uiTopLevel.Variables;
+ if (!tmpvar)
+ tmpvar =
+ uiTopLevel.Variables =
+ (uiVariable_t *) uiMalloc(sizeof(*tmpvar));
+ else {
+ while (tmpvar->Next)
+ tmpvar = tmpvar->Next;
+ tmpvar =
+ tmpvar->Next = (uiVariable_t *) uiMalloc(sizeof(*tmpvar));
+ }
+ tmpvar->Name = strdup(varname);
+ tmpvar->Next = (uiVariable_t *) NULL;
+ }
+ tmpvar->Value = variable;
+ tmpvar->VarType = type;
+
+ return UI_OK;
+}
+
+
+int UiUpdateVariable(varname)
+char *varname;
+{
+ uiVariable_t *tmpvar;
+ char *tmpstr;
+ static char staticstr[100]; /* Is this overkill? */
+
+ tmpstr = staticstr;
+ if (tmpvar = uiFindVariable(varname)) {
+ switch (tmpvar->WdgType) {
+ case uiWTtext:
+ switch (tmpvar->VarType) {
+ case uiVTint:
+ sprintf(staticstr, "%d", *(int *) tmpvar->Value);
+ break;
+ case uiVTdouble:
+ sprintf(staticstr, "%d", *(int *) tmpvar->Value);
+ break;
+ case uiVTstring:
+ tmpstr = (char *) tmpvar->Value;
+ }
+ XmTextSetString(tmpvar->Wdg, tmpstr);
+ break;
+ case uiWToptionmenu:
+ /* Not implemented yet */
+ break;
+ case uiWTradiobox:
+ /* Not implemented yet */
+ break;
+ case uiWTcheckbutton:
+ XtVaSetValues(tmpvar->Wdg,
+ XmNset, (*(int *) tmpvar->Value != 0), NULL);
+ break;
+ case uiWTscale:
+ /* Not implemented yet */
+ break;
+ }
+ return UI_OK;
+ }
+ return UI_NOTFOUND;
+}
+
+
+void UiGetNextAction(helponactioncb)
+void (*helponactioncb) (char *actionstring);
+{
+ uiHelpOnActionCB = helponactioncb;
+}
+
+
+int UiAddTimeOut(timeout, callback, data)
+int timeout;
+void (*callback) (void *data);
+void *data;
+{
+ uitimeoutcallback = callback;
+
+ return (int) XtAddTimeOut(timeout, uitimeouthandler, (caddr_t) data);
+}
+
+
+void UiDeleteTimeOut(timeoutid)
+int timeoutid;
+{
+ XtRemoveTimeOut((XtIntervalId) timeoutid);
+}
+
+
+int UiAddInputFD(fd, callback, data)
+int fd;
+void (*callback) (void *data);
+void *data;
+{
+ uifdinputcallback = callback;
+
+ return (int) XtAddInput(fd, XtInputReadMask | XtInputExceptMask,
+ uifdinputhandler, (caddr_t) data);
+}
+
+
+void UiDeleteInputFD(inputid)
+int inputid;
+{
+ XtRemoveInput((XtInputId) inputid);
+}
+
+
+void UiAddStringToCutBuffer(data)
+char *data;
+{
+ static char *cutbuffer = (char *) NULL;
+ int oldlen;
+
+ if (data) {
+ oldlen = cutbuffer ? strlen(cutbuffer) : 0;
+
+ cutbuffer = (char *) uiReAlloc((void *) cutbuffer,
+ oldlen + strlen(data) + 1);
+ strcpy(&cutbuffer[oldlen], data);
+ } else if (cutbuffer) {
+ XStoreBytes(XtDisplay(uiTopLevel.TopGfx.TopWdg), cutbuffer,
+ strlen(cutbuffer));
+ uiFree(cutbuffer);
+ cutbuffer = (char *) NULL;
+ } else
+ XStoreBytes(XtDisplay(uiTopLevel.TopGfx.TopWdg), "", 0);
+}
+
+
+void UiDisplayPopup(callback, topaddress, items, nitems)
+void (*callback) (char *address, char *topaddress, char *parentaddress);
+char *topaddress;
+char **items;
+int nitems;
+{
+ Widget topwdg = uiPageInfo.CurrentPage->Gfx.TopWdg;
+ ArgList args;
+ Cardinal nargs;
+ Widget pmwdg, rcwdg, buttonwdg;
+ Window root, child;
+ int root_x, root_y, win_x, win_y;
+ unsigned int mask;
+
+ uipopupcallback = callback;
+ uipopuptopaddress = topaddress;
+
+ if (XQueryPointer(XtDisplay(topwdg), XtWindow(topwdg), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &mask)) {
+ args = uiVaSetArgs(&nargs,
+ XmNborderWidth, 0,
+ XmNwidth, 100,
+ XmNheight, 100, NULL);
+ pmwdg = XmCreateMenuShell(topwdg, "popupmenu", args, nargs);
+
+ args = uiVaSetArgs(&nargs,
+ XmNx, (Position) (root_x - 20),
+ XmNy, (Position) (root_y - 5),
+ XmNspacing, 0,
+ XmNmarginWidth, 0,
+ XmNmarginHeight, 0, NULL);
+ rcwdg = XmCreateRowColumn(pmwdg, "rowcol", args, nargs);
+ while (nitems--) {
+ args = uiVaSetArgs(&nargs,
+ XmNhighlightThickness, 0, NULL);
+ buttonwdg = XmCreatePushButtonGadget(rcwdg, items[nitems],
+ args, nargs);
+ XtAddCallback(buttonwdg, XmNactivateCallback,
+ (XtCallbackProc) uipopupcb, (caddr_t) items[nitems]);
+ XtManageChild(buttonwdg);
+ }
+
+ XtManageChild(rcwdg);
+ XtRealizeWidget(pmwdg);
+ XtMapWidget(pmwdg);
+
+ XGrabPointer(XtDisplay(pmwdg), XtWindow(pmwdg), TRUE, 0,
+ GrabModeAsync, GrabModeAsync, XtWindow(pmwdg),
+ uiArrowCursor, CurrentTime);
+
+ XFlush(XtDisplay(pmwdg));
+ }
+}
+
+
+uiAction_t *
+ uiFindAction(actionname)
+char *actionname;
+{
+ uiAction_t *tmpaction = uiTopLevel.Actions;
+
+ while (tmpaction) {
+ if (!strcmp(actionname, tmpaction->Name))
+ return tmpaction;
+
+ tmpaction = tmpaction->Next;
+ }
+
+ return (uiAction_t *) NULL;
+}
+
+
+uiKey_t *
+ uiFindKey(keyname, modifier)
+char *keyname;
+int modifier;
+{
+ uiKey_t *tmpkey = uiTopLevel.Keys;
+
+ while (tmpkey) {
+ if (!strcmp(keyname, tmpkey->Name) && modifier == tmpkey->Modifier)
+ return tmpkey;
+
+ tmpkey = tmpkey->Next;
+ }
+
+ return (uiKey_t *) NULL;
+}
+
+
+uiVariable_t *
+ uiFindVariable(varname)
+char *varname;
+{
+ uiVariable_t *tmpvar = uiTopLevel.Variables;
+
+ while (tmpvar) {
+ if (!strcmp(varname, tmpvar->Name))
+ return tmpvar;
+
+ tmpvar = tmpvar->Next;
+ }
+
+ return (uiVariable_t *) NULL;
+}
+
+
+int uiAddWidgetInfo(varname, wdg, wdgtype)
+char *varname;
+Widget wdg;
+uiWdgType_t wdgtype;
+{
+ uiVariable_t *tmpvar;
+
+ if (tmpvar = uiFindVariable(varname)) {
+ tmpvar->Wdg = wdg;
+ tmpvar->WdgType = wdgtype;
+
+ return UI_OK;
+ }
+ return UI_NOTFOUND;
+}
+
+
+void uiDialogActivateCB(wdg, actiondata, calldata)
+Widget wdg;
+uiActionData_t *actiondata;
+XmAnyCallbackStruct *calldata;
+{
+ uiAction_t *tmpaction;
+
+ actiondata->Page = uiPageInfo.CurrentPage;
+ uiPageInfo.Wdg = wdg;
+ uiPageInfo.CallData = (void *) calldata;
+
+ if (tmpaction = uiFindAction(actiondata->ActionName)) {
+ uiDefineCursor(uiBusyCursor);
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) (actiondata->ActionName);
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else
+ (*tmpaction->Callback) (actiondata->Page->Hierarchy->Address,
+ actiondata->Page->HText,
+ actiondata->Page->HTextObject,
+ tmpaction->Parameter);
+ uiUndefineCursor();
+ }
+}
+
+
+void uiDialogVariableCB(wdg, varname, calldata)
+Widget wdg;
+caddr_t varname;
+XmAnyCallbackStruct *calldata;
+{
+ uiVariable_t *tmpvar;
+ char *tmpstr;
+
+ if (tmpvar = uiFindVariable((char *) varname)) {
+ switch (tmpvar->WdgType) {
+ case uiWTtext:
+ tmpstr = XmTextGetString(tmpvar->Wdg);
+ switch (tmpvar->VarType) {
+ case uiVTint:
+ *(int *) tmpvar->Value = atoi(tmpstr);
+ break;
+ case uiVTdouble:
+ *(double *) tmpvar->Value = atof(tmpstr);
+ break;
+ case uiVTstring:
+ strcpy((char *) tmpvar->Value, tmpstr);
+ }
+ XtFree(tmpstr);
+ break;
+ case uiWToptionmenu:
+ /* Not implemented yet */
+ break;
+ case uiWTradiobox:
+ /* Not implemented yet */
+ break;
+ case uiWTcheckbutton:
+ *(int *) tmpvar->Value = uiGetArg(tmpvar->Wdg, XmNset);
+ break;
+ case uiWTscale:
+ /* Not implemented yet */
+ break;
+ }
+ }
+}
+
+
+void uiDefineCursor(cursor)
+Cursor cursor;
+{
+ uiHierarchy_t *tmphierarchy = uiTopLevel.Hierarchies;
+ uiPage_t *tmppage;
+
+ while (tmphierarchy) {
+ tmppage = tmphierarchy->Pages;
+ while (tmppage) {
+ if (tmppage->Visible)
+ XDefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(tmppage->Gfx.TopWdg),
+ cursor);
+ tmppage = tmppage->Next;
+ }
+ tmphierarchy = tmphierarchy->Next;
+ }
+
+ XDefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.TopGfx.TopWdg),
+ cursor);
+ if (uiTopLevel.PageSettingsGfx.FormWdg)
+ XDefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.PageSettingsGfx.FormWdg),
+ cursor);
+ if (uiTopLevel.SearchGfx.FormWdg)
+ XDefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.SearchGfx.FormWdg),
+ cursor);
+ if (uiTopLevel.ListGfx.FormWdg)
+ XDefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.ListGfx.FormWdg),
+ cursor);
+}
+
+
+void uiUndefineCursor()
+{
+ uiHierarchy_t *tmphierarchy = uiTopLevel.Hierarchies;
+ uiPage_t *tmppage;
+
+ while (tmphierarchy) {
+ tmppage = tmphierarchy->Pages;
+ while (tmppage) {
+ if (tmppage->Visible)
+ XUndefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(tmppage->Gfx.TopWdg));
+ tmppage = tmppage->Next;
+ }
+ tmphierarchy = tmphierarchy->Next;
+ }
+
+ XUndefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.TopGfx.TopWdg));
+ if (uiTopLevel.PageSettingsGfx.FormWdg)
+ XUndefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.PageSettingsGfx.FormWdg));
+ if (uiTopLevel.SearchGfx.FormWdg)
+ XUndefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.SearchGfx.FormWdg));
+ if (uiTopLevel.ListGfx.FormWdg)
+ XUndefineCursor(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.ListGfx.FormWdg));
+}
+
+
+ArgList
+uiVaSetArgs(nargs, va_alist)
+int *nargs;
+va_dcl
+{
+ static Arg args[50];
+ String tmpstr;
+ va_list pvar;
+
+ *nargs = 0;
+
+ va_start(pvar);
+ tmpstr = va_arg(pvar, String);
+ while (tmpstr) {
+ XtSetArg(args[(int) *nargs], tmpstr, va_arg(pvar, XtArgVal));
+ *nargs += 1;
+ tmpstr = va_arg(pvar, String);
+ }
+ va_end(pvar);
+
+ return args;
+}
+
+
+XtArgVal
+uiGetArg(wdg, resource)
+Widget wdg;
+String resource;
+{
+ Arg args[1];
+
+ XtSetArg(args[0], resource, (XtArgVal) 0);
+ XtGetValues(wdg, args, 1);
+
+ return args[0].value;
+}
+
+
+void *
+ uiMalloc(size)
+int size;
+{
+ void *tmpptr;
+
+ if (!(tmpptr = (void *) malloc(size))) {
+ uiDisplayFatal("No swap, buy a computer");
+ exit(1);
+ } /* Not reached */
+ return tmpptr;
+}
+
+
+void *
+ uiReAlloc(ptr, size)
+void *ptr;
+int size;
+{
+ void *tmpptr;
+
+ if (!ptr)
+ return uiMalloc(size);
+ else if (!(tmpptr = (void *) realloc((char *) ptr, size))) {
+ uiDisplayFatal("No swap, buy a computer");
+ exit(1);
+ } /* Not reached */
+ return tmpptr;
+}
+
+
+void uiFree(ptr)
+void *ptr;
+{
+ if (ptr)
+ free(ptr);
+}
+
+
+void uiDisplayWarning(text)
+char *text;
+{
+ (void) fprintf(stderr, "Ui-warning: %s\n", text);
+}
+
+
+void uiDisplayFatal(text)
+char *text;
+{
+ (void) fprintf(stderr, "Ui-fatal: %s\n", text);
+
+ abort();
+}
+
+
+void uiWidgetPlacement(wdg, placement)
+Widget wdg;
+int placement;
+{
+ Window root, child;
+ int root_x, root_y, win_x, win_y;
+ unsigned int mask;
+
+ if (placement) {
+ if (XQueryPointer(XtDisplay(wdg),
+ XtWindow(wdg), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &mask))
+ XtMoveWidget(wdg, root_x - 50, root_y - 50);
+ }
+}
+
+
+static void uitimeouthandler(data, id)
+XtPointer data;
+XtIntervalId *id;
+{
+ (*uitimeoutcallback) (data);
+}
+
+
+static void uifdinputhandler(data, fd, id)
+XtPointer data;
+int *fd;
+XtInputId *id;
+{
+ uiinputid = *id;
+
+ (*uifdinputcallback) (data);
+}
+
+
+static void uipopupcb(wdg, address, calldata)
+Widget wdg;
+char *address;
+XmAnyCallbackStruct *calldata;
+{
+ XtDestroyWidget(XtParent(XtParent(wdg)));
+
+ uipopupcallback(address, uipopuptopaddress, address);
+}
--- /dev/null
+static char *rcsid = "$Id: UiPage.c,v 1.4 1992/03/26 18:13:50 kny Exp kny $";
+
+#include "UiIncludes.h"
+
+
+static uiHierarchy_t *uifindoraddhierarchy(char *topaddress);
+static uiHierarchy_t *uifindhierarchy(char *topaddress);
+static int uideletehierarchy(uiHierarchy_t * hierarchy);
+static uiPage_t *uifindpage(HText_t * htext, uiHierarchy_t * hierarchy);
+static uiPage_t *
+ uiaddpage(HText_t * htext, HTextObject_t * htextobject,
+ uiHierarchy_t * hierarchy, uiPage_t * prevpage);
+static int uideletepage(uiPage_t * page, uiHierarchy_t * hierarchy);
+static void uideletepagecallbacks(uiPage_t * page);
+static uiPage_t *uifindshadowpage(uiHierarchy_t * hierarchy, uiPage_t * page);
+static int uicreatepagewidgets(uiPage_t * page, uiPage_t * prevpage,
+ char *title);
+static void uicreatepageform(uiPage_t * page, char *title, Widget topwdg);
+static Widget uicreatepagemenu(uiPage_t * page, Widget formwdg);
+static Widget uicreatepagemenuitem(uiPage_t * page, Widget menuwdg,
+ int itempos, int level);
+static int uifindnextitem(int itempos, int level);
+static Widget uicreatepagecontrol(uiPage_t * page, Widget formwdg, char *title);
+static void uicreatepagelabel(Widget parentwdg, char *label);
+static void uicreatepagebutton(uiPage_t * page, Widget parentwdg, char *name,
+ int leftpos, int rightpos);
+static Widget uicreatepagefind(uiPage_t * page, Widget formwdg,
+ Widget controlwdg);
+static Widget uicreatepagescroll(uiPage_t * page, Widget formwdg,
+ Widget menuwdg, Widget controlwdg);
+static void uiconnectpage(uiPage_t * page);
+static void uipageupdatescrollbars(uiPage_t * page);
+static uiActionData_t *uicreatepageactiondata(uiPage_t * page,
+ char *actionname);
+static void uisetcurrentpage(uiPage_t * page);
+static int uideletepageinternal(char *topaddress, HText_t * htext);
+
+static void uipageactivatecb(Widget wdg, uiActionData_t * actiondata,
+ XmAnyCallbackStruct * calldata);
+static void uipagekludgecb(Widget wdg, uiActionData_t * actiondata,
+ XEvent * event);
+static void uipageexposecb(Widget wdg, uiPage_t * page,
+ XmDrawingAreaCallbackStruct * calldata);
+static void uipageresizecb(Widget wdg, uiPage_t * page,
+ XmDrawingAreaCallbackStruct * calldata);
+static void uipageinputcb(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+static void uipagescrollbarcb(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+static void uipagedowncb(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+static void uipageupcb(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+static void uipagetopcb(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+static void uipagebottomcb(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+
+uiPageInfo_t uiPageInfo =
+{
+ (uiPage_t *) NULL,
+ (Widget) NULL,
+ (void *) NULL
+};
+
+
+int UiDisplayPage(topaddress, prevhtext, htext, htextobject, title)
+char *topaddress;
+HText_t *prevhtext;
+HText_t *htext;
+HTextObject_t *htextobject;
+char *title;
+{
+ uiHierarchy_t *hierarchy;
+ uiPage_t *prevpage, *page;
+
+ if (!(hierarchy = uifindoraddhierarchy(topaddress)))
+ return UI_ERROR;
+
+ if (!(page = uifindpage(htext, hierarchy)) || !page->Visible) {
+ prevpage = uifindpage(prevhtext, hierarchy);
+
+ if (!page)
+ if (!(page = uiaddpage(htext, htextobject, hierarchy, prevpage))) {
+ if (!hierarchy->Pages)
+ (void) uideletehierarchy(hierarchy); /* already an error */
+
+ return UI_ERROR;
+ }
+ if (uicreatepagewidgets(page, prevpage, title) == UI_OK) {
+ uisetcurrentpage(page);
+
+ return UI_OK;
+ } else
+ return UI_ERROR;
+ } else {
+ XRaiseWindow(XtDisplay(page->Gfx.TopWdg), XtWindow(page->Gfx.TopWdg));
+ uisetcurrentpage(page);
+ }
+
+ return UI_OK;
+}
+
+
+int UiDeletePage(topaddress, htext)
+char *topaddress;
+HText_t *htext;
+{
+ uiHierarchy_t *hierarchy;
+ uiPage_t *page, *shadowpage;
+ uiAction_t *tmpaction;
+
+ if (!(hierarchy = uifindhierarchy(topaddress)))
+ return UI_ERROR;
+
+ if (!(page = uifindpage(htext, hierarchy)))
+ return UI_ERROR;
+
+ XlDeleteText(htext);
+
+ shadowpage = uifindshadowpage(hierarchy, page);
+
+ if (page->Visible)
+ XtDestroyWidget(XtParent(page->Gfx.FormWdg));
+ uideletepage(page, hierarchy);
+
+ if (shadowpage) { /* Recursive destroy, oh yeah */
+ tmpaction = uiFindAction("Close");
+ (tmpaction->Callback) (topaddress, shadowpage->HText,
+ shadowpage->HTextObject, tmpaction->Parameter);
+ }
+ return UI_OK;
+}
+
+
+int UiSetCursor(topaddress, htext, htextobject)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+{
+ uiHierarchy_t *hierarchy;
+ uiPage_t *page;
+ int tmpx, tmpy;
+
+ if (!(hierarchy = uifindhierarchy(topaddress)))
+ return UI_ERROR;
+
+ if (!(page = uifindpage(htext, hierarchy)))
+ return UI_ERROR;
+
+ page->HTextObject = htextobject;
+
+ if (!page->Visible)
+ return UI_OK;
+
+ XlSetCursor(htext, htextobject);
+
+ XlGetCoordinates(&tmpx, &tmpy, htextobject);
+ if (tmpx < page->Layout.X || tmpx > page->Layout.X + page->Layout.Width)
+ page->Layout.X = tmpx - page->Layout.Width / 2;
+ if (tmpy < page->Layout.Y || tmpy > page->Layout.Y + page->Layout.Height)
+ page->Layout.Y = tmpy - page->Layout.Height / 2;
+
+ uipageupdatescrollbars(page);
+ XlMoveWindow(page->Layout.X, page->Layout.Y, page->HText);
+
+ return UI_OK;
+}
+
+
+void uiPageUpdateWindow(page)
+uiPage_t *page;
+{
+ HTextObject_t *htextobject;
+ int tmpwidth;
+
+ if (page->Settings.UseFixed)
+ tmpwidth = page->Settings.FixedWidth - page->Settings.LeftMargin -
+ page->Settings.RightMargin;
+ else
+ tmpwidth = page->Layout.Width - page->Settings.LeftMargin -
+ page->Settings.RightMargin;
+
+ htextobject = XlLocateHTextObject(0, 0, page->HText);
+ XlFormatText(page->Settings.LeftMargin, tmpwidth,
+ page->Settings.TopMargin, &page->Layout.VirtualWidth,
+ &page->Layout.VirtualHeight, page->HText);
+ XlGetCoordinates(&page->Layout.X, &page->Layout.Y, htextobject);
+
+ if (page->Layout.VirtualWidth > tmpwidth + page->Settings.LeftMargin)
+ page->Layout.VirtualWidth += page->Settings.RightMargin;
+ else
+ page->Layout.VirtualWidth = tmpwidth + page->Settings.LeftMargin +
+ page->Settings.RightMargin;
+ page->Layout.VirtualHeight += page->Settings.BottomMargin;
+
+ if (!page->Settings.UseFixed)
+ page->Layout.X = 0;
+ uipageupdatescrollbars(page);
+
+ XlSetPageCoordinates(page->Layout.X, page->Layout.Y, page->HText);
+}
+
+
+void uiPageAttachCallbacks()
+{
+ UiAttachCallback("Top", uipagetopcb, (void *) NULL);
+ UiAttachCallback("Bottom", uipagebottomcb, (void *) NULL);
+}
+
+
+void uiPageDefineKeys()
+{
+ UiBindKey("space", UI_NONE, uipagedowncb, (void *) NULL);
+ UiBindKey("Delete", UI_NONE, uipageupcb, (void *) NULL);
+
+ UiBindKey("less", UI_SHIFT, uipagetopcb, (void *) NULL);
+ UiBindKey("greater", UI_SHIFT, uipagebottomcb, (void *) NULL);
+}
+
+
+static uiHierarchy_t *
+ uifindoraddhierarchy(topaddress)
+char *topaddress;
+{
+ uiHierarchy_t *tmphierarchy;
+
+ if (!(tmphierarchy = uifindhierarchy(topaddress))) {
+ tmphierarchy = uiTopLevel.Hierarchies;
+ if (!tmphierarchy)
+ tmphierarchy = uiTopLevel.Hierarchies =
+ (uiHierarchy_t *) uiMalloc(sizeof(*tmphierarchy));
+ else {
+ while (tmphierarchy->Next)
+ tmphierarchy = tmphierarchy->Next;
+ tmphierarchy = tmphierarchy->Next =
+ (uiHierarchy_t *) uiMalloc(sizeof(*tmphierarchy));
+ }
+ tmphierarchy->Address = topaddress;
+ tmphierarchy->Pages = (uiPage_t *) NULL;
+ tmphierarchy->Next = (uiHierarchy_t *) NULL;
+ }
+ return tmphierarchy;
+}
+
+
+static uiHierarchy_t *
+ uifindhierarchy(topaddress)
+char *topaddress;
+{
+ uiHierarchy_t *tmphierarchy = uiTopLevel.Hierarchies;
+
+ while (tmphierarchy && strcmp(tmphierarchy->Address, topaddress))
+ tmphierarchy = tmphierarchy->Next;
+
+ return tmphierarchy;
+}
+
+
+static int uideletehierarchy(hierarchy)
+uiHierarchy_t *hierarchy;
+{
+ uiHierarchy_t *tmphierarchy = uiTopLevel.Hierarchies;
+
+ if (hierarchy == tmphierarchy)
+ if (tmphierarchy->Next) {
+ uiTopLevel.Hierarchies = hierarchy->Next;
+ uisetcurrentpage(hierarchy->Next->Pages);
+ } else {
+ uiTopLevel.Hierarchies = (uiHierarchy_t *) NULL;
+ uisetcurrentpage((uiPage_t *) NULL);
+ }
+ else {
+ while (tmphierarchy->Next && tmphierarchy->Next != hierarchy)
+ tmphierarchy = tmphierarchy->Next;
+ if (tmphierarchy->Next) {
+ tmphierarchy->Next = tmphierarchy->Next->Next;
+ uisetcurrentpage(tmphierarchy->Pages);
+ } else {
+ /* This shouldn't happen unless we have a stray pointer */
+ uiDisplayWarning("Messed up hierarchy-list");
+
+ return UI_ERROR;
+ }
+ }
+
+ uiFree(hierarchy);
+
+ return UI_OK;
+}
+
+
+static uiPage_t *
+ uifindpage(htext, hierarchy)
+HText_t *htext;
+uiHierarchy_t *hierarchy;
+{
+ uiPage_t *tmppage = hierarchy->Pages;
+
+ while (tmppage && tmppage->HText != htext)
+ tmppage = tmppage->Next;
+
+ return tmppage;
+}
+
+
+static uiPage_t *
+ uiaddpage(htext, htextobject, hierarchy, prevpage)
+HText_t *htext;
+HTextObject_t *htextobject;
+uiHierarchy_t *hierarchy;
+uiPage_t *prevpage;
+{
+ uiPage_t *tmppage = hierarchy->Pages;
+
+ if (!tmppage)
+ tmppage = hierarchy->Pages =
+ (uiPage_t *) uiMalloc(sizeof(*tmppage));
+ else {
+ while (tmppage->Next)
+ tmppage = tmppage->Next;
+ tmppage = tmppage->Next =
+ (uiPage_t *) uiMalloc(sizeof(*tmppage));
+ }
+ tmppage->HText = htext;
+ tmppage->HTextObject = htextobject;
+ tmppage->Hierarchy = hierarchy;
+
+ if (prevpage) {
+ tmppage->Settings.TopMargin = prevpage->Settings.TopMargin;
+ tmppage->Settings.BottomMargin = prevpage->Settings.BottomMargin;
+ tmppage->Settings.LeftMargin = prevpage->Settings.LeftMargin;
+ tmppage->Settings.RightMargin = prevpage->Settings.RightMargin;
+ tmppage->Settings.OnePageMode = prevpage->Settings.OnePageMode;
+ tmppage->Settings.UseFixed = prevpage->Settings.UseFixed;
+ tmppage->Settings.FixedWidth = prevpage->Settings.FixedWidth;
+ tmppage->Layout.Width = prevpage->Layout.Width;
+ tmppage->Layout.Height = prevpage->Layout.Height;
+ } else {
+ uiGlobalSettings_t *gs = &uiTopLevel.GlobalSettings;
+
+ tmppage->Settings.TopMargin = gs->TopMargin;
+ tmppage->Settings.BottomMargin = gs->BottomMargin;
+ tmppage->Settings.LeftMargin = gs->LeftMargin;
+ tmppage->Settings.RightMargin = gs->RightMargin;
+ tmppage->Settings.OnePageMode = gs->OnePageMode;
+ tmppage->Settings.UseFixed = gs->UseFixed;
+ tmppage->Settings.FixedWidth = gs->FixedWidth;
+ tmppage->Layout.Width = gs->Width;
+ tmppage->Layout.Height = gs->Height;
+ }
+
+ /* X and Y are href-dependent, Width and Height default, or previous */
+ tmppage->Layout.X = 0;
+ tmppage->Layout.Y = 0;
+
+ tmppage->Callbacks = (uiPageCBList_t *) NULL;
+ tmppage->Next = (uiPage_t *) NULL;
+
+ return tmppage;
+}
+
+
+static int uideletepage(page, hierarchy)
+uiPage_t *page;
+uiHierarchy_t *hierarchy;
+{
+ uiPage_t *tmppage = hierarchy->Pages;
+
+ if (tmppage == page)
+ if (tmppage->Next) {
+ hierarchy->Pages = tmppage->Next;
+ uisetcurrentpage(tmppage->Next);
+ } else
+ uideletehierarchy(hierarchy);
+ else {
+ while (tmppage->Next && tmppage->Next != page)
+ tmppage = tmppage->Next;
+ if (tmppage->Next) {
+ tmppage->Next = tmppage->Next->Next;
+ if (tmppage->Next)
+ uisetcurrentpage(tmppage->Next);
+ else
+ uisetcurrentpage(tmppage);
+ } else {
+ /* This shouldn't happen unless we have a stray pointer */
+ uiDisplayWarning("Messed up page-list");
+
+ return UI_ERROR;
+ }
+ }
+
+ uiListUpdateDialog(page);
+ uideletepagecallbacks(page);
+ uiFree(page);
+
+ return UI_OK;
+}
+
+
+static void uideletepagecallbacks(page)
+uiPage_t *page;
+{
+ uiPageCBList_t *tmpcb = page->Callbacks;
+
+ while (tmpcb) {
+ tmpcb = tmpcb->Next;
+ uiFree(page->Callbacks);
+ page->Callbacks = tmpcb;
+ }
+}
+
+
+static uiPage_t *
+ uifindshadowpage(hierarchy, page)
+uiHierarchy_t *hierarchy;
+uiPage_t *page;
+{
+ uiPage_t *tmppage = hierarchy->Pages;
+
+ while (tmppage)
+ if (tmppage != page && tmppage->Gfx.TopWdg == page->Gfx.TopWdg)
+ return tmppage;
+ else
+ tmppage = tmppage->Next;
+
+ return (uiPage_t *) NULL;
+}
+
+
+static int uicreatepagewidgets(page, prevpage, title)
+uiPage_t *page;
+uiPage_t *prevpage;
+char *title;
+{
+ uiTopLevelGfx_t *topgfx = &uiTopLevel.TopGfx;
+ uiPageGfx_t *pagegfx = &page->Gfx;
+ Widget topwdg, bottomwdg;
+
+ /* Ahemm, we could of course try to salvage as much as possible
+ of the widget tree, but why bother? No, just destroy everything
+ except for the toplevel shell, no need to remove callbacks and
+ event handlers
+ */
+ if (prevpage && prevpage->Settings.OnePageMode) {
+ topwdg = prevpage->Gfx.TopWdg;
+ uideletepageinternal(prevpage->Hierarchy->Address, prevpage->HText);
+ uicreatepageform(page, title, topwdg);
+ } else
+ uicreatepageform(page, title, (Widget) NULL);
+
+ page->Visible = TRUE;
+ pagegfx->MenuWdg = uicreatepagemenu(page, pagegfx->FormWdg);
+ XtManageChild(pagegfx->MenuWdg);
+ pagegfx->ControlWdg = uicreatepagecontrol(page, pagegfx->FormWdg, title);
+ XtManageChild(pagegfx->ControlWdg);
+ page->Gfx.FindTextWdg = (Widget) NULL;
+ if (HTAnchor_isIndex(page->HText->node_anchor)) {
+ pagegfx->FindWdg = uicreatepagefind(page, pagegfx->FormWdg,
+ pagegfx->ControlWdg);
+ XtManageChild(pagegfx->FindWdg);
+ bottomwdg = pagegfx->FindWdg;
+ } else
+ bottomwdg = pagegfx->ControlWdg;
+ pagegfx->DrawAreaWdg = uicreatepagescroll(page, pagegfx->FormWdg,
+ pagegfx->MenuWdg, bottomwdg);
+
+ XtManageChild(pagegfx->FormWdg);
+ XtRealizeWidget(pagegfx->TopWdg);
+
+ /* Do setup that cannot be done before managing the form */
+ XtVaSetValues(pagegfx->HScrollBarWdg,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, uiGetArg(pagegfx->FormWdg, XmNwidth) -
+ uiGetArg(pagegfx->DrawAreaWdg, XmNwidth), NULL);
+ uiconnectpage(page);
+
+ /* Is this really necessary?
+ XmUpdateDisplay(XtParent(pagegfx->FormWdg));
+ Nope, don't think so */
+
+ return UI_OK;
+}
+
+
+static void uicreatepageform(page, title, topwdg)
+uiPage_t *page;
+char *title;
+Widget topwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ char *tmptitle;
+
+ if (topwdg)
+ page->Gfx.TopWdg = topwdg;
+ else
+ page->Gfx.TopWdg = XtCreateApplicationShell("Page",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ if (title) {
+ tmptitle = uiMalloc(strlen(UI_ERWISE_TITLE) + strlen(title) + 4);
+ sprintf(tmptitle, "%s - %s", UI_ERWISE_TITLE, title);
+ XtVaSetValues(page->Gfx.TopWdg,
+ XmNtitle, tmptitle, NULL);
+ uiFree(tmptitle);
+ } else
+ XtVaSetValues(page->Gfx.TopWdg,
+ XmNtitle, UI_ERWISE_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ NULL);
+ page->Gfx.FormWdg = XmCreateForm(page->Gfx.TopWdg, "Form", args, nargs);
+}
+
+
+static char *uimenu[] =
+{
+ "Page", NULL,
+ " Search", "Search",
+ " Copy", "Copy",
+ " List", "List",
+ " Load to file", "Load to file",
+ " Print", "Print",
+ " Settings", "Settings",
+ " ", NULL,
+ " Close", "Close",
+ "Movement", "Movement",
+ " Top", "Top",
+ " Bottom", "Bottom",
+ " Prev tag", "Prev tag",
+ " Next tag", "Next tag",
+ "Hierarchy", NULL,
+ " Home", "Home",
+ " Recall", "Recall",
+ " Back", "Back",
+ " Prev page", "Prev page",
+ " Next page", "Next page",
+ " Close", NULL,
+ " hierarchy", "Close hierarchy",
+ "Misc", NULL,
+ " Connections", "Connections",
+ " Controlpanel", "Controlpanel",
+ " Defaults", "Defaults",
+ "Help", NULL,
+ " On function", "On function",
+ " Manual", "Help",
+ NULL
+};
+
+static Widget
+ uicreatepagemenu(page, formwdg)
+uiPage_t *page;
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget menuwdg, tmpmenuwdg;
+ int itempos = 0;
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNtopAttachment, XmATTACH_FORM, NULL);
+ menuwdg = XmCreateMenuBar(formwdg, "menubar", args, nargs);
+
+ do {
+ tmpmenuwdg = uicreatepagemenuitem(page, menuwdg, itempos, 0);
+ if (ui_HELPMENU(uimenu[itempos]))
+ XtVaSetValues(menuwdg,
+ XmNmenuHelpWidget, tmpmenuwdg, NULL);
+ itempos = uifindnextitem(itempos, 0);
+ }
+ while (ui_VALID(itempos));
+
+ return menuwdg;
+}
+
+
+static Widget
+ uicreatepagemenuitem(page, menuwdg, itempos, level)
+uiPage_t *page;
+Widget menuwdg;
+int itempos;
+int level;
+{
+ int childitempos = itempos;
+ int childlevel = level + 1;
+ char *label;
+ ArgList args;
+ Cardinal nargs;
+ Widget pulldownwdg;
+ Widget cascadewdg;
+ Widget tmpwdg;
+ uiActionData_t *actiondata;
+
+ label = &uimenu[itempos][level];
+ if (ui_VALID(uifindnextitem(itempos, childlevel))) {
+ pulldownwdg = XmCreatePulldownMenu(menuwdg, "Pulldown", NULL, 0);
+ args = uiVaSetArgs(&nargs, XmNsubMenuId, pulldownwdg, NULL);
+ cascadewdg = XmCreateCascadeButtonGadget(menuwdg, label, args, nargs);
+ XtManageChild(cascadewdg);
+
+ while (ui_VALID(childitempos =
+ uifindnextitem(childitempos, childlevel)))
+ uicreatepagemenuitem(page, pulldownwdg, childitempos, childlevel);
+
+ tmpwdg = cascadewdg;
+ } else {
+ if (label[0]) {
+ if (ui_TOGGLE(label)) {
+ tmpwdg = XmCreateToggleButtonGadget(menuwdg, label, NULL, 0);
+ } else {
+ tmpwdg = XmCreatePushButtonGadget(menuwdg, label, NULL, 0);
+ actiondata = uicreatepageactiondata(page, uimenu[itempos + 1]);
+ XtAddCallback(tmpwdg, XmNactivateCallback,
+ (XtCallbackProc) uipageactivatecb,
+ (caddr_t) actiondata);
+ }
+ } else
+ tmpwdg = XmCreateSeparatorGadget(menuwdg, "Separator", NULL, 0);
+ XtManageChild(tmpwdg);
+ }
+
+ return tmpwdg;
+}
+
+
+static int uifindnextitem(itempos, level)
+int itempos;
+int level;
+{
+ int i = itempos + 2;
+
+ while (uimenu[i] &&
+ (uimenu[i][level] == ' ' || uimenu[i][level] == '*'))
+ i += 2;
+ if (!uimenu[i] ||
+ (level && uimenu[i][level - 1] != ' ' && uimenu[i][level - 1] != '*'))
+ return UI_INVALID;
+
+ return i;
+}
+
+
+static Widget
+ uicreatepagecontrol(page, formwdg, title)
+uiPage_t *page;
+Widget formwdg;
+char *title;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget controlwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNheight, 70,
+ XmNshadowThickness, 2,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ controlwdg = XmCreateForm(formwdg, "Control", args, nargs);
+
+ uicreatepagelabel(controlwdg,
+ HTAnchor_address((HTAnchor *) page->HText->node_anchor));
+
+ uicreatepagebutton(page, controlwdg, "Prev tag", 1, 16);
+ uicreatepagebutton(page, controlwdg, "Next tag", 17, 32);
+ uicreatepagebutton(page, controlwdg, "Prev page", 35, 50);
+ uicreatepagebutton(page, controlwdg, "Back", 51, 66);
+ uicreatepagebutton(page, controlwdg, "Next page", 67, 82);
+ uicreatepagebutton(page, controlwdg, "Close", 85, 99);
+
+ return controlwdg;
+}
+
+
+static void uicreatepagelabel(parentwdg, label)
+Widget parentwdg;
+char *label;
+{
+ Widget labelwdg;
+ XmString labelstr;
+
+ labelstr = XmStringCreateSimple(label);
+ labelwdg = XmCreateLabelGadget(parentwdg, "Label", (ArgList) NULL, 0);
+ XtVaSetValues(labelwdg,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, 5,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, 5,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, 5,
+ XmNlabelString, labelstr, NULL);
+
+ XtManageChild(labelwdg);
+}
+
+
+static void uicreatepagebutton(page, parentwdg, name, leftpos, rightpos)
+uiPage_t *page;
+Widget parentwdg;
+char *name;
+int leftpos;
+int rightpos;
+{
+ Widget tmpwdg;
+ uiActionData_t *actiondata;
+
+ tmpwdg = XmCreatePushButtonGadget(parentwdg, name, (ArgList) NULL, 0);
+ XtVaSetValues(tmpwdg,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, 5,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, leftpos,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, rightpos, NULL);
+ actiondata = uicreatepageactiondata(page, name);
+ XtAddCallback(tmpwdg, XmNactivateCallback, uipageactivatecb,
+ (caddr_t) actiondata);
+
+ XtManageChild(tmpwdg);
+}
+
+
+static Widget
+ uicreatepagefind(page, formwdg, controlwdg)
+uiPage_t *page;
+Widget formwdg;
+Widget controlwdg;
+{
+ Widget framewdg, findformwdg, buttonwdg, textwdg;
+ uiActionData_t *actiondata;
+ XmString labelstr;
+
+ labelstr = XmStringCreateSimple(" Find: ");
+
+ framewdg = XmCreateFrame(formwdg, "FindFrame", (ArgList) NULL, 0);
+ XtVaSetValues(framewdg,
+ XmNshadowType, XmSHADOW_OUT,
+ XmNmarginWidth, 2,
+ XmNmarginHeight, 2,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, controlwdg,
+ XmNbottomOffset, 1, NULL);
+
+ findformwdg = XmCreateForm(framewdg, "FindForm", (ArgList) NULL, 0);
+ XtManageChild(findformwdg);
+
+ buttonwdg = XmCreatePushButtonGadget(findformwdg, "FindButton",
+ (ArgList) NULL, 0);
+ XtVaSetValues(buttonwdg,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ actiondata = uicreatepageactiondata(page, "IndexFind");
+ XtAddCallback(buttonwdg, XmNactivateCallback, uipageactivatecb,
+ (caddr_t) actiondata);
+ XmStringFree(labelstr);
+ XtManageChild(buttonwdg);
+
+ textwdg = XmCreateText(findformwdg, "FindText", (ArgList) NULL, 0);
+ XtVaSetValues(textwdg,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, buttonwdg,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ XtAddCallback(textwdg, XmNactivateCallback, uipageactivatecb,
+ (caddr_t) actiondata);
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) "FindText");
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) "FindText");
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) "FindText");
+ (void) uiAddWidgetInfo("FindText", textwdg, uiWTtext); /* Ignore */
+ page->Gfx.FindTextWdg = textwdg;
+ XtManageChild(textwdg);
+
+ return framewdg;
+}
+
+
+static Widget
+ uicreatepagescroll(page, formwdg, menuwdg, bottomwdg)
+uiPage_t *page;
+Widget formwdg;
+Widget menuwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget drawwdg, hsbwdg, vsbwdg;
+ uiActionData_t *actiondata;
+
+ args = uiVaSetArgs(&nargs,
+ XmNorientation, XmHORIZONTAL,
+ XmNwidth, page->Layout.Width,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, 2, NULL);
+ hsbwdg = XmCreateScrollBar(formwdg, "HScrollBar", args, nargs);
+ page->Gfx.HScrollBarWdg = hsbwdg;
+ actiondata = uicreatepageactiondata(page, "HScrollBar");
+ XtAddCallback(hsbwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uipageactivatecb, (caddr_t *) actiondata);
+ UiAttachCallback("HScrollBar", uipagescrollbarcb, (void *) "HScrollBar");
+
+ args = uiVaSetArgs(&nargs,
+ XmNorientation, XmVERTICAL,
+ XmNheight, page->Layout.Height,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, menuwdg,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, hsbwdg, NULL);
+ vsbwdg = XmCreateScrollBar(formwdg, "VScrollBar", args, nargs);
+ page->Gfx.VScrollBarWdg = vsbwdg;
+ actiondata = uicreatepageactiondata(page, "VScrollBar");
+ XtAddCallback(vsbwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uipageactivatecb, (caddr_t *) actiondata);
+ UiAttachCallback("VScrollBar", uipagescrollbarcb, (void *) "VScrollBar");
+
+ args = uiVaSetArgs(&nargs,
+ XmNwidth, page->Layout.Width,
+ XmNheight, page->Layout.Height,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, menuwdg,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_WIDGET,
+ XmNrightWidget, vsbwdg,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, hsbwdg, NULL);
+ drawwdg = XmCreateDrawingArea(formwdg, "Draw", args, nargs);
+ XtAddCallback(drawwdg, XmNexposeCallback, (XtCallbackProc) uipageexposecb,
+ (caddr_t) page);
+ XtAddCallback(drawwdg, XmNresizeCallback, (XtCallbackProc) uipageresizecb,
+ (caddr_t) page);
+ actiondata = uicreatepageactiondata(page, "PageInput");
+ XtAddCallback(drawwdg, XmNinputCallback, (XtCallbackProc) uipageactivatecb,
+ (caddr_t) actiondata);
+ XtAddEventHandler(drawwdg, KeyPressMask, FALSE, uipagekludgecb,
+ (caddr_t) actiondata);
+ UiAttachCallback("PageInput", uipageinputcb, (void *) NULL);
+
+ XtManageChild(drawwdg);
+ XtManageChild(hsbwdg);
+ XtManageChild(vsbwdg);
+
+ return drawwdg;
+}
+
+
+static void uiconnectpage(page)
+uiPage_t *page;
+{
+ Widget drawwdg = page->Gfx.DrawAreaWdg;
+ Widget hsbwdg = page->Gfx.HScrollBarWdg;
+ Widget vsbwdg = page->Gfx.VScrollBarWdg;
+ int tmpwidth;
+
+ XlSetupText(XtDisplay(drawwdg), XtWindow(drawwdg),
+ (Pixel) uiGetArg(drawwdg, XmNforeground),
+ (Pixel) uiGetArg(drawwdg, XmNbackground), page->HText);
+
+ if (page->Settings.UseFixed)
+ tmpwidth = page->Settings.FixedWidth - page->Settings.LeftMargin -
+ page->Settings.RightMargin;
+ else
+ tmpwidth = page->Layout.Width - page->Settings.LeftMargin -
+ page->Settings.RightMargin;
+
+ XlFormatText(page->Settings.LeftMargin, tmpwidth,
+ page->Settings.TopMargin, &page->Layout.VirtualWidth,
+ &page->Layout.VirtualHeight, page->HText);
+
+ if (page->Layout.VirtualWidth > tmpwidth + page->Settings.LeftMargin)
+ page->Layout.VirtualWidth += page->Settings.RightMargin;
+ else
+ page->Layout.VirtualWidth = tmpwidth + page->Settings.LeftMargin +
+ page->Settings.RightMargin;
+ page->Layout.VirtualHeight += page->Settings.BottomMargin;
+
+ if (page->HTextObject)
+ XlGetCoordinates(&page->Layout.X, &page->Layout.Y, page->HTextObject);
+ page->Layout.X = 0;
+ uipageupdatescrollbars(page);
+ if (page->HTextObject)
+ XlMoveWindow(page->Layout.X, page->Layout.Y, page->HText);
+
+ XlSetCursor(page->HText, page->HTextObject);
+}
+
+
+static void uipageupdatescrollbars(page)
+uiPage_t *page;
+{
+ Widget hsbwdg = page->Gfx.HScrollBarWdg;
+ Widget vsbwdg = page->Gfx.VScrollBarWdg;
+ int maxwidth, maxheight;
+ int hsbwidth, vsbheight;
+
+ maxwidth = page->Layout.VirtualWidth;
+ if (page->Layout.X + page->Layout.Width > maxwidth)
+ page->Layout.X -= ((page->Layout.X + page->Layout.Width) - maxwidth);
+ hsbwidth = (page->Layout.Width > maxwidth) ? maxwidth : page->Layout.Width;
+ if (page->Layout.X < 0)
+ page->Layout.X = 0;
+
+ maxheight = page->Layout.VirtualHeight;
+ if (page->Layout.Y + page->Layout.Height > maxheight)
+ page->Layout.Y -= ((page->Layout.Y + page->Layout.Height) - maxheight);
+ vsbheight =
+ (page->Layout.Height > maxheight) ? maxheight : page->Layout.Height;
+ if (page->Layout.Y < 0)
+ page->Layout.Y = 0;
+
+
+ XtVaSetValues(hsbwdg,
+ XmNmaximum, maxwidth,
+ XmNvalue, page->Layout.X,
+ XmNsliderSize, hsbwidth,
+ XmNincrement, hsbwidth / 10,
+ XmNpageIncrement, hsbwidth, NULL);
+ XtVaSetValues(vsbwdg,
+ XmNmaximum, maxheight,
+ XmNvalue, page->Layout.Y,
+ XmNsliderSize, vsbheight,
+ XmNincrement, vsbheight / 10,
+ XmNpageIncrement, vsbheight, NULL);
+}
+
+
+uiActionData_t *
+ uicreatepageactiondata(page, actionname)
+uiPage_t *page;
+char *actionname;
+{
+ uiPageCBList_t *tmppagecb = page->Callbacks;
+
+ if (!tmppagecb)
+ tmppagecb =
+ page->Callbacks = (uiPageCBList_t *) uiMalloc(sizeof(*tmppagecb));
+ else {
+ while (tmppagecb->Next)
+ tmppagecb = tmppagecb->Next;
+ tmppagecb = tmppagecb->Next =
+ (uiPageCBList_t *) uiMalloc(sizeof(*tmppagecb));
+ }
+ tmppagecb->ActionData.ActionName = actionname;
+ tmppagecb->ActionData.Page = page;
+ tmppagecb->Next = (uiPageCBList_t *) NULL;
+
+ return &tmppagecb->ActionData;
+}
+
+
+static void uisetcurrentpage(page)
+uiPage_t *page;
+{
+ uiPage_t *oldpage;
+
+ oldpage = uiPageInfo.CurrentPage;
+ uiPageInfo.CurrentPage = page;
+
+ if (oldpage != page) {
+ uiPageSettingsUpdateDialog();
+ uiSearchUpdateDialog();
+ uiControlPanelUpdateDialog();
+ uiPrintUpdateDialog();
+ uiRecallUpdateDialog();
+ uiConnectionsUpdateDialog();
+ }
+}
+
+
+static int uideletepageinternal(topaddress, htext)
+char *topaddress;
+HText_t *htext;
+{
+ uiHierarchy_t *hierarchy;
+ uiPage_t *page;
+ Widget topwdg;
+
+ if (!(hierarchy = uifindhierarchy(topaddress)))
+ return UI_ERROR;
+
+ if (!(page = uifindpage(htext, hierarchy)))
+ return UI_ERROR;
+
+/* XlDeleteText(htext);*/
+
+ topwdg = page->Gfx.TopWdg;
+ page = hierarchy->Pages;
+ while (page) {
+ if (page->Gfx.TopWdg == topwdg) {
+ if (page->Visible)
+ XtDestroyWidget(page->Gfx.FormWdg);
+ page->Visible = FALSE;
+ }
+ page = page->Next;
+ }
+/* uideletepage(page, hierarchy);*/
+
+ return UI_OK;
+}
+
+
+static void uipageactivatecb(wdg, actiondata, calldata)
+Widget wdg;
+uiActionData_t *actiondata;
+XmAnyCallbackStruct *calldata;
+{
+ uiAction_t *tmpaction;
+
+ uiPageInfo.Wdg = wdg;
+ uiPageInfo.CallData = (void *) calldata;
+ uisetcurrentpage(actiondata->Page);
+ if (actiondata->Page->Gfx.FindTextWdg) {
+ (void) uiAddWidgetInfo("FindText", actiondata->Page->Gfx.FindTextWdg,
+ uiWTtext); /* Ignore */
+ (void) uiDialogVariableCB((Widget) NULL, "FindText",
+ (XmAnyCallbackStruct *) NULL); /* Hmm? */
+ }
+ if (tmpaction = uiFindAction(actiondata->ActionName)) {
+ uiDefineCursor(uiBusyCursor);
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) (actiondata->ActionName);
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else
+ (*tmpaction->Callback) (actiondata->Page->Hierarchy->Address,
+ actiondata->Page->HText,
+ actiondata->Page->HTextObject,
+ tmpaction->Parameter);
+ uiUndefineCursor();
+ }
+}
+
+
+/*
+ * Massive braindamage ahead ... default translation in
+ * drawingarea-widget for return is activate, even if the widget
+ * doesn't support activate. Gawd! Anyway, we have to resort to this:
+ */
+
+static void uipagekludgecb(wdg, actiondata, event)
+Widget wdg;
+uiActionData_t *actiondata;
+XEvent *event;
+{
+ XKeyEvent *kevent = (XKeyEvent *) event;
+ XmAnyCallbackStruct tmpstruct;
+
+ if (XLookupKeysym(kevent, kevent->state) == XK_Return) {
+ tmpstruct.event = event;
+ uipageactivatecb(wdg, actiondata, &tmpstruct);
+ }
+}
+
+
+static void uipageexposecb(wdg, page, calldata)
+Widget wdg;
+uiPage_t *page;
+XmDrawingAreaCallbackStruct *calldata;
+{
+ XExposeEvent *event = (XExposeEvent *) calldata->event;
+
+#ifdef DEBUG
+ printf("Explode: %d %d %d %d %x\n",
+ event->x, event->y, event->width, event->height, page->HText);
+#endif
+ XlRedraw(event->x, event->y, event->width, event->height, page->HText);
+}
+
+
+static void uipageresizecb(wdg, page, calldata)
+Widget wdg;
+uiPage_t *page;
+XmDrawingAreaCallbackStruct *calldata;
+{
+ Widget hsbwdg = page->Gfx.HScrollBarWdg;
+ Widget vsbwdg = page->Gfx.VScrollBarWdg;
+ HTextObject_t *htextobject;
+
+#ifdef DEBUG
+ printf("Resize: %d %d\n",
+ (int) ((Dimension) uiGetArg(wdg, XmNwidth)),
+ (int) ((Dimension) uiGetArg(wdg, XmNheight)));
+#endif
+
+ if (!XtIsRealized(page->Gfx.DrawAreaWdg))
+ return;
+
+ XlClearWindow(page->Layout.Width, page->Layout.Height, page->HText);
+
+ page->Layout.Width = (int) ((Dimension) uiGetArg(wdg, XmNwidth));
+ page->Layout.Height = (int) ((Dimension) uiGetArg(wdg, XmNheight));
+
+ uiPageUpdateWindow(page);
+}
+
+
+static void uipageinputcb(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ Widget wdg = uiPageInfo.Wdg;
+ uiPage_t *page = uiPageInfo.CurrentPage;
+ XmDrawingAreaCallbackStruct *calldata =
+ (XmDrawingAreaCallbackStruct *) uiPageInfo.CallData;
+ XButtonEvent *bevent = (XButtonEvent *) calldata->event;
+ XKeyEvent *kevent = (XKeyEvent *) calldata->event;
+ static int dragx, dragy;
+ static Time oldtime = (Time) 0;
+ uiAction_t *tmpaction;
+ uiKey_t *tmpkey;
+ KeySym keysym;
+ char *keysymstring;
+ switch (bevent->type) {
+ case ButtonPress:
+ switch (bevent->button) {
+ case 1:
+ page->HTextObject = XlLocateHTextObject(bevent->x, bevent->y,
+ page->HText);
+ XlSetCursor(htext, page->HTextObject);
+ if (page->HTextObject) {
+ if (bevent->time - oldtime <
+ uiTopLevel.GlobalSettings.DoubleClickTime)
+ tmpaction = uiFindAction("Get page");
+ else
+ tmpaction = uiFindAction("Click page");
+ if (tmpaction) {
+ uiDefineCursor(uiBusyCursor);
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) ("Get page");
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else
+ (*tmpaction->Callback) (topaddress, htext,
+ page->HTextObject,
+ tmpaction->Parameter);
+ uiUndefineCursor();
+ }
+ oldtime = (Time) 0;
+ }
+ oldtime = bevent->time;
+ break;
+ case 2:
+ dragx = bevent->x;
+ dragy = bevent->y;
+ break;
+ }
+ break;
+ case ButtonRelease:
+ switch (bevent->button) {
+ case 2:
+ page->Layout.X -= (bevent->x - dragx);
+ page->Layout.Y -= (bevent->y - dragy);
+ uipageupdatescrollbars(page);
+ XlMoveWindow(page->Layout.X, page->Layout.Y, page->HText);
+ break;
+ }
+ break;
+ case KeyPress:
+ keysym = XLookupKeysym(kevent, 0);
+ if (keysym != NoSymbol && (keysymstring = XKeysymToString(keysym))) {
+ if (tmpkey = uiFindKey(keysymstring, kevent->state)) {
+ uiDefineCursor(uiBusyCursor);
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) (keysymstring);
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else
+ (*tmpkey->Callback) (topaddress,
+ htext,
+ page->HTextObject,
+ tmpkey->Parameter);
+ uiUndefineCursor();
+ }
+ }
+ break;
+ }
+}
+
+
+static void uipagescrollbarcb(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ XmUpdateDisplay(uiPageInfo.CurrentPage->Gfx.DrawAreaWdg);
+
+ if (!strcmp("HScrollBar", (char *) parameter))
+ uiPageInfo.CurrentPage->Layout.X =
+ ((XmScrollBarCallbackStruct *) uiPageInfo.CallData)->value;
+ else
+ uiPageInfo.CurrentPage->Layout.Y =
+ ((XmScrollBarCallbackStruct *) uiPageInfo.CallData)->value;
+
+#ifdef DEBUG
+ printf("scrollbar: %d %d\n", uiPageInfo.CurrentPage->Layout.X,
+ uiPageInfo.CurrentPage->Layout.Y);
+#endif
+ XlMoveWindow(uiPageInfo.CurrentPage->Layout.X,
+ uiPageInfo.CurrentPage->Layout.Y,
+ uiPageInfo.CurrentPage->HText);
+}
+
+
+static void uipagedowncb(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ uiPage_t *page = uiPageInfo.CurrentPage;
+
+ page->Layout.Y = page->Layout.Y + page->Layout.Height;
+
+ uipageupdatescrollbars(page);
+ XlMoveWindow(page->Layout.X, page->Layout.Y, page->HText);
+}
+
+
+static void uipageupcb(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ uiPage_t *page = uiPageInfo.CurrentPage;
+
+ page->Layout.Y = page->Layout.Y - page->Layout.Height;
+
+ uipageupdatescrollbars(page);
+ XlMoveWindow(page->Layout.X, page->Layout.Y, page->HText);
+}
+
+
+static void uipagetopcb(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ uiPage_t *page = uiPageInfo.CurrentPage;
+
+ page->Layout.Y = 0;
+
+ uipageupdatescrollbars(page);
+ XlMoveWindow(page->Layout.X, page->Layout.Y, page->HText);
+}
+
+
+static void uipagebottomcb(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ uiPage_t *page = uiPageInfo.CurrentPage;
+
+ page->Layout.Y = page->Layout.VirtualHeight - page->Layout.Height;
+
+ uipageupdatescrollbars(page);
+ XlMoveWindow(page->Layout.X, page->Layout.Y, page->HText);
+}
--- /dev/null
+static char *rcsid = "$Id: UiPageSettings.c,v 1.1 1992/03/26 18:13:50 kny Exp kny $";
+
+#include "UiIncludes.h"
+
+
+static void uibindpsvariables(void);
+static void uiupdatepsvariables(void);
+static Widget uicreatepsformdialog();
+static Widget uicreatepslabel(Widget parent);
+static Widget
+ uicreatepsmargin(Widget parent, Widget topwdg, char *name,
+ int position);
+static Widget uicreatepsseparator(Widget formwdg, Widget topwdg);
+static Widget uicreatepsusefixed(Widget parent, Widget topwdg);
+static Widget uicreatepssinglepage(Widget parent, Widget topwdg);
+static void uicreatepsbuttons(Widget formwdg, Widget topwdg);
+
+static void uipagesettingsmargincb(char *address, HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter);
+static void uipagesettingsusefixedcb(char *address, HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter);
+static void uipagesettingsbuttoncb(char *address, HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter);
+
+
+int UiDisplayPageSettingsDialog(type)
+int type;
+{
+ uiPageSettingsGfx_t *psgfx = &uiTopLevel.PageSettingsGfx;
+ Widget separatorwdg;
+
+ uibindpsvariables();
+
+ if (psgfx->FormWdg) {
+ XtMapWidget(XtParent(psgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(psgfx->FormWdg),
+ uiTopLevel.GlobalSettings.PageSettingsPlacement);
+
+ uiupdatepsvariables();
+
+ return UI_OK;
+ }
+ psgfx->FormWdg = uicreatepsformdialog();
+ psgfx->LabelWdg = uicreatepslabel(psgfx->FormWdg);
+
+ psgfx->LeftMarginWdg = uicreatepsmargin(psgfx->FormWdg, psgfx->LabelWdg,
+ "Left", UI_LEFT);
+ psgfx->RightMarginWdg =
+ uicreatepsmargin(psgfx->FormWdg, psgfx->LeftMarginWdg,
+ "Right", UI_LEFT);
+ psgfx->TopMarginWdg = uicreatepsmargin(psgfx->FormWdg, psgfx->LabelWdg,
+ "Top", UI_RIGHT);
+ psgfx->BottomMarginWdg =
+ uicreatepsmargin(psgfx->FormWdg, psgfx->TopMarginWdg,
+ "Bottom", UI_RIGHT);
+
+ separatorwdg = uicreatepsseparator(psgfx->FormWdg, psgfx->RightMarginWdg);
+
+ psgfx->UseFixedWdg = uicreatepsusefixed(psgfx->FormWdg,
+ separatorwdg);
+ psgfx->SinglePageWdg = uicreatepssinglepage(psgfx->FormWdg,
+ psgfx->UseFixedWdg);
+
+ separatorwdg = uicreatepsseparator(psgfx->FormWdg, psgfx->SinglePageWdg);
+ uicreatepsbuttons(psgfx->FormWdg, separatorwdg);
+ XtManageChild(psgfx->FormWdg);
+ XtRealizeWidget(XtParent(psgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(psgfx->FormWdg),
+ uiTopLevel.GlobalSettings.PageSettingsPlacement);
+
+ uiupdatepsvariables();
+
+ return UI_OK;
+}
+
+
+void uiPageSettingsUpdateDialog()
+{
+ if (uiTopLevel.PageSettingsGfx.FormWdg) {
+ if (uiPageInfo.CurrentPage) {
+ uibindpsvariables();
+ uiupdatepsvariables();
+ } else
+ XtUnmapWidget(XtParent(uiTopLevel.PageSettingsGfx.FormWdg));
+ }
+}
+
+
+static void uibindpsvariables()
+{
+ UiBindVariable("TopMargin",
+ (void *) &uiPageInfo.CurrentPage->Settings.TopMargin,
+ uiVTint);
+ UiBindVariable("BottomMargin",
+ (void *) &uiPageInfo.CurrentPage->Settings.BottomMargin,
+ uiVTint);
+ UiBindVariable("LeftMargin",
+ (void *) &uiPageInfo.CurrentPage->Settings.LeftMargin,
+ uiVTint);
+ UiBindVariable("RightMargin",
+ (void *) &uiPageInfo.CurrentPage->Settings.RightMargin,
+ uiVTint);
+
+ UiBindVariable("UseFixed",
+ (void *) &uiPageInfo.CurrentPage->Settings.UseFixed,
+ uiVTint);
+ UiBindVariable("FixedWidth",
+ (void *) &uiPageInfo.CurrentPage->Settings.FixedWidth,
+ uiVTint);
+ UiBindVariable("OnePageMode",
+ (void *) &uiPageInfo.CurrentPage->Settings.OnePageMode,
+ uiVTint);
+}
+
+
+static void uiupdatepsvariables()
+{
+ UiUpdateVariable("TopMargin");
+ UiUpdateVariable("BottomMargin");
+ UiUpdateVariable("LeftMargin");
+ UiUpdateVariable("RightMargin");
+
+ UiUpdateVariable("UseFixed");
+ UiUpdateVariable("FixedWidth");
+ UiUpdateVariable("OnePageMode");
+}
+
+
+static Widget
+ uicreatepsformdialog()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("PageSettings",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_SETTINGS_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "PageSettings", args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreatepslabel(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ Widget labelwdg;
+
+ labelstr = XmStringCreateSimple("Define Margins:");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "TextLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ return labelwdg;
+}
+
+
+static uiActionData_t uiactiondata[8] =
+{
+ {"LArrowDown", (uiPage_t *) NULL},
+ {"LArrowUp", (uiPage_t *) NULL},
+ {"RArrowDown", (uiPage_t *) NULL},
+ {"RArrowUp", (uiPage_t *) NULL},
+ {"TArrowDown", (uiPage_t *) NULL},
+ {"TArrowUp", (uiPage_t *) NULL},
+ {"BArrowDown", (uiPage_t *) NULL},
+ {"BArrowUp", (uiPage_t *) NULL}
+};
+
+static Widget uipstextwidget[] =
+{
+ (Widget) NULL,
+ (Widget) NULL,
+ (Widget) NULL,
+ (Widget) NULL
+};
+
+static Widget
+ uicreatepsmargin(formwdg, topwdg, name, pos)
+Widget formwdg;
+Widget topwdg;
+char *name;
+int pos;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ static int callnr = 0;
+ Widget marginformwdg, labelwdg;
+ Widget margindownwdg, marginupwdg, textwdg;
+ static char textvar[4][13]; /* strlen("BottomMargin") */
+ char *text;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5 + 50 * (pos == UI_RIGHT),
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 45 + 50 * (pos == UI_RIGHT), NULL);
+ marginformwdg = XmCreateForm(formwdg, "MarginForm", args, nargs);
+ XtManageChild(marginformwdg);
+
+ labelstr = XmStringCreateSimple(name);
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNalignment, XmALIGNMENT_BEGINNING,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 40,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(marginformwdg, "TextLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_DOWN,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNtopAttachment, XmATTACH_POSITION,
+ XmNtopPosition, 50,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ margindownwdg = XmCreateArrowButtonGadget(marginformwdg,
+ uiactiondata[callnr].ActionName,
+ args, nargs);
+ uiactiondata[callnr].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(margindownwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & uiactiondata[callnr]);
+ UiAttachCallback(uiactiondata[callnr].ActionName, uipagesettingsmargincb,
+ uiactiondata[callnr].ActionName);
+ callnr++;
+ XtManageChild(margindownwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_UP,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_POSITION,
+ XmNbottomPosition, 50, NULL);
+ marginupwdg = XmCreateArrowButtonGadget(marginformwdg, "ArrowDown",
+ args, nargs);
+ uiactiondata[callnr].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(marginupwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & uiactiondata[callnr]);
+ UiAttachCallback(uiactiondata[callnr].ActionName, uipagesettingsmargincb,
+ uiactiondata[callnr].ActionName);
+ callnr++;
+ XtManageChild(marginupwdg);
+
+ text = textvar[callnr / 2 - 1];
+ sprintf(text, "%sMargin", name);
+ args = uiVaSetArgs(&nargs,
+ XmNcolumns, 4,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_WIDGET,
+ XmNrightWidget, margindownwdg,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ textwdg = XmCreateText(marginformwdg, text, args, nargs);
+ uipstextwidget[callnr / 2 - 1] = textwdg;
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) text);
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) text);
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) text);
+ (void) uiAddWidgetInfo(text, textwdg, uiWTtext); /* ignore */
+ XtManageChild(textwdg);
+
+ return marginformwdg;
+}
+
+
+static Widget
+ uicreatepsseparator(formwdg, topwdg)
+Widget formwdg;
+Widget topwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(formwdg, "PSSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ return separatorwdg;
+}
+
+
+static Widget
+ uicreatepsusefixed(formwdg, topwdg)
+Widget formwdg;
+Widget topwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget tmpformwdg, usefixedwdg;
+ Widget textwdg, usefixeddownwdg, usefixedupwdg;
+ static uiActionData_t actiondata[2];
+
+ labelstr = XmStringCreateSimple("Use Fixed Width");
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 20, NULL);
+ tmpformwdg = XmCreateForm(formwdg, "UseFixedForm", args, nargs);
+ XtManageChild(tmpformwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ usefixedwdg = XmCreateToggleButtonGadget(tmpformwdg, "UseFixed",
+ args, nargs);
+ XtAddCallback(usefixedwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "UseFixed");
+ /* Ignore */
+ (void) uiAddWidgetInfo("UseFixed", usefixedwdg, uiWTcheckbutton);
+ XtManageChild(usefixedwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNcolumns, 4,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, usefixedwdg,
+ XmNleftOffset, UI_PAGESETTINGS_WDG_OFFSET, NULL);
+ textwdg = XmCreateText(tmpformwdg, "FixedWidth", args, nargs);
+ uiTopLevel.PageSettingsGfx.UseFixedTextWdg = textwdg;
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "FixedWidth");
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "FixedWidth");
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "FixedWidth");
+ /* Ignore */
+ (void) uiAddWidgetInfo("FixedWidth", textwdg, uiWTtext);
+ XtManageChild(textwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_DOWN,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, textwdg,
+ XmNtopAttachment, XmATTACH_POSITION,
+ XmNtopPosition, 50, NULL);
+ usefixeddownwdg = XmCreateArrowButtonGadget(tmpformwdg, "UseFixedDown",
+ args, nargs);
+ actiondata[0].ActionName = "UseFixedDown";
+ actiondata[0].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(usefixeddownwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[0]);
+ UiAttachCallback("UseFixedDown", uipagesettingsusefixedcb, "UseFixedDown");
+ XtManageChild(usefixeddownwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_UP,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, textwdg,
+ XmNbottomAttachment, XmATTACH_POSITION,
+ XmNbottomPosition, 50, NULL);
+ usefixedupwdg = XmCreateArrowButtonGadget(tmpformwdg, "UseFixedUp",
+ args, nargs);
+ actiondata[1].ActionName = "UseFixedUp";
+ actiondata[1].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(usefixedupwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[1]);
+ UiAttachCallback("UseFixedUp", uipagesettingsusefixedcb, "UseFixedUp");
+ XtManageChild(usefixedupwdg);
+
+ return tmpformwdg;
+}
+
+
+static Widget
+ uicreatepssinglepage(formwdg, usefixedwdg)
+Widget formwdg;
+Widget usefixedwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget singlepagewdg;
+
+ labelstr = XmStringCreateSimple("Single Page Mode");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, usefixedwdg,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 20, NULL);
+ singlepagewdg = XmCreateToggleButtonGadget(formwdg, "OnePageMode",
+ args, nargs);
+ XtAddCallback(singlepagewdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "OnePageMode");
+ /* Ignore */
+ (void) uiAddWidgetInfo("OnePageMode", singlepagewdg, uiWTcheckbutton);
+ XtManageChild(singlepagewdg);
+
+ return singlepagewdg;
+}
+
+
+static void uicreatepsbuttons(formwdg, topwdg)
+Widget formwdg;
+Widget topwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget okwdg, applywdg, closewdg;
+ static uiActionData_t actiondata[3];
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 25,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, 10, NULL);
+ okwdg = XmCreatePushButtonGadget(formwdg, "Ok", args, nargs);
+ actiondata[0].ActionName = "PSOk";
+ actiondata[0].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(okwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[0]);
+ UiAttachCallback("PSOk", uipagesettingsbuttoncb, "PSOk");
+ XtManageChild(okwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 40,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 60,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, 10, NULL);
+ applywdg = XmCreatePushButtonGadget(formwdg, "Apply", args, nargs);
+ actiondata[1].ActionName = "PSApply";
+ actiondata[1].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(applywdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[1]);
+ UiAttachCallback("PSApply", uipagesettingsbuttoncb, "PSApply");
+ XtManageChild(applywdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PAGESETTINGS_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 75,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, 10, NULL);
+ closewdg = XmCreatePushButtonGadget(formwdg, "Close", args, nargs);
+ actiondata[2].ActionName = "PSClose";
+ actiondata[2].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(closewdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[2]);
+ UiAttachCallback("PSClose", uipagesettingsbuttoncb, "PSClose");
+ XtManageChild(closewdg);
+}
+
+
+static void uipagesettingsmargincb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ int i;
+ Widget textwdg;
+ char *text;
+ int margin;
+ char tmpbuffer[4];
+
+ for (i = 0; i < 8; i++)
+ if (!strcmp(uiactiondata[i].ActionName, (char *) parameter)) {
+ textwdg = uipstextwidget[i / 2];
+ text = XmTextGetString(textwdg);
+ margin = atoi(text);
+ if (i % 2) {
+ margin += 10;
+ if (margin > 9999)
+ margin = 9999;
+ sprintf(tmpbuffer, "%d", margin);
+ XmTextSetString(textwdg, tmpbuffer);
+ } else {
+ margin = (margin - 10) * (margin > 9);
+ sprintf(tmpbuffer, "%d", margin);
+ XmTextSetString(textwdg, tmpbuffer);
+ }
+ XtFree(text);
+
+ return;
+ }
+}
+
+
+static void uipagesettingsusefixedcb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ Widget textwdg = uiTopLevel.PageSettingsGfx.UseFixedTextWdg;
+ char *fixedtext;
+ int width;
+ char tmpbuffer[4];
+
+ fixedtext = XmTextGetString(textwdg);
+ width = atoi(fixedtext);
+
+ if (!strcmp("UseFixedDown", (char *) parameter)) {
+ if (width) {
+ width = (width - 10) * (width > 9);
+ sprintf(tmpbuffer, "%d", width);
+ XmTextSetString(textwdg, tmpbuffer);
+ }
+ } else {
+ width += 10;
+ if (width > 9999)
+ width = 9999;
+ sprintf(tmpbuffer, "%d", width);
+ XmTextSetString(textwdg, tmpbuffer);
+ }
+
+ XtFree(fixedtext);
+}
+
+
+static void uipagesettingsbuttoncb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ uiPage_t *page = uiPageInfo.CurrentPage;
+
+ if (!strcmp("PSOk", (char *) parameter)) {
+ XlClearWindow(page->Layout.Width, page->Layout.Height, page->HText);
+ uiPageUpdateWindow(page);
+ XtUnmapWidget(XtParent(uiTopLevel.PageSettingsGfx.FormWdg));
+ } else if (!strcmp("PSApply", (char *) parameter)) {
+ XlClearWindow(page->Layout.Width, page->Layout.Height,
+ page->HText);
+ uiPageUpdateWindow(page);
+ } else if (!strcmp("PSClose", (char *) parameter))
+ XtUnmapWidget(XtParent(uiTopLevel.PageSettingsGfx.FormWdg));
+ else /* Shouldn't reach this point */
+ uiDisplayWarning("psbuttoncb called with illegal parameter");
+}
--- /dev/null
+static char *rcsid = "$Id$";
+
+#include "UiIncludes.h"
+
+
+static Widget uicreateprintformdialog();
+static Widget uicreateprintcmd(Widget formwdg);
+static Widget
+ uicreateprintmargin(Widget formwdg, Widget topwdg,
+ char *name, char *labeltext, int pos);
+static Widget uicreateprintseparator(Widget formwdg, Widget topwdg);
+static Widget uicreateprintwidth(Widget formwdg, Widget topwdg);
+static Widget uicreateprintfile(Widget formwdg, Widget topwdg);
+static void uicreateprintbuttons(Widget formwdg, Widget topwdg);
+static void uiprintmargincb(char *address, HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter);
+static void uiprintwidthcb(char *address, HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter);
+static void uiprintbuttoncb(char *address, HText_t * htext,
+ HTextObject_t * htextobject,
+ void *parameter);
+
+
+static uiActionData_t uiactiondata[8] =
+{
+ {"LArrowDown", (uiPage_t *) NULL},
+ {"LArrowUp", (uiPage_t *) NULL},
+ {"RArrowDown", (uiPage_t *) NULL},
+ {"RArrowUp", (uiPage_t *) NULL},
+ {"TArrowDown", (uiPage_t *) NULL},
+ {"TArrowUp", (uiPage_t *) NULL},
+ {"BArrowDown", (uiPage_t *) NULL},
+ {"BArrowUp", (uiPage_t *) NULL}
+};
+
+
+static Widget uiprinttextwidget[] =
+{
+ (Widget) NULL,
+ (Widget) NULL,
+ (Widget) NULL,
+ (Widget) NULL
+};
+
+
+int UiDisplayPrintDialog(type)
+int type;
+{
+ uiPrintGfx_t *printgfx = &uiTopLevel.PrintGfx;
+ Widget separatorwdg, tmpwdg;
+
+
+ if (printgfx->FormWdg) {
+ XtMapWidget(XtParent(printgfx->FormWdg));
+
+ return UI_OK;
+ }
+ printgfx->FormWdg = uicreateprintformdialog();
+
+ printgfx->PrintCmdWdg = uicreateprintcmd(printgfx->FormWdg);
+ printgfx->PrintFileWdg = uicreateprintfile(printgfx->FormWdg,
+ printgfx->PrintCmdWdg);
+
+ printgfx->LeftMarginWdg = uicreateprintmargin(printgfx->FormWdg,
+ printgfx->PrintFileWdg,
+ "PrintLeft", "Left",
+ UI_LEFT);
+ printgfx->RightMarginWdg =
+ uicreateprintmargin(printgfx->FormWdg, printgfx->LeftMarginWdg,
+ "PrintRight", "Right", UI_LEFT);
+ printgfx->TopMarginWdg = uicreateprintmargin(printgfx->FormWdg,
+ printgfx->PrintFileWdg,
+ "PrintTop", "Top", UI_RIGHT);
+ printgfx->BottomMarginWdg =
+ uicreateprintmargin(printgfx->FormWdg, printgfx->TopMarginWdg,
+ "PrintBottom", "Bottom", UI_RIGHT);
+
+ tmpwdg = uicreateprintwidth(printgfx->FormWdg, printgfx->BottomMarginWdg);
+
+ separatorwdg = uicreateprintseparator(printgfx->FormWdg, tmpwdg);
+ uicreateprintbuttons(printgfx->FormWdg, separatorwdg);
+ XtManageChild(printgfx->FormWdg);
+ XtRealizeWidget(XtParent(printgfx->FormWdg));
+
+ return UI_OK;
+}
+
+
+void uiPrintUpdateDialog()
+{
+ if (uiTopLevel.PrintGfx.FormWdg) {
+ if (uiPageInfo.CurrentPage) {
+ } else
+ XtUnmapWidget(XtParent(uiTopLevel.PrintGfx.FormWdg));
+ }
+}
+
+
+static Widget
+ uicreateprintformdialog()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("Print",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_PRINT_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "Print", args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreateprintmargin(formwdg, topwdg, name, labeltext, pos)
+Widget formwdg;
+Widget topwdg;
+char *name;
+char *labeltext;
+int pos;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ static int callnr = 0;
+ Widget marginformwdg, labelwdg;
+ Widget margindownwdg, marginupwdg, textwdg;
+ static char textvar[4][18]; /* strlen("PrintBottomMargin") */
+ char *text;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PRINT_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5 + 50 * (pos == UI_RIGHT),
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 45 + 50 * (pos == UI_RIGHT), NULL);
+ marginformwdg = XmCreateForm(formwdg, "MarginForm", args, nargs);
+ XtManageChild(marginformwdg);
+
+ labelstr = XmStringCreateSimple(labeltext);
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNalignment, XmALIGNMENT_BEGINNING,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 40,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(marginformwdg, "TextLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_DOWN,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNtopAttachment, XmATTACH_POSITION,
+ XmNtopPosition, 50,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ margindownwdg = XmCreateArrowButtonGadget(marginformwdg,
+ uiactiondata[callnr].ActionName,
+ args, nargs);
+ uiactiondata[callnr].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(margindownwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & uiactiondata[callnr]);
+ UiAttachCallback(uiactiondata[callnr].ActionName, uiprintmargincb,
+ uiactiondata[callnr].ActionName);
+ callnr++;
+ XtManageChild(margindownwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_UP,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_POSITION,
+ XmNbottomPosition, 50, NULL);
+ marginupwdg = XmCreateArrowButtonGadget(marginformwdg, "ArrowDown",
+ args, nargs);
+ uiactiondata[callnr].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(marginupwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & uiactiondata[callnr]);
+ UiAttachCallback(uiactiondata[callnr].ActionName, uiprintmargincb,
+ uiactiondata[callnr].ActionName);
+ callnr++;
+ XtManageChild(marginupwdg);
+
+ text = textvar[callnr / 2 - 1];
+ sprintf(text, "%sMargin", name);
+ args = uiVaSetArgs(&nargs,
+ XmNcolumns, 4,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_WIDGET,
+ XmNrightWidget, margindownwdg,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNvalue, "0", NULL);
+ textwdg = XmCreateText(marginformwdg, text, args, nargs);
+ uiprinttextwidget[callnr / 2 - 1] = textwdg;
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) text);
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) text);
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) text);
+ (void) uiAddWidgetInfo(text, textwdg, uiWTtext); /* ignore */
+ XtManageChild(textwdg);
+
+ return marginformwdg;
+}
+
+
+static Widget
+ uicreateprintseparator(formwdg, topwdg)
+Widget formwdg;
+Widget topwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PRINT_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(formwdg, "PRINTSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ return separatorwdg;
+}
+
+
+static Widget
+ uicreateprintcmd(formwdg)
+Widget formwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget tmpformwdg;
+ Widget labelwdg;
+ Widget textwdg;
+ static uiActionData_t actiondata[2];
+
+ labelstr = XmStringCreateSimple("Print command");
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_PRINT_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_PRINT_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_PRINT_WDG_OFFSET, NULL);
+ tmpformwdg = XmCreateForm(formwdg, "PrintcmdForm", args, nargs);
+ XtManageChild(tmpformwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(tmpformwdg, "Label", args, nargs);
+ XtManageChild(labelwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_WIDGET,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, labelwdg,
+ XmNleftOffset, UI_PRINT_WDG_OFFSET,
+ XmNvalue, "lpr", NULL);
+ textwdg = XmCreateText(tmpformwdg, "PrintCmd", args, nargs);
+ uiTopLevel.PrintGfx.WidthWdg = textwdg;
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintCommand");
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintCommand");
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintCommand");
+ /* Ignore */
+ (void) uiAddWidgetInfo("PrintCommand", textwdg, uiWTtext);
+ XtManageChild(textwdg);
+
+ return tmpformwdg;
+}
+
+
+static Widget
+ uicreateprintfile(formwdg, topwdg)
+Widget formwdg;
+Widget topwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget tmpformwdg, widthwdg;
+ Widget textwdg;
+ static uiActionData_t actiondata[2];
+
+ labelstr = XmStringCreateSimple("Print to a file:");
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PRINT_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_PRINT_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_PRINT_WDG_OFFSET, NULL);
+ tmpformwdg = XmCreateForm(formwdg, "FileForm", args, nargs);
+ XtManageChild(tmpformwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ widthwdg = XmCreateToggleButtonGadget(tmpformwdg, "PrintToFile",
+ args, nargs);
+ XtAddCallback(widthwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintToFile");
+ /* Ignore */
+ (void) uiAddWidgetInfo("PrintToFile", widthwdg, uiWTcheckbutton);
+ XtManageChild(widthwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, widthwdg,
+ XmNvalue, "foobar.www", NULL);
+ textwdg = XmCreateText(tmpformwdg, "PrintFileName", args, nargs);
+ uiTopLevel.PrintGfx.WidthWdg = textwdg;
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintFileName");
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintfileName");
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintFileName");
+ /* Ignore */
+ (void) uiAddWidgetInfo("PrintFileName", textwdg, uiWTtext);
+ XtManageChild(textwdg);
+
+ return tmpformwdg;
+}
+
+
+static Widget
+ uicreateprintwidth(formwdg, topwdg)
+Widget formwdg;
+Widget topwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget tmpformwdg, labelwdg;
+ Widget textwdg, widthdownwdg, widthupwdg;
+ static uiActionData_t actiondata[2];
+
+ labelstr = XmStringCreateSimple("Width");
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PRINT_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 45, NULL);
+ tmpformwdg = XmCreateForm(formwdg, "WidthForm", args, nargs);
+ XtManageChild(tmpformwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNalignment, XmALIGNMENT_BEGINNING,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 40,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(tmpformwdg, "Label", args, nargs);
+ XtManageChild(labelwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_DOWN,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNtopAttachment, XmATTACH_POSITION,
+ XmNtopPosition, 50,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ widthdownwdg = XmCreateArrowButtonGadget(tmpformwdg, "WidthDown",
+ args, nargs);
+ actiondata[0].ActionName = "WidthDown";
+ actiondata[0].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(widthdownwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[0]);
+ UiAttachCallback("WidthDown", uiprintwidthcb, "WidthDown");
+ XtManageChild(widthdownwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_UP,
+ XmNwidth, 15,
+ XmNheight, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_POSITION,
+ XmNbottomPosition, 50, NULL);
+ widthupwdg = XmCreateArrowButtonGadget(tmpformwdg, "WidthUp",
+ args, nargs);
+ actiondata[1].ActionName = "WidthUp";
+ actiondata[1].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(widthupwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[1]);
+ UiAttachCallback("WidthUp", uiprintwidthcb, "WidthUp");
+ XtManageChild(widthupwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNcolumns, 4,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_WIDGET,
+ XmNrightWidget, widthdownwdg,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNvalue, "80", NULL);
+ textwdg = XmCreateText(tmpformwdg, "PrintWidth", args, nargs);
+ uiTopLevel.PrintGfx.WidthWdg = textwdg;
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintWidth");
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintWidth");
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "PrintWidth");
+ /* Ignore */
+ (void) uiAddWidgetInfo("PrintWidth", textwdg, uiWTtext);
+ XtManageChild(textwdg);
+
+ return tmpformwdg;
+}
+
+
+static void uicreateprintbuttons(formwdg, topwdg)
+Widget formwdg;
+Widget topwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget okwdg, closewdg;
+ static uiActionData_t actiondata[3];
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PRINT_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 25,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_PRINT_WDG_OFFSET, NULL);
+ okwdg = XmCreatePushButtonGadget(formwdg, "Print", args, nargs);
+ actiondata[0].ActionName = "PRINTOk";
+ actiondata[0].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(okwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[0]);
+ UiAttachCallback("PRINTOk", uiprintbuttoncb, "PRINTOk");
+ XtManageChild(okwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_PRINT_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 75,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_PRINT_WDG_OFFSET, NULL);
+ closewdg = XmCreatePushButtonGadget(formwdg, "Close", args, nargs);
+ actiondata[2].ActionName = "PRINTClose";
+ actiondata[2].Page = uiPageInfo.CurrentPage;
+ XtAddCallback(closewdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB,
+ (caddr_t) & actiondata[2]);
+ UiAttachCallback("PRINTClose", uiprintbuttoncb, "PRINTClose");
+ XtManageChild(closewdg);
+}
+
+
+
+static void uiprintmargincb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ int i;
+ Widget textwdg;
+ char *text;
+ int margin;
+ char tmpbuffer[5];
+
+ for (i = 0; i < 8; i++)
+ if (!strcmp(uiactiondata[i].ActionName, (char *) parameter)) {
+ textwdg = uiprinttextwidget[i / 2];
+ text = XmTextGetString(textwdg);
+ margin = atoi(text);
+ if (i % 2) {
+ margin += 1;
+ if (margin > 9999)
+ margin = 9999;
+ sprintf(tmpbuffer, "%d", margin);
+ XmTextSetString(textwdg, tmpbuffer);
+ } else {
+ margin = (margin - 1) * (margin > 0);
+ sprintf(tmpbuffer, "%d", margin);
+ XmTextSetString(textwdg, tmpbuffer);
+ }
+ XtFree(text);
+
+ return;
+ }
+}
+
+
+static void uiprintwidthcb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ Widget textwdg = uiTopLevel.PrintGfx.WidthWdg;
+ char *fixedtext;
+ int width;
+ char tmpbuffer[5];
+
+ fixedtext = XmTextGetString(textwdg);
+ width = atoi(fixedtext);
+
+ if (!strcmp("WidthDown", (char *) parameter)) {
+ if (width) {
+ width = (width - 5) * (width > 4);
+ sprintf(tmpbuffer, "%d", width);
+ XmTextSetString(textwdg, tmpbuffer);
+ }
+ } else {
+ width += 5;
+ if (width > 9999)
+ width = 9999;
+ sprintf(tmpbuffer, "%d", width);
+ XmTextSetString(textwdg, tmpbuffer);
+ }
+
+ XtFree(fixedtext);
+}
+
+
+static void uiprintbuttoncb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ uiPage_t *page = uiPageInfo.CurrentPage;
+
+ if (!strcmp("PRINTOk", (char *) parameter)) {
+ Print(htext);
+ XtUnmapWidget(XtParent(uiTopLevel.PrintGfx.FormWdg));
+ } else if (!strcmp("PRINTClose", (char *) parameter))
+ XtUnmapWidget(XtParent(uiTopLevel.PrintGfx.FormWdg));
+ else /* Shouldn't reach this point */
+ uiDisplayWarning("printbuttoncb called with illegal parameter");
+}
--- /dev/null
+/* $Id: UiProtos.h,v 1.4 1992/03/26 18:13:50 kny Exp kny $ */
+
+
+/*
+ * Misc. prototypes (external to library)
+ */
+
+extern int fprintf(FILE * stream, char *format,...);
+
+
+/*
+ * UiInit.c
+ */
+
+extern uiTopLevel_t uiTopLevel;
+extern char **uiSelectionArray;
+extern Cursor uiBusyCursor;
+extern Cursor uiArrowCursor;
+extern void *(*uiConfigPF) (void *table, char *item);
+extern void *(*uiConfigSetPF) (void *table, char *item, void *value);
+
+
+/*
+ * UiControlPanel.c
+ */
+
+
+/*
+ * UiSelectionBox.c
+ */
+
+
+/*
+ * UiPage.c
+ */
+
+extern void uiPageUpdateWindow(uiPage_t * page);
+extern void uiPageAttachCallbacks(void);
+extern void uiPageDefineKeys(void);
+
+extern uiPageInfo_t uiPageInfo;
+
+
+/*
+ * UiSearch.c
+ */
+
+extern void uiSearchUpdateDialog(void);
+
+
+/*
+ * UiPageSettings.c
+ */
+
+extern void uiPageSettingsUpdateDialog(void);
+
+
+/*
+ * UiList.c
+ */
+
+extern void uiListUpdateDialog(uiPage_t * page);
+
+
+/*
+ * UiRecall.c
+ */
+
+extern void uiRecallUpdateDialog(void);
+
+
+/*
+ * UiMisc.c
+ */
+
+extern uiAction_t *uiFindAction(char *actionname);
+extern uiKey_t *uiFindKey(char *keyname, int modifier);
+extern uiVariable_t *uiFindVariable(char *varname);
+extern int uiAddWidgetInfo(char *varname, Widget wdg, uiWdgType_t wdgtype);
+extern void uiDialogActivateCB(Widget wdg, uiActionData_t * actiondata,
+ XmAnyCallbackStruct * calldata);
+extern void uiDialogVariableCB(Widget wdg, caddr_t variablename,
+ XmAnyCallbackStruct * calldata);
+extern void uiDefineCursor(Cursor cursor);
+extern void uiUndefineCursor(void);
+extern ArgList uiVaSetArgs( /*int *nargs, va_alist*/ );
+extern XtArgVal uiGetArg(Widget wdg, String resource);
+extern void *uiMalloc(int size);
+extern void *uiReAlloc(void *, int size);
+extern void uiFree(void *ptr);
+extern void uiDisplayWarning(char *text);
+extern void uiDisplayFatal(char *text);
+extern void uiWidgetPlacement(Widget wdg, int placement);
+extern void (*uiHelpOnActionCB) (char *actionstring);
--- /dev/null
+static char *rcsid = "$Id$";
+
+
+#include "UiIncludes.h"
+
+
+static void uirecallfreeprevious(void);
+static void uirecallsetitems(char **listitems, int nitems);
+
+static Widget uicreaterecallform(void);
+static Widget uicreaterecalllabel(Widget parent);
+static Widget uicreaterecallopen(Widget parent);
+static Widget uicreaterecallclose(Widget parent);
+static Widget uicreaterecallseparator(Widget parent, Widget bottomwdg);
+static Widget
+ uicreaterecalllist(Widget parent, Widget topwdg,
+ Widget bottomwdg);
+static void uirecallopencb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+static void uirecallclosecb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+
+
+static char *uitopaddress = (char *) NULL;
+static char **uilistitems;
+static int uinitems;
+static void (*uirecallcallback) (char *topaddress, char *address,
+ char *parentaddress);
+
+
+int UiDisplayRecallDialog(listitems, nitems, callback)
+char **listitems;
+int nitems;
+void (*callback) (char *topaddress, char *address, char *parentaddress);
+{
+ uiRecallGfx_t *recallgfx = &uiTopLevel.RecallGfx;
+
+ uirecallfreeprevious();
+
+ uitopaddress = uiPageInfo.CurrentPage->Hierarchy->Address;
+ uilistitems = listitems;
+ uinitems = nitems;
+ uirecallcallback = callback;
+
+ if (recallgfx->FormWdg) {
+ XtMapWidget(XtParent(recallgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(recallgfx->FormWdg),
+ uiTopLevel.GlobalSettings.RecallPlacement);
+
+ uirecallsetitems(listitems, nitems);
+
+ return UI_OK;
+ }
+ recallgfx->FormWdg = uicreaterecallform();
+ recallgfx->LabelWdg = uicreaterecalllabel(recallgfx->FormWdg);
+ recallgfx->OpenWdg = uicreaterecallopen(recallgfx->FormWdg);
+ recallgfx->CloseWdg = uicreaterecallclose(recallgfx->FormWdg);
+ recallgfx->SeparatorWdg = uicreaterecallseparator(recallgfx->FormWdg,
+ recallgfx->OpenWdg);
+ recallgfx->ListWdg = uicreaterecalllist(recallgfx->FormWdg,
+ recallgfx->LabelWdg,
+ recallgfx->SeparatorWdg);
+
+ uirecallsetitems(listitems, nitems);
+
+ XtManageChild(recallgfx->FormWdg);
+ XtRealizeWidget(XtParent(recallgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(recallgfx->FormWdg),
+ uiTopLevel.GlobalSettings.RecallPlacement);
+
+ return UI_OK;
+}
+
+
+void uiRecallUpdateDialog()
+{
+ if (!uiPageInfo.CurrentPage && uiTopLevel.RecallGfx.FormWdg) {
+ uirecallfreeprevious();
+ uirecallsetitems((char **) NULL, 0);
+ uitopaddress = (char *) NULL;
+ XtUnmapWidget(XtParent(uiTopLevel.RecallGfx.FormWdg));
+ }
+}
+
+
+static Widget
+ uicreaterecallform()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("Recall",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_RECALL_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "RecallDialog", args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreaterecalllabel(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ Widget labelwdg;
+
+ labelstr = XmStringCreateSimple("List of documents");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "ListLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ return labelwdg;
+}
+
+
+static Widget
+ uicreaterecallopen(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget openwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 40,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET, NULL);
+ openwdg = XmCreatePushButtonGadget(formwdg, "Open", args, nargs);
+ XtAddCallback(openwdg, XmNactivateCallback,
+ (XtCallbackProc) uirecallopencb, (caddr_t) NULL);
+ XtManageChild(openwdg);
+
+ return openwdg;
+}
+
+
+static Widget
+ uicreaterecallclose(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget closewdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 60,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET, NULL);
+ closewdg = XmCreatePushButtonGadget(formwdg, "Close", args, nargs);
+ XtAddCallback(closewdg, XmNactivateCallback,
+ (XtCallbackProc) uirecallclosecb, (caddr_t) NULL);
+ XtManageChild(closewdg);
+
+ return closewdg;
+}
+
+
+static Widget
+ uicreaterecallseparator(formwdg, bottomwdg)
+Widget formwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(formwdg, "ListSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ return separatorwdg;
+}
+
+
+static Widget
+ uicreaterecalllist(formwdg, topwdg, bottomwdg)
+Widget formwdg;
+Widget topwdg;
+Widget bottomwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget listwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNvisibleItemCount, 15,
+ XmNwidth, 300,
+ XmNselectionPolicy, XmSINGLE_SELECT,
+ XmNlistSizePolicy, XmCONSTANT,
+ XmNscrollBarDisplayPolicy, XmSTATIC,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, bottomwdg,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_LIST_WDG_OFFSET, NULL);
+ listwdg = XmCreateScrolledList(formwdg, "ListList", args, nargs);
+ XtManageChild(listwdg);
+ XtAddCallback(listwdg, XmNdefaultActionCallback,
+ (XtCallbackProc) uirecallopencb, (caddr_t) NULL);
+
+ return listwdg;
+}
+
+
+void uirecallfreeprevious()
+{
+ if (uitopaddress && uinitems) {
+ while (uinitems--)
+ uiFree(uilistitems[uinitems]);
+
+ uiFree(uilistitems);
+ }
+}
+
+
+static void uirecallsetitems(listitems, nitems)
+char **listitems;
+int nitems;
+{
+ Widget listwdg = uiTopLevel.RecallGfx.ListWdg;
+ int i;
+ XmString *tmpstr = uiMalloc(nitems * sizeof(XmString));
+
+ XmListDeleteAllItems(listwdg);
+ if (nitems) {
+ for (i = 0; i < nitems; i++)
+ tmpstr[i] = XmStringCreateSimple(listitems[i]);
+
+ XmListAddItems(listwdg, tmpstr, nitems, 0);
+ for (i = 0; i < nitems; i++)
+ XmStringFree(tmpstr[i]);
+ uiFree((void *) tmpstr);
+ }
+}
+
+
+static void uirecallopencb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ Widget listwdg = uiTopLevel.RecallGfx.ListWdg;
+ int *poslist;
+ int poscount;
+
+ if (uinitems)
+ if (XmListGetSelectedPos(listwdg, &poslist, &poscount)) {
+ uiDefineCursor(uiBusyCursor);
+ if (uiHelpOnActionCB) {
+ (*uiHelpOnActionCB) ("Get page");
+ uiHelpOnActionCB = (void (*) (char *actionstring)) NULL;
+ } else
+ (*uirecallcallback) (uilistitems[poslist[0] - 1],
+ uitopaddress, (char *) NULL);
+
+ uiUndefineCursor();
+
+ XtFree(poslist);
+ }
+}
+
+
+static void uirecallclosecb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.RecallGfx.FormWdg));
+}
--- /dev/null
+static char *rcsid = "$Id: UiSearch.c,v 1.1 1992/03/26 18:13:50 kny Exp kss $";
+
+#include "UiIncludes.h"
+
+
+static Widget uicreatesearchformdialog();
+static Widget uicreatesearchtext(Widget formwdg);
+static Widget uicreatesearchlevel(Widget formwdg, Widget textwdg);
+static Widget uicreatesearchlevelform(Widget formwdg, Widget levelwdg);
+static Widget uicreatesearchleveldown(Widget formwdg);
+static Widget uicreatesearchlevelup(Widget formwdg);
+static Widget uicreatesearchcase(Widget formwdg, Widget levelwdg);
+static Widget uicreatesearchbackward(Widget formwdg, Widget levelwdg);
+static Widget uicreatesearchforward(Widget formwdg, Widget textwdg);
+static Widget uicreatesearchlabel(Widget formwdg, Widget closewdg);
+static Widget uicreatesearchclose(Widget formwdg, Widget forwardwdg);
+
+static void uisearchlevelcb(char *address, HText_t * htex,
+ HTextObject_t * htextobject, void *parameter);
+static void uisearchclosecb(char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+
+
+int UiDisplaySearchDialog(type)
+int type;
+{
+ uiSearchGfx_t *searchgfx = &uiTopLevel.SearchGfx;
+
+ if (searchgfx->FormWdg) {
+ XtMapWidget(XtParent(searchgfx->FormWdg));
+ uiWidgetPlacement(XtParent(searchgfx->FormWdg),
+ uiTopLevel.GlobalSettings.SearchPlacement);
+ uiSearchUpdateDialog();
+ return UI_OK;
+ }
+ searchgfx->FormWdg = uicreatesearchformdialog();
+ searchgfx->TextWdg = uicreatesearchtext(searchgfx->FormWdg);
+ searchgfx->LevelWdg = uicreatesearchlevel(searchgfx->FormWdg,
+ searchgfx->TextWdg);
+ searchgfx->LevelFormWdg = uicreatesearchlevelform(searchgfx->FormWdg,
+ searchgfx->LevelWdg);
+ searchgfx->CaseWdg = uicreatesearchcase(searchgfx->FormWdg,
+ searchgfx->LevelWdg);
+ searchgfx->BackwardWdg = uicreatesearchbackward(searchgfx->FormWdg,
+ searchgfx->TextWdg);
+ searchgfx->ForwardWdg = uicreatesearchforward(searchgfx->FormWdg,
+ searchgfx->BackwardWdg);
+ searchgfx->CloseWdg = uicreatesearchclose(searchgfx->FormWdg,
+ searchgfx->ForwardWdg);
+ searchgfx->LabelWdg = uicreatesearchlabel(searchgfx->FormWdg,
+ searchgfx->CloseWdg);
+
+ XtManageChild(searchgfx->FormWdg);
+ XtRealizeWidget(XtParent(searchgfx->FormWdg));
+
+ uiWidgetPlacement(XtParent(searchgfx->FormWdg),
+ uiTopLevel.GlobalSettings.SearchPlacement);
+
+ return UI_OK;
+}
+
+
+void uiSearchUpdateDialog()
+{
+ XmString labelstr;
+
+ if (uiTopLevel.SearchGfx.FormWdg) {
+ if (uiPageInfo.CurrentPage) {
+ labelstr =
+ XmStringCreateSimple(HTAnchor_address((HTAnchor *)
+ uiPageInfo.CurrentPage->
+ HText->node_anchor));
+ XtVaSetValues(uiTopLevel.SearchGfx.LabelWdg,
+ XmNlabelString, labelstr, NULL);
+ XmStringFree(labelstr);
+ } else
+ XtUnmapWidget(XtParent(uiTopLevel.SearchGfx.FormWdg));
+ }
+}
+
+
+static Widget
+ uicreatesearchformdialog()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("Search",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNtitle, UI_SEARCH_TITLE, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "Search", args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreatesearchtext(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ Widget labelwdg, textwdg;
+
+ labelstr = XmStringCreateSimple("Search for:");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_SEARCH_WDG_OFFSET, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "TextLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ args = uiVaSetArgs(&nargs,
+ XmNcolumns, 40,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, labelwdg,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET / 2,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_SEARCH_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_SEARCH_WDG_OFFSET, NULL);
+ textwdg = XmCreateText(formwdg, "Text", args, nargs);
+ XtAddCallback(textwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) "SearchText");
+ XtAddCallback(textwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) "SearchText");
+ XtAddCallback(textwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) "SearchText");
+ (void) uiAddWidgetInfo("SearchText", textwdg, uiWTtext); /* Ignore */
+ XtManageChild(textwdg);
+
+ return textwdg;
+}
+
+
+static Widget
+ uicreatesearchlevel(formwdg, textwdg)
+Widget formwdg;
+Widget textwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ XmString labelstr;
+ Widget labelwdg, levelwdg;
+
+ labelstr = XmStringCreateSimple("Depth of search:");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, textwdg,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_SEARCH_WDG_OFFSET, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "LevelLabel", args, nargs);
+ XtManageChild(labelwdg);
+ XmStringFree(labelstr);
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, labelwdg,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET / 2,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_SEARCH_WDG_OFFSET,
+ XmNcolumns, 3,
+ XmNmaxLength, 3,
+ XmNvalue, "1", NULL);
+ levelwdg = XmCreateText(formwdg, "Level", args, nargs);
+ XtAddCallback(levelwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "SearchLevel");
+ XtAddCallback(levelwdg, XmNlosingFocusCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "SearchLevel");
+ XtAddCallback(levelwdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB,
+ (caddr_t) "SearchLevel");
+ (void) uiAddWidgetInfo("SearchLevel", levelwdg, uiWTtext); /* Ignore */
+ XtManageChild(levelwdg);
+
+ return levelwdg;
+}
+
+
+static Widget
+ uicreatesearchlevelform(formwdg, levelwdg)
+Widget formwdg;
+Widget levelwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget levelformwdg;
+ uiSearchGfx_t *searchgfx = &uiTopLevel.SearchGfx;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNtopWidget, levelwdg,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, levelwdg,
+ XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNbottomWidget, levelwdg, NULL);
+ levelformwdg = XmCreateForm(formwdg, "LevelForm", args, nargs);
+ XtManageChild(levelformwdg);
+
+ searchgfx->LevelDownWdg = uicreatesearchleveldown(levelformwdg);
+ searchgfx->LevelUpWdg = uicreatesearchlevelup(levelformwdg);
+
+ return levelformwdg;
+}
+
+
+static Widget
+ uicreatesearchleveldown(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget leveldownwdg;
+ char *actionname = "LevelDown";
+ static uiActionData_t actiondata;
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_DOWN,
+ XmNwidth, 15,
+ XmNtopAttachment, XmATTACH_POSITION,
+ XmNtopPosition, 50,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ leveldownwdg = XmCreateArrowButtonGadget(formwdg, actionname,
+ args, nargs);
+ actiondata.ActionName = actionname;
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(leveldownwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) & actiondata);
+ UiAttachCallback(actionname, uisearchlevelcb, (void *) actionname);
+ XtManageChild(leveldownwdg);
+
+ return leveldownwdg;
+}
+
+
+static Widget
+ uicreatesearchlevelup(formwdg)
+Widget formwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget levelupwdg;
+ char *actionname = "LevelUp";
+ static uiActionData_t actiondata;
+
+ args = uiVaSetArgs(&nargs,
+ XmNarrowDirection, XmARROW_UP,
+ XmNwidth, 15,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_POSITION,
+ XmNbottomPosition, 50, NULL);
+ levelupwdg = XmCreateArrowButtonGadget(formwdg, "LevelUp",
+ args, nargs);
+ actiondata.ActionName = actionname;
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(levelupwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) & actiondata);
+ UiAttachCallback(actionname, uisearchlevelcb, (void *) actionname);
+ XtManageChild(levelupwdg);
+
+ return levelupwdg;
+}
+
+
+static Widget
+ uicreatesearchcase(formwdg, levelwdg)
+Widget formwdg;
+Widget levelwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget casewdg;
+
+ labelstr = XmStringCreateSimple("Case sensitive");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNtopWidget, levelwdg,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 30,
+ XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNbottomWidget, levelwdg, NULL);
+ casewdg = XmCreateToggleButtonGadget(formwdg, "Case", args, nargs);
+ XtAddCallback(casewdg, XmNvalueChangedCallback,
+ (XtCallbackProc) uiDialogVariableCB, (caddr_t) "SearchCase");
+ /* Ignore */
+ (void) uiAddWidgetInfo("SearchCase", casewdg, uiWTcheckbutton);
+ XtManageChild(casewdg);
+
+ return casewdg;
+}
+
+
+static Widget
+ uicreatesearchbackward(formwdg, textwdg)
+Widget formwdg;
+Widget textwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget backwardwdg;
+ char *actionname = "SearchBackward";
+ static uiActionData_t actiondata;
+
+ labelstr = XmStringCreateSimple("Search backward");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, textwdg,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNrightWidget, textwdg, NULL);
+ backwardwdg = XmCreatePushButtonGadget(formwdg, "SearchBackward",
+ args, nargs);
+ actiondata.ActionName = actionname;
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(backwardwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) & actiondata);
+ XtManageChild(backwardwdg);
+ XmStringFree(labelstr);
+
+ return backwardwdg;
+}
+
+
+static Widget
+ uicreatesearchforward(formwdg, backwardwdg)
+Widget formwdg;
+Widget backwardwdg;
+{
+ XmString labelstr;
+ ArgList args;
+ Cardinal nargs;
+ Widget forwardwdg;
+ char *actionname = "SearchForward";
+ static uiActionData_t actiondata;
+
+ labelstr = XmStringCreateSimple("Search forward");
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, labelstr,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, backwardwdg,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET / 2,
+ XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNleftWidget, backwardwdg,
+ XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNrightWidget, backwardwdg, NULL);
+ forwardwdg = XmCreatePushButtonGadget(formwdg, "SearchForward",
+ args, nargs);
+ actiondata.ActionName = actionname;
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(forwardwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) & actiondata);
+ XtManageChild(forwardwdg);
+ XmStringFree(labelstr);
+
+ return forwardwdg;
+}
+
+
+static Widget
+ uicreatesearchclose(parentwdg, topwdg)
+Widget parentwdg;
+Widget topwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+ Widget tmpwdg;
+ static uiActionData_t actiondata;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, topwdg,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(parentwdg, "SearchSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ tmpwdg = XmCreatePushButtonGadget(parentwdg, "Close", (ArgList) NULL, 0);
+ XtVaSetValues(tmpwdg,
+ XmNwidth, 70,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_SEARCH_WDG_OFFSET,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, separatorwdg,
+ XmNtopOffset, UI_SEARCH_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, UI_SEARCH_WDG_OFFSET, NULL);
+ actiondata.ActionName = "SearchClose";
+ actiondata.Page = uiPageInfo.CurrentPage;
+ XtAddCallback(tmpwdg, XmNactivateCallback,
+ (XtCallbackProc) uiDialogActivateCB, (caddr_t) & actiondata);
+ UiAttachCallback("SearchClose", uisearchclosecb, "SearchClose");
+
+ XtManageChild(tmpwdg);
+
+ return tmpwdg;
+}
+
+
+static Widget
+ uicreatesearchlabel(formwdg, rightwdg)
+Widget formwdg;
+Widget rightwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget labelwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNtopWidget, rightwdg,
+ XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNbottomWidget, rightwdg,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, UI_SEARCH_WDG_OFFSET,
+ XmNrightAttachment, XmATTACH_WIDGET,
+ XmNrightWidget, rightwdg,
+ XmNrightOffset, UI_SEARCH_WDG_OFFSET, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "Label", args, nargs);
+ XtManageChild(labelwdg);
+
+ return labelwdg;
+}
+
+
+static void uisearchlevelcb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ Widget levelwdg = uiTopLevel.SearchGfx.LevelWdg;
+ char *leveltext;
+ int level;
+ char tmpbuffer[4];
+
+ leveltext = XmTextGetString(levelwdg);
+ level = atoi(leveltext);
+
+ if (!strcmp("LevelDown", (char *) parameter)) {
+ if (level > 1) {
+ level--;
+ sprintf(tmpbuffer, "%d", level);
+ XmTextSetString(levelwdg, tmpbuffer);
+ }
+ } else if (level < 1) {
+ level++;
+ sprintf(tmpbuffer, "%d", level);
+ XmTextSetString(levelwdg, tmpbuffer);
+ }
+ XtFree(leveltext);
+}
+
+
+static void uisearchclosecb(address, htext, htextobject, parameter)
+char *address;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.SearchGfx.FormWdg));
+}
--- /dev/null
+static char *rcsid = "$Id: UiSelectionBox.c,v 1.3 1992/03/26 18:13:50 kny Exp $";
+
+#include "UiIncludes.h"
+
+
+static Widget uicreatesbformdialog();
+static Widget
+ uicreatesbfsbox(Widget formwdg,
+ void (*callback) (char *nodename));
+static Widget uicreatesbseparator(Widget formwdg, Widget fsboxwdg);
+static Widget uicreatesbadd(Widget formwdg, Widget fsboxwdg,
+ Widget separatorwdg);
+static Widget uicreatesbdelete(Widget formwdg, Widget fsboxwdg);
+static Widget uicreatesblist(Widget formwdg, Widget deletewdg,
+ Widget separatorwdg);
+static char *uifixselection(char *selection);
+
+static void uiselectionboxokcb(Widget wdg, caddr_t callback,
+ XmPushButtonCallbackStruct * calldata);
+static void uiselectionboxcancelcb(Widget wdg, caddr_t ignored,
+ XmPushButtonCallbackStruct * calldata);
+static void uiselectionboxaddcb(Widget wdg, caddr_t ignored,
+ XmPushButtonCallbackStruct * calldata);
+static void uiselectionboxdeletecb(Widget wdg, caddr_t ignored,
+ XmPushButtonCallbackStruct * calldata);
+static void uiselectionboxclickcb(Widget wdg, caddr_t ignored,
+ XmListCallbackStruct * calldata);
+static void uiselectionboxupdateconfig(void);
+
+
+uiTopLevel_t uiTopLevel;
+char **uiSelectionArray;
+
+
+static int uidummy;
+
+
+int UiDisplaySelectionBox(callback)
+void (*callback) (char *nodename);
+{
+ uiSelectionBoxGfx_t *sbgfx = &uiTopLevel.SBGfx;
+ XmString dummystr;
+ int i = 0;
+
+ if (sbgfx->FormWdg) {
+ XtMapWidget(XtParent(sbgfx->FormWdg));
+
+ return UI_OK;
+ }
+ sbgfx->FormWdg = uicreatesbformdialog();
+ sbgfx->FSBoxWdg = uicreatesbfsbox(sbgfx->FormWdg, callback);
+ sbgfx->SeparatorWdg = uicreatesbseparator(sbgfx->FormWdg, sbgfx->FSBoxWdg);
+ sbgfx->AddWdg = uicreatesbadd(sbgfx->FormWdg, sbgfx->FSBoxWdg,
+ sbgfx->SeparatorWdg);
+ sbgfx->DeleteWdg = uicreatesbdelete(sbgfx->FormWdg, sbgfx->FSBoxWdg);
+ sbgfx->ListWdg = uicreatesblist(sbgfx->FormWdg, sbgfx->DeleteWdg,
+ sbgfx->SeparatorWdg);
+
+ XtManageChild(sbgfx->FormWdg);
+ XtRealizeWidget(XtParent(sbgfx->FormWdg));
+
+ if (!uiSelectionArray) {
+ dummystr = XmStringCreateSimple(" ");
+ XmListAddItem(uiTopLevel.SBGfx.ListWdg, dummystr, 0);
+ XtSetSensitive(uiTopLevel.SBGfx.ListWdg, FALSE);
+ XmStringFree(dummystr);
+ uidummy = TRUE;
+ } else {
+ while (uiSelectionArray[i]) {
+ dummystr = XmStringCreateSimple(uiSelectionArray[i++]);
+ XmListAddItem(uiTopLevel.SBGfx.ListWdg, dummystr, 0);
+ XmStringFree(dummystr);
+ }
+ uidummy = FALSE;
+ }
+
+ return UI_OK;
+}
+
+
+static Widget
+ uicreatesbformdialog()
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget formwdg;
+ Widget topwdg;
+
+ topwdg = XtCreateApplicationShell("SelectionBox",
+ topLevelShellWidgetClass,
+ NULL, 0);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "SelectionBox",
+ args, nargs);
+
+ return formwdg;
+}
+
+
+static Widget
+ uicreatesbfsbox(formwdg, callback)
+Widget formwdg;
+void (*callback) (char *nodename);
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget fsboxwdg, textwdg, okwdg, cancelwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, 1,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNleftOffset, 1,
+ XmNbottomOffset, 1,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ fsboxwdg = XmCreateFileSelectionBox(formwdg, "FSBox",
+ args, nargs);
+ XtUnmanageChild(XmFileSelectionBoxGetChild(fsboxwdg,
+ XmDIALOG_HELP_BUTTON));
+
+ textwdg = XmFileSelectionBoxGetChild(fsboxwdg, XmDIALOG_TEXT);
+ XmTextSetString(textwdg, "");
+
+ okwdg = XmFileSelectionBoxGetChild(fsboxwdg, XmDIALOG_OK_BUTTON);
+ XtAddCallback(okwdg, XmNactivateCallback, uiselectionboxokcb,
+ (caddr_t) callback);
+
+ cancelwdg = XmFileSelectionBoxGetChild(fsboxwdg, XmDIALOG_CANCEL_BUTTON);
+ XtAddCallback(cancelwdg, XmNactivateCallback, uiselectionboxcancelcb,
+ (caddr_t) NULL);
+ XtManageChild(fsboxwdg);
+
+ return fsboxwdg;
+}
+
+
+static Widget
+ uicreatesbseparator(formwdg, fsboxwdg)
+Widget formwdg;
+Widget fsboxwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget separatorwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNorientation, XmVERTICAL,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, fsboxwdg,
+ XmNleftOffset, 10,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNbottomAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(formwdg, "Separator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ return separatorwdg;
+}
+
+
+static Widget
+ uicreatesbadd(formwdg, fsboxwdg, separatorwdg)
+Widget formwdg;
+Widget fsboxwdg;
+Widget separatorwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget addwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNwidth, 70,
+ XmNleftOffset, 20,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNbottomWidget, fsboxwdg,
+ XmNbottomOffset, 20,
+ XmNleftWidget, separatorwdg, NULL);
+ addwdg = XmCreatePushButtonGadget(formwdg, "Add",
+ args, nargs);
+ XtManageChild(addwdg);
+ XtAddCallback(addwdg, XmNactivateCallback, uiselectionboxaddcb,
+ (caddr_t) NULL);
+
+ return addwdg;
+}
+
+
+static Widget
+ uicreatesbdelete(formwdg, fsboxwdg)
+Widget formwdg;
+Widget fsboxwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget deletewdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNwidth, 70,
+ XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
+ XmNbottomWidget, fsboxwdg,
+ XmNbottomOffset, 20,
+ XmNrightOffset, 10,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ deletewdg = XmCreatePushButtonGadget(formwdg, "Delete",
+ args, nargs);
+ XtManageChild(deletewdg);
+ XtAddCallback(deletewdg, XmNactivateCallback, uiselectionboxdeletecb,
+ (caddr_t) NULL);
+
+ return deletewdg;
+}
+
+
+static Widget
+ uicreatesblist(formwdg, deletewdg, separatorwdg)
+Widget formwdg;
+Widget deletewdg;
+Widget separatorwdg;
+{
+ ArgList args;
+ Cardinal nargs;
+ Widget listwdg;
+
+ args = uiVaSetArgs(&nargs,
+ XmNvisibleItemCount, 15,
+ XmNwidth, 200,
+ XmNselectionPolicy, XmSINGLE_SELECT,
+ XmNlistSizePolicy, XmCONSTANT,
+ XmNscrollBarDisplayPolicy, XmSTATIC,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, 11,
+ XmNbottomAttachment, XmATTACH_WIDGET,
+ XmNbottomWidget, deletewdg,
+ XmNbottomOffset, 20,
+ XmNrightAttachment, XmATTACH_FORM,
+ XmNrightOffset, 11,
+ XmNleftOffset, 20,
+ XmNleftAttachment, XmATTACH_WIDGET,
+ XmNleftWidget, separatorwdg, NULL);
+ listwdg = XmCreateScrolledList(formwdg, "List",
+ args, nargs);
+ XtManageChild(listwdg);
+ XtAddCallback(listwdg, XmNdefaultActionCallback, uiselectionboxclickcb,
+ (caddr_t) NULL);
+
+ return listwdg;
+}
+
+
+static char *
+ uifixselection(selection)
+char *selection;
+{
+ char *newselection;
+
+ if (!selection)
+ return selection;
+
+ if (index(selection, ':'))
+ return strdup(selection);
+
+ newselection = uiMalloc(strlen(selection) + strlen("file:") + 1);
+ strcpy(newselection, "file:");
+ strcat(newselection, selection);
+
+ return newselection;
+}
+
+
+static void uiselectionboxokcb(wdg, callback, calldata)
+Widget wdg;
+caddr_t callback;
+XmPushButtonCallbackStruct *calldata;
+{
+ Widget textwdg;
+ char *selection, *fixedselection;
+
+ textwdg = XmFileSelectionBoxGetChild(uiTopLevel.SBGfx.FSBoxWdg,
+ XmDIALOG_TEXT);
+ selection = XmTextGetString(textwdg);
+ fixedselection = uifixselection(selection);
+ XtUnmapWidget(XtParent(uiTopLevel.SBGfx.FormWdg));
+ (*(void (*) (char *nodename)) callback) (fixedselection);
+
+ XtFree(selection);
+ XtFree(fixedselection);
+}
+
+
+static void uiselectionboxcancelcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmPushButtonCallbackStruct *calldata;
+{
+ XtUnmapWidget(XtParent(uiTopLevel.SBGfx.FormWdg));
+}
+
+
+static void uiselectionboxaddcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmPushButtonCallbackStruct *calldata;
+{
+ Widget textwdg;
+ char *selection, *fixedselection;
+ XmString selectionstr;
+ int *poslist;
+ int poscount;
+
+ textwdg = XmFileSelectionBoxGetChild(uiTopLevel.SBGfx.FSBoxWdg,
+ XmDIALOG_TEXT);
+ selection = XmTextGetString(textwdg);
+ fixedselection = uifixselection(selection);
+
+ if (fixedselection && fixedselection[0]) {
+ selectionstr = XmStringCreateSimple(fixedselection);
+ if (uidummy) {
+ XmListDeletePos(uiTopLevel.SBGfx.ListWdg, 1);
+ XtSetSensitive(uiTopLevel.SBGfx.ListWdg, TRUE);
+ uidummy = FALSE;
+ }
+ if (XmListGetSelectedPos(uiTopLevel.SBGfx.ListWdg, &poslist,
+ &poscount)) {
+ XmListDeselectPos(uiTopLevel.SBGfx.ListWdg, poslist[0]);
+ XmListAddItem(uiTopLevel.SBGfx.ListWdg, selectionstr, poslist[0]);
+ XmListSelectPos(uiTopLevel.SBGfx.ListWdg, poslist[0] + 1, FALSE);
+ XtFree(poslist);
+ } else
+ XmListAddItem(uiTopLevel.SBGfx.ListWdg, selectionstr, 0);
+ XmStringFree(selectionstr);
+ }
+ XtFree(selection);
+ XtFree(fixedselection);
+
+ uiselectionboxupdateconfig();
+}
+
+
+static void uiselectionboxdeletecb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmPushButtonCallbackStruct *calldata;
+{
+ int *poslist;
+ int poscount;
+ XmString dummystr;
+
+ /* We should have only one selected item */
+ if (XmListGetSelectedPos(uiTopLevel.SBGfx.ListWdg, &poslist, &poscount)) {
+ XmListDeletePos(uiTopLevel.SBGfx.ListWdg, poslist[0]);
+ XmListSelectPos(uiTopLevel.SBGfx.ListWdg, poslist[0], FALSE);
+ XtFree(poslist);
+ }
+ if (!uiGetArg(uiTopLevel.SBGfx.ListWdg, XmNitemCount)) {
+ dummystr = XmStringCreateSimple(" ");
+ XmListAddItem(uiTopLevel.SBGfx.ListWdg, dummystr, 0);
+ XmStringFree(dummystr);
+ XtSetSensitive(uiTopLevel.SBGfx.ListWdg, FALSE);
+ uidummy = TRUE;
+ }
+ uiselectionboxupdateconfig();
+}
+
+
+static void uiselectionboxclickcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ Widget textwdg;
+ char *selection;
+
+ XmStringGetLtoR(calldata->item, XmSTRING_DEFAULT_CHARSET, &selection);
+ textwdg = XmFileSelectionBoxGetChild(uiTopLevel.SBGfx.FSBoxWdg,
+ XmDIALOG_TEXT);
+ XmTextSetString(textwdg, selection);
+ XtFree(selection);
+}
+
+
+static void uiselectionboxupdateconfig()
+{
+ Widget listwdg = uiTopLevel.SBGfx.ListWdg;
+ int nitems, i;
+ char **items;
+ XmStringTable stringtable;
+ void *table;
+
+ nitems = uiGetArg(listwdg, XmNitemCount);
+ items = (char **) uiMalloc((nitems + 1) * sizeof(*items));
+
+ stringtable = (XmStringTable) uiGetArg(listwdg, XmNitems);
+ for (i = 0; i < nitems; i++)
+ XmStringGetLtoR(stringtable[i], XmSTRING_DEFAULT_CHARSET, &items[i]);
+ items[nitems] = (char *) NULL;
+
+ table = uiConfigPF((void *) NULL, C_DEFAULTS);
+ (void) uiConfigSetPF(table, C_DEFAULTSTABLE, (void *) items);
+}
--- /dev/null
+typedef struct {
+ int TopMargin, BottomMargin;
+ int LeftMargin, RightMargin;
+ int UseFixed;
+ int FixedWidth;
+ int OnePageMode;
+} uiPageSettings_t;
+
+
+typedef struct {
+ int X, Y;
+ int Width, Height;
+ int VirtualWidth, VirtualHeight;
+} uiPageLayout_t;
+
+
+typedef struct {
+ Widget TopWdg;
+ Widget FormWdg;
+ Widget MenuWdg;
+ Widget DrawAreaWdg;
+ Widget HScrollBarWdg;
+ Widget VScrollBarWdg;
+ Widget FindFrameWdg;
+ Widget FindWdg;
+ Widget FindTextWdg;
+ Widget ControlWdg;
+} uiPageGfx_t;
+
+
+struct _uipage;
+
+typedef struct {
+ char *ActionName;
+ struct _uipage *Page;
+} uiActionData_t;
+
+
+typedef struct _pagecblist {
+ uiActionData_t ActionData;
+ struct _pagecblist *Next;
+} uiPageCBList_t;
+
+
+struct _uihierarchy;
+
+typedef struct _uipage {
+ HText_t *HText;
+ HTextObject_t *HTextObject;
+ int Visible;
+ struct _uihierarchy *Hierarchy;
+ uiPageSettings_t Settings;
+ uiPageLayout_t Layout;
+ uiPageGfx_t Gfx;
+ uiPageCBList_t *Callbacks;
+ struct _uipage *Next;
+} uiPage_t;
+
+
+typedef struct _uihierarchy {
+ char *Address;
+ uiPage_t *Pages;
+ struct _uihierarchy *Next;
+} uiHierarchy_t;
+
+
+typedef struct _uiaction {
+ char *Name;
+ void (*Callback) (char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+ void *Parameter;
+ struct _uiaction *Next;
+} uiAction_t;
+
+
+typedef struct _uikey {
+ char *Name;
+ int Modifier;
+ void (*Callback) (char *address, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+ void *Parameter;
+ struct _uikey *Next;
+} uiKey_t;
+
+
+typedef enum {
+ uiWTtext,
+ uiWToptionmenu,
+ uiWTradiobox,
+ uiWTcheckbutton,
+ uiWTscale
+} uiWdgType_t;
+
+
+typedef struct _uivariable {
+ char *Name;
+ void *Value;
+ uiVarType_t VarType;
+ Widget Wdg;
+ uiWdgType_t WdgType;
+ struct _uivariable *Next;
+} uiVariable_t;
+
+
+typedef struct {
+ int TopMargin, BottomMargin;
+ int LeftMargin, RightMargin;
+ int UseFixed;
+ int FixedWidth;
+ int OnePageMode;
+ int Width;
+ int Height;
+ int SearchPlacement;
+ int ControlPanelPlacement;
+ int ListPlacement;
+ int RecallPlacement;
+ int PageSettingsPlacement;
+ Time DoubleClickTime;
+} uiGlobalSettings_t;
+
+
+typedef struct {
+ Widget TopWdg;
+ Widget FormWdg;
+ Widget InfoWdg;
+ Widget OpenWdg;
+ Widget QuitWdg;
+ Widget HelpWdg;
+} uiTopLevelGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget FSBoxWdg;
+ Widget SeparatorWdg;
+ Widget ListWdg;
+ Widget AddWdg;
+ Widget DeleteWdg;
+} uiSelectionBoxGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget TextWdg;
+ Widget LevelWdg;
+ Widget LevelFormWdg;
+ Widget LevelDownWdg;
+ Widget LevelUpWdg;
+ Widget CaseWdg;
+ Widget BackwardWdg;
+ Widget ForwardWdg;
+ Widget LabelWdg;
+ Widget CloseWdg;
+} uiSearchGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget LabelWdg;
+ Widget LeftMarginWdg;
+ Widget RightMarginWdg;
+ Widget TopMarginWdg;
+ Widget BottomMarginWdg;
+ Widget LeftMarginTextWdg;
+ Widget RightMarginTextWdg;
+ Widget TopMarginTextWdg;
+ Widget BottomMarginTextWdg;
+ Widget UseFixedWdg;
+ Widget UseFixedTextWdg;
+ Widget SinglePageWdg;
+} uiPageSettingsGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget PrintCmdWdg;
+ Widget PrintFileWdg;
+ Widget LeftMarginWdg;
+ Widget RightMarginWdg;
+ Widget TopMarginWdg;
+ Widget BottomMarginWdg;
+ Widget LeftMarginTextWdg;
+ Widget RightMarginTextWdg;
+ Widget TopMarginTextWdg;
+ Widget BottomMarginTextWdg;
+ Widget WidthWdg;
+} uiPrintGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget LabelWdg;
+ Widget ListWdg;
+ Widget SeparatorWdg;
+ Widget OpenWdg;
+ Widget CloseWdg;
+} uiListGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget LabelWdg;
+ Widget ListWdg;
+ Widget SeparatorWdg;
+ Widget OpenWdg;
+ Widget CloseWdg;
+} uiRecallGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget OkWdg;
+} uiInfoGfx_t;
+
+
+typedef struct {
+ Widget SearchWdg;
+ Widget FormWdg;
+ Widget HomeWdg;
+ Widget RecallWdg;
+ Widget CloseWdg;
+ Widget LabelWdg;
+ Widget DialogCloseWdg;
+ Widget ListWdg;
+} uiControlPanelGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget LabelWdg;
+ Widget SearchWindow;
+ Widget ControlPanel;
+ Widget ListWindow;
+ Widget RecallWindow;
+ Widget PageSettings;
+ Widget CloseWdg;
+} uiDefaultsGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget LabelWdg;
+ Widget KillWdg;
+ Widget CloseWdg;
+ Widget SeparatorWdg;
+ Widget ListWdg;
+} uiConnectionsGfx_t;
+
+
+typedef struct {
+ Widget FormWdg;
+ Widget FSBoxWdg;
+} uiFileSelectionGfx_t;
+
+
+typedef struct {
+ uiHierarchy_t *Hierarchies;
+ uiAction_t *Actions;
+ uiKey_t *Keys;
+ uiVariable_t *Variables;
+ uiGlobalSettings_t GlobalSettings;
+ uiTopLevelGfx_t TopGfx;
+ uiSelectionBoxGfx_t SBGfx;
+ uiSearchGfx_t SearchGfx;
+ uiPageSettingsGfx_t PageSettingsGfx;
+ uiListGfx_t ListGfx;
+ uiRecallGfx_t RecallGfx;
+ uiInfoGfx_t InfoGfx;
+ uiControlPanelGfx_t ControlPanelGfx;
+ uiDefaultsGfx_t DefaultsGfx;
+ uiPrintGfx_t PrintGfx;
+ uiConnectionsGfx_t ConnectionsGfx;
+ uiFileSelectionGfx_t FSGfx;
+} uiTopLevel_t;
+
+
+typedef struct {
+ uiPage_t *CurrentPage;
+ Widget Wdg;
+ void *CallData;
+} uiPageInfo_t;
--- /dev/null
+static char *rcsid = "$Id$";
+
+#include "UiIncludes.h"
+
+
+static void uiwarningokcb(Widget wdg, caddr_t callback,
+ XmListCallbackStruct * calldata);
+static void uiwarningcancelcb(Widget wdg, caddr_t callback,
+ XmListCallbackStruct * calldata);
+
+int UiDisplayWarningDialog(warning, callback)
+char *warning;
+void (*callback) (int button);
+{
+ Widget labelwdg;
+ Widget separatorwdg;
+ Widget okwdg;
+ Widget cancelwdg;
+ XmString warningstr;
+ ArgList args;
+ Cardinal nargs;
+ Window root, child;
+ int root_x, root_y, win_x, win_y;
+ unsigned int mask;
+ Widget formwdg;
+ Widget topwdg;
+ char tmpstr[11];
+
+ if (XQueryPointer(XtDisplay(uiTopLevel.TopGfx.TopWdg),
+ XtWindow(uiTopLevel.TopGfx.TopWdg), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &mask)) {
+ sprintf(tmpstr, "+%d+%d", root_x - 50, root_y - 50);
+
+ topwdg = XtCreateApplicationShell("Warning",
+ topLevelShellWidgetClass,
+ NULL, 0);
+ XtVaSetValues(topwdg,
+ XmNgeometry, tmpstr, NULL);
+
+ args = uiVaSetArgs(&nargs,
+ XmNresizePolicy, XmRESIZE_NONE,
+ XmNautoUnmanage, FALSE, NULL);
+ formwdg = XmCreateForm(topwdg, "WarningDialog", args, nargs);
+
+ warningstr = XmStringCreateSimple(warning);
+ args = uiVaSetArgs(&nargs,
+ XmNlabelString, warningstr,
+ XmNtopAttachment, XmATTACH_FORM,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ labelwdg = XmCreateLabelGadget(formwdg, "WarningLabel",
+ args, nargs);
+ XtManageChild(labelwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, labelwdg,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNleftAttachment, XmATTACH_FORM,
+ XmNrightAttachment, XmATTACH_FORM, NULL);
+ separatorwdg = XmCreateSeparatorGadget(formwdg, "WarningSeparator",
+ args, nargs);
+ XtManageChild(separatorwdg);
+
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 5,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 40,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, separatorwdg,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET, NULL);
+ okwdg = XmCreatePushButtonGadget(formwdg, "Ok", args, nargs);
+ XtAddCallback(okwdg, XmNactivateCallback,
+ (XtCallbackProc) uiwarningokcb, (caddr_t) callback);
+ XtManageChild(okwdg);
+
+ if (callback) {
+ args = uiVaSetArgs(&nargs,
+ XmNleftAttachment, XmATTACH_POSITION,
+ XmNleftPosition, 60,
+ XmNrightAttachment, XmATTACH_POSITION,
+ XmNrightPosition, 95,
+ XmNtopAttachment, XmATTACH_WIDGET,
+ XmNtopWidget, separatorwdg,
+ XmNtopOffset, UI_LIST_WDG_OFFSET,
+ XmNbottomAttachment, XmATTACH_FORM,
+ XmNbottomOffset, UI_LIST_WDG_OFFSET, NULL);
+ cancelwdg = XmCreatePushButtonGadget(formwdg, "Cancel",
+ args, nargs);
+ XtAddCallback(cancelwdg, XmNactivateCallback,
+ (XtCallbackProc) uiwarningcancelcb,
+ (caddr_t) callback);
+ XtManageChild(cancelwdg);
+ }
+ XtManageChild(formwdg);
+ XtRealizeWidget(XtParent(formwdg));
+
+ return UI_OK;
+ }
+}
+
+
+static void uiwarningokcb(wdg, callback, calldata)
+Widget wdg;
+caddr_t callback;
+XmListCallbackStruct *calldata;
+{
+ int button = UI_OK;
+
+ if (callback)
+ (*(void (*) (int button)) callback) (UI_OK);
+
+ XtUnmapWidget(XtParent(XtParent(wdg)));
+}
+
+
+static void uiwarningcancelcb(wdg, ignored, calldata)
+Widget wdg;
+caddr_t ignored;
+XmListCallbackStruct *calldata;
+{
+ XtUnmapWidget(XtParent(XtParent(wdg)));
+}
--- /dev/null
+#
+#
+#
+
+ OBJS = XlFormatText.o XlSetup.o XlUtil.o XlWindow.o XlStyle.o
+ SRCS = XlFormatText.c XlSetup.c XlUtil.c XlWindow.c XlStyle.c
+
+ XLDIR = ../Xl
+ HTDIR = ../HText
+ WWWDIR = ../Cl/WWWLibrary
+ MOTIF_HDRS = -I/p/motif/include
+ ERWISE_HDRS = -I$(XLDIR) -I$(HTDIR) -I$(WWWDIR)
+ DEFINES = $(ERWISE_HDRS) $(MOTIF_HDRS)
+
+NormalLibraryTarget(Xl, $(OBJS))
+
+DependTarget()
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a10887>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../.
+ CURRENT_DIR = ./Xl
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+
+ OBJS = XlFormatText.o XlSetup.o XlUtil.o XlWindow.o XlStyle.o
+ SRCS = XlFormatText.c XlSetup.c XlUtil.c XlWindow.c XlStyle.c
+
+ XLDIR = ../Xl
+ HTDIR = ../HText
+ WWWDIR = ../Cl/WWWLibrary
+ MOTIF_HDRS = -I/p/motif/include
+ ERWISE_HDRS = -I$(XLDIR) -I$(HTDIR) -I$(WWWDIR)
+ DEFINES = $(ERWISE_HDRS) $(MOTIF_HDRS)
+
+all:: libXl.a
+
+libXl.a: $(OBJS)
+ $(RM) $@
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+depend::
+ $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+/*
+ * Xl.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Tue Mar 10 20:43:22 1992 tvr
+ * Last modified: Wed May 13 06:21:11 1992 tvr
+ *
+ */
+
+
+/*
+ * Prototypes
+ */
+int XlFormatText(int leftmargin, int width, int topmargin,
+ int *vwidth, int *vheight, HText_t * htext);
+
+int XlSetupResources(void *(*func) (void *, char *));
+
+int XlSetupText(Display * display, Window window,
+ unsigned long fg,
+ unsigned long bg,
+ HText_t * htext);
+
+void XlSetPageCoordinates(int virtualx, int virtualy, HText_t * htext);
+
+void XlGetCoordinates(int *virtualx, int *virtualy,
+ HTextObject_t * htextobject);
+
+HTextObject_t *XlLocateHTextObject(int windowx, int windowy,
+ HText_t * htext);
+
+void XlDeleteText(HText_t * htext);
+
+void XlRedraw(int windowx, int windowy, int width, int height,
+ HText_t * htext);
+
+void XlMoveWindow(int newvx, int newvy, HText_t * htext);
+
+void XlClearWindow(int width, int height, HText_t * htext);
+
+void XlSetCursor(HText_t * htext, HTextObject_t * object);
--- /dev/null
+/*
+ * XlConfig.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Wed May 13 06:21:04 1992 tvr
+ * Last modified: Wed May 13 06:21:14 1992 tvr
+ *
+ */
+
+
+/*
+ * Fucking configurestuff here
+ */
+
+#define C_FONTS "Fonts"
+
+#define C_FONT_NORMAL "normal"
+#define C_FONT_LIST "list"
+#define C_FONT_LISTCOMPACT "listcompact"
+#define C_FONT_GLOSSARY "glossary"
+#define C_FONT_GLOSSARYCOMPACT "glossarycompact"
+#define C_FONT_EXAMPLE "example"
+#define C_FONT_LISTING "listing"
+#define C_FONT_ADDRESS "address"
+#define C_FONT_HEADER1 "header1"
+#define C_FONT_HEADER2 "header2"
+#define C_FONT_HEADER3 "header3"
+#define C_FONT_HEADER4 "header4"
+#define C_FONT_HEADER5 "header5"
+#define C_FONT_HEADER6 "header6"
+#define C_FONT_HEADER7 "header7"
--- /dev/null
+/*
+ * XlDefaultFonts.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Sat Mar 7 03:33:24 1992 tvr
+ * Last modified: Mon Mar 9 05:27:20 1992 tvr
+ *
+ */
+
+#define FONT_NORMAL "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1"
+
+#define FONT_LIST "8x13"
+
+#define FONT_LISTCOMPACT "6x13"
+
+#define FONT_GLOSSARY "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1"
+
+#define FONT_GLOSSARYCOMPACT "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1"
+
+/*
+ * Text on the LISTING tag is to be portrayed in a fixed width font, so that any formatting done by
+ * character spacing on successive lines will be maintained.
+ *
+ * At least 132 characters have to fit on a line.
+ */
+#define FONT_EXAMPLE "7x13"
+
+#define FONT_LISTING "7x13"
+
+#define FONT_ADDRESS "8x13"
+
+#define FONT_HEADER1 "-adobe-times-medium-r-normal--20-140-100-100-p-96-iso8859-1"
+
+#define FONT_HEADER2 "-adobe-times-medium-r-normal--18-180-75-75-p-94-iso8859-1"
+
+#define FONT_HEADER3 "-adobe-times-medium-r-normal--17-120-100-100-p-84-iso8859-1"
+
+#define FONT_HEADER4 "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"
+
+#define FONT_HEADER5 "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"
+
+#define FONT_HEADER6 "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"
+
+#define FONT_HEADER7 "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"
--- /dev/null
+/*
+ * XlFormatText.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Tue Mar 3 02:54:45 1992 tvr
+ * Last modified: Tue May 12 04:26:29 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#include "HTAnchor.h"
+#include "HTStyle.h"
+#include "../HText/HText.h"
+
+#include "XlFormatText.h"
+
+int xl_calc_position();
+int xl_character_width();
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+/*
+ * Set up how to format text (current left and right margins)
+ */
+void xl_set_margins(p, left, right, c_l, c_r, x, y, low_y, m)
+HTextObject_t *p;
+int left, right;
+int *c_l, *c_r;
+int *x, *y;
+int low_y;
+int m;
+{
+ int i;
+
+ switch (m) {
+ case MARGIN_START_STYLE:
+ i = xl_object_mode(p);
+
+ *c_l = xl_calc_position(p, I_LEFT, left, right);
+
+ *x = xl_calc_position(p, I_LEFT | I_FIRST, left, right);
+
+ if (i & STYLE_RAW) {
+ *c_r = INT_MAX;
+ } else {
+
+ if (i & STYLE_CHANGE_REGION_ON_TAB) {
+
+ *c_r = xl_calc_position(p, I_MIDDLE_L, left, right);
+
+ } else {
+
+ *c_r = xl_calc_position(p, I_RIGHT, left, right);
+
+ }
+ }
+ break;
+
+ case MARGIN_HANDLE_P_OBJECT:
+ if (xl_object_mode(p) & STYLE_CHANGE_REGION_ON_TAB) {
+
+ *c_l = xl_calc_position(p, I_MIDDLE_R, left, right);
+ *c_r = xl_calc_position(p, I_RIGHT, left, right);
+ *y = low_y;
+ *x = xl_calc_position(p, I_MIDDLE_R | I_FIRST, left, right);
+
+ } else {
+
+ *x += 60; /* :-) */
+
+#ifdef XL_DEBUG
+ printf("xl_set_margins(): normal tab ... barf\n");
+#endif
+ }
+ break;
+
+#ifdef XL_DEBUG
+ default:
+ printf("xl_set_margins: illegal mode\n");
+#endif
+ }
+}
+
+
+/*
+ * Check how many objects belongs to this line.
+ */
+int xl_check_objects(pp, x_corner, y, right)
+HTextObject_t **pp;
+int *x_corner;
+int y;
+int right;
+{
+ HTextObject_t *p, *p_old;
+
+ int x;
+
+ int r = 0;
+
+ p = *pp;
+
+ p_old = NULL;
+
+ x = *x_corner;
+
+ while (!r) {
+ /*
+ * Region ends ?
+ */
+ if (!p || (p->paragraph)) {
+ r |= FORMAT_REGION_ENDS;
+ }
+ /*
+ * End of text
+ */
+ if (!p) {
+ break;
+ }
+ /*
+ * New style?
+ */
+ if (p_old && (p_old->style != p->style)) {
+ r |= FORMAT_NEW_STYLE;
+ r |= FORMAT_REGION_ENDS;
+ }
+ /*
+ * Text full ?
+ */
+ if ((x + p->width) >= right) {
+ r |= FORMAT_NEXT_OBJECT_TOO_LONG;
+ }
+ /*
+ * Setup object
+ */
+ p->x = x;
+ p->y = y;
+
+ x += p->width + xl_wordgap(p);
+
+
+ if (!r) {
+ p_old = p;
+
+ p = p->next;
+ }
+ }
+
+ /*
+ * Return pointer to where to go on.
+ */
+ if (p_old) {
+ *pp = p;
+ }
+ *x_corner = x;
+
+ return r;
+}
+
+/*
+ * Set new x-koordinate if line of objects is not 'leftified'
+ * Set new y coordinate above all objects.
+ */
+void xl_modify_objects(p_start, p_end, right, mode)
+HTextObject_t *p_start;
+HTextObject_t *p_end;
+int right;
+int mode;
+{
+ HTextObject_t *p = p_start;
+ HTextObject_t *p_last;
+
+ int offset;
+
+ /*
+ * Set last object
+ */
+
+ if (p_start == p_end) {
+
+#ifdef XL_DEBUG
+ if (!p_start->paragraph) {
+ printf("zero object ?\n");
+ }
+#endif
+ p_last = p_start;
+
+ } else if (p_end) {
+
+ p_last = p_end->prev;
+
+ } else {
+
+ for (p_last = p; p_last->next; p_last = p_last->next);
+
+ }
+
+ switch (xl_object_style(p_start)) {
+ case STYLE_LEFTIFY:
+ /*
+ * Do nothing.
+ */
+ break;
+
+ case STYLE_CENTER:
+
+ offset = (right - (p_last->x + p_last->width)) / 2;
+
+ for (p; p != p_end; p = p->next) {
+ p->x += offset;
+ }
+ break;
+
+#ifdef XL_DEBUG
+ default:
+ printf("Style not supported yet\n");
+#endif
+ }
+#if 0
+ *newy = p_start->y + xl_lineheightandgap(p_start, p_end);
+#endif
+}
+
+
+/*
+ * width is a request which can be denied (in case of ftp-text for
+ * example)
+ * Maximum width used on the page is returned. Everything else on the screen
+ * is formatted using given width.
+ */
+int XlFormatText(leftmargin, width, topmargin, vwidth, vheight, htext)
+int leftmargin, width;
+int topmargin;
+int *vwidth, *vheight;
+HText_t *htext;
+{
+ int stepped_y;
+
+ int max_right_position = leftmargin;
+
+ /*
+ * Current x,y coordinates.
+ */
+ int x, y;
+
+ /*
+ * When there are many regions next to other, store starting
+ * upper and lower levels
+ */
+ int low_y = 0;
+ int high_y = 0;
+
+ /*
+ * current format region
+ */
+ int current_left;
+ int current_right;
+
+ /*
+ * Point out line
+ */
+ HTextObject_t *p = htext->first;
+
+ HTextObject_t *p_start = 0;
+
+ /*
+ * Should check ascend (if there is any text)
+ */
+ if (p) {
+
+ low_y = high_y = y = topmargin;
+
+ xl_set_margins(p, leftmargin, leftmargin + width,
+ ¤t_left, ¤t_right,
+ &x, &y, low_y, MARGIN_START_STYLE);
+ }
+ /*
+ * Loop through text
+ */
+ while (p) {
+ int mode;
+
+ int high_y_old;
+
+ stepped_y = 0;
+
+ high_y_old = y;
+
+ /*
+ * What objects are on this line ?
+ */
+ p_start = p;
+
+ mode = xl_check_objects(&p, &x, y, current_right);
+
+ /*
+ * Check for zero objects. This prevents endless loop and makes
+ * sure this object will be modified
+ */
+ if ((p == p_start) && p && !p->paragraph &&
+ (mode & FORMAT_NEXT_OBJECT_TOO_LONG)) {
+ mode |= FORMAT_ONLY_OBJECT_TOO_LONG;
+ p = p->next;
+ }
+ /*
+ * Update object positions if needs justifying etc
+ */
+ xl_modify_objects(p_start, p, current_right, mode);
+
+ /*
+ * Check maximum object x position
+ */
+
+ if (p && p->prev &&
+ ((p->prev->x + p->prev->width) > max_right_position)) {
+ max_right_position = p->prev->x + p->prev->width;
+ }
+ if (xl_object_mode(p_start) & STYLE_RAW) {
+ /*
+ * Raw style HTextObject paragraphs
+ */
+
+ if (p && p_start->paragraph) {
+ p = p->next;
+
+ }
+ switch (p_start->paragraph) {
+ case HTEXT_NEWLINE:
+ /*
+ * New line
+ */
+ x = current_left;
+
+ y += xl_linespace(p_start, p);
+
+ low_y = high_y = MAX(y, high_y);
+ break;
+
+ case HTEXT_TAB:
+ /*
+ * Tabulator
+ */
+#if 0
+ {
+ int i = 0;
+ HTextObject_t *pp;
+
+ for (pp = p_start; pp != p; pp = pp->next) {
+ switch (pp->paragraph) {
+ case 0:
+ i += pp->length;
+ break;
+
+ case HTEXT_TAB:
+ i = 0;
+ }
+ }
+
+ i = 8 - (i % 8);
+
+ x += xl_character_width(p_start) * i;
+ }
+#endif
+ {
+ int i;
+ int cl = xl_character_width(p_start);
+
+ i = ((x - leftmargin) % (cl * 8));
+
+ x += (cl * 8) - i;
+ }
+
+ break;
+ }
+ } else {
+ /*
+ * Hypertext style
+ */
+
+ /*
+ * Wrap
+ */
+ if (mode & FORMAT_NEXT_OBJECT_TOO_LONG) {
+ x = current_left;
+ y += xl_linespace(p_start, p);
+
+ high_y = MAX(y, high_y);
+
+ if (mode & FORMAT_ONLY_OBJECT_TOO_LONG) {
+ low_y = high_y;
+ }
+ stepped_y++;
+ }
+ /*
+ * Check paragraph objects
+ */
+ if (p_start->paragraph) {
+ switch (p_start->paragraph) {
+ case HTEXT_NEWLINE:
+
+ x = current_left;
+ if (!stepped_y) {
+ y += xl_linespace(p_start, p);
+
+ stepped_y++;
+
+ high_y = MAX(y, high_y);
+ }
+ high_y = y;
+
+#ifdef XL_DEBUG
+ printf("XlFormatText(): there should not be newlines in htext\n");
+#endif
+ break;
+
+ case HTEXT_PARAGRAPH:
+
+ if (!stepped_y) {
+ y += xl_linespace(p_start, p);
+ y += xl_paragraphspace(p_start, p);
+
+ stepped_y++;
+ }
+ low_y = high_y = y;
+
+ xl_set_margins(p, leftmargin, leftmargin + width,
+ ¤t_left, ¤t_right,
+ &x, &y, low_y, MARGIN_START_STYLE);
+ break;
+
+ case HTEXT_TAB:
+
+ xl_set_margins(p, leftmargin, leftmargin + width,
+ ¤t_left, ¤t_right, &x, &y,
+ low_y, MARGIN_HANDLE_P_OBJECT);
+ break;
+
+ case HTEXT_CONTINUE:
+ printf("format: dont understand continued objects here\n");
+ exit(1);
+ break;
+
+ }
+
+ p = p->next;
+
+ }
+ }
+
+ /*
+ * Make sure paragraph endings happen
+ */
+ if (p && (p->style != p_start->style)) {
+ mode |= FORMAT_NEW_STYLE;
+ }
+ /*
+ * Check for new style
+ */
+ if (mode & FORMAT_NEW_STYLE) {
+ /*
+ * Make sure one and only line is advanced always
+ */
+ if (y < high_y) {
+ if (!stepped_y) {
+ high_y += xl_linespace(p_start, p);
+ }
+ high_y += xl_stylespace(p_start, p);
+
+ y = low_y = high_y;
+
+ stepped_y++;
+ } else {
+ if (high_y_old == high_y) {
+ high_y += xl_linespace(p_start, p);
+ }
+ if (p) {
+ high_y += xl_stylespace_before(p, p);
+ }
+ high_y += xl_stylespace(p_start, p);
+
+ y = low_y = high_y;
+
+ stepped_y++;
+ }
+
+ xl_set_margins(p, leftmargin, leftmargin + width,
+ ¤t_left, ¤t_right,
+ &x, &y, low_y, MARGIN_START_STYLE);
+ }
+ }
+
+#if 0
+ /*
+ * Check region ending
+ */
+ /* tab sivulle tai tab sivulleyl|s depending on object and so on */
+ /* p = p->next */
+ /* set regions with margin_handle_p_object */
+ /* check where to start (y, x). x = regionstart or tab */
+
+ if ((mode & FORMAT_REGION_ENDS) && p) {
+ int i;
+
+ i = p->paragraph;
+
+ switch (i) {
+ case HTEXT_PARAGRAPH:
+ high_y += xl_lineheightandgap(p_start, p);
+
+ y = low_y = high_y;
+
+ xl_set_margins(p, leftmargin, leftmargin + width,
+ ¤t_left, ¤t_right,
+ &x, &y, low_y, MARGIN_START_STYLE);
+ break;
+
+ case HTEXT_NEWLINE:
+ /*high_y += xl_lineheightandgap(p_start, p);*/
+ y = low_y = high_y;
+ x = current_left;
+
+ break;
+
+ case HTEXT_TAB:
+ xl_set_margins(p, leftmargin, leftmargin + width,
+ ¤t_left, ¤t_right, &x, &y, low_y,
+ MARGIN_HANDLE_P_OBJECT);
+ break;
+
+ case HTEXT_CONTINUE:
+ printf("format: dont understand continued objects here\n");
+ exit(1);
+ break;
+
+ }
+
+ if (i) {
+ p = p->next;
+ }
+ }
+ /*
+ * Check New style
+ */
+ if (mode & FORMAT_NEW_STYLE) {
+ high_y = low_y = y;
+
+ xl_set_margins(p, leftmargin, leftmargin + width,
+ ¤t_left, ¤t_right,
+ &x, &y, low_y, MARGIN_START_STYLE);
+ }
+#endif
+
+ /*
+ * Give width and height to caller
+ */
+
+ if (!stepped_y) {
+ if (p_start)
+ y += xl_linespace(p_start, p);
+ else
+ y = 1;
+ }
+ *vwidth = MAX(max_right_position, width);
+
+ *vheight = y;
+
+ return 0;
+}
--- /dev/null
+/*
+ * XlFormatText.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Fri Mar 6 20:44:40 1992 tvr
+ * Last modified: Mon Mar 9 04:57:21 1992 tvr
+ *
+ */
+
+/*
+ * Returncode of line checking
+ */
+#define FORMAT_FULL_LINE 1
+#define FORMAT_NEXT_OBJECT_TOO_LONG 2
+#define FORMAT_REGION_ENDS 4
+#define FORMAT_NEW_STYLE 8
+#define FORMAT_ONLY_OBJECT_TOO_LONG 16
+
+/*
+ * Indent defines
+ */
+#define I_LEFT 1
+#define I_FIRST 2
+#define I_MIDDLE_L 4
+#define I_MIDDLE_R 8
+#define I_RIGHT 16
+
+/*
+ * Font style flags stored on XlStyle_t
+ */
+
+/*
+ * Line styles
+ */
+#define STYLE_LEFTIFY 0
+#define STYLE_RIGHTIFY 1
+#define STYLE_CENTER 2
+#define STYLE_JUSTIFY 3
+
+#define STYLE_MASK 3
+
+/*
+ * Do not format text
+ */
+#define STYLE_RAW 4
+
+/*
+ * Generate region change on tabulator
+ */
+#define STYLE_CHANGE_REGION_ON_TAB 8
+
+
+/*
+ * How to set current margins
+ */
+
+#define MARGIN_START_STYLE 0
+#define MARGIN_HANDLE_P_OBJECT 1
--- /dev/null
+/*
+ * XlSetup.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Mon Mar 2 22:06:56 1992 tvr
+ * Last modified: Wed May 13 06:44:12 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <X11/Xlib.h>
+
+#include "HTAnchor.h"
+#include "HTStyle.h"
+#include "../HText/HText.h"
+
+#include "Xl.h"
+#include "XlStyle.h"
+#include "XlTypes.h"
+#include "XlFormatText.h"
+
+#include "XlConfig.h"
+
+int xl_junk_object(HTextObject_t * p);
+
+/*
+ * Find a style
+ */
+XlStyle_t *
+ xl_get_style_and_gc(p, currentgc, t)
+HTextObject_t *p;
+GC *currentgc;
+HText_t *t;
+{
+ XlStyle_t *loop = t->xl_global->XlStyles;
+
+ if (!p->style) {
+ sleep(1);
+ }
+ while (loop->fontname && strcmp(loop->styletags, p->style->SGMLTag)) {
+ loop++;
+ }
+ if (loop->fontname) {
+ if (currentgc)
+ *currentgc = t->xl_global->gcs[loop - t->xl_global->XlStyles];
+
+ return loop;
+ }
+#ifdef XL_DEBUG
+ printf("holy mony, style not found\n");
+#endif
+ return NULL;
+}
+
+
+
+/*
+ * Setup resources for Xl (this can be changed at runtime some day)
+ */
+int XlSetupResources(func)
+void *(*func) ();
+{
+ void *table;
+ char *item;
+ XlStyle_t *styles;
+
+ char *resource;
+
+ table = (void *) (*func) ((void *) NULL, C_FONTS);
+
+ styles = XlStyles;
+
+ for (styles = XlStyles; styles->fontname; styles++) {
+ resource = (char *) (*func) (table, styles->config_name);
+
+ if (resource) {
+
+ if (styles->must_free_fontname)
+ free(styles->fontname);
+
+ styles->must_free_fontname = 1;
+
+ styles->fontname = (char *) strdup(resource);
+#ifdef XL_DEBUG
+ printf("XlConfigure: %s -> %s\n", styles->config_name, resource);
+#endif
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+/*
+ * For every page, setup Xl-stuff (including dpy, for multiple screens)
+ * - Setup GC's
+ * - Calculate width and height for each object
+ * - Set page display coordinates to (0, 0)
+ * - Delete null space-objects (only spaces on nonraw-mode)
+ * - Something else (uh?)
+ */
+int XlSetupText(display, window, fg, bg, htext)
+Display *display;
+Window window;
+unsigned long fg;
+unsigned long bg;
+HText_t *htext;
+{
+ HTextObject_t *p;
+
+ XlStyle_t *s, *s_alloc;
+
+ HTStyle *st = NULL;
+ XlStyle_t *current;
+
+ GC currentgc;
+
+ int i;
+
+ int struct_length;
+
+ /*
+ * safe
+ */
+ if (!htext)
+ return;
+
+
+ /*
+ * Duplicate Style-structure
+ */
+
+ s = XlStyles;
+
+ while (s->fontname)
+ s++;
+
+ /*
+ * NOTE!!! Add one element because of null element at the end !!!
+ */
+ struct_length = sizeof(XlStyle_t) * ((s - XlStyles) + 1);
+
+ s_alloc = s = (XlStyle_t *) malloc(struct_length);
+
+ if (!s) {
+ printf("cannot malloc on Xl\n");
+
+ exit(1);
+ }
+ memcpy(s, XlStyles, struct_length);
+
+ /*
+ * Load fonts. Note. Fonts should be cached for every display.
+ */
+ while (s->fontname) {
+ s->fontinfo =
+ (XFontStruct *) XLoadQueryFont(display, s->fontname);
+
+ if (!s->fontinfo) {
+ printf("XlSetup: Cannot load font %s\nXlSetup: trying 'fixed'.\n",
+ s->fontname);
+
+ s->fontinfo =
+ (XFontStruct *) XLoadQueryFont(display, "fixed");
+
+ /*
+ * Set font up on XlStyles -table so that font wont be tried
+ * every time.
+ */
+ {
+ XlStyle_t *ss = XlStyles + (s - s_alloc);
+
+ if (ss->must_free_fontname)
+ free(ss->fontname);
+
+ ss->fontname = (char *) strdup("fixed");
+ }
+
+
+ if (!s->fontinfo) {
+
+ printf("XlSetup: Cannot load 'fixed' ... sorry.\n");
+
+ exit(1);
+ }
+ }
+ /*
+ * Next font
+ */
+ s++;
+ }
+
+ /*
+ * Allocate space for page specific Xl data
+ */
+
+ if (!htext->xl_global) {
+
+ htext->xl_global = (XlGlobalData_t *) malloc(sizeof(XlGlobalData_t));
+
+ memset(htext->xl_global, 0, sizeof(XlGlobalData_t));
+
+ }
+ htext->xl_global->dpy = display;
+
+ htext->xl_global->window = window;
+
+ htext->xl_global->XlStyles = s_alloc;
+
+ /*
+ * Set up GC:s
+ */
+ htext->xl_global->xorgc = XCreateGC(htext->xl_global->dpy,
+ htext->xl_global->window,
+ 0,
+ NULL);
+
+ XSetFunction(htext->xl_global->dpy, htext->xl_global->xorgc, GXxor);
+
+ XSetForeground(htext->xl_global->dpy, htext->xl_global->xorgc, fg ^ bg);
+
+
+ htext->xl_global->nr_gcs = s - s_alloc;
+
+ htext->xl_global->gcs = (GC *) malloc((s - s_alloc) * sizeof(GC));
+
+ for (s = s_alloc, i = 0; s->fontname; s++, i++) {
+
+ htext->xl_global->gcs[i] =
+ XCreateGC(htext->xl_global->dpy,
+ htext->xl_global->window, 0, NULL);
+
+ XSetForeground(htext->xl_global->dpy,
+ htext->xl_global->gcs[i],
+ fg);
+
+ XSetFont(htext->xl_global->dpy,
+ htext->xl_global->gcs[i],
+ s->fontinfo->fid);
+
+ s->char_width = (int) XTextWidth(s->fontinfo, "i", 1);
+ }
+
+ /*
+ * Set up graphics exposures to XCopyArea GC
+ */
+ XSetGraphicsExposures(display, htext->xl_global->gcs[0], True);
+
+ /*
+ * Loop all objects
+ */
+ p = htext->first;
+
+ while (p) {
+
+ /*
+ * Allocate space for Xl specific object part
+ */
+
+ p->xl_data = (XlObjectData_t *) malloc(sizeof(XlObjectData_t));
+
+ if (!p->xl_data) {
+ printf("cannot malloc in XlSetupText\n");
+ exit(1);
+ }
+ memset(p->xl_data, 0, sizeof(XlObjectData_t));
+
+ /*
+ * Setup Xl styles. Check Xl style only on style changes
+ */
+ if (!st || (st != p->style)) {
+
+ current = xl_get_style_and_gc(p, ¤tgc, htext);
+
+ st = p->style;
+ }
+ p->xl_data->style = current;
+
+ p->xl_data->gc = currentgc;
+
+ /*
+ * Set up text dimensions. Use 'XTextExtents()'.
+ */
+ p->width = (int) XTextWidth(current->fontinfo,
+ (const char *) p->data,
+ p->length);
+
+ p->height = current->fontinfo->ascent + current->fontinfo->descent;
+
+ /*
+ * Next
+ */
+
+ /*
+ * Check if this object is 'junk'-object and delete it if needed.
+ * Has to be here, because we need styles.
+ */
+ if (xl_junk_object(p)) {
+ HTextObject_t *prev = p->prev;
+
+ /*
+ * Set links
+ */
+ if (prev) {
+
+ prev->next = p->next;
+
+ } else {
+
+ htext->first = p->next;
+
+ }
+
+ if (p->next) {
+
+ p->next->prev = prev;
+
+ } else {
+
+ htext->last = prev;
+
+ }
+
+ /*
+ * Free everything allocated
+ */
+ if (p->data)
+ free(p->data);
+
+ free(p->xl_data);
+
+ free(p);
+ }
+ p = p->next;
+
+ }
+
+ /*
+ * Cannot fail ;)
+ */
+ return 0;
+}
+
+
+
+/*
+ * If this object is not needed, it is 'junk' -object
+ */
+int xl_junk_object(p)
+HTextObject_t *p;
+{
+ register int i;
+
+ if (p->paragraph)
+ return 0;
+
+ if (xl_object_mode(p) & STYLE_RAW)
+ return 0;
+
+ for (i = 0; i < p->length; i++)
+ if (p->data[i] != ' ')
+ return 0;
+
+ return 1;
+}
--- /dev/null
+/*
+ * XlStyle.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Thu Mar 5 00:56:46 1992 tvr
+ * Last modified: Wed May 13 06:21:48 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+
+#include "HTAnchor.h"
+#include "HTStyle.h"
+#include "../HText/HText.h"
+
+#include "Xl.h"
+#include "XlStyle.h"
+#include "XlTypes.h"
+#include "XlFormatText.h"
+
+#include "XlDefaultFonts.h"
+
+#include "XlConfig.h"
+
+int xl_object_mode();
+
+/*
+ * All hypertext styles. Also needed configure data (font configure-name)
+ */
+
+#define CREATE_STYLE(font, cname, tag, mode, first, left, right) \
+{NULL, font, 0, cname, tag, 0, mode, first, left, right, 140, 100, 100, 50}
+
+XlStyle_t XlStyles[] =
+{
+ CREATE_STYLE(FONT_NORMAL,
+ C_FONT_NORMAL,
+ "P",
+ STYLE_LEFTIFY,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_LIST,
+ C_FONT_LIST,
+ "UL",
+ STYLE_LEFTIFY,
+ 0, 5, 95),
+
+ CREATE_STYLE(FONT_LISTCOMPACT,
+ C_FONT_LISTCOMPACT,
+ "ULC",
+ STYLE_LEFTIFY,
+ 0, 5, 95),
+
+ CREATE_STYLE(FONT_GLOSSARY,
+ C_FONT_GLOSSARY,
+ "DL",
+ STYLE_LEFTIFY | STYLE_CHANGE_REGION_ON_TAB,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_GLOSSARYCOMPACT,
+ C_FONT_GLOSSARYCOMPACT,
+ "DLC",
+ STYLE_LEFTIFY | STYLE_CHANGE_REGION_ON_TAB,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_EXAMPLE,
+ C_FONT_EXAMPLE,
+ "XMP",
+ STYLE_LEFTIFY | STYLE_RAW,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_LISTING,
+ C_FONT_LISTING,
+ "LISTING",
+ STYLE_LEFTIFY | STYLE_RAW,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_ADDRESS,
+ C_FONT_ADDRESS,
+ "ADDRESS",
+ STYLE_LEFTIFY,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_HEADER1,
+ C_FONT_HEADER1,
+ "H1",
+ STYLE_CENTER,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_HEADER2,
+ C_FONT_HEADER2,
+ "H2",
+ STYLE_CENTER,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_HEADER3,
+ C_FONT_HEADER3,
+ "H3",
+ STYLE_CENTER,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_HEADER4,
+ C_FONT_HEADER4,
+ "H4",
+ STYLE_CENTER,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_HEADER5,
+ C_FONT_HEADER5,
+ "H5",
+ STYLE_CENTER,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_HEADER6,
+ C_FONT_HEADER6,
+ "H6",
+ STYLE_CENTER,
+ 0, 0, 100),
+
+ CREATE_STYLE(FONT_HEADER7,
+ C_FONT_HEADER7,
+ "H7",
+ STYLE_CENTER,
+ 0, 0, 100),
+
+ CREATE_STYLE(NULL,
+ NULL,
+ NULL,
+ 0,
+ 0, 0, 0),
+};
+
+
+/*
+ * How much to increase y coordinate after this line ?
+ */
+/* ARGS_IN_USE */
+
+int xl_linespace(p_start, p_end)
+HTextObject_t *p_start;
+HTextObject_t *p_end;
+{
+ if (p_start->xl_data->style->fontinfo) {
+
+ return ((p_start->xl_data->style->fontinfo->ascent +
+ p_start->xl_data->style->fontinfo->descent) *
+ p_start->xl_data->style->space_line) / 100;
+ } else {
+
+ return p_start->xl_data->style->space_line / 100;
+ }
+}
+
+
+int xl_paragraphspace(p_start, p_end)
+HTextObject_t *p_start;
+HTextObject_t *p_end;
+{
+ if (p_start->xl_data->style->fontinfo) {
+
+ return ((p_start->xl_data->style->fontinfo->ascent +
+ p_start->xl_data->style->fontinfo->descent) *
+ p_start->xl_data->style->space_paragraph) / 100;
+ } else {
+
+ return p_start->xl_data->style->space_paragraph / 100;
+ }
+}
+
+
+int xl_stylespace(p_start, p_end)
+HTextObject_t *p_start;
+HTextObject_t *p_end;
+{
+ if (p_start->xl_data->style->fontinfo) {
+
+ return ((p_start->xl_data->style->fontinfo->ascent +
+ p_start->xl_data->style->fontinfo->descent) *
+ p_start->xl_data->style->space_style) / 100;
+
+ } else {
+
+ return 1;
+ }
+}
+
+
+int xl_stylespace_before(p_start, p_end)
+HTextObject_t *p_start;
+HTextObject_t *p_end;
+{
+ if (p_start->xl_data->style->fontinfo) {
+
+ return ((p_start->xl_data->style->fontinfo->ascent +
+ p_start->xl_data->style->fontinfo->descent) *
+ p_start->xl_data->style->space_style_before) / 100;
+ } else {
+
+ return 1;
+ }
+}
+
+
+/*
+ * How much to increase x-coordinate after this object ?
+ */
+/* ARGS_IN_USE */
+int xl_wordgap(p)
+HTextObject_t *p;
+{
+ if (xl_object_mode(p) & STYLE_RAW)
+ return 0;
+ else
+ return p->xl_data->style->char_width;
+}
+
+
+/*
+ * Return width of a character 'a'. Used to mostly when calculating
+ * tabulator spaces.
+ */
+int xl_character_width(p)
+HTextObject_t *p;
+{
+ return p->xl_data->style->char_width;
+}
+
+
+/*
+ * Return style of this object
+ */
+int xl_object_style(p)
+HTextObject_t *p;
+{
+ return p->xl_data->style->mode & STYLE_MASK;
+}
+
+
+/*
+ * Return mode of this object
+ */
+int xl_object_mode(p)
+HTextObject_t *p;
+{
+ return p->xl_data->style->mode;
+}
+
+
+/*
+ * Calculate position of a coordinate according to left and right margins
+ */
+
+int xl_calc_position(p, which, left, right)
+HTextObject_t *p;
+int which;
+int left;
+int right;
+{
+ int r = 0;
+ int delta = right - left;
+
+ XlStyle_t *s = p->xl_data->style;
+
+ if (which & I_LEFT) {
+ r += (s->left * delta) / 100;
+ }
+ if (which & I_MIDDLE_L) {
+ r += (MIDDLE_L_HACK * delta) / 100;
+ }
+ if (which & I_MIDDLE_R) {
+ r += (MIDDLE_R_HACK * delta) / 100;
+ }
+ if (which & I_RIGHT) {
+ r += (s->right * delta) / 100;
+ }
+ if (which & I_FIRST) {
+ r += (s->indent1st * delta) / 100;
+ }
+ r += left;
+
+ return r;
+}
--- /dev/null
+/*
+ * XlStyle.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Thu Mar 5 00:32:52 1992 tvr
+ * Last modified: Tue May 12 21:49:52 1992 tvr
+ *
+ */
+
+/*
+ * Flags needed for text formatting are on XlFormatText.h
+ */
+
+/*
+ * This structure contains *all* information needed to format text
+ */
+
+typedef struct XlStyle {
+ /*
+ * Font structure
+ */
+ XFontStruct *fontinfo;
+
+ /*
+ * Name of the font used to display this style. When we setup resources,
+ * identify whether we should or should not free original string.
+ */
+ char *fontname;
+ int must_free_fontname;
+
+ /*
+ * Name of the font on configure -data
+ */
+
+ char *config_name;
+
+ /*
+ * Tags. This way no enumeration is needed
+ */
+ char *styletags;
+
+ /*
+ * Width of a character 'm'.
+ */
+ int char_width;
+
+ /*
+ * Stylespecific object positioning
+ */
+ int mode;
+
+ /*
+ * How much to indent first line of a paragraph
+ */
+ int indent1st;
+
+ /*
+ * left and righ limits
+ */
+ int left;
+ int right;
+
+ /*
+ * Spaces on linespaces, stylechanges and paragraphchanges
+ */
+ int space_line;
+ int space_paragraph;
+ int space_style_before;
+ int space_style;
+
+} XlStyle_t;
+
+
+
+extern XlStyle_t XlStyles[];
+extern int xl_lineheightandgap();
+extern int xl_wordgap();
+extern int xl_object_style();
+
+
+
+#define MIDDLE_L_HACK 25
+#define MIDDLE_R_HACK 30
--- /dev/null
+/*
+ * XlTypes.h --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Thu Feb 27 21:50:02 1992 tvr
+ * Last modified: Tue Apr 21 00:32:43 1992 tvr
+ *
+ */
+
+/*
+ * This structure consists of all Xl specific object data
+ */
+typedef struct XlObjectData {
+ /*
+ * X11 info. This graphical context has all information about
+ * the used font. Text sizes can be calculated when font is
+ * known.
+ */
+ GC gc;
+
+ /*
+ * Pointer to XlStyle table.
+ */
+ struct XlStyle *style;
+
+} XlObjectData_t;
+
+
+/*
+ * Global data stored for a hypertext page.
+ */
+typedef struct XlGlobalData {
+ /*
+ * X11 specific data for a page
+ */
+ Display *dpy;
+ Window window;
+
+ /*
+ * Coordinates of a view window left upper corner
+ */
+ long x;
+ long y;
+
+ /*
+ * store GC:s for all fonts here
+ */
+ GC *gcs;
+
+ GC xorgc;
+
+ int nr_gcs;
+
+ /*
+ * Save styledata here
+ */
+
+ XlStyle_t *XlStyles;
+
+} XlGlobalData_t;
+
+
+
+#if 0
+
+/*
+ * No paragraph ending
+ */
+#define PTYPE_NONE 0
+
+/*
+ * Normal paragraph ending.
+ */
+#define PTYPE_NORMAL 1
+
+/*
+ * On a paragraph ending reset y value to same level where we started.
+ * store maximum y.
+ */
+#define PTYPE_CONTINUE 2
+
+/*
+ * On a paragraph ending set y value to maximum y value of stored
+ * 'PTYPE_CONTINUE' -values.
+ */
+#define PTYPE_NEXT 3
+
+
+#endif
--- /dev/null
+/*
+ * XlUtil.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Tue Mar 3 02:55:55 1992 tvr
+ * Last modified: Mon May 11 00:16:48 1992 tvr
+ *
+ */
+
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <X11/Xlib.h>
+
+#include "HTAnchor.h"
+#include "HTStyle.h"
+#include "../HText/HText.h"
+
+#include "XlStyle.h"
+#include "XlFormatText.h"
+#include "XlTypes.h"
+
+/*
+ * Does nothing but updates htext-object positions. This has to be
+ * used after text is reformatted (on window size change).
+ */
+void XlSetPageCoordinates(virtualx, virtualy, htext)
+int virtualx, virtualy;
+HText_t *htext;
+{
+ htext->xl_global->x = virtualx;
+ htext->xl_global->y = virtualy;
+}
+
+
+/*
+ * Get HTextObject position (virtual position of screen area to display)
+ */
+void XlGetCoordinates(virtualx, virtualy, htextobject)
+int *virtualx, *virtualy;
+HTextObject_t *htextobject;
+{
+ if (!htextobject)
+ return;
+
+ *virtualx = htextobject->x;
+ *virtualy = htextobject->y;
+}
+
+
+/*
+ * Can this object be cursor?
+ */
+int xl_can_be_cursor(htextobject)
+HTextObject_t *htextobject;
+{
+ int i;
+
+ if (htextobject->paragraph)
+ return FALSE;
+
+ for (i = 0; i < htextobject->length; i++)
+ if (htextobject->data[i] != ' ')
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Get pointer to hypertextobject nearest to chosen coordinates
+ */
+HTextObject_t *
+ XlLocateHTextObject(windowx, windowy, htext)
+int windowx, windowy;
+HText_t *htext;
+{
+ HTextObject_t *p;
+ HTextObject_t *p_closest = NULL;
+
+ int virtualx;
+ int virtualy;
+ int distance;
+
+ virtualx = windowx + htext->xl_global->x;
+ virtualy = windowy + htext->xl_global->y;
+
+ for (p = htext->first; p; p = p->next) {
+ int i = xl_object_on_region(htext, p, windowx, windowy, 0, 0);
+
+ if (xl_can_be_cursor(p)) {
+ if (!i) {
+ /*
+ * Point inside object ?
+ */
+ p_closest = p;
+ p = htext->last;
+
+ } else {
+ /*
+ * Is this object closest ?
+ */
+ if (!p_closest) {
+ p_closest = p;
+
+ distance = i;
+ } else if (i < distance) {
+ distance = i;
+
+ p_closest = p;
+ }
+ }
+ }
+ }
+
+#ifdef XL_DEBUG
+ if (p_closest) {
+ printf("XlLocateHTextObject(%d, %d) -> (%d, %d) tag %s object '%s'\n",
+ windowx, windowy,
+ p_closest->x, p_closest->y,
+ p_closest->xl_data->style->styletags,
+ p_closest ? p_closest->data : "");
+ }
+#endif
+ return p_closest;
+}
+
+/*
+ * Delete all Xl data from a page. Free all data allocated on Xl-library.
+ */
+void XlDeleteText(htext)
+HText_t *htext;
+{
+ int i;
+
+ /*
+ * Free X11 resources
+ */
+ for (i = 0; i < htext->xl_global->nr_gcs; i++) {
+ XFreeGC(htext->xl_global->dpy, htext->xl_global->gcs[i]);
+ XFreeFont(htext->xl_global->dpy,
+ htext->xl_global->XlStyles[i].fontinfo);
+ }
+
+ XFreeGC(htext->xl_global->dpy, htext->xl_global->xorgc);
+
+ /*
+ * Free data allocated here
+ */
+
+ {
+ HTextObject_t *p;
+
+ p = htext->first;
+
+ while (p) {
+ free(p->xl_data);
+
+ p = p->next;
+ }
+ }
+
+ free(htext->xl_global->XlStyles);
+
+ free(htext->xl_global->gcs);
+
+ free(htext->xl_global);
+}
+
+
+/*
+ * What is the length of this without spaces
+ */
+int xl_nospacelength(p, data, len)
+HTextObject_t *p;
+char *data;
+int len;
+{
+ if (xl_object_mode(p) & STYLE_RAW) {
+
+ return len;
+ } else {
+
+ int i;
+
+ for (i = 0; (i < len) && (*data++ != ' '); i++);
+
+ return i;
+ }
+}
+
+
+/*
+ * Set up stuff needed to format text intelligently
+ */
+void XlFormatTextForPrinting(htext, lmargin, rmargin)
+HText_t *htext;
+int lmargin;
+int rmargin;
+{
+ HTextObject_t *p;
+ int i, struct_len;
+ XlStyle_t *loop = XlStyles;
+ int junk1;
+ int junk2;
+
+ if (!htext)
+ return;
+
+ /*
+ * Set up format info
+ */
+
+ i = 1;
+
+ while (loop->fontname) {
+
+ loop++;
+
+ i++;
+ }
+
+ struct_len = sizeof(XlStyle_t) * i;
+
+ loop = (XlStyle_t *) malloc(struct_len);
+
+ htext->xl_global = (XlGlobalData_t *) malloc(sizeof(XlGlobalData_t));
+
+ htext->xl_global->XlStyles = loop;
+
+ memcpy(loop, XlStyles, struct_len);
+
+ while (--i) {
+
+ loop->char_width = 1;
+
+ loop++;
+ }
+
+ /*
+ * Set up length and width
+ */
+ p = htext->first;
+
+ while (p) {
+ HTStyle *st = NULL;
+
+ XlStyle_t *current;
+
+ p->height = 1;
+
+ if (!st || (st != p->style)) {
+
+ current = (XlStyle_t *) xl_get_style_and_gc(p, NULL, htext);
+
+ st = p->style;
+ }
+ p->xl_data = (XlObjectData_t *) malloc(sizeof(XlObjectData_t));
+
+ p->xl_data->style = current;
+
+ p->width = xl_nospacelength(p, p->data, p->length);
+
+ p = p->next;
+ }
+
+ XlFormatText(lmargin, rmargin - lmargin, 0, &junk1, &junk2, htext);
+
+ /*
+ * Free local stuff
+ */
+
+ p = htext->first;
+
+ while (p) {
+
+ free(p->xl_data);
+
+ p = p->next;
+ }
+
+ free(loop);
+
+ free(htext->xl_global);
+}
--- /dev/null
+/*
+ * XlWindow.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi>
+ * Copyright (c) 1992 Teemu Rantanen
+ * All rights reserved
+ *
+ * Created: Tue Mar 3 02:59:10 1992 tvr
+ * Last modified: Tue Apr 21 00:34:09 1992 tvr
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <X11/Xlib.h>
+
+#include "HTAnchor.h"
+#include "HTStyle.h"
+#include "../HText/HText.h"
+
+#include "Xl.h"
+#include "XlStyle.h"
+#include "XlTypes.h"
+#include "XlFormatText.h"
+
+/*
+ * Make cursor positioning more intelligent
+ */
+#define Y_MULTIPLIER 50
+
+/*
+ * Is there spaces at the end of data ?
+ */
+int xl_space_index(data, length)
+char *data;
+int length;
+{
+ int i;
+
+ if (!data)
+ return -1;
+
+ for (i = 0; i < length; i++)
+ if (*data++ == ' ')
+ return i;
+
+ return length;
+}
+
+
+/*
+ * Draw one Xl object to screen
+ */
+void xl_draw_object(htext, object)
+HText_t *htext;
+HTextObject_t *object;
+{
+ /*
+ * If this object is cursor, clear area or else partial updating
+ * does not work correctly
+ */
+
+ if (object == htext->cursor) {
+ XClearArea(htext->xl_global->dpy,
+ htext->xl_global->window,
+ object->x - htext->xl_global->x,
+ object->y - htext->xl_global->y,
+ object->width,
+ object->height,
+ False);
+ }
+ XDrawString(htext->xl_global->dpy,
+ htext->xl_global->window,
+ object->xl_data->gc,
+ object->x - htext->xl_global->x,
+ object->y - htext->xl_global->y +
+ object->xl_data->style->fontinfo->ascent,
+ object->data,
+ object->length);
+
+ /*
+ * Draw underline for anchors
+ */
+ if (object->anchor) {
+ int y;
+ int x;
+ int width;
+
+ y = object->y + object->xl_data->style->fontinfo->ascent +
+ object->xl_data->style->fontinfo->descent -
+ htext->xl_global->y;
+
+ x = object->x - htext->xl_global->x;
+
+ width = object->width;
+
+ if (object->next && (object->anchor == object->next->anchor) &&
+ (object->y == object->next->y)) {
+ width += xl_wordgap(object);
+ }
+ XDrawLine(htext->xl_global->dpy,
+ htext->xl_global->window,
+ object->xl_data->gc,
+ x, y,
+ x + width, y);
+ }
+ /*
+ * Is this object cursor ?
+ */
+ if (object == htext->cursor) {
+ int cursorwidth;
+
+ /*
+ * If cursor is on raw mode, get rid of spaces at the end
+ */
+ if (xl_object_mode(object) & STYLE_RAW) {
+ int i = xl_space_index(object->data, object->length);
+
+ if (i >= 0) {
+ cursorwidth = (int) XTextWidth(object->xl_data->style->fontinfo,
+ object->data,
+ i);
+ } else {
+ cursorwidth = object->width;
+ }
+ } else {
+ cursorwidth = object->width;
+ }
+
+ XDrawRectangle(htext->xl_global->dpy,
+ htext->xl_global->window,
+ htext->xl_global->xorgc,
+ object->x - htext->xl_global->x,
+ object->y - htext->xl_global->y,
+ cursorwidth - 1,
+ object->height - 1);
+ }
+}
+
+
+/*
+ * Check is object is on wanted region. Return 0 if point is on region.
+ * Otherwise return distance. NOTE. y-distance is multiplied by a big
+ * number because this way cursor positioning works more intelligently than
+ * without it.
+ */
+int xl_object_on_region(htext, object, x, y, w, h)
+HText_t *htext;
+HTextObject_t *object;
+int x, y;
+int w, h;
+{
+ int r = 0;
+
+ /*
+ * Change real coordinates to virtual coordinates
+ */
+ x += htext->xl_global->x;
+ y += htext->xl_global->y;
+
+ if ((object->y + object->height) < y)
+ r += (y - (object->y + object->height)) * Y_MULTIPLIER;
+
+ if (object->y > (y + h))
+ r += (object->y - (y + h)) * Y_MULTIPLIER;
+
+ if ((object->x + object->width) < x)
+ r += x - (object->x + object->width);
+
+ if (object->x > (x + w))
+ r += object->x - (x + w);
+
+ return r;
+}
+
+
+
+/*
+ * Redraw region of the window. Draw all objects (or parts of the objects)
+ * on redraw region.
+ */
+void XlRedraw(windowx, windowy, width, height, htext)
+int windowx, windowy;
+int width, height;
+HText_t *htext;
+{
+ HTextObject_t *p;
+
+ /*
+ * This is stupid. This has to be written again
+ */
+
+ p = htext->first;
+
+ while (p) {
+ if (xl_object_on_region(htext, p, windowx, windowy, width, height) == 0) {
+ xl_draw_object(htext, p);
+ }
+ p = p->next;
+ }
+}
+
+
+/*
+ * Move window to other coordinates. Xl can optimize window moving by using
+ * regioncopy and updating only parts of display.
+ */
+void XlMoveWindow(newvx, newvy, htext)
+int newvx, newvy;
+HText_t *htext;
+{
+ XWindowAttributes a;
+
+ long deltax, deltay;
+
+ /*
+ * Need to know window dimensions
+ */
+ XGetWindowAttributes(htext->xl_global->dpy,
+ htext->xl_global->window,
+ &a);
+
+ /*
+ * How much to move
+ */
+ deltax = newvx - htext->xl_global->x;
+ deltay = newvy - htext->xl_global->y;
+
+ /*
+ * Can move be optimized ?
+ */
+ if ((abs(deltax) < a.width) && (abs(deltay) < a.height)) {
+ XCopyArea(htext->xl_global->dpy,
+ htext->xl_global->window,
+ htext->xl_global->window,
+ htext->xl_global->gcs[0], /* dummy GC */
+ deltax < 0 ? 0 : deltax,
+ deltay < 0 ? 0 : deltay,
+ a.width - abs(deltax),
+ a.height - abs(deltay),
+ deltax < 0 ? -deltax : 0,
+ deltay < 0 ? -deltay : 0);
+ }
+ /*
+ * Set new corner coordinates
+ */
+
+ XlSetPageCoordinates(newvx, newvy, htext);
+
+ /*
+ * Clear borders to be updated again
+ */
+ if (deltax != 0) {
+ XClearArea(htext->xl_global->dpy,
+ htext->xl_global->window,
+ deltax > 0 ? a.width - deltax : 0,
+ 0,
+ abs(deltax),
+ a.height,
+ True);
+ }
+ if (deltay != 0) {
+ XClearArea(htext->xl_global->dpy,
+ htext->xl_global->window,
+ 0,
+ deltay > 0 ? a.height - deltay : 0,
+ a.width,
+ abs(deltay),
+ True);
+ }
+}
+
+
+
+/*
+ * Clear window
+ */
+void XlClearWindow(width, height, htext)
+int width;
+int height;
+HText_t *htext;
+{
+ XClearArea(htext->xl_global->dpy,
+ htext->xl_global->window,
+ 0, 0, width, height, True);
+}
+
+
+/*
+ * Setup cursorposition on a page
+ */
+void XlSetCursor(htext, object)
+HText_t *htext;
+HTextObject_t *object;
+{
+ XWindowAttributes a;
+ HTextObject_t *old_object;
+
+
+ if (!htext || !htext->xl_global ||
+ !htext->xl_global->dpy ||
+ !htext->xl_global->window)
+ return;
+
+ /*
+ * Need to know window dimensions
+ */
+ XGetWindowAttributes(htext->xl_global->dpy,
+ htext->xl_global->window,
+ &a);
+
+ /*
+ * Clear old cursor
+ */
+ if (htext->cursor) {
+ if (xl_object_on_region(htext, htext->cursor, 0, 0,
+ a.width, a.height) == 0) {
+ XClearArea(htext->xl_global->dpy,
+ htext->xl_global->window,
+ htext->cursor->x - htext->xl_global->x,
+ htext->cursor->y - htext->xl_global->y,
+ htext->cursor->width,
+ htext->cursor->height,
+ False);
+
+ /*
+ * When drawing old area, must clear htext->cursor for a while
+ */
+ old_object = htext->cursor;
+
+ htext->cursor = 0;
+
+ xl_draw_object(htext, old_object);
+ }
+ }
+ old_object = object;
+ htext->cursor = object;
+
+ if (htext->cursor) {
+ if (xl_object_on_region(htext, object, 0, 0, a.width, a.height) == 0) {
+#if 0
+ /*
+ * This is moved to draw object. partial drawing updating of
+ * cursor causes otherwise problems
+ */
+ XClearArea(htext->xl_global->dpy,
+ htext->xl_global->window,
+ htext->cursor->x - htext->xl_global->x,
+ htext->cursor->y - htext->xl_global->y,
+ htext->cursor->width,
+ htext->cursor->height,
+ False);
+#endif
+ xl_draw_object(htext, htext->cursor);
+ }
+ }
+}
--- /dev/null
+#include "Includes.h"
+
+#define BUFFER_SIZE 79
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#define INDENT_STR " "
+
+static char *strdupmax(char *str, int length);
+static char *parseid(char *str);
+static char *parsevalue(char *str);
+static char *readline(FILE * fp);
+
+static int ConfigLines = 0;
+
+
+static Config_t Fonts[] =
+{
+ {RESOURCE, C_FONT_NORMAL, (void *) "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1"},
+ {RESOURCE, C_FONT_LIST, (void *) "8x13"},
+ {RESOURCE, C_FONT_LISTCOMPACT, (void *) "6x13"},
+ {RESOURCE, C_FONT_GLOSSARY, (void *) "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1"},
+ {RESOURCE, C_FONT_GLOSSARYCOMPACT, (void *) "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1"},
+ {RESOURCE, C_FONT_EXAMPLE, (void *) "7x13"},
+ {RESOURCE, C_FONT_LISTING, (void *) "7x13"},
+ {RESOURCE, C_FONT_ADDRESS, (void *) "8x13"},
+ {RESOURCE, C_FONT_HEADER1, (void *) "-adobe-times-medium-r-normal--20-140-100-100-p-96-iso8859-1"},
+ {RESOURCE, C_FONT_HEADER2, (void *) "-adobe-times-medium-r-normal--18-180-75-75-p-94-iso8859-1"},
+ {RESOURCE, C_FONT_HEADER3, (void *) "-adobe-times-medium-r-normal--17-120-100-100-p-84-iso8859-1"},
+ {RESOURCE, C_FONT_HEADER4, (void *) "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"},
+ {RESOURCE, C_FONT_HEADER5, (void *) "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"},
+ {RESOURCE, C_FONT_HEADER6, (void *) "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"},
+ {RESOURCE, C_FONT_HEADER7, (void *) "-adobe-times-medium-r-normal--14-100-100-100-p-74-iso8859-1"},
+ {EOC, (char *) NULL, (void *) NULL}
+};
+
+
+static Config_t GlobalSettings[] =
+{
+ {RESOURCE, C_TOPMARGIN, (void *) "0"},
+ {RESOURCE, C_BOTTOMMARGIN, (void *) "0"},
+ {RESOURCE, C_LEFTMARGIN, (void *) "0"},
+ {RESOURCE, C_RIGHTMARGIN, (void *) "0"},
+ {RESOURCE, C_FIXEDWIDTHMODE, (void *) "Off"},
+ {RESOURCE, C_FIXEDWIDTH, (void *) "560"},
+ {RESOURCE, C_ONEPAGEMODE, (void *) "Off"},
+ {RESOURCE, C_WIDTH, (void *) "560"},
+ {RESOURCE, C_HEIGHT, (void *) "600"},
+ {RESOURCE, C_DOUBLECLICKTIME, (void *) "500"},
+ {RESOURCE, C_SEARCH, (void *) "Fixed"},
+ {RESOURCE, C_CONTROLPANEL, (void *) "Fixed"},
+ {RESOURCE, C_LIST, (void *) "Fixed"},
+ {RESOURCE, C_RECALL, (void *) "Fixed"},
+ {RESOURCE, C_PAGESETTINGS, (void *) "Fixed"},
+ {EOC, (char *) NULL, (void *) NULL}
+};
+
+
+static Config_t Print[] =
+{
+ {RESOURCE, C_COMMAND, (void *) "lpr"},
+ {RESOURCE, C_FILENAME, (void *) "print.out"},
+ {RESOURCE, C_PRINTTOFILE, (void *) "False"},
+ {RESOURCE, C_TOPMARGIN, (void *) "0"},
+ {RESOURCE, C_BOTTOMMARGIN, (void *) "0"},
+ {RESOURCE, C_LEFTMARGIN, (void *) "0"},
+ {RESOURCE, C_RIGHTMARGIN, (void *) "0"},
+ {RESOURCE, C_WIDTH, (void *) "80"},
+ {EOC, (char *) NULL, (void *) NULL}
+};
+
+
+static Config_t Defaults[] =
+{
+ {DYNAMIC_PTR, C_DEFAULTSTABLE, (void *) NULL},
+ {EOC, (char *) NULL, (void *) NULL}
+};
+
+
+static Config_t KeyBindings[] =
+{
+ {RESOURCE, C_GETPAGE, (void *) "Return"},
+ {RESOURCE, C_PREVWORD, (void *) "Left"},
+ {RESOURCE, C_NEXTWORD, (void *) "Right"},
+ {RESOURCE, C_PREVTAG, (void *) "Up"},
+ {RESOURCE, C_NEXTTAG, (void *) "Down"},
+ {RESOURCE, C_CLOSE, (void *) "^c"},
+ {RESOURCE, C_SEARCH, (void *) "^s"},
+ {RESOURCE, C_SETTINGS, (void *) "S"},
+ {RESOURCE, C_PRINTDOC, (void *) "p"},
+ {RESOURCE, C_LIST, (void *) "L"},
+ {EOC, (char *) NULL, (void *) NULL}
+};
+
+
+Config_t Config[] =
+{
+ {COMMENT, C_COMMENT, (void *) "Erwise configuration file"},
+ {BLOCK, C_FONTS, (void *) &Fonts},
+ {BLOCK, C_KEYBINDINGS, (void *) &KeyBindings},
+ {BLOCK, C_PRINT, (void *) &Print},
+ {BLOCK, C_GLOBALSETTINGS, (void *) &GlobalSettings},
+ {DYNAMIC, C_DEFAULTS, (void *) &Defaults},
+ {EOC, (char *) NULL, (void *) NULL}
+};
+
+
+/*
+ * misc routines
+ */
+static char *
+ strdupmax(str, length)
+char *str;
+int length;
+{
+ char *dup = (char *) NULL;
+
+ if (str) {
+ dup = (char *) malloc((length + 1) * sizeof(char));
+ strncpy(dup, str, length);
+ dup[length] = '\0';
+ }
+ return dup;
+}
+
+
+static char *
+ stripnewline(str)
+char *str;
+{
+ int length;
+
+ if (str) {
+ length = strlen(str);
+ if (length && (str[length - 1] == '\n'))
+ str[length - 1] = '\0';
+ }
+ return str;
+}
+
+
+/*
+ * config's code starts here
+ */
+static char *
+ readline(fp)
+FILE *fp;
+{
+ char buffer[BUFFER_SIZE + 1];
+ char *line = (char *) NULL;
+ char *data;
+ int length = 1;
+
+ line = (char *) malloc(sizeof(char));
+ line[0] = '\0';
+
+ while (!feof(fp) && !strrchr(line, '\n')) {
+ if (data = fgets(buffer, BUFFER_SIZE, fp)) {
+ line =
+ (char *) realloc(line, (strlen(data) + length) * sizeof(char));
+ strcat(line, data);
+ length = strlen(line) + 1;
+ }
+ }
+#ifdef DEBUG_CONFIG
+ printf("read line: '%s'\n", line);
+#endif
+ ConfigLines++;
+ return line;
+}
+
+
+/*
+ * returns a copy of id
+ */
+static char *
+ parseid(str)
+char *str;
+{
+ char *ptr, *id = (char *) NULL;
+ int length = 0;
+
+ while (str && *str && isspace(*str))
+ str++;
+ ptr = str;
+ while (str && *str && !isspace(str[length]))
+ length++;
+ id = strdupmax(ptr, length);
+#ifdef DEBUG_CONFIG
+ printf("id: '%s'\n", id);
+#endif
+ return id;
+}
+
+
+/*
+ * returns a copy of value
+ */
+static char *
+ parsevalue(str)
+char *str;
+{
+ char *ptr;
+ char *value = (char *) NULL;
+
+ if (ptr = strchr(str, '=')) {
+ ptr++;
+ while (ptr && *ptr && isspace(*ptr))
+ ptr++;
+ value = stripnewline(strdup(ptr));
+ }
+ return value;
+}
+
+
+static Config_t *
+ getitem(id, table)
+char *id;
+Config_t *table;
+{
+ Config_t *walker;
+
+ walker = table;
+ while (walker && (walker->type != EOC)) {
+ if (!strcmp(id, walker->id))
+ return (walker);
+ walker++;
+ }
+ return ((Config_t *) NULL);
+}
+
+
+ConfigType_t
+getidtype(id, table)
+char *id;
+Config_t *table;
+{
+ Config_t *walker;
+
+ if (!strncmp(id, "{", 1))
+ return (START_OF_BLOCK);
+ if (!strncmp(id, "}", 1))
+ return (END_OF_BLOCK);
+ if (!strncmp(id, "", 1))
+ return (EMPTY);
+ if (!strncmp(id, "#", 1))
+ return (COMMENT);
+
+ if (walker = getitem(id, table))
+ return (walker->type);
+ return (UNKNOWN);
+}
+
+
+static char *
+ parsedynamicobject(line)
+char *line;
+{
+ char *ptr;
+
+ ptr = line;
+ while (ptr && *ptr && isspace(*ptr))
+ ptr++;
+ return (stripnewline(strdup(ptr)));
+}
+
+
+static int restoredynamicblock(fp, table)
+FILE *fp;
+Config_t *table;
+{
+ char *line;
+ char *id;
+ int done = FALSE;
+ char **items = (char **) NULL;
+ int count = 0;
+
+ do {
+ line = readline(fp);
+ if (line[0] == '\0')
+ done = TRUE;
+ else {
+ id = parseid(line);
+ switch (getidtype(id, table)) {
+ case END_OF_BLOCK:
+ done = TRUE;
+ case START_OF_BLOCK:
+ break;
+ default:
+ if (!count) {
+ count = 1;
+ items = (char **) malloc(2 * sizeof(char *));
+ } else {
+ count++;
+ items =
+ (char **) realloc(items, (count + 1) * sizeof(char *));
+ }
+ items[count - 1] = parsedynamicobject(line);
+ items[count] = (char *) NULL;
+#ifdef DEBUG_CONFIG
+ printf("added to count[%d] value '%s'\n",
+ count - 1, items[count - 1]);
+#endif
+ break;
+ }
+ free(id);
+ }
+ free(line);
+ } while (!done);
+ table->value = (void *) items;
+ return 0;
+}
+
+
+static void *
+ setitemvalue(item, value)
+Config_t *item;
+void *value;
+{
+ void *oldvalue = (void *) NULL;
+
+ switch (item->type) {
+ case DYNAMIC_PTR:
+ oldvalue = item->value;
+ item->value = value;
+ break;
+ case RESOURCE:
+ if (item->value)
+ free(item->value);
+ item->value = value;
+ break;
+ default:
+ /* error recovery - not needed? */
+ fprintf(stderr, "unknown type for given item\n");
+ }
+ return oldvalue;
+}
+
+
+static int restoreblock(fp, table)
+FILE *fp;
+Config_t *table;
+{
+ char *id, *value;
+ char *line;
+ int done = FALSE;
+ int ret;
+ Config_t *item;
+ int blockcount = 0;
+ int unknown = FALSE;
+ char *syncline;
+ int syncdone;
+
+#ifdef DEBUG_CONFIG
+ printf("parsing block\n");
+#endif
+ while (!feof(fp) && !done) {
+ line = readline(fp);
+ if (line[0] == '\0') {
+ id = (char *) NULL;
+ } else {
+ id = parseid(line);
+ item = getitem(id, table);
+ switch (getidtype(id, table)) {
+ case RESOURCE:
+ value = parsevalue(line);
+ /* we don't care about this return value... */
+ value = setitemvalue(item, (void *) strdup(value));
+ unknown = FALSE;
+ break;
+ case BLOCK:
+#ifdef DEBUG_CONFIG
+ printf("block: '%s'\n", id);
+#endif
+ ret = restoreblock(fp, (Config_t *) item->value);
+ unknown = FALSE;
+ break;
+ case START_OF_BLOCK:
+ if (!unknown)
+ blockcount++;
+ else {
+#ifdef DEBUG_CONFIG
+ printf("syncing\n");
+#endif
+ syncdone = FALSE;
+ while (!syncdone && !feof(fp) && (syncline = readline(fp))) {
+ if (strchr(syncline, '}'))
+ syncdone = TRUE;
+ free(syncline);
+ }
+ }
+ unknown = FALSE;
+ break;
+ case END_OF_BLOCK:
+ blockcount--;
+ if (blockcount == 0)
+ done = TRUE;
+ else
+ fprintf(stderr, "parse error at line %d\n", ConfigLines);
+ unknown = FALSE;
+ break;
+ case DYNAMIC:
+#ifdef DEBUG_CONFIG
+ printf("dynamic: '%s'\n", id);
+#endif
+ ret = restoredynamicblock(fp, (Config_t *) item->value);
+ unknown = FALSE;
+ break;
+ case UNKNOWN:
+ fprintf(stderr, "Unknown tag type '%s'\n", id);
+ unknown = TRUE;
+ break;
+ case EMPTY:
+ case COMMENT:
+ default:
+ unknown = FALSE;
+ break;
+ }
+ }
+ free(line);
+ }
+ if (blockcount) {
+ if (blockcount < 0)
+ fprintf(stderr, "missing { at %d\n", ConfigLines);
+ if (blockcount > 0)
+ fprintf(stderr, "missing } at %d\n", ConfigLines);
+ }
+#ifdef DEBUG_CONFIG
+ printf("end of block\n");
+#endif
+}
+
+
+int ConfigRestore(fp)
+FILE *fp;
+{
+ ConfigLines = 0;
+ restoreblock(fp, Config);
+}
+
+
+static void indent(fp, depth)
+FILE *fp;
+int depth;
+{
+ while (depth-- > 0)
+ fprintf(fp, INDENT_STR);
+}
+
+
+int saveblock(fp, table, depth)
+FILE *fp;
+Config_t *table;
+int depth;
+{
+ Config_t *walker;
+ char **dynamic_object;
+ int ret;
+
+ walker = table;
+ while (walker && (walker->type != EOC)) {
+ switch (walker->type) {
+ case COMMENT:
+ fprintf(fp, "# %s\n", (char *) walker->value);
+ break;
+ case RESOURCE:
+ indent(fp, depth);
+ fprintf(fp, "%s = %s\n", walker->id, (char *) walker->value);
+ break;
+ case DYNAMIC_PTR:
+ if (dynamic_object = (char **) walker->value)
+ while (*dynamic_object) {
+ indent(fp, depth);
+ fprintf(fp, "%s\n", (char *) *dynamic_object);
+ dynamic_object++;
+ }
+ break;
+ case BLOCK:
+ case DYNAMIC:
+ fprintf(fp, "\n");
+ indent(fp, depth);
+ fprintf(fp, "%s\n", walker->id);
+ indent(fp, depth);
+ fprintf(fp, "{\n");
+ if (walker->type == BLOCK)
+ ret = saveblock(fp, (Config_t *) walker->value, depth + 1);
+ else
+ ret = saveblock(fp, (Config_t *) walker->value, depth + 1);
+ indent(fp, depth);
+ fprintf(fp, "}\n");
+ break;
+ /*
+ * case DYNAMIC: indent(fp, depth - 1); fprintf(fp, "%s\n",
+ * walker->id); indent(fp, depth - 1); fprintf(fp, "{\n"); ret =
+ * saveblock(fp, (Config_t *)walker->value, depth + 1);
+ * indent(fp, depth - 1); fprintf(fp, "}\n"); break;
+ */
+ default:
+ fprintf(stderr, "unknown type for '%s'\n", walker->id);
+ }
+ walker++;
+ }
+}
+
+
+int ConfigSave(fp)
+FILE *fp;
+{
+ saveblock(fp, Config, 0);
+ fflush(fp);
+}
+
+
+static void configinitloop(table)
+Config_t *table;
+{
+ Config_t *walker;
+
+ walker = table;
+ while (walker && (walker->type != EOC)) {
+ switch (walker->type) {
+ case RESOURCE:
+ walker->value = (void *) strdup((char *) walker->value);
+#ifdef DEBUG_CONFIG
+ printf("init: '%s': '%s'\n", walker->id, (void *) walker->value);
+#endif
+ break;
+ case BLOCK:
+#ifdef DEBUG_CONFIG
+ printf("init: table = %s\n", walker->id);
+#endif
+ configinitloop((Config_t *) walker->value);
+ break;
+ }
+ walker++;
+ }
+}
+
+
+void ConfigInit(void)
+{
+ configinitloop(Config);
+}
+
+
+void *
+ ConfigGetValue(tableptr, id)
+void *tableptr;
+char *id;
+{
+ Config_t *table = (Config_t *) tableptr;
+ Config_t *item;
+
+ if (!table)
+ table = Config;
+ if (item = getitem(id, table))
+ return (item->value);
+ return ((void *) NULL);
+}
+
+
+void *
+ ConfigSetValue(tableptr, id, value)
+void *tableptr;
+char *id;
+void *value;
+{
+ Config_t *table = (Config_t *) tableptr;
+ void *ret = (void *) NULL;
+ Config_t *item;
+
+ if (!table)
+ table = Config;
+ if (item = getitem(id, table))
+ switch (item->type) {
+ case RESOURCE:
+ if (item->value)
+ free(item->value);
+ item->value = value;
+ break;
+ case DYNAMIC_PTR:
+ ret = item->value;
+ item->value = value;
+ break;
+ default:
+ ;
+ }
+ return ret;
+}
--- /dev/null
+/* $Id: Defs.h,v 1.1 1992/05/18 21:43:03 tvr Exp tvr $ */
+
+
+#define ERWISERC ".erwiserc"
+
+#define HELP_DIR "file:/p/lib/erwise/help/"
+#define HELP_TOPLEVEL "file:/p/lib/erwise/help/help1.html"
+
+#define AUTOGET 0
+#define NO_AUTOGET 1
+
+#define POLLING 1
+#define SELECTING 2
+
+/*
+ * #define C_FONT_NORMAL "normal" #define C_FONT_LIST "list" #define
+ * C_FONT_LISTCOMPACT "listcompact" #define C_FONT_GLOSSARY
+ * "glossary" #define C_FONT_GLOSSARYCOMPACT "glossarycompact" #define
+ * C_FONT_EXAMPLE "example" #define C_FONT_LISTING "listing"
+ * #define C_FONT_ADDRESS "address" #define C_FONT_HEADER1
+ * "header1" #define C_FONT_HEADER2 "header2" #define C_FONT_HEADER3
+ * "header3" #define C_FONT_HEADER4 "header4" #define C_FONT_HEADER5
+ * "header5" #define C_FONT_HEADER6 "header6" #define C_FONT_HEADER7
+ * "header7"
+ */
+
+#define C_COMMAND "command"
+#define C_FILENAME "filename"
+#define C_PRINTTOFILE "printtofile"
+
+/*
+ * #define C_TOPMARGIN "topmargin" #define C_BOTTOMMARGIN "bottommargin"
+ * #define C_LEFTMARGIN "leftmargin" #define C_RIGHTMARGIN "rightmargin"
+ * #define C_WIDTH "width" #define C_HEIGHT "height" #define
+ * C_ONEPAGEMODE "onepagemode" #define C_FIXEDWIDTHMODE "fixedwidthmode"
+ * #define C_FIXEDWIDTH "fixedwidth" #define C_DOUBLECLICKTIME
+ * "doubleclicktime"
+ */
+
+/*
+ * #define C_SEARCH "search" #define C_CONTROLPANEL "controlpanel"
+ * #define C_LIST "list" #define C_RECALL "recall" #define
+ * C_PAGESETTINGS "pagesettings"
+ */
+
+
+/* #define C_DEFAULTSTABLE "defaultstable" */
+#define C_COMMENT "comment"
+
+/* #define C_FONTS "Fonts" */
+#define C_PRINT "Print"
+#define C_WINDOWPLACEMENT "WindowPlacement"
+#define C_KEYBINDINGS "KeyBindings"
+#define C_PRINT "Print"
+/* #define C_GLOBALSETTINGS "GlobalSettings" */
+#define C_PAGE "Page"
+/* #define C_DEFAULTS "Defaults" */
+
+#define C_GETPAGE "getpage"
+#define C_PREVWORD "prevword"
+#define C_NEXTWORD "nextword"
+#define C_PREVTAG "prevtag"
+#define C_NEXTTAG "nexttag"
+#define C_CLOSE "close"
+#define C_SEARCH "search"
+#define C_SETTINGS "settings"
+#define C_PRINTDOC "printdoc"
+#define C_LIST "list"
+
+
+#define STR_FALSE "false"
+#define STR_TRUE "true"
+#define STR_OFF "off"
+#define STR_ON "on"
+#define STR_YES "yes"
+#define STR_NO "no"
--- /dev/null
+static char *rcsid = "$Id: Help.c,v 1.1 1992/05/18 21:43:03 tvr Exp tvr $";
+
+#include "Includes.h"
+
+static struct anchorstr_st {
+ char *action, *address;
+} anchortable[] =
+
+{
+ "PageInput", "browserwin.html#browserwindow",
+ "Search", "browserwin.html#search",
+ "Copy", "browserwin.html#copy",
+ "List", "browserwin.html#list",
+ "Print", "browserwin.html#print",
+ "Settings", "browserwin.html#settings",
+ "Close", "browserwin.html#close",
+ "Top", "browserwin.html#top",
+ "Bottom", "browserwin.html#bottom",
+ "Prev tag", "browserwin.html#prevtag",
+ "Next tag", "browserwin.html#nexttag",
+ "Home", "browserwin.html#home",
+ "Recall", "browserwin.html#recall",
+ "Back", "browserwin.html#back",
+ "Prev page", "browserwin.html#prevpage",
+ "Next page", "browserwin.html#nextpage",
+ "Close hierarchy", "browserwin.html#close_hierarchy",
+ "Controlpanel", "browserwin.html#controlpanel",
+ "Defaults", "browserwin.html#defaults",
+ "On action", "browserwin.html#on_action",
+ "Help", "browserwin.html#manual",
+ NULL, NULL
+};
+
+static void helponactioncb(char *actionstring);
+
+
+void HelpOnFunctionCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiGetNextAction(helponactioncb);
+}
+
+
+void HelpManualCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ if (!FindPage(Pages, HELP_TOPLEVEL))
+ AddPage(&Pages, HELP_TOPLEVEL, (HText_t *) NULL, (Page_t *) NULL);
+
+ StartLoading(HELP_TOPLEVEL, HELP_TOPLEVEL, HELP_TOPLEVEL);
+}
+
+
+static void helponactioncb(actionstring)
+char *actionstring;
+{
+ int i;
+ char *addressstring;
+ Page_t *toppage;
+
+ if (!FindPage(Pages, HELP_TOPLEVEL)) {
+ toppage = AddPage(&Pages, HELP_TOPLEVEL, (HText_t *) NULL,
+ (Page_t *) NULL);
+ AddPage(&toppage->Children, HELP_TOPLEVEL, (HText_t *) NULL,
+ toppage);
+ }
+ for (i = 0; anchortable[i].action; i++) {
+ if (!strcmp(anchortable[i].action, actionstring)) {
+ addressstring = (char *) malloc(strlen(HELP_DIR) +
+ strlen(anchortable[i].address) +
+ 1);
+ sprintf(addressstring, "%s%s",
+ HELP_DIR, anchortable[i].address);
+ StartLoading(addressstring, HELP_TOPLEVEL, HELP_TOPLEVEL);
+
+ return;
+ }
+ }
+}
--- /dev/null
+#
+#
+#
+
+ OBJS = main.o Setup.o TopLevel.o Page.o Misc.o Help.o \
+ Print.o Config.o
+ SRCS = main.c Setup.c TopLevel.c Page.c Misc.c Help.c \
+ Print.c Config.c
+
+ XLDIR = ../Xl
+ HTDIR = ../HText
+ CLDIR = ../Cl
+ WWWDIR = $(CLDIR)/WWWLibrary
+ UIDIR = ../Ui
+
+ MOTIF_HDRS = -I/p/motif/include
+ ERWISE_HDRS = -I$(XLDIR) -I$(HTDIR) -I$(CLDIR) -I$(WWWDIR) -I$(UIDIR)
+ DEFINES = $(ERWISE_HDRS) $(MOTIF_HDRS)
+
+LOCAL_LIBRARIES = -L$(WWWDIR) -lWWW \
+ -L$(UIDIR) -lUi \
+ -L$(CLDIR) -lCl \
+ -L$(XLDIR) -lXl \
+ -L$(HTDIR) -lHt
+
+ LDLIBS = -L/p/motif/lib -lXm -lXt -lX11
+
+ComplexProgramTarget(erwise)
--- /dev/null
+/* $Id: Includes.h,v 1.1 1992/05/18 21:43:03 tvr Exp tvr $ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "Cl.h"
+#include "HTParse.h"
+#include "Ui.h"
+#include "XlConfig.h"
+
+#include "Defs.h"
+#include "Types.h"
+#include "Protos.h"
--- /dev/null
+# Makefile generated by imake - do not edit!
+# $XConsortium: imake.c,v 1.65 91/07/25 17:50:17 rws Exp $
+#
+# The cpp used on this machine replaces all newlines and multiple tabs and
+# spaces in a macro expansion with a single space. Imake tries to compensate
+# for this, but is not always successful.
+#
+
+# -------------------------------------------------------------------------
+# Makefile generated from "Imake.tmpl" and </tmp/IIf.a10927>
+# $XConsortium: Imake.tmpl,v 1.139 91/09/16 08:52:48 rws Exp $
+#
+# Platform-specific parameters may be set in the appropriate <vendor>.cf
+# configuration files. Site-specific parameters should be set in the file
+# site.def. Full rebuilds are recommended if any parameters are changed.
+#
+# If your C preprocessor does not define any unique symbols, you will need
+# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
+# "make World" the first time).
+#
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that need to come before
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+# -------------------------------------------------------------------------
+# platform-specific configuration parameters - edit sun.cf to change
+
+# platform: $XConsortium: sun.cf,v 1.72.1.1 92/03/18 13:13:37 rws Exp $
+
+# operating system: SunOS 4.1.2
+
+# $XConsortium: sunLib.rules,v 1.7 91/12/20 11:19:47 rws Exp $
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+# -------------------------------------------------------------------------
+# site-specific configuration parameters that go after
+# the platform-specific parameters - edit site.def to change
+
+# site: $XConsortium: site.def,v 1.2 91/07/30 20:26:44 rws Exp $
+
+ SHELL = /bin/sh
+
+ TOP = ../.
+ CURRENT_DIR = ./erwise
+
+ AR = ar clq
+ BOOTSTRAPCFLAGS =
+ CC = gcc2 -pipe -fstrength-reduce -fpcc-struct-return
+ AS = as
+
+ COMPRESS = compress
+ CPP = /lib/cpp $(STD_CPP_DEFINES)
+ PREPROCESSCMD = gcc2 -pipe -fstrength-reduce -fpcc-struct-return -E $(STD_CPP_DEFINES)
+ INSTALL = install
+ LD = ld
+ LINT = lint
+ LINTLIBFLAG = -C
+ LINTOPTS = -axz
+ LN = ln -s
+ MAKE = make
+ MV = mv
+ CP = cp
+
+ RANLIB = ranlib
+ RANLIBINSTFLAGS =
+
+ RM = rm -f
+ TROFF = psroff
+ MSMACROS = -ms
+ TBL = tbl
+ EQN = eqn
+ STD_INCLUDES =
+ STD_CPP_DEFINES =
+ STD_DEFINES =
+ EXTRA_LOAD_FLAGS = -B/usr/bin/
+ EXTRA_LIBRARIES =
+ TAGS = ctags
+
+ SHAREDCODEDEF = -DSHAREDCODE
+ SHLIBDEF = -DSUNSHLIB
+
+ PROTO_DEFINES =
+
+ INSTPGMFLAGS =
+
+ INSTBINFLAGS = -m 0755
+ INSTUIDFLAGS = -m 4755
+ INSTLIBFLAGS = -m 0644
+ INSTINCFLAGS = -m 0444
+ INSTMANFLAGS = -m 0444
+ INSTDATFLAGS = -m 0444
+ INSTKMEMFLAGS = -g kmem -m 2755
+
+ PROJECTROOT = /v/X11R5
+
+ TOP_INCLUDES = -I$(INCROOT)
+
+ CDEBUGFLAGS = -O
+ CCOPTIONS =
+
+ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES)
+ ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(DEFINES)
+ CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
+ LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
+
+ LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+ LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(LOCAL_LDFLAGS) -L$(USRLIBDIR)
+
+ LDCOMBINEFLAGS = -X -r
+ DEPENDFLAGS =
+
+ MACROFILE = sun.cf
+ RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
+
+ IMAKE_DEFINES =
+
+ IRULESRC = $(CONFIGDIR)
+ IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
+
+ ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
+ $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
+ $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
+
+# -------------------------------------------------------------------------
+# X Window System Build Parameters
+# $XConsortium: Project.tmpl,v 1.138 91/09/10 09:02:12 rws Exp $
+
+# -------------------------------------------------------------------------
+# X Window System make variables; this need to be coordinated with rules
+
+ PATHSEP = /
+ USRLIBDIR = /v/X11R5/lib
+ BINDIR = /v/X11R5/bin
+ INCROOT = /v/X11R5/include
+ BUILDINCROOT = $(TOP)
+ BUILDINCDIR = $(BUILDINCROOT)/X11
+ BUILDINCTOP = ..
+ INCDIR = $(INCROOT)/X11
+ ADMDIR = /usr/adm
+ LIBDIR = $(USRLIBDIR)/X11
+ CONFIGDIR = $(LIBDIR)/config
+ LINTLIBDIR = $(USRLIBDIR)/lint
+
+ FONTDIR = $(LIBDIR)/fonts
+ XINITDIR = $(LIBDIR)/xinit
+ XDMDIR = $(LIBDIR)/xdm
+ TWMDIR = $(LIBDIR)/twm
+ MANPATH = /v/X11R5/man
+ MANSOURCEPATH = $(MANPATH)/man
+ MANSUFFIX = n
+ LIBMANSUFFIX = 3
+ MANDIR = $(MANSOURCEPATH)$(MANSUFFIX)
+ LIBMANDIR = $(MANSOURCEPATH)$(LIBMANSUFFIX)
+ NLSDIR = $(LIBDIR)/nls
+ PEXAPIDIR = $(LIBDIR)/PEX
+ XAPPLOADDIR = $(LIBDIR)/app-defaults
+ FONTCFLAGS = -t
+
+ INSTAPPFLAGS = $(INSTDATFLAGS)
+
+ IMAKE = imake
+ DEPEND = makedepend
+ RGB = rgb
+
+ FONTC = bdftopcf
+
+ MKFONTDIR = mkfontdir
+ MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier
+
+ CONFIGSRC = $(TOP)/config
+ DOCUTILSRC = $(TOP)/doc/util
+ CLIENTSRC = $(TOP)/clients
+ DEMOSRC = $(TOP)/demos
+ LIBSRC = $(TOP)/lib
+ FONTSRC = $(TOP)/fonts
+ INCLUDESRC = $(TOP)/X11
+ SERVERSRC = $(TOP)/server
+ UTILSRC = $(TOP)/util
+ SCRIPTSRC = $(UTILSRC)/scripts
+ EXAMPLESRC = $(TOP)/examples
+ CONTRIBSRC = $(TOP)/../contrib
+ DOCSRC = $(TOP)/doc
+ RGBSRC = $(TOP)/rgb
+ DEPENDSRC = $(UTILSRC)/makedepend
+ IMAKESRC = $(CONFIGSRC)
+ XAUTHSRC = $(LIBSRC)/Xau
+ XLIBSRC = $(LIBSRC)/X
+ XMUSRC = $(LIBSRC)/Xmu
+ TOOLKITSRC = $(LIBSRC)/Xt
+ AWIDGETSRC = $(LIBSRC)/Xaw
+ OLDXLIBSRC = $(LIBSRC)/oldX
+ XDMCPLIBSRC = $(LIBSRC)/Xdmcp
+ BDFTOSNFSRC = $(FONTSRC)/bdftosnf
+ BDFTOSNFSRC = $(FONTSRC)/clients/bdftosnf
+ BDFTOPCFSRC = $(FONTSRC)/clients/bdftopcf
+ MKFONTDIRSRC = $(FONTSRC)/clients/mkfontdir
+ FSLIBSRC = $(FONTSRC)/lib/fs
+ FONTSERVERSRC = $(FONTSRC)/server
+ EXTENSIONSRC = $(TOP)/extensions
+ XILIBSRC = $(EXTENSIONSRC)/lib/xinput
+ PHIGSLIBSRC = $(EXTENSIONSRC)/lib/PEX
+
+# $XConsortium: sunLib.tmpl,v 1.14.1.1 92/03/17 14:58:46 rws Exp $
+
+SHLIBLDFLAGS = -assert pure-text
+PICFLAGS = -fPIC
+
+ DEPEXTENSIONLIB =
+ EXTENSIONLIB = -lXext
+
+ DEPXLIB = $(DEPEXTENSIONLIB)
+ XLIB = $(EXTENSIONLIB) -lX11
+
+ DEPXMULIB = $(USRLIBDIR)/libXmu.sa.$(SOXMUREV)
+ XMULIBONLY = -lXmu
+ XMULIB = -lXmu
+
+ DEPOLDXLIB =
+ OLDXLIB = -loldX
+
+ DEPXTOOLLIB = $(USRLIBDIR)/libXt.sa.$(SOXTREV)
+ XTOOLLIB = -lXt
+
+ DEPXAWLIB = $(USRLIBDIR)/libXaw.sa.$(SOXAWREV)
+ XAWLIB = -lXaw
+
+ DEPXILIB =
+ XILIB = -lXi
+
+ SOXLIBREV = 4.10
+ SOXTREV = 4.10
+ SOXAWREV = 5.0
+ SOOLDXREV = 4.10
+ SOXMUREV = 4.10
+ SOXEXTREV = 4.10
+ SOXINPUTREV = 4.10
+
+ DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
+ XAUTHLIB = -lXau
+ DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a
+ XDMCPLIB = -lXdmcp
+
+ DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a
+ PHIGSLIB = -lphigs
+
+ DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a
+ XBSDLIB = -lXbsd
+
+ LINTEXTENSIONLIB = $(LINTLIBDIR)/llib-lXext.ln
+ LINTXLIB = $(LINTLIBDIR)/llib-lX11.ln
+ LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln
+ LINTXTOOL = $(LINTLIBDIR)/llib-lXt.ln
+ LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln
+ LINTXI = $(LINTLIBDIR)/llib-lXi.ln
+ LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln
+
+ DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
+
+ DEPLIBS1 = $(DEPLIBS)
+ DEPLIBS2 = $(DEPLIBS)
+ DEPLIBS3 = $(DEPLIBS)
+
+# -------------------------------------------------------------------------
+# Imake rules for building libraries, programs, scripts, and data files
+# rules: $XConsortium: Imake.rules,v 1.123 91/09/16 20:12:16 rws Exp $
+
+# -------------------------------------------------------------------------
+# start of Imakefile
+
+#
+#
+#
+
+ OBJS = main.o Setup.o TopLevel.o Page.o Misc.o Help.o \
+ Print.o Config.o
+ SRCS = main.c Setup.c TopLevel.c Page.c Misc.c Help.c \
+ Print.c Config.c
+
+ XLDIR = ../Xl
+ HTDIR = ../HText
+ CLDIR = ../Cl
+ WWWDIR = $(CLDIR)/WWWLibrary
+ UIDIR = ../Ui
+
+ MOTIF_HDRS = -I/p/motif/include
+ ERWISE_HDRS = -I$(XLDIR) -I$(HTDIR) -I$(CLDIR) -I$(WWWDIR) -I$(UIDIR)
+ DEFINES = $(ERWISE_HDRS) $(MOTIF_HDRS)
+
+LOCAL_LIBRARIES = -L$(WWWDIR) -lWWW \
+ -L$(UIDIR) -lUi \
+ -L$(CLDIR) -lCl \
+ -L$(XLDIR) -lXl \
+ -L$(HTDIR) -lHt
+
+ LDLIBS = -L/p/motif/lib -lXm -lXt -lX11
+
+ PROGRAM = erwise
+
+all:: erwise
+
+erwise: $(OBJS) $(DEPLIBS)
+ $(RM) $@
+ $(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
+
+saber_erwise:: $(SRCS)
+ # load $(ALLDEFINES) $(SRCS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+osaber_erwise:: $(OBJS)
+ # load $(ALLDEFINES) $(OBJS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
+
+install:: erwise
+ @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \
+ else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi
+ $(INSTALL) -c $(INSTPGMFLAGS) erwise $(DESTDIR)$(BINDIR)
+
+install.man:: erwise.man
+ @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \
+ else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi
+ $(INSTALL) -c $(INSTMANFLAGS) erwise.man $(DESTDIR)$(MANDIR)/erwise.$(MANSUFFIX)
+
+depend::
+ $(DEPEND) $(DEPENDFLAGS) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
+
+lint:
+ $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
+lint1:
+ $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
+
+clean::
+ $(RM) $(PROGRAM)
+
+# -------------------------------------------------------------------------
+# common rules for all Makefiles - do not edit
+
+emptyrule::
+
+clean::
+ $(RM_CMD) "#"*
+
+Makefile::
+ -@if [ -f Makefile ]; then set -x; \
+ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
+ else exit 0; fi
+ $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
+
+tags::
+ $(TAGS) -w *.[ch]
+ $(TAGS) -xw *.[ch] > TAGS
+
+saber:
+ # load $(ALLDEFINES) $(SRCS)
+
+osaber:
+ # load $(ALLDEFINES) $(OBJS)
+
+# -------------------------------------------------------------------------
+# empty rules for directories that do not have SUBDIRS - do not edit
+
+install::
+ @echo "install in $(CURRENT_DIR) done"
+
+install.man::
+ @echo "install.man in $(CURRENT_DIR) done"
+
+Makefiles::
+
+includes::
+
+# -------------------------------------------------------------------------
+# dependencies generated by makedepend
+
--- /dev/null
+static char *rcsid = "$Id: Misc.c,v 1.1 1992/05/18 21:43:03 tvr Exp $";
+
+#include "Includes.h"
+
+
+void displaypage(char *topaddress, HText_t * parenthtext, HText_t * htext,
+ char *address);
+int addresscmp(char *addr1, char *addr2);
+
+
+Connection_t *Connections = (Connection_t *) NULL;
+Page_t *Pages = (Page_t *) NULL;
+
+
+Page_t *FindPage(hierarchy, address)
+Page_t *hierarchy;
+char *address;
+{
+ while (address && hierarchy)
+ if (!addresscmp(hierarchy->Address, address))
+ return hierarchy;
+ else
+ hierarchy = hierarchy->Next;
+
+ return (Page_t *) NULL;
+}
+
+
+Page_t *
+ GlobalFindPage(address)
+char *address;
+{
+ Page_t *hierarchy = Pages, *tmppage;
+
+ while (address && hierarchy)
+ if (tmppage = FindPage(hierarchy->Children, address))
+ return tmppage;
+ else
+ hierarchy = hierarchy->Next;
+
+ return (Page_t *) NULL;
+}
+
+
+Page_t *
+ AddPage(page, address, htext, toppage)
+Page_t **page;
+char *address;
+HText_t *htext;
+Page_t *toppage;
+{
+ if (*page) {
+ while ((*page)->Next)
+ page = &(*page)->Next;
+ (*page)->Next = (Page_t *) Malloc(sizeof(**page));
+ page = &(*page)->Next;
+ } else
+ *page = (Page_t *) Malloc(sizeof(**page));
+
+ (*page)->Address = strdup(address);
+ (*page)->HText = htext;
+ (*page)->ParentPage = toppage;
+ (*page)->Parents = (Page_t *) NULL;
+ (*page)->Children = (Page_t *) NULL;
+ (*page)->Next = (Page_t *) NULL;
+
+ return *page;
+}
+
+
+void DeletePage(page, address)
+Page_t **page;
+char *address;
+{
+ Page_t *oldpage = *page;
+
+ if (!strcmp((*page)->Address, address)) {
+ *page = (*page)->Next;
+ Free(oldpage);
+ } else
+ while (*page)
+ if (!strcmp((*page)->Address, address)) {
+ *page = (*page)->Next;
+ Free(oldpage);
+ } else {
+ page = &(*page)->Next;
+ oldpage = *page;
+ }
+}
+
+
+void DisplayWarning(text)
+char *text;
+{
+ fprintf(stderr, "Warning: %s\n", text);
+}
+
+
+void DisplayFatal(text)
+char *text;
+{
+ fprintf(stderr, "Fatal: %s\n", text);
+
+ abort();
+}
+
+
+int CanBeCursor(htextobject)
+HTextObject_t *htextobject;
+{
+ int i;
+
+ if (htextobject->paragraph)
+ return FALSE;
+
+ for (i = 0; i < htextobject->length; i++)
+ if (htextobject->data[i] != ' ')
+ return TRUE;
+
+ return FALSE;
+}
+
+
+void *
+ Malloc(size)
+int size;
+{
+ void *tmpptr;
+
+ if (!(tmpptr = (void *) malloc(size))) {
+ DisplayFatal("No swap, buy a computer");
+ exit(1);
+ } /* Not reached */
+ return tmpptr;
+}
+
+
+void *
+ ReAlloc(ptr, size)
+void *ptr;
+int size;
+{
+ void *tmpptr;
+
+ if (!ptr)
+ return Malloc(size);
+ else if (!(tmpptr = (void *) realloc((char *) ptr, size))) {
+ DisplayFatal("No swap, buy a computer");
+ exit(1);
+ } /* Not reached */
+ return tmpptr;
+}
+
+
+void Free(ptr)
+void *ptr;
+{
+ if (ptr)
+ free(ptr);
+}
+
+
+void StartLoading(address, topaddress, parentaddress)
+char *address;
+char *topaddress;
+char *parentaddress;
+{
+ Page_t *oldpage, *tmppage, *toppage, *parentpage;
+ HText_t *newhtext;
+ ClConnection_t *clconnection;
+ Connection_t *connection;
+
+ toppage = FindPage(Pages, topaddress);
+ parentpage = (toppage && parentaddress) ?
+ FindPage(toppage->Children, parentaddress) : (Page_t *) NULL;
+
+ if (toppage && (oldpage = GlobalFindPage(address))) {
+ if (tmppage = FindPage(toppage->Children, address)) {
+ if (tmppage->HText) {
+ /* add the parent */
+ if (parentaddress && strcmp(parentaddress, address) &&
+ !FindPage(tmppage->Parents, parentaddress))
+ AddPage(&tmppage->Parents, parentaddress, tmppage->HText,
+ parentpage);
+ /* display the page */
+ displaypage(toppage ? toppage->Address : (char *) NULL,
+ parentpage ? parentpage->HText : (HText_t *) NULL,
+ tmppage->HText, address);
+
+ return;
+ }
+ } else {
+ if (oldpage->HText) {
+#if 0
+ /* copy the htext */
+ newhtext = HtDuplicate(oldpage->HText);
+ /* add the page */
+ tmppage = AddPage(&toppage->Children, address, newhtext,
+ toppage);
+ /* add the parent */
+ if (parentaddress && strcmp(parentaddress, address) &&
+ !FindPage(tmppage->Parents, parentaddress))
+ AddPage(&tmppage->Parents, parentaddress, tmppage->HText,
+ parentpage);
+ /* display the page */
+ displaypage(toppage ? toppage->Address : (char *) NULL,
+ parentpage ? parentpage->HText : (HText_t *) NULL,
+ newhtext, address);
+
+ return;
+#endif
+ HTAnchor_setDocument((void *) oldpage->HText->node_anchor,
+ (void *) NULL);
+
+ }
+ }
+ }
+ if (FindConnection(address))
+ return;
+
+ if (!(clconnection = ClOpenConnection(address))) {
+ DisplayWarning("Error in ClOpenConnection");
+ return;
+ }
+ connection = AddConnection(address, toppage, parentpage, clconnection);
+
+ PollConnection(connection);
+}
+
+
+void PollConnection(connection)
+Connection_t *connection;
+{
+ HText_t *htext;
+ int status;
+ int oldfd = connection->FD;
+ char *topaddress, *parentaddress;
+ Page_t *tmppage, *toppage, *parentpage;
+
+ htext = ClReadData(connection->ClConnection, &status, &connection->FD);
+
+ switch (status) {
+ case CL_CONTINUES:
+ if (connection->FD && connection->Status == POLLING) {
+ connection->InputId =
+ UiAddInputFD(connection->FD,
+ (void (*) (void *)) &PollConnection,
+ (void *) connection);
+ connection->Status = SELECTING;
+ } else if (!connection->FD) {
+ if (oldfd)
+ UiDeleteInputFD(connection->InputId);
+ connection->TimeOutId =
+ UiAddTimeOut(200, (void (*) (void *)) &PollConnection,
+ (void *) connection);
+ connection->Status = POLLING;
+ }
+ break;
+ case CL_COMPLETED:
+ if (connection->Status == SELECTING)
+ UiDeleteInputFD(connection->InputId);
+ if (htext && !connection->TopPage->HText)
+ connection->TopPage->HText = htext;
+
+ if (htext) {
+ parentaddress = connection->ParentPage ?
+ connection->ParentPage->Address : (char *) NULL;
+ toppage = connection->TopPage;
+
+ parentpage = connection->ParentPage;
+ if (!(tmppage = FindPage(toppage->Children, connection->Address))) {
+ tmppage = AddPage(&toppage->Children, connection->Address,
+ htext, toppage);
+ /* add the parent (what the fuck have I been thinkin' here?) */
+ if (connection->ParentPage && parentaddress &&
+ !FindPage(tmppage->Parents, parentaddress))
+ AddPage(&tmppage->Parents, parentaddress,
+ tmppage->HText, parentpage);
+ } else
+ tmppage->HText = htext;
+
+ displaypage(connection->TopPage ?
+ connection->TopPage->Address : (char *) NULL,
+ connection->ParentPage ?
+ connection->ParentPage->HText : (HText_t *) NULL,
+ htext, connection->Address);
+ }
+ DeleteConnection(connection->Address);
+ break;
+ case CL_FAILED:
+ if (connection->Status == SELECTING)
+ UiDeleteInputFD(connection->InputId);
+ DeleteConnection(connection->Address);
+ break;
+ default:
+ DisplayWarning("Uh? :O");
+ }
+}
+
+
+void displaypage(topaddress, parenthtext, htext, address)
+char *topaddress;
+HText_t *parenthtext;
+HText_t *htext;
+char *address;
+{
+ HTextAnchor_t *htanchor = (HTextAnchor_t *) NULL;
+ HTextObject_t *htextobject;
+ char *tag = HTParse(address, "", PARSE_ANCHOR);
+
+ if (tag && tag[0]) {
+ htanchor = htext->anchorlist;
+ while (htanchor)
+ if (htanchor->anchor && htanchor->anchor->tag &&
+ !strcmp(htanchor->anchor->tag, tag))
+ break;
+ else
+ htanchor = htanchor->next;
+ Free(tag);
+ }
+ htextobject = htanchor ? htanchor->object : htext->first;
+
+ while (htextobject && !CanBeCursor(htextobject))
+ htextobject = htextobject->next;
+
+ UiDisplayPage(topaddress, parenthtext, htext, htextobject,
+ (char *) HTAnchor_title(htext->node_anchor));
+}
+
+
+Connection_t *
+ AddConnection(address, toppage, parentpage, clconnection)
+char *address;
+Page_t *toppage;
+Page_t *parentpage;
+ClConnection_t *clconnection;
+{
+ Connection_t *tmpconnection = Connections;
+
+ if (tmpconnection) {
+ while (tmpconnection->Next)
+ tmpconnection = tmpconnection->Next;
+ tmpconnection = tmpconnection->Next = Malloc(sizeof(*tmpconnection));
+ } else
+ tmpconnection = Connections = Malloc(sizeof(*tmpconnection));
+
+ tmpconnection->Address = strdup(address);
+ tmpconnection->TopPage = toppage;
+ tmpconnection->ParentPage = parentpage;
+ tmpconnection->ClConnection = clconnection;
+ tmpconnection->FD = 0;
+ tmpconnection->Status = POLLING;
+ tmpconnection->Next = (Connection_t *) NULL;
+
+ if (UiConnectionsDialogDisplayed())
+ ConnectionsCB((char *) NULL, (HText_t *) NULL,
+ (HTextObject_t *) NULL, (void *) NULL);
+
+ return tmpconnection;
+}
+
+
+Connection_t *
+ FindConnection(address)
+char *address;
+{
+ Connection_t *tmpconnection = Connections;
+
+ while (tmpconnection)
+ if (!addresscmp(tmpconnection->Address, address))
+ return tmpconnection;
+ else
+ tmpconnection = tmpconnection->Next;
+
+ return (Connection_t *) NULL;
+}
+
+
+void DeleteConnection(address)
+char *address;
+{
+ Connection_t *tmpconnection = Connections;
+
+ if (tmpconnection)
+ if (!strcmp(tmpconnection->Address, address))
+ Connections = Connections->Next;
+ else {
+ while (tmpconnection->Next &&
+ strcmp(tmpconnection->Next->Address, address))
+ tmpconnection = tmpconnection->Next;
+ if (tmpconnection->Next) {
+ Connection_t *tmptmpconnection;
+
+ tmptmpconnection = tmpconnection->Next;
+ tmpconnection->Next = tmpconnection->Next->Next;
+ tmpconnection = tmptmpconnection;
+ } else
+ tmpconnection = (Connection_t *) NULL;
+ }
+ if (tmpconnection) {
+ if (UiConnectionsDialogDisplayed())
+ ConnectionsCB((char *) NULL, (HText_t *) NULL,
+ (HTextObject_t *) NULL, (void *) NULL);
+ Free(tmpconnection->Address);
+ Free(tmpconnection);
+ } else
+ DisplayWarning("DeleteConnection failed");
+}
+
+
+int addresscmp(addr1, addr2)
+char *addr1, *addr2;
+{
+ int i = 0;
+
+ while (addr1[i] && addr2[i] && addr1[i] != '#' && addr2[i] != '#')
+ if (addr1[i] != addr2[i])
+ return 1;
+ else
+ i++;
+
+ if ((addr1[i] && addr1[i] != '#') || (addr2[i] && addr2[i] != '#'))
+ return 1;
+
+ return 0;
+}
--- /dev/null
+static char *rcsid = "$Id: Page.c,v 1.1 1992/05/18 21:43:03 tvr Exp $";
+
+#include "Includes.h"
+
+
+void getanddisplaypage(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject);
+int matchingstring(char *word);
+
+
+char FindText[256] = "\0";
+char SearchText[256] = "\0";
+int SearchDepth = 1;
+int SearchCase = FALSE;
+
+
+static int SearchDialogType;
+static int PageSettingsDialogType;
+
+static char *CopyTopAddress;
+static HText_t *CopyHText;
+static HTextObject_t *CopyHTextObject;
+
+
+void PageSearchCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiDisplaySearchDialog(SearchDialogType);
+}
+
+
+void PageCopyCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ CopyHTextObject = htextobject;
+ CopyTopAddress = strdup(topaddress);
+ CopyHText = htext;
+}
+
+
+void PageListCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ int i = 0, j, stringlength;
+ char **items = (char **) NULL;
+ char **addresses = (char **) NULL;
+ HTextObject_t *tmphtextobject = htext->first;
+ HTAnchor *tmpanchor, *destanchor;
+
+ while (tmphtextobject)
+ if (tmpanchor = (HTAnchor *) tmphtextobject->anchor) {
+ addresses = (char **) ReAlloc((void *) addresses,
+ ++i * sizeof(char *));
+ destanchor =
+ HTAnchor_followMainLink((HTAnchor *) tmphtextobject->anchor);
+ addresses[i - 1] = HTAnchor_address(destanchor);
+ items = (char **) ReAlloc((void *) items, i * sizeof(char *));
+ j = 1;
+ items[i - 1] = (char *) NULL;
+ while (tmphtextobject &&
+ (HTAnchor *) tmphtextobject->anchor == tmpanchor) {
+ stringlength = strlen(tmphtextobject->data);
+ j += stringlength;
+ items[i - 1] = (char *) ReAlloc((void *) items[i - 1],
+ j * sizeof(char));
+ strcpy(&items[i - 1][j - stringlength - 1],
+ tmphtextobject->data);
+ items[i - 1][j - 1] = '\0';
+ tmphtextobject = tmphtextobject->next;
+ }
+ } else
+ tmphtextobject = tmphtextobject->next;
+
+ UiDisplayListDialog(items, addresses, i, StartLoading);
+}
+
+
+void PageLoadToFileCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTAnchor *destanchor;
+
+ if (!htextobject || !htextobject->anchor) {
+ UiDisplayWarningDialog("No active tag", (void (*) (int)) NULL);
+ return;
+ }
+ destanchor = HTAnchor_followMainLink((HTAnchor *) htextobject->anchor);
+ if (ClCanLoadToFile(HTAnchor_address(destanchor)))
+ UiDisplayFileSelection(PageGetPageCB);
+ else
+ UiDisplayWarningDialog("Load to file not supported for this tag",
+ (void (*) (int)) NULL);
+}
+
+
+int TruthValue(value)
+char *value;
+{
+ if (value && (!strncasecmp(value, STR_TRUE, strlen(STR_TRUE)) ||
+ !strncasecmp(value, STR_ON, strlen(STR_ON)) ||
+ !strncasecmp(value, STR_YES, strlen(STR_YES))))
+ return TRUE;
+ return FALSE;
+}
+
+
+void PagePrintCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ static void *table = (void *) NULL;
+ int update = FALSE;
+ char *configstr;
+
+ if (!table) {
+ update = TRUE;
+ table = ConfigGetValue((void *) NULL, C_PRINT);
+ PrintTopMargin = atoi((char *) ConfigGetValue(table, C_TOPMARGIN));
+ PrintBottomMargin =
+ atoi((char *) ConfigGetValue(table, C_BOTTOMMARGIN));
+ PrintLeftMargin = atoi((char *) ConfigGetValue(table, C_LEFTMARGIN));
+ PrintWidth = atoi((char *) ConfigGetValue(table, C_WIDTH));
+ if (configstr = (char *) ConfigGetValue(table, C_COMMAND))
+ strcpy(PrintCommand, configstr);
+ else
+ strcpy(PrintCommand, "");
+ PrintToFile = TruthValue((char *) ConfigGetValue(table, C_PRINTTOFILE));
+ if (configstr = (char *) ConfigGetValue(table, C_FILENAME))
+ strcpy(PrintFileName, configstr);
+ else
+ strcpy(PrintFileName, "");
+ }
+ UiDisplayPrintDialog(htext);
+
+ if (update) {
+ UiUpdateVariable("PrintTopMargin");
+ UiUpdateVariable("PrintBottomMargin");
+ UiUpdateVariable("PrintLeftMargin");
+ UiUpdateVariable("PrintWidth");
+ UiUpdateVariable("PrintCommand");
+ UiUpdateVariable("PrintToFile");
+ UiUpdateVariable("PrintFileName");
+ }
+}
+
+
+void PageSettingsCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiDisplayPageSettingsDialog(PageSettingsDialogType);
+}
+
+
+void PageCloseCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ char *address = HTAnchor_address((HTAnchor *) htext->node_anchor);
+ Page_t *toppage, *page;
+
+ toppage = FindPage(Pages, topaddress);
+ page = FindPage(toppage->Children, address);
+
+ UiDeletePage(toppage->Address, htext);
+ page->HText = (HText_t *) NULL;
+ HText_free(htext);
+
+ page = toppage->Children;
+ while (page)
+ if (page->HText)
+ return;
+ else
+ page = page->Next;
+
+ HierarchyClose(topaddress, htext, htextobject, parameter);
+}
+
+
+void PagePrevWordCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTextObject_t *tmphtextobject;
+
+ if (!htextobject)
+ return;
+
+ tmphtextobject = htextobject->prev;
+
+ while (tmphtextobject && !CanBeCursor(tmphtextobject))
+ tmphtextobject = tmphtextobject->prev;
+
+ if (tmphtextobject)
+ UiSetCursor(topaddress, htext, tmphtextobject);
+}
+
+
+void PageNextWordCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTextObject_t *tmphtextobject;
+
+ if (!htextobject)
+ return;
+
+ tmphtextobject = htextobject->next;
+
+ while (tmphtextobject && !CanBeCursor(tmphtextobject))
+ tmphtextobject = tmphtextobject->next;
+
+ if (tmphtextobject)
+ UiSetCursor(topaddress, htext, tmphtextobject);
+}
+
+
+void PagePrevTagCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTextAnchor_t *tmphtanchor;
+ HTAnchor *tmpanchor, *destanchor;
+ HText_t *newhtext;
+ HTextObject_t *newhtextobject;
+
+ if (!htextobject)
+ return;
+
+ tmpanchor = (HTAnchor *) htextobject->anchor;
+
+ /* Ignore htextobject with same anchor */
+ while (tmpanchor && htextobject &&
+ ((HTAnchor *) htextobject->anchor == tmpanchor))
+ htextobject = htextobject->prev;
+
+ /* Search for previous anchor */
+ while (htextobject && !htextobject->anchor)
+ htextobject = htextobject->prev;
+
+ /* No anchor found */
+ if (!htextobject)
+ return;
+
+ /* We want the first word in the tag to be highlighted */
+ while (htextobject->prev &&
+ (htextobject->anchor == htextobject->prev->anchor))
+ htextobject = htextobject->prev;
+
+ UiSetCursor(topaddress, htext, htextobject);
+
+ if ((int) parameter == NO_AUTOGET)
+ return;
+
+ getanddisplaypage(topaddress, htext, htextobject);
+}
+
+
+void PageNextTagCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTAnchor *tmpanchor;
+ HTextObject_t *newhtextobject;
+
+ if (!htextobject)
+ return;
+
+ tmpanchor = (HTAnchor *) htextobject->anchor;
+
+ /* Ignore htextobject with same anchor */
+ while (tmpanchor && htextobject &&
+ ((HTAnchor *) htextobject->anchor == tmpanchor))
+ htextobject = htextobject->next;
+
+ /* Search for previous anchor */
+ while (htextobject && !htextobject->anchor)
+ htextobject = htextobject->next;
+
+ /* No anchor found */
+ if (!htextobject)
+ return;
+
+ UiSetCursor(topaddress, htext, htextobject);
+
+ if ((int) parameter == NO_AUTOGET)
+ return;
+
+ getanddisplaypage(topaddress, htext, htextobject);
+}
+
+
+void PageHomeCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ StartLoading(topaddress, topaddress, (char *) NULL);
+}
+
+
+void PageRecallCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ Page_t *toppage, *page;
+ int i = 0;
+ char **items = (char **) NULL;
+
+ toppage = FindPage(Pages, topaddress);
+ page = toppage->Children;
+
+ while (page) {
+ items = (char **) ReAlloc((void *) items, ++i * sizeof(char *));
+ items[i - 1] = strdup(page->Address);
+ page = page->Next;
+ }
+
+ UiDisplayRecallDialog(items, i, StartLoading);
+}
+
+
+void PageBackCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ char *address = HTAnchor_address((HTAnchor *) htext->node_anchor);
+ Page_t *toppage, *parentpage, *page;
+
+ toppage = FindPage(Pages, topaddress);
+ page = FindPage(toppage->Children, address);
+
+ if (parentpage = page->Parents) {
+ if (parentpage->Next)
+ PageGeneratePopup(parentpage, topaddress);
+ else {
+ while (parentpage->Next)
+ parentpage = parentpage->Next;
+ StartLoading(parentpage->Address, topaddress, parentpage->Address);
+ }
+ }
+}
+
+
+PageGeneratePopup(parentpage, topaddress)
+Page_t *parentpage;
+char *topaddress;
+{
+ char **items = (char **) NULL;
+ int nitems = 0;
+
+ while (parentpage) {
+ items = (char **) ReAlloc((void *) items, ++nitems * sizeof(char *));
+ items[nitems - 1] = parentpage->Address;
+ parentpage = parentpage->Next;
+ }
+
+ UiDisplayPopup(StartLoading, topaddress, items, nitems);
+}
+
+
+HTextObject_t *
+ FindHTextObject(htext, address)
+HText_t *htext;
+char *address;
+{
+ HTextObject_t *newhtextobject;
+ HTAnchor *destanchor;
+
+ newhtextobject = htext->first;
+ while (newhtextobject) {
+ if (newhtextobject->anchor) {
+ destanchor =
+ HTAnchor_followMainLink((HTAnchor *) newhtextobject->anchor);
+ if (destanchor && !strcmp(HTAnchor_address(destanchor), address))
+ return newhtextobject;
+ }
+ newhtextobject = newhtextobject->next;
+ }
+
+ return (HTextObject_t *) NULL;
+}
+
+
+void PagePrevPageCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ char *address = HTAnchor_address((HTAnchor *) htext->node_anchor);
+ Page_t *toppage, *parentpage, *page;
+ HTextObject_t *newhtextobject;
+
+ toppage = FindPage(Pages, topaddress);
+ page = FindPage(toppage->Children, address);
+
+ if (parentpage = page->Parents) {
+ if (parentpage->Next)
+ PageGeneratePopup(parentpage, topaddress);
+ while (parentpage->Next)
+ parentpage = parentpage->Next;
+ parentpage = parentpage->ParentPage;
+ if (parentpage->HText) {
+ newhtextobject = FindHTextObject(parentpage->HText, page->Address);
+ if (newhtextobject)
+ PagePrevTagCB(topaddress, parentpage->HText,
+ newhtextobject, (void *) AUTOGET);
+ } else
+ StartLoading(parentpage->Address, topaddress, (char *) NULL);
+ }
+}
+
+
+void PageNextPageCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ char *address = HTAnchor_address((HTAnchor *) htext->node_anchor);
+ Page_t *toppage, *parentpage, *page;
+ HTextObject_t *newhtextobject;
+
+ toppage = FindPage(Pages, topaddress);
+ page = FindPage(toppage->Children, address);
+
+ if (parentpage = page->Parents) {
+ if (parentpage->Next)
+ PageGeneratePopup(parentpage, topaddress);
+ while (parentpage->Next)
+ parentpage = parentpage->Next;
+ parentpage = parentpage->ParentPage;
+ if (parentpage->HText) {
+ newhtextobject = FindHTextObject(parentpage->HText, page->Address);
+ if (newhtextobject)
+ PageNextTagCB(topaddress, parentpage->HText,
+ newhtextobject, (void *) AUTOGET);
+ } else
+ StartLoading(parentpage->Address, topaddress, (char *) NULL);
+ }
+}
+
+
+void PageGetPageCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ if (!htextobject || !htextobject->anchor)
+ return;
+
+ if (parameter)
+ ClSetFileNameForLoadingToFile((char *) parameter);
+
+ getanddisplaypage(topaddress, htext, htextobject);
+}
+
+
+void PageClickCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTextObject_t *tmphtextobject = htext->first;
+ int state = 0;
+
+ if (CopyHTextObject && !strcmp(topaddress, CopyTopAddress)
+ && htext == CopyHText)
+ while (tmphtextobject) {
+ if (tmphtextobject == CopyHTextObject ||
+ tmphtextobject == htextobject)
+ state += 1 + (CopyHTextObject == htextobject);
+ switch (state) {
+ case 2:
+ if (tmphtextobject->data)
+ UiAddStringToCutBuffer(tmphtextobject->data);
+ else
+ UiAddStringToCutBuffer("\n");
+ UiAddStringToCutBuffer((char *) NULL);
+ tmphtextobject = (HTextObject_t *) NULL;
+ Free(CopyTopAddress);
+ break;
+ case 1:
+ if (tmphtextobject->data)
+ UiAddStringToCutBuffer(tmphtextobject->data);
+ else
+ UiAddStringToCutBuffer("\n");
+ /* Fall through */
+ default:
+ tmphtextobject = tmphtextobject->next;
+ }
+ }
+
+ CopyHTextObject = (HTextObject_t *) NULL;
+}
+
+
+void IndexFindCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ char *newaddress;
+
+ if (!FindText[0])
+ return;
+
+ HTMainAnchor = htext->node_anchor; /* Kludguality */
+ newaddress = (char *) HTSearchAddress(FindText); /* missa proto, meeTu? */
+
+ StartLoading(newaddress, topaddress,
+ HTAnchor_address((HTAnchor *) htext->node_anchor));
+ Free(newaddress);
+}
+
+
+static char *hiertopaddress;
+static HText_t *hierhtext;
+static HTextObject_t *hierhtextobject;
+static void *hierparameter;
+
+void HierarchyCloseCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ hiertopaddress = topaddress;
+ hierhtext = htext;
+ hierhtextobject = htextobject;
+ hierparameter = parameter;
+
+ UiDisplayWarningDialog("Close hierarchy?", HierarchyNukeCB);
+}
+
+
+void HierarchyNukeCB(button)
+int button;
+{
+ HierarchyClose(hiertopaddress, hierhtext, hierhtextobject, hierparameter);
+}
+
+
+void HierarchyClose(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ Page_t *toppage;
+
+ toppage = FindPage(Pages, topaddress);
+
+ while (toppage->Children) {
+ if (toppage->Children->HText) {
+ HText_free(toppage->Children->HText);
+ UiDeletePage(toppage->Address, toppage->Children->HText);
+ }
+ while (toppage->Children->Parents)
+ DeletePage(&toppage->Children->Parents,
+ toppage->Children->Parents->Address);
+ DeletePage(&toppage->Children, toppage->Children->Address);
+ }
+
+ DeletePage(&Pages, toppage->Address);
+}
+
+
+void SearchBackwardCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTextObject_t *newhtextobject;
+
+ if (!htextobject)
+ return;
+
+ newhtextobject = htextobject->prev;
+ while (newhtextobject && !matchingstring(newhtextobject->data))
+ newhtextobject = newhtextobject->prev;
+
+ if (newhtextobject)
+ UiSetCursor(topaddress, htext, newhtextobject);
+}
+
+
+void SearchForwardCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ HTextObject_t *newhtextobject;
+
+ if (!htextobject)
+ return;
+
+ newhtextobject = htextobject->next;
+ while (newhtextobject && !matchingstring(newhtextobject->data))
+ newhtextobject = newhtextobject->next;
+
+ if (newhtextobject)
+ UiSetCursor(topaddress, htext, newhtextobject);
+}
+
+
+void ConnectionsCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ Connection_t *tmpconnection = Connections;
+ char **listitems = (char **) NULL;
+ void **connections = (void **) NULL;
+ int nitems = 0;
+
+ while (tmpconnection) {
+ listitems = (char **) ReAlloc((void *) listitems,
+ ++nitems * sizeof(char *));
+ listitems[nitems - 1] = tmpconnection->Address;
+ connections = (void **) ReAlloc((void *) connections,
+ nitems * sizeof(void *));
+ connections[nitems - 1] = tmpconnection;
+ tmpconnection = tmpconnection->Next;
+ }
+
+ UiDisplayConnectionsDialog(listitems, connections, nitems, KillCB);
+}
+
+
+void KillCB(connection)
+void *connection;
+{
+ Connection_t *tmpconnection = (Connection_t *) connection;
+
+ switch (tmpconnection->Status) {
+ case SELECTING:
+ UiDeleteInputFD(tmpconnection->InputId);
+ break;
+ case POLLING:
+ UiDeleteTimeOut(tmpconnection->TimeOutId);
+ }
+
+ ClCloseConnection(tmpconnection->ClConnection);
+ DeleteConnection(tmpconnection->Address);
+}
+
+
+void ControlPanelCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiDisplayControlPanel();
+}
+
+
+void DefaultsCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiDisplayDefaultsDialog();
+}
+
+
+void getanddisplaypage(topaddress, htext, htextobject)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+{
+ HTAnchor *destanchor;
+
+ destanchor = HTAnchor_followMainLink((HTAnchor *) htextobject->anchor);
+ HTMainAnchor = (HTParentAnchor *) NULL;
+
+ StartLoading(HTAnchor_address(destanchor),
+ topaddress,
+ HTAnchor_address((HTAnchor *) htext->node_anchor));
+}
+
+
+int matchingstring(word)
+char *word;
+{
+ char *tmpptr = word;
+ int searchlength = strlen(SearchText);
+
+ while (tmpptr && strlen(tmpptr) >= searchlength) {
+ if (SearchCase) {
+ if (!strncmp(tmpptr, SearchText, searchlength))
+ return TRUE;
+ } else if (!strncasecmp(tmpptr, SearchText, searchlength))
+ return TRUE;
+ tmpptr++;
+ }
+
+ return FALSE;
+}
--- /dev/null
+/*
+ * Print.c --
+ *
+ * Author: Teemu Rantanen <tvr@cs.hut.fi> Copyright (c) 1992 Teemu Rantanen All
+ * rights reserved
+ *
+ * Created: Sun Apr 26 21:30:47 1992 tvr Last modified: Mon May 11 22:56:41 1992
+ * tvr
+ *
+ */
+
+#include "Includes.h"
+
+#include <fcntl.h>
+
+int PrintTopMargin = 0;
+int PrintBottomMargin = 0;
+int PrintLeftMargin = 0;
+int PrintWidth = 80;
+int PrintToFile = 0;
+
+char PrintCommand[1024] = "lpr";
+char PrintFileName[1024] = "foobar.www";
+
+
+/*
+ * One object on a line
+ */
+typedef struct PrintObject_s {
+
+ HTextObject_t *HtObject;
+
+ struct PrintObject_s *Next;
+} PrintObject_t;
+
+
+/*
+ * All line objects and info on line
+ */
+typedef struct PrintLine_s {
+
+ int LineY;
+
+ PrintObject_t *Objects;
+
+ struct PrintLine_s *Next;
+
+} PrintLine_t;
+
+
+
+/*
+ * Allocate new PrintObject.
+ */
+PrintObject_t *
+ new_print_object()
+{
+ PrintObject_t *p;
+
+ p = (PrintObject_t *) malloc(sizeof(*p));
+
+ if (!p)
+ return p;
+
+ memset(p, 0, sizeof(*p));
+
+ return p;
+}
+
+
+/*
+ * Allocate new PrintLine.
+ */
+PrintLine_t *
+ new_print_line()
+{
+ PrintLine_t *p;
+
+ p = (PrintLine_t *) malloc(sizeof(*p));
+
+ if (!p)
+ return p;
+
+ memset(p, 0, sizeof(*p));
+
+ return p;
+}
+
+
+/*
+ * Append object to a line. Sort objects according to x position
+ */
+int printobject_append(line, htobject)
+PrintLine_t *line;
+HTextObject_t *htobject;
+{
+ PrintObject_t *object = line->Objects;
+ PrintObject_t *prev = 0;
+
+ /*
+ * First object on a line
+ */
+ if (!object) {
+ if (!(line->Objects = new_print_object()))
+ return 0;
+
+ line->Objects->HtObject = htobject;
+
+ return 1;
+ }
+ /*
+ * Check on which place do we put this ?
+ */
+ while (object && (htobject->x > object->HtObject->x)) {
+
+ prev = object;
+
+ object = object->Next;
+ }
+
+ /*
+ * Set object to line-list
+ */
+
+ {
+ PrintObject_t *new_object = new_print_object();
+
+ if (!new_object)
+ return 0;
+
+ new_object->Next = object;
+
+ new_object->HtObject = htobject;
+
+ if (prev) {
+
+ prev->Next = new_object;
+
+ } else {
+
+ line->Objects = new_object;
+
+ }
+ }
+}
+
+
+/*
+ * Check on which line object should be appended
+ */
+PrintLine_t *
+ print_check_line_append(first, object)
+PrintLine_t *first;
+HTextObject_t *object;
+{
+ PrintLine_t *p;
+ PrintLine_t *new_line;
+ PrintLine_t *prev;
+
+ /*
+ * If this is first line, no problemo ...
+ */
+ if (!first) {
+
+ p = new_print_line();
+
+ if (!p)
+ return 0;
+
+ p->LineY = object->y;
+
+ if (!printobject_append(p, object))
+ return 0;
+
+ return p;
+ }
+ /*
+ * Find a line
+ */
+ p = first;
+ prev = 0;
+
+ while (p && (p->LineY < object->y)) {
+
+ prev = p;
+
+ p = p->Next;
+ }
+
+ /*
+ * Line already exists ?
+ */
+ if (p && (p->LineY == object->y)) {
+
+ if (!printobject_append(p, object))
+ return 0;
+
+ return first;
+ }
+ /*
+ * Line does not exist ... make one
+ */
+
+ new_line = new_print_line();
+
+ if (!new_line)
+ return 0;
+
+ new_line->LineY = object->y;
+
+ if (prev) {
+ /*
+ * Append to middle of the list
+ */
+ prev->Next = new_line;
+
+ new_line->Next = p;
+
+ if (!printobject_append(new_line, object))
+ return 0;
+
+ return first;
+ } else {
+ /*
+ * Append to first
+ */
+ new_line->Next = p;
+
+ if (!printobject_append(new_line, object))
+ return 0;
+
+ return new_line;
+ }
+
+ /*
+ * Should not get here
+ */
+ return 0;
+}
+
+
+/*
+ * Print using this command
+ */
+int erwise_popen(command)
+char *command;
+{
+ int fd[2];
+
+ int ppid;
+
+ if (pipe(fd)) {
+
+ printf("erwise_popen: cannot make pipe\n");
+
+ return -1;
+ }
+ switch (ppid = fork()) {
+ case 0:
+
+ dup2(fd[0], 0);
+
+ close(fd[1]);
+ close(fd[0]);
+
+ system(command);
+
+ close(0);
+
+ exit(0);
+
+ break;
+
+ case -1:
+
+ printf("cannot fork\n");
+
+ return -1;
+
+ break;
+
+ default:
+
+ close(fd[0]);
+
+ return (fd[1]);
+ }
+
+ /*
+ * should not get here ...
+ */
+ return -1;
+}
+
+
+
+/*
+ * Open files, handle commands, call DoPrint
+ */
+int Print(htext)
+HText_t *htext;
+{
+ int fd;
+
+ if ((PrintWidth <= 0) || (PrintTopMargin < 0) || (PrintBottomMargin < 0) ||
+ (PrintLeftMargin < 0)) {
+
+ printf("Print: parameters insane\n");
+
+ return 1;
+ }
+ if (PrintToFile) {
+
+ fd = open(PrintFileName, O_WRONLY | O_CREAT, 0666);
+
+ if (fd < 0) {
+
+ printf("Print: cannot create file %s\n", PrintFileName);
+
+ return 1;
+ }
+ DoPrint(htext, fd, PrintWidth, PrintLeftMargin, PrintTopMargin,
+ PrintBottomMargin);
+
+ close(fd);
+
+ } else {
+
+ fd = erwise_popen(PrintCommand);
+
+ if (fd < 0) {
+
+ printf("Print: failed printing to command %s\n", PrintCommand);
+
+ return 1;
+ }
+ DoPrint(htext, fd, PrintWidth, PrintLeftMargin, PrintTopMargin,
+ PrintBottomMargin);
+
+ close(fd);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Handle printing. Format text (ascii) and put it to wanted fd
+ */
+int DoPrint(old_htext, fd, width, lmargin, top, bottom)
+HText_t *old_htext;
+int fd;
+int width;
+int lmargin;
+int top;
+int bottom;
+{
+ PrintLine_t *first_line = 0;
+
+ HText_t *htext = 0;
+
+ htext = (HText_t *) HtDuplicate(old_htext);
+
+ if (!htext)
+ return 0;
+
+ /*
+ * Format text using fixed width. After this call every object is
+ * positioned correctly.
+ */
+ XlFormatTextForPrinting(htext, lmargin, lmargin + width);
+
+ /*
+ * Because some objects may not be in x,y order, contruct list of lines
+ * so that lines are in order 0->j and for every line objects are in
+ * order 0->i.
+ *
+ * Because of allmost all objects are in order by default, contruct lists
+ * from last to first. Now most objects can be inserted as the first
+ * object of the first line.
+ */
+ {
+ HTextObject_t *p;
+
+ p = htext->last;
+
+ while (p) {
+
+ /*
+ * XXXXX free allocated on error
+ */
+ first_line = print_check_line_append(first_line, p);
+
+ p = p->prev;
+ }
+ }
+
+ /*
+ * Now, print line by line
+ */
+
+ {
+ PrintLine_t *line = first_line;
+
+ char newline[1];
+
+ int y = 0;
+ int max_x;
+
+ *newline = 10;
+
+ /*
+ * Write top margin
+ */
+ for (; top > 0; top--)
+ write(fd, newline, 1);
+
+ while (line) {
+ /*
+ * Print empty lines
+ */
+
+ while (y < line->LineY) {
+ y++;
+
+ write(fd, newline, 1);
+ }
+
+ /*
+ * Get maximum x on a line
+ */
+ {
+ PrintObject_t *p;
+
+ p = line->Objects;
+
+ max_x = 0;
+
+ while (p) {
+
+ if (max_x < (p->HtObject->x + p->HtObject->width))
+ max_x = p->HtObject->x + p->HtObject->width;
+
+ p = p->Next;
+ }
+ }
+
+ /*
+ * Collect data on a line and print it
+ */
+ {
+ PrintObject_t *p;
+
+ char *d = malloc(max_x + 1);
+
+ p = line->Objects;
+
+ /*
+ * XXXXXX free
+ */
+ if (!d)
+ return;
+
+ memset(d, ' ', max_x + 1);
+
+ while (p) {
+ if (p->HtObject->data) {
+
+ memcpy(d + p->HtObject->x, p->HtObject->data,
+ p->HtObject->length);
+ }
+ p = p->Next;
+ }
+
+ write(fd, d, max_x + 1);
+
+ free(d);
+ }
+
+ line = line->Next;
+
+ }
+
+ write(fd, newline, 1);
+
+ /*
+ * Write bottom margin
+ */
+ for (; bottom > 0; bottom--)
+ write(fd, newline, 1);
+
+ }
+
+ /*
+ * Free objects allocated here
+ */
+
+ {
+ PrintLine_t *l;
+ PrintObject_t *p;
+
+ l = first_line;
+
+ while (l) {
+
+ p = l->Objects;
+
+ while (p) {
+
+ free(p);
+
+ p = p->Next;
+ }
+
+ free(l);
+
+ l = l->Next;
+ }
+ }
+
+ /*
+ * Delete extra page
+ */
+
+ HText_free(htext);
+}
--- /dev/null
+/* $Id: Protos.h,v 1.1 1992/05/18 21:43:03 tvr Exp $ */
+
+
+/*
+ * From other objects/libraries
+ */
+
+extern HTParentAnchor *HTMainAnchor; /* Can you spell kludge? */
+extern struct HText *HtLocalText;
+
+
+/*
+ * Main.c
+ */
+
+extern FILE *OpenErwiserc(char *type);
+
+
+/*
+ * Setup.c
+ */
+
+extern void AttachCallbacks(void);
+extern void BindKeys(void);
+extern void BindVariables(void);
+
+
+/*
+ * TopLevel.c
+ */
+
+extern void TopQuitCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void NukeErwiseCB(int button);
+extern void TopInfoCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void TopOpenCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void TopHelpCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void GetPageCB(char *nodename);
+
+extern char FindText[256];
+extern char SearchText[256];
+int SearchDepth;
+int SearchCase;
+
+
+/*
+ * Page.c
+ */
+
+extern void PageSearchCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageCopyCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageListCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageLoadToFileCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PagePrintCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageSettingsCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageCloseCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PagePrevWordCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageNextWordCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PagePrevTagCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageNextTagCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageHomeCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageRecallCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageBackCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PagePrevPageCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageNextPageCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageGetPageCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void PageClickCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void IndexFindCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void HierarchyCloseCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void HierarchyNukeCB(int button);
+extern void HierarchyClose(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void SearchBackwardCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void SearchForwardCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void ConnectionsCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void KillCB(void *connection);
+extern void ControlPanelCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void DefaultsCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+
+
+/*
+ * Help.c
+ */
+
+extern void HelpOnFunctionCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+extern void HelpManualCB(char *topaddress, HText_t * htext,
+ HTextObject_t * htextobject, void *parameter);
+
+
+/*
+ * Print.c
+ */
+
+extern int PrintTopMargin;
+extern int PrintBottomMargin;
+extern int PrintLeftMargin;
+extern int PrintWidth;
+extern char PrintCommand[1024];
+extern int PrintToFile;
+extern char PrintFileName[1024];
+
+
+/*
+ * Misc.c
+ */
+
+extern Page_t *FindPage(Page_t * hierarchy, char *address);
+extern Page_t *GlobalFindPage(char *address);
+extern Page_t *AddPage(Page_t ** page, char *address, HText_t * htext,
+ Page_t * toppage);
+extern void DeletePage(Page_t ** page, char *address);
+extern void DisplayWarning(char *text);
+extern void DisplayFatal(char *text);
+extern int CanBeCursor(HTextObject_t * htextobject);
+extern void *Malloc(int size);
+extern void *ReAlloc(void *ptr, int size);
+extern void Free(void *ptr);
+extern void StartLoading(char *address, char *topaddress, char *parentaddress);
+void PollConnection(Connection_t * connection);
+Connection_t *AddConnection(char *address, Page_t * toppage, Page_t * parentpage,
+ ClConnection_t * clconnection);
+Connection_t *FindConnection(char *address);
+void DeleteConnection(char *address);
+
+extern Page_t *Pages;
+extern Connection_t *Connections;
+
+
+/*
+ * Config.c
+ */
+
+extern void ConfigInit(void);
+extern int ConfigRestore(FILE * fp);
+extern int ConfigSave(FILE * fp);
+extern void *ConfigGetValue(void *table, char *id);
+extern void *ConfigSetValue(void *table, char *id, void *value);
--- /dev/null
+static char *rcsid = "$Id: Setup.c,v 1.1 1992/05/18 21:43:03 tvr Exp $";
+
+#include "Includes.h"
+
+
+void attachtoplevelcallbacks(void);
+void attachpagecallbacks(void);
+void attachhierarchycallbacks(void);
+void attachsearchcallbacks(void);
+void bindpagevariables(void);
+void bindsearchvariables(void);
+void bindprintvariables(void);
+
+
+void AttachCallbacks()
+{
+ attachtoplevelcallbacks();
+ attachpagecallbacks();
+ attachhierarchycallbacks();
+ attachsearchcallbacks();
+}
+
+
+
+char *
+ parse_key(type, item)
+int *type;
+char *item;
+{
+ char *p;
+
+ if (!item)
+ return item;
+
+ if (*item == '^') {
+ *type = UI_CTRL;
+
+ p = strdup(item + 1);
+
+ if (strlen(p) == 1)
+ *p = tolower(*p);
+
+ return p;
+ }
+ if (strlen(item) == 1) {
+ if (isupper(*item)) {
+ *type = UI_SHIFT;
+ } else {
+ *type = UI_NONE;
+ }
+ p = (char *) strdup(item);
+
+ *p = tolower(*p);
+
+ return p;
+ }
+ *type = UI_NONE;
+
+ return (char *) strdup(item);
+}
+
+
+/*
+ * Keyboard bindings
+ */
+
+typedef struct erwise_key_bindings_s {
+ char *itemname;
+ void (*callback) ();
+ void *data;
+} erwise_key_bindings_t;
+
+erwise_key_bindings_t erwise_keys[] =
+{
+ {C_GETPAGE, PageGetPageCB, NULL},
+ {C_PREVWORD, PagePrevWordCB, NULL},
+ {C_NEXTWORD, PageNextWordCB, NULL},
+ {C_PREVTAG, PagePrevTagCB, (void *) NO_AUTOGET},
+ {C_NEXTTAG, PageNextTagCB, (void *) NO_AUTOGET},
+ {C_CLOSE, PageCloseCB, NULL},
+ {C_SEARCH, PageSearchCB, NULL},
+ {C_SETTINGS, PageSettingsCB, NULL},
+ {C_LIST, PageListCB, NULL},
+ {C_PRINTDOC, PagePrintCB, NULL},
+ {NULL, NULL, NULL},
+};
+
+
+void BindKeys()
+{
+ void *table;
+ char *item;
+ char *key;
+ int keytype;
+
+ erwise_key_bindings_t *k;
+
+ table = (void *) ConfigGetValue((void *) NULL, C_KEYBINDINGS);
+
+ for (k = erwise_keys; k->itemname; k++) {
+ item = (char *) ConfigGetValue(table, k->itemname);
+
+ if (item) {
+ key = parse_key(&keytype, item);
+
+ if (key) {
+ UiBindKey(key, keytype, k->callback, k->data);
+ free(key);
+ }
+ }
+ }
+}
+
+
+void BindVariables()
+{
+ bindpagevariables();
+ bindsearchvariables();
+ bindprintvariables();
+}
+
+
+void attachtoplevelcallbacks()
+{
+ UiAttachCallback("Quit", TopQuitCB, (void *) NULL);
+ UiAttachCallback("Info", TopInfoCB, (void *) NULL);
+ UiAttachCallback("Open", TopOpenCB, (void *) NULL);
+ UiAttachCallback("Help", HelpManualCB, (void *) NULL);
+}
+
+
+void attachpagecallbacks()
+{
+ UiAttachCallback("Search", PageSearchCB, (void *) NULL);
+ UiAttachCallback("Copy", PageCopyCB, (void *) NULL);
+ UiAttachCallback("List", PageListCB, (void *) NULL);
+ UiAttachCallback("Load to file", PageLoadToFileCB, (void *) NULL);
+ UiAttachCallback("Print", PagePrintCB, (void *) NULL);
+ UiAttachCallback("Settings", PageSettingsCB, (void *) NULL);
+ UiAttachCallback("Close", PageCloseCB, (void *) NULL);
+
+ UiAttachCallback("Prev tag", PagePrevTagCB, (void *) AUTOGET);
+ UiAttachCallback("Next tag", PageNextTagCB, (void *) AUTOGET);
+
+ UiAttachCallback("Home", PageHomeCB, (void *) NULL);
+ UiAttachCallback("Recall", PageRecallCB, (void *) NULL);
+ UiAttachCallback("Back", PageBackCB, (void *) NULL);
+ UiAttachCallback("Prev page", PagePrevPageCB, (void *) NULL);
+ UiAttachCallback("Next page", PageNextPageCB, (void *) NULL);
+
+ UiAttachCallback("On function", HelpOnFunctionCB, (void *) NULL);
+
+ UiAttachCallback("Get page", PageGetPageCB, (void *) NULL);
+ UiAttachCallback("Click page", PageClickCB, (void *) NULL);
+ UiAttachCallback("IndexFind", IndexFindCB, (void *) NULL);
+}
+
+
+void attachhierarchycallbacks()
+{
+ UiAttachCallback("Connections", ConnectionsCB, (void *) NULL);
+ UiAttachCallback("Controlpanel", ControlPanelCB, (void *) NULL);
+ UiAttachCallback("Defaults", DefaultsCB, (void *) NULL);
+ UiAttachCallback("Close hierarchy", HierarchyCloseCB, (void *) NULL);
+}
+
+
+void attachsearchcallbacks()
+{
+ UiAttachCallback("SearchBackward", SearchBackwardCB, (void *) NULL);
+ UiAttachCallback("SearchForward", SearchForwardCB, (void *) NULL);
+}
+
+
+void bindpagevariables()
+{
+ UiBindVariable("FindText", (void *) FindText, uiVTstring);
+}
+
+
+void bindsearchvariables()
+{
+ UiBindVariable("SearchText", (void *) SearchText, uiVTstring);
+ UiBindVariable("SearchDepth", (void *) &SearchDepth, uiVTint);
+ UiBindVariable("SearchCase", (void *) &SearchCase, uiVTint);
+}
+
+
+void bindprintvariables()
+{
+ UiBindVariable("PrintTopMargin", (void *) &PrintTopMargin, uiVTint);
+ UiBindVariable("PrintBottomMargin", (void *) &PrintBottomMargin, uiVTint);
+ UiBindVariable("PrintLeftMargin", (void *) &PrintLeftMargin, uiVTint);
+ UiBindVariable("PrintWidth", (void *) &PrintWidth, uiVTint);
+ UiBindVariable("PrintCommand", (void *) &PrintCommand, uiVTstring);
+ UiBindVariable("PrintToFile", (void *) &PrintToFile, uiVTint);
+ UiBindVariable("PrintFileName", (void *) &PrintFileName, uiVTstring);
+}
--- /dev/null
+static char *rcsid = "$Id: TopLevel.c,v 1.1 1992/05/18 21:43:03 tvr Exp $";
+
+#include "Includes.h"
+
+
+void TopQuitCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiDisplayWarningDialog("Quit Erwise?", NukeErwiseCB);
+}
+
+
+void NukeErwiseCB(button)
+int button;
+{
+ FILE *fp;
+
+ if (fp = OpenErwiserc("w")) {
+ ConfigSave(fp);
+ fclose(fp);
+ } else
+ fprintf(stderr, "Warning: could not save settings to .erwiserc\n");
+
+ exit(0);
+}
+
+
+void TopInfoCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiDisplayInfo();
+}
+
+
+void TopOpenCB(topaddress, htext, htextobject, parameter)
+char *topaddress;
+HText_t *htext;
+HTextObject_t *htextobject;
+void *parameter;
+{
+ UiDisplaySelectionBox(GetPageCB);
+}
+
+
+void GetPageCB(address)
+char *address;
+{
+ if (FindPage(Pages, address)) {
+ DisplayWarning("Already loaded");
+ return;
+ }
+ AddPage(&Pages, address, (HText_t *) NULL, (Page_t *) NULL);
+
+ StartLoading(address, address, (char *) NULL);
+}
--- /dev/null
+/* $Id: Types.h,v 1.1 1992/05/18 21:43:03 tvr Exp $ */
+
+
+typedef struct _page {
+ char *Address;
+ HText_t *HText;
+ struct _page *ParentPage;
+ struct _page *Parents;
+ struct _page *Children; /* only two levels */
+ struct _page *Next;
+} Page_t;
+
+
+typedef struct _connection {
+ char *Address;
+ int Status;
+ int FD;
+ int InputId;
+ int TimeOutId;
+ ClConnection_t *ClConnection;
+ Page_t *TopPage;
+ Page_t *ParentPage;
+ struct _connection *Next;
+} Connection_t;
+
+
+typedef enum {
+ EOC, /* eof */
+ EMPTY, /* "" */
+ UNKNOWN,
+ RESOURCE, /* resource definition, id = value */
+ BLOCK, /* a block containing resources */
+ DYNAMIC, /* dynamic BLOCK */
+ DYNAMIC_PTR, /* ptr to dynamic data (void *ptr[]) */
+ COMMENT, /* "# ..." */
+ START_OF_BLOCK, /* '{' */
+ END_OF_BLOCK /* '}' */
+} ConfigType_t;
+
+
+typedef struct _config {
+ ConfigType_t type;
+ char *id;
+ void *value;
+} Config_t;
--- /dev/null
+static char *rcsid = "$Id: main.c,v 1.1 1992/05/18 21:43:03 tvr Exp $";
+
+#include "Includes.h"
+
+
+
+void main(argc, argv)
+int argc;
+char *argv[];
+{
+ FILE *fp;
+
+ ConfigInit();
+
+ if (fp = OpenErwiserc("r")) {
+ ConfigRestore(fp);
+ fclose(fp);
+ }
+ if (UiInitialize(argc, argv, ConfigGetValue, ConfigSetValue) != UI_OK)
+ DisplayFatal("Error initializing Ui-toolkit");
+
+ AttachCallbacks();
+ BindKeys();
+ BindVariables();
+
+ UiMainLoop();
+}
+
+#define RCPOSTFIX ".old"
+FILE *
+ OpenErwiserc(type)
+char *type;
+{
+ char *tmpstr;
+ char *bustr;
+ FILE *fp;
+
+ if (!getenv("HOME"))
+ return (FILE *) NULL;
+
+ tmpstr = strdup(getenv("HOME"));
+
+ tmpstr = (char *) ReAlloc((void *) tmpstr, strlen(tmpstr) +
+ strlen(ERWISERC) + 2);
+ strcat(tmpstr, "/");
+ strcat(tmpstr, ERWISERC);
+ if (!strcmp(type, "w")) {
+ bustr = (char *) Malloc((strlen(tmpstr) + strlen(RCPOSTFIX) + 1) *
+ sizeof(char));
+ strcpy(bustr, tmpstr);
+ strcat(bustr, RCPOSTFIX);
+ rename(tmpstr, bustr);
+ free(bustr);
+ }
+ fp = fopen(tmpstr, type);
+ Free(tmpstr);
+
+ return fp;
+}
+
+
+#ifdef mips
+char *
+ strdup(s)
+char *s;
+{
+ char *p = (char *) malloc(strlen(s) + 1);
+
+ strcpy(p, s);
+
+ return p;
+}
+
+#endif