diff options
author | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2007-08-14 05:14:52 +0000 |
commit | ab8cc85adde879fb963c94d15675783f2cf4b183 (patch) | |
tree | c202482327f474583b750b2c45dedfc4e4312b1d /src/hyper/event.pamphlet | |
download | open-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz |
Initial population.
Diffstat (limited to 'src/hyper/event.pamphlet')
-rw-r--r-- | src/hyper/event.pamphlet | 1099 |
1 files changed, 1099 insertions, 0 deletions
diff --git a/src/hyper/event.pamphlet b/src/hyper/event.pamphlet new file mode 100644 index 00000000..3dcb69ff --- /dev/null +++ b/src/hyper/event.pamphlet @@ -0,0 +1,1099 @@ +\documentclass{article} +\usepackage{axiom} +\begin{document} +\title{\$SPAD/src/event} +\author{The Axiom Team} +\maketitle +\begin{abstract} +\end{abstract} +\eject +\tableofcontents +\eject +\section{event.h} +<<event.h>>= +<<license>> +#ifndef _EVENT_H_ +#define _EVENT_H_ 1 + +#include "hyper.h" + +extern Window gActiveWindow; +extern int gNeedIconName; + +#endif +@ +\section{event.c} +<<event.c>>= +#define _EVENT_C +#include "axiom-c-macros.h" +#include "useproto.h" +#include "debug.h" + + +#include "hyper.h" + +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/cursorfont.h> +#include <sys/signal.h> +#include <setjmp.h> +#include <sys/types.h> +#include <sys/time.h> + +#ifdef SGIplatform +#include <bstring.h> +#endif + +#include "event.h" +#include "keyin.h" +#include "mem.h" +#include "display.h" +#include "parse.h" +#include "parse-paste.h" +#include "initx.h" +#include "scrollbar.h" +#include "group.h" + +#include "all_hyper_proto.H1" +#include "sockio-c.H1" + +jmp_buf env; +Window gActiveWindow; +int motion = 0; +int gNeedIconName = 0; +unsigned long bigmask= 0xffffffff; +static HyperLink *gSavedInputAreaLink = NULL; + + + +/* + * This is the main X loop. It keeps grabbing events. Since the only way the + * window can die is through an event, it never actually end. One of the + * subroutines it calls is responsible for killing everything + */ + +void +mainEventLoop(void) +{ + XEvent event; + int Xcon; + fd_set rd, dum1, dum2; + motion = 0; + gActiveWindow = -1; + set_error_handlers(); + Xcon = ConnectionNumber(gXDisplay); + + while (1) { +/* fprintf(stderr,"event:mainEventLoop: loop top\n");*/ + while (gSessionHashTable.num_entries == 0) + pause(); + + /* XFlush(gXDisplay); */ + + if (!motion) + init_cursor_states(); + motion = 0; + + if (!spad_socket == 0) { + FD_ZERO(&rd); + FD_ZERO(&dum1); + FD_ZERO(&dum2); + FD_CLR(0, &dum1); + FD_CLR(0, &dum2); + FD_CLR(0, &rd); + FD_SET(spad_socket->socket, &rd); + FD_SET(Xcon, &rd); + if (!session_server == 0) { + FD_SET(session_server->socket, &rd); + } + if (XEventsQueued(gXDisplay, QueuedAlready)) { + XNextEvent(gXDisplay, &event); + handle_event(&event); + } + else { + select(FD_SETSIZE,(void *)&rd,(void *)&dum1,(void *)&dum2,NULL); + if (FD_ISSET(Xcon, &rd) || + XEventsQueued(gXDisplay, QueuedAfterFlush)) { + XNextEvent(gXDisplay, &event); + handle_event(&event); + } + else if FD_ISSET + (spad_socket->socket, &rd) + /* + * Axiom Socket do what handle_event does The 100 is + * $SpadStuff in hypertex.boot + */ + { + if (100 == get_int(spad_socket)) { + set_window(gParentWindow->fMainWindow); + make_busy_cursors(); + get_new_window(); + } + } + /* + * Session Socket Telling us about the death of a spadbuf + * (plus maybe more later) service_session_socket in + * spadint.c + */ + else + if (session_server && FD_ISSET(session_server->socket, &rd)) { + service_session_socket(); + } + } + } + else { + XNextEvent(gXDisplay, &event); + handle_event(&event); + } + } +} + +static void +handle_event(XEvent * event) +{ + XWindowAttributes wa; +/* fprintf(stderr,"event:handle_event entered\n");*/ + set_window(event->xany.window); + if (event->type == MotionNotify) { +/* fprintf(stderr,"event:handle_event type=MotionNotify\n");*/ + handle_motion_event((XMotionEvent *)event); + motion = 1; + return; + } + make_busy_cursors(); + switch (event->type) { + case DestroyNotify: +/* fprintf(stderr,"event:handle_event type=DestroyNotify\n");*/ + break; + case Expose: +/* fprintf(stderr,"event:handle_event type=Expose\n");*/ + XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa); + if ((gWindow->width == 0 && gWindow->height == 0) || + (wa.width != gWindow->width || wa.height != gWindow->height)) { + gWindow->width = wa.width; + gWindow->height = wa.height; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + } + else /** just redraw the thing **/ + expose_page(gWindow->page); + XFlush(gXDisplay); + clear_exposures(gWindow->fMainWindow); + clear_exposures(gWindow->fScrollWindow); + break; + case ButtonPress: +/* fprintf(stderr,"event:handle_event type=ButtonPress\n");*/ + handle_button(event->xbutton.button, (XButtonEvent *)event); + XFlush(gXDisplay); + if (gWindow) { + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fMainWindow, + Expose, event)); + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fScrollWindow, + Expose, event)); + } + break; + case KeyPress: +/* fprintf(stderr,"event:handle_event type=KeyPress\n");*/ + handle_key(event); + if (gWindow) { + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fMainWindow, + Expose, event)); + while (XCheckTypedWindowEvent(gXDisplay, gWindow->fScrollWindow, + Expose, event)); + } + break; + case MapNotify: +/* fprintf(stderr,"event:handle_event type=MapNotify\n");*/ + create_window(); + break; + + case SelectionNotify: +/* fprintf(stderr,"event:handle_event type=SelectionNotify\n");*/ + /* this is in response to a previous request in an input area */ + if ( gSavedInputAreaLink ) { + XSelectionEvent *pSelEvent; + Atom dataProperty; + pSelEvent = (XSelectionEvent *) event; + dataProperty = XInternAtom(gXDisplay, "PASTE_SELECTION", False); + /* change the input focus */ + + /* change_input_focus(gSavedInputAreaLink); */ + + /* try to get the selection as a window property */ + + if ( pSelEvent->requestor == gWindow->fMainWindow && + pSelEvent->selection == XA_PRIMARY && + /* pSelEvent->time == CurrentTime && */ + pSelEvent->target == XA_STRING && + pSelEvent->property == dataProperty ) + { + Atom actual_type; + int actual_format; + unsigned long nitems, leftover; + char *pSelection = NULL; + + if (Success == XGetWindowProperty(gXDisplay, + gWindow->fMainWindow, + pSelEvent->property, 0L, 100000000L, True, + AnyPropertyType, &actual_type, &actual_format, + &nitems, &leftover, (unsigned char **) &pSelection) ) + { + char *pBuffer; + InputItem *item = gSavedInputAreaLink->reference.string; + + for (pBuffer = pSelection; *pBuffer; ++pBuffer) + add_buffer_to_sym(pBuffer, item); + + XFree(pSelection); + } + } + + /* clear the link info */ + + gSavedInputAreaLink = NULL; + } + break; + + default: +/* fprintf(stderr,"event:handle_event type=default\n");*/ + break; + } + +} + +static void +create_window(void) +{ + XWindowAttributes wa; + + XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa); + + gWindow->width = wa.width; + gWindow->height = wa.height; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + + /* then select for the events I normally would like to catch */ + XSelectInput(gXDisplay, gWindow->fMainWindow, ButtonPress | KeyPressMask | + PointerMotionMask | + ExposureMask /* | EnterWindowMask | LeaveWindowMask */ ); + XSelectInput(gXDisplay, gWindow->fScrollWindow, ExposureMask); + +} + +/* + * This routine is called when the quitbutton is hit. For the moment I am + * just going to leave it all behind + */ + +void +quitHyperDoc(void) +{ + HyperDocPage *page; + + if (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow) { + if (!strcmp(gWindow->page->name, "ProtectedQuitPage")){ + exitHyperDoc(); + } + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ProtectedQuitPage"); + if (page == NULL) { + fprintf(stderr, "Unknown page name %s\n", "ProtectedQuitPage"); + exitHyperDoc(); + return; + } + if (gWindow->fDownLinkStackIndex == MaxDownlinkDepth) + fprintf(stderr, "exceeded maximum link nesting level\n"); + else + gWindow->fDownLinkStack[gWindow->fDownLinkStackIndex++] = gWindow->page; + gWindow->page = page; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + } + else + exitHyperDoc(); +} + + +/* + * find_page takes as an argument the HyperDoc for a page name and returns + * the associated page + */ + +static HyperDocPage * +find_page(TextNode * node) +{ + char *page_name; + HyperDocPage *page; + + /* try and find the page name */ + page_name = print_to_string(node); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page_name); + + if (page == NULL) { + /* try to find the unknown page */ + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "UnknownPage"); + if (page == NULL) { + /* Yikes, Even that could not be found */ + fprintf(stderr, "Unknown page name %s\n", page_name); + } + else { + if (page->type == UnloadedPageType) + page->type = UlUnknownPage; + else + page->type = UnknownPage; + } + } + return page; +} + +/* + * These are macros for taking care of the downlink stack, and the memolink + * stack. + */ + +#define NotSpecial(t) ((t == Quitbutton || t == Returnbutton || \ + t == Upbutton || t == UnknownPage || \ + t == UlUnknownPage || t == ErrorPage) ?(0):(1)) + +/* pushes a page onto the down link stack */ + +static void +downlink(void) +{ + if (gWindow->fDownLinkStackIndex == MaxDownlinkDepth) + fprintf(stderr, "exceeded maximum link nesting level\n"); + else + gWindow->fDownLinkStack[gWindow->fDownLinkStackIndex++] = gWindow->page; +} + +static void +memolink(void) +{ + if (gWindow->fMemoStackIndex == MaxMemoDepth) + fprintf(stderr, "exceeded maximum link nesting level\n"); + else { + gWindow->fMemoStack[gWindow->fMemoStackIndex] = gWindow->page; + gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex++] = gWindow->fDownLinkStackIndex; + } +} + +static void +killAxiomPage(HyperDocPage * page) +{ + char command[512]; + + sprintf(command, "(|htpDestroyPage| '%s)", page->name); + send_lisp_command(command); +} + +static void +kill_page(HyperDocPage * page) +{ + page->scroll_off = 0; + if (page->type == SpadGen) { + hash_delete(gWindow->fPageHashTable, page->name); + killAxiomPage(page); + free_page(page); + } +} + +/* pops the memo stack */ + +static HyperDocPage * +returnlink(void) +{ + int i; + + if (gWindow->fMemoStackIndex == 0) { + BeepAtTheUser(); + return NULL; + } + else { + kill_page(gWindow->page); + for (i = gWindow->fDownLinkStackIndex - 1; + i >= gWindow->fDownLinkStackTop[gWindow->fMemoStackIndex - 1]; + i--) + { + kill_page(gWindow->fDownLinkStack[i]); + } + gWindow->fDownLinkStackIndex = + gWindow->fDownLinkStackTop[--gWindow->fMemoStackIndex]; + return (gWindow->fMemoStack[gWindow->fMemoStackIndex]); + } +} + +/* pops a page if it can from the downlink stack */ + +static HyperDocPage * +uplink(void) +{ + if (gWindow->fDownLinkStackIndex == 0) + return returnlink(); + else { + kill_page(gWindow->page); + return (gWindow->fDownLinkStack[--gWindow->fDownLinkStackIndex]); + } +} + +static void +windowlink_handler(TextNode * node) +{ + char *page_name; + + /* first try and find the page */ + page_name = print_to_string(node); + + if (init_top_window(page_name) == -1) { + return; + } +/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;*/ +} + +void +make_window_link(char *name) +{ + if (init_top_window(name) != -1) +{}/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; */ +} + + +static void +lispwindowlink_handler(HyperLink * link) +{ + + /* + * Since we are popping up a new window, then we had better change all + * the cursors right away. We won't get another chance at it. + */ + + if (init_top_window(NULL) != -1) { + HyperDocPage *page = NULL; + int frame = gWindow->fAxiomFrame; + + page = issue_server_command(link); + gWindow->fAxiomFrame = frame; + gWindow->page = page; +/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;*/ + } +} + +static HyperDocPage * +paste_button(PasteNode * paste) +{ + HyperDocPage *page = NULL; + int pastewhere=paste->where; + + + if ( paste->end_node ==NULL || paste->begin_node==NULL || paste->arg_node==NULL ){ + BeepAtTheUser(); + return NULL; + } + + page=parse_patch(paste); +/* paste has changed after this call so use pastewhere*/ + + if (pastewhere && page ) { + if (0 == strcmp(page->name, "ErrorPage")) + page = NULL; + } + else + BeepAtTheUser(); + + return page; +} + +void +helpForHyperDoc(void) +{ + HyperDocPage *page = NULL; + + /* do not do anything if we are already at the "no more help" page */ + + if (0 == strcmp(gWindow->page->name, NoMoreHelpPage)) + return; + + /* if no help page recorded, use the standard "no more help" page */ + + if (!gWindow->page->helppage) + gWindow->page->helppage = alloc_string(NoMoreHelpPage); + + /* if we are on the main help page, use "no more help" page */ + + if (0 == strcmp(gWindow->page->name, TopLevelHelpPage)) + gWindow->page->helppage = alloc_string(NoMoreHelpPage); + + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, gWindow->page->helppage); + + if (page) + make_window_link(gWindow->page->helppage); + else + BeepAtTheUser(); +} + +static HyperLink * +findButtonInList(HDWindow * window, int x, int y) +{ + ButtonList *bl; + + if (!window || window->page->type == UnloadedPageType) + return NULL; + for (bl = window->page->s_button_list; bl != NULL; bl = bl->next) + if (x >= bl->x0 && x <= bl->x1 && y >= bl->y0 && y <= bl->y1) + return bl->link; + for (bl = window->page->button_list; bl != NULL; bl = bl->next) + if (x >= bl->x0 && x <= bl->x1 && y >= bl->y0 && y <= bl->y1) + return bl->link; + return NULL; +} + +static HyperLink * +get_hyper_link(XButtonEvent * event) +{ + HyperLink *l1, *l2; + + l1 = (HyperLink *) hash_find(gWindow->fWindowHashTable, (char *)&(event->window)); + if (l1) + return l1; + l2 = findButtonInList(gWindow, event->x, event->y); + return l2; +} + +/* + * Handle a button pressed event. window is the subwindow in which the event + * occured, and button is the button which was pressed + */ + +static void +handle_button(int button, XButtonEvent * event) +{ + HyperLink *link; + HyperDocPage *page = NULL; + char *page_name; + + /* find page name from sub-window handle */ + + link = get_hyper_link(event); + + if (link == NULL) { /* user clicked on an inactive area */ +/* BeepAtTheUser(); */ /* I always thought this was annoying. RSS */ + return; + } + + switch (link->type) { + case Pastebutton: + page = paste_button(link->reference.paste); + break; + case Link: + page_name = print_to_string(link->reference.node); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, page_name); + break; + case Helpbutton: + helpForHyperDoc(); + page = NULL; + break; + case Scrollbar: + scrollScroller(event); + break; + case Scrollupbutton: + scrollUp(); + break; + case Scrolldownbutton: + scrollDown(); + break; + + case Inputstring: + /* We must be changing input focus or getting a selection */ + + change_input_focus(link); + if ( button == Button2 ) { + XConvertSelection(gXDisplay, XA_PRIMARY, XA_STRING, + XInternAtom(gXDisplay, "PASTE_SELECTION", False), + gWindow->fMainWindow, CurrentTime); + gSavedInputAreaLink = link; + } + break; + + case SimpleBox: + page = NULL; + toggle_input_box(link); + break; + case Radiobox: + page = NULL; + toggle_radio_box(link); + break; + case Quitbutton: + quitHyperDoc(); + break; + case Returnbutton: /* pop memo information */ + page = returnlink(); + break; + case Upbutton: /* pop downlink information */ + page = uplink(); + break; + case Downlink: + page = find_page(link->reference.node); + if (page && NotSpecial(page->type)) + downlink(); + break; + case Memolink: + page = find_page(link->reference.node); + if (page && NotSpecial(page->type)) + memolink(); + break; + case Windowlink: + page = find_page(link->reference.node); + if (page && NotSpecial(page->type)) { + windowlink_handler(link->reference.node); + gNeedIconName = 1; + page = NULL; + } + break; + case Lispwindowlink: + lispwindowlink_handler(link); + gNeedIconName = 1; + page = NULL; + break; + case LispMemoLink: + case Spadmemolink: + page = issue_server_command(link); + if (page && NotSpecial(page->type)) + memolink(); + break; + case LispDownLink: + case Spaddownlink: + page = issue_server_command(link); + if (page && NotSpecial(page->type)) + downlink(); + break; + case Spadlink: + case Lisplink: + page = issue_server_command(link); + break; + case Lispcommand: + case Qspadcall: + case Spadcall: + page = issue_server_command(link); + break; + case Lispcommandquit: + case Spadcallquit: + case Qspadcallquit: + page = issue_server_command(link); + exitHyperDoc(); + break; + case Spadcommand: + case Spadgraph: + case Spadsrc: + issue_spadcommand(gWindow->page, link->reference.node, + button == Button1, link->type); + break; + case Unixlink: + page = issue_unixlink(link->reference.node); + if (page && NotSpecial(page->type)) { + downlink(); + } + break; + case Unixcommand: + issue_unixcommand(link->reference.node); + break; + default: + break; + } + + if (page) { + switch (page->type) { /* check for special button types */ + case Quitbutton: + exitHyperDoc(); + return; + case Returnbutton: + gWindow->page = returnlink(); + break; + case Upbutton: + gWindow->page = uplink(); + break; + case ErrorPage: + case UnknownPage: + case UlUnknownPage: + if (page->type == UlUnknownPage) + page->type = UnloadedPageType; + downlink(); + gWindow->page = page; + break; + default: /* a normal link */ + gWindow->page = page; + break; + } + if (link->type != Pastebutton) + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; /* reset the window hash */ + } +} + + +void +exitHyperDoc(void) +{ + XEvent event; + + + if (gSessionHashTable.num_entries == 1 || gParentWindow == gWindow) { + free_hd_window(gWindow); + exit(0); + } + hash_delete(&gSessionHashTable, (char *)&gWindow->fMainWindow); + + /* + * Now we quickly want to flush all the events associated with this + * window from existence + */ + + XFlush(gXDisplay); + while (XCheckWindowEvent(gXDisplay, gWindow->fMainWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fScrollWindow,bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fDisplayedWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fScrollUpWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->fScrollDownWindow, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->scrollbar, bigmask, &event)) { + } + while (XCheckWindowEvent(gXDisplay, gWindow->scroller, bigmask, &event)) { + } + + XDestroyWindow(gXDisplay, gWindow->fMainWindow); + free_hd_window(gWindow); + gWindow = NULL; + gActiveWindow = -1; + XFlush(gXDisplay); +} + +static int +set_window(Window window) +{ + Window root, parent, *children, grandparent,myarg; + HDWindow *htw; + unsigned int nchildren; + int st; + + myarg=window; + nchildren = 0; + htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&myarg); + if (htw != NULL) { + gWindow = htw; + return 1; + } + st = XQueryTree(gXDisplay, myarg, &root, &parent, &children, &nchildren); + if (st==0) goto ERROR; + if (nchildren > 0) + XFree(children); + htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&parent); + if (htw != NULL) { + gWindow = htw; + return 1; + + } + else { + /* check for a grandparent */ + st = XQueryTree(gXDisplay, parent, &root, &grandparent, &children, &nchildren); + if (st==0) goto ERROR; + if (nchildren > 0) + XFree(children); + htw = (HDWindow *) hash_find(&gSessionHashTable, (char *)&grandparent); + if (htw != NULL) { + gWindow = htw; + return 1; + } + } + + /* + * fprintf(stderr, "window(%d) and it's parent(%d) aren't in + * gSessionHashTable\n", window, parent); + + we never found that window. this happens if (not iff) we exit from + an unfocused non-main window under certain wm's and click-to-type. the program returns here with + the window handle that was just destroyed. So let's set the global gWindow + to the main window. + */ + +ERROR: + gWindow=gParentWindow; + return 0; +} + +/* + * This procedure whips thru the stack and clears all expose events for the + * given routine + */ +static void +clear_exposures(Window w) +{ + XEvent report; + + XFlush(gXDisplay); + while (XCheckTypedWindowEvent(gXDisplay, w, Expose, &report)); +} +void +get_new_window(void) +{ + + int val; + char buf[128]; + int frame; + Window wid; + HDWindow *htw; + HyperDocPage *hpage; + + + /* + * If I am going to try and start a new window, then I should make sure I + * have a coonection to listen on + * + * BUT This code is entered when a socket selects + * + * if (spad_socket == NULL) { spad_socket = + * connect_to_local_server(SpadServer, MenuServer, 10); if (spad_socket + * == NULL) { fprintf(stderr, "Get_new_window: Couldn't Connect to + * SpadServer\n"); return -1; } } + * + */ + + + frame = get_int(spad_socket); + val = get_int(spad_socket); + switch (val) { + case StartPage: + init_top_window(NULL); + val = get_int(spad_socket); + init_scanner(); + input_type = FromSpadSocket; + input_string = ""; + gWindow->page = parse_page_from_socket(); + gWindow->fAxiomFrame = frame; + XFlush(gXDisplay); + break; + case LinkToPage: + get_string_buf(spad_socket, buf, 128); + if (init_top_window(buf) == -1) { + fprintf(stderr, "get_new_window: Did not find page %s\n", buf); + /* return -1; */ + } + gWindow->fAxiomFrame = frame; + break; + case PopUpPage: + val = get_int(spad_socket); + init_form_window(NULL, val); + send_int(spad_socket, gWindow->fMainWindow); + init_scanner(); + input_type = FromSpadSocket; + input_string = ""; + gWindow->page = parse_page_from_socket(); + compute_form_page(gWindow->page); + + XMapWindow(gXDisplay, gWindow->fMainWindow); + + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + gWindow->fAxiomFrame = frame; + XFlush(gXDisplay); + break; + case PopUpNamedPage: + val = get_int(spad_socket); + get_string_buf(spad_socket, buf, 128); + + if (init_form_window(buf, val) == -1) { + send_int(spad_socket, -1); + break; + } + load_page(gWindow->page); + compute_form_page(gWindow->page); + + XMapWindow(gXDisplay, gWindow->fMainWindow); + + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + gWindow->fAxiomFrame = frame; + XFlush(gXDisplay); + send_int(spad_socket, gWindow->fMainWindow); + /* fprintf(stderr, "Window Id was %d\n", gWindow->fMainWindow); */ + break; + case ReplaceNamedPage: + wid = (Window) get_int(spad_socket); + get_string_buf(spad_socket, buf, 128); + + htw = (HDWindow *) hash_find(&gSessionHashTable,(char *)&wid); + if (htw == NULL) break; + hpage = (HyperDocPage *) hash_find(gWindow->fPageHashTable, buf); + if (hpage == NULL) break; + gWindow = htw; + gWindow->page = hpage; + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + clear_exposures(gWindow->fMainWindow); + clear_exposures(gWindow->fScrollWindow); + XFlush(gXDisplay); + break; + case ReplacePage: + wid = (Window) get_int(spad_socket); + set_window(wid); + init_scanner(); + input_type = FromSpadSocket; + input_string = ""; + gWindow->page = parse_page_from_socket(); + display_page(gWindow->page); + gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; + clear_exposures(gWindow->fMainWindow); + clear_exposures(gWindow->fScrollWindow); + XFlush(gXDisplay); + break; + case KillPage: + /* Here the user wishes to kill the page */ + wid = (Window) get_int(spad_socket); + htw = (HDWindow *) hash_find(&gSessionHashTable,(char *)&wid); + if (htw !=NULL) { + gWindow = htw; + exitHyperDoc(); + break; + } + break; + } + } +static void +set_cursor(HDWindow *window,Cursor state) +{ + if (state == gBusyCursor) + XDefineCursor(gXDisplay, window->fMainWindow, gBusyCursor); + else if (state == gActiveCursor) + XDefineCursor(gXDisplay, window->fMainWindow, gActiveCursor); + else + XDefineCursor(gXDisplay, window->fMainWindow, gNormalCursor); + XFlush(gXDisplay); +} + +static void +change_cursor(Cursor state, HDWindow *window) +{ + if (window->fDisplayedCursor == state) + return; + window->fDisplayedCursor = state; + set_cursor(window, state); +} + +static void +handle_motion_event(XMotionEvent *event) +{ + if (!gWindow) + return; + if (findButtonInList(gWindow, event->x, event->y) != NULL) + change_cursor(gActiveCursor, gWindow); + else + change_cursor(gNormalCursor, gWindow); +} + +static void +init_cursor_state(HDWindow *window) +{ + if (window) { + int x, y, rx, ry, but; + Window r, c; + + XQueryPointer(gXDisplay, window->fMainWindow, + &r, &c, &rx, &ry, &x, &y,(unsigned int *) &but); + if (findButtonInList(window, x, y) != NULL) + change_cursor(gActiveCursor, window); + else + change_cursor(gNormalCursor, window); + } +} + +static void +init_cursor_states(void) +{ + hash_map(&gSessionHashTable,(MappableFunction) init_cursor_state); +} + + +static void +make_busy_cursor(HDWindow *window) +{ + change_cursor(gBusyCursor, window); +} + +static void +make_busy_cursors(void) +{ + hash_map(&gSessionHashTable, (MappableFunction)make_busy_cursor); +} + +static int +HyperDocErrorHandler(Display *display, XErrorEvent *xe) +{ + if (xe->request_code != 15) { + char buf[1024]; + + XGetErrorText(display, xe->error_code, buf, sizeof(buf)); + + fprintf(stderr, "error code = %d\n", xe->error_code); + fprintf(stderr, "major op code = %d\n", xe->request_code); + fprintf(stderr, "minor op code = %d\n", xe->minor_code); + fprintf(stderr, "XID = %ld\n", xe->resourceid); + fprintf(stderr, "%s\n", buf); + + if (xe->request_code != 15) + exit(-1); + } + return(0); +} + + + +static void +set_error_handlers(void) +{ + XSetErrorHandler(HyperDocErrorHandler); +} +@ +\section{License} +<<license>>= +/* +Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Neither the name of The Numerical ALgorithms Group Ltd. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +@ +<<*>>= +<<license>> +<<event.c>> +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document} |