aboutsummaryrefslogtreecommitdiff
path: root/src/hyper/event.c
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2010-07-29 19:52:43 +0000
committerdos-reis <gdr@axiomatics.org>2010-07-29 19:52:43 +0000
commit1b7a0340896d0fb7b2d99ba9c1358cac9f7b03d3 (patch)
treee0776cb40c64012874aee5767f27ee183d3ea537 /src/hyper/event.c
parent17004f202c892fd4d933b94c6b7441c45a06e80b (diff)
downloadopen-axiom-1b7a0340896d0fb7b2d99ba9c1358cac9f7b03d3.tar.gz
* lib/XSpadFill.c: Tidy.
* lib/pixmap.c: Likewise. * lib/spadcolors.c: Likewise. * include/ReadBitmap.H1: Remove. * include/all_hyper_proto.H1: Likewise. * include/cond.H1: Likewise. * include/cursor.H1: Likewise. * include/dialog.H1: Likewise. * include/display.H1: Likewise. * include/event.H1: Likewise. * include/extent1.H1: Likewise. * include/extent2.H1: Likewise. * include/form_ext.H1: Likewise. * include/group.H1: Likewise. * include/htinp.H1: Likewise. * include/hyper.H1: Likewise. * include/initx.H1: Likewise. * include/input.H1: Likewise. * include/item.H1: Likewise. * include/keyin.H1: Likewise. * include/macro.H1: Likewise. * include/mem.H1: Likewise. * include/parse.H1: Likewise. * include/parse_aux.H1: Likewise. * include/parse_input.H1: Likewise. * include/parse_paste.H1: Likewise. * include/parse_types.H1: Likewise. * include/scrollbar.H1: Likewise. * include/show_types.H1: Likewise. * include/spadcolors.H1: Likewise. * include/spadint.H1: Likewise. * include/titlebar.H1: Likewise. * hyper/Makefile.in: Compile and Link with a C++ compiler. * hyper/ReadBitmap.c: Make it acceptable to a C++ compiler. * hyper/cond.c: Likewise. * hyper/dialog.c: Likewise. * hyper/display.c: Likewise. * hyper/display.h: Likewise. * hyper/event.c: Likewise. * hyper/event.h: Likewise. * hyper/extent.h: Likewise. * hyper/extent1.c: Likewise. * hyper/extent2.c: Likewise. * hyper/form-ext.c: Likewise. * hyper/group.c: Likewise. * hyper/group.h: Likewise. * hyper/htadd.c: Likewise. * hyper/htinp.c: Likewise. * hyper/hyper.c: Likewise. * hyper/hyper.h: Likewise. * hyper/initx.c: Likewise. * hyper/initx.h: Likewise. * hyper/input.c: Likewise. * hyper/item.c: Likewise. * hyper/keyin.h: Likewise. * hyper/keyin.c: Likewise. * hyper/macro.c: Likewise. * hyper/mem.c: Likewise. * hyper/parse-aux.c: Likewise. * hyper/parse-input.c: Likewise. * hyper/parse-paste.c: Likewise. * hyper/parse-paste.h: Likewise. * hyper/parse-types.h: Likewise. * hyper/parse-types.c: Likewise. * hyper/parse.h: Likewise. * hyper/parse.c: Likewise. * hyper/scrollbar.c: Likewise. * hyper/scrollbar.h: Likewise. * hyper/show-types.c: Likewise. * hyper/spadint.c: Likewise. * hyper/titlebar.c: Likewise. * hyper/titlebar.h: Likewise. * graph/view3D/smoothShade3d.c: Include spadcolors.h * graph/view3D/stuff3d.c: Likewise. * graph/include/view.h (saymem): #undef before #define. * graph/view2D/write2d.c: Include pixmap.h. * graph/view3D/process3d.c: Likewise. * graph/view3D/write3d.c: Likewise. * graph/view3D/header.h: Remove macro definition for endColor and colorStep. * include/bsdsignal.h: Remove. * include/edin.H1: Likewise. * include/fnct_key.H1: Likewise. * include/halloc.h: Likewise. * include/hash.h: Likewise. * include/prt.H1: Likewise. * include/rgb.H1: Likewise. * include/sockio.h: Likewise. * include/util.h: Likewise. * include/pixmap.h: Rename from pixmap.H1
Diffstat (limited to 'src/hyper/event.c')
-rw-r--r--src/hyper/event.c968
1 files changed, 485 insertions, 483 deletions
diff --git a/src/hyper/event.c b/src/hyper/event.c
index 80c907d3..0ba54a27 100644
--- a/src/hyper/event.c
+++ b/src/hyper/event.c
@@ -1,7 +1,7 @@
/*
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
All rights reserved.
- Copyright (C) 2007-2008, Gabriel Dos Reis.
+ Copyright (C) 2007-2010, Gabriel Dos Reis.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -34,12 +34,8 @@
*/
#define _EVENT_C
-#include "openaxiom-c-macros.h"
-
-#include "debug.h"
-#include "sockio.h"
-#include "hyper.h"
+#include "openaxiom-c-macros.h"
#include <X11/X.h>
#include <X11/Xatom.h>
@@ -49,6 +45,9 @@
#include <sys/types.h>
#include <sys/time.h>
+#include "debug.h"
+#include "sockio.h"
+#include "hyper.h"
#include "event.h"
#include "keyin.h"
#include "hyper.h"
@@ -59,8 +58,6 @@
#include "scrollbar.h"
#include "group.h"
#include "lex.h"
-
-#include "all_hyper_proto.H1"
#include "sockio.h"
jmp_buf env;
@@ -71,317 +68,197 @@ 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)
+static int
+HyperDocErrorHandler(Display *display, XErrorEvent *xe)
{
- 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();
+ if (xe->request_code != 15) {
+ char buf[1024];
- /* XFlush(gXDisplay); */
+ XGetErrorText(display, xe->error_code, buf, sizeof(buf));
- if (!motion)
- init_cursor_states();
- motion = 0;
+ 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 (!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);
- }
- }
+ if (xe->request_code != 15)
+ exit(-1);
+ }
+ return(0);
}
static void
-handle_event(XEvent * event)
+set_error_handlers(void)
{
- 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); */
+ XSetErrorHandler(HyperDocErrorHandler);
+}
- /* try to get the selection as a window property */
+static int
+set_window(Window window)
+{
+ Window root, parent, *children, grandparent,myarg;
+ HDWindow *htw;
+ unsigned int nchildren;
+ int st;
- 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;
+ 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;
- 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;
+ }
+ 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;
+ }
+ }
- for (pBuffer = pSelection; *pBuffer; ++pBuffer)
- add_buffer_to_sym(pBuffer, item);
+ /*
+ * 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.
+ */
- XFree(pSelection);
- }
- }
+ERROR:
+ gWindow=gParentWindow;
+ return 0;
+}
- /* clear the link info */
- gSavedInputAreaLink = NULL;
- }
- break;
+static HyperLink *
+findButtonInList(HDWindow * window, int x, int y)
+{
+ ButtonList *bl;
- default:
-/* fprintf(stderr,"event:handle_event type=default\n");*/
- break;
- }
+ 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 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
-create_window(void)
+change_cursor(Cursor state, HDWindow *window)
{
- XWindowAttributes wa;
+ if (window->fDisplayedCursor == state)
+ return;
+ window->fDisplayedCursor = state;
+ set_cursor(window, state);
+}
- XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa);
- gWindow->width = wa.width;
- gWindow->height = wa.height;
- display_page(gWindow->page);
- gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;
+static void
+make_busy_cursor(HDWindow *window)
+{
+ change_cursor(gBusyCursor, window);
+}
- /* 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);
+static void
+make_busy_cursors(void)
+{
+ hash_map(&gSessionHashTable, (MappableFunction)make_busy_cursor);
+}
+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);
}
+
/*
- * This routine is called when the quitbutton is hit. For the moment I am
- * just going to leave it all behind
+ * This procedure whips thru the stack and clears all expose events for the
+ * given routine
*/
-
-void
-quitHyperDoc(void)
+static void
+clear_exposures(Window w)
{
- HyperDocPage *page;
+ XEvent report;
- 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();
+ XFlush(gXDisplay);
+ while (XCheckTypedWindowEvent(gXDisplay, w, Expose, &report));
}
+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;
+}
-/*
- * find_page takes as an argument the HyperDoc for a page name and returns
- * the associated page
- */
static HyperDocPage *
-find_page(TextNode * node)
+paste_button(PasteNode * paste)
{
- char *page_name;
- HyperDocPage *page;
+ HyperDocPage *page = NULL;
+ int pastewhere=paste->where;
- /* 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;
+ if ( paste->end_node ==NULL || paste->begin_node==NULL || paste->arg_node==NULL ){
+ BeepAtTheUser();
+ return NULL;
}
- }
- return page;
-}
-
-/*
- * These are macros for taking care of the downlink stack, and the memolink
- * stack.
- */
-
-#define NotSpecial(t) \
- ((t == openaxiom_Quitbutton_token || t == openaxiom_Returnbutton_token \
- || t == openaxiom_Upbutton_token || t == UnknownPage \
- || t == UlUnknownPage || t == ErrorPage) \
- ?(0):(1))
-/* pushes a page onto the down link stack */
+ page=parse_patch(paste);
+/* paste has changed after this call so use pastewhere*/
-static void
-downlink(void)
-{
- if (gWindow->fDownLinkStackIndex == MaxDownlinkDepth)
- fprintf(stderr, "exceeded maximum link nesting level\n");
+ if (pastewhere && page ) {
+ if (0 == strcmp(page->name, "ErrorPage"))
+ page = NULL;
+ }
else
- gWindow->fDownLinkStack[gWindow->fDownLinkStackIndex++] = gWindow->page;
-}
+ BeepAtTheUser();
-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;
- }
+ return page;
}
static void
@@ -442,6 +319,60 @@ uplink(void)
}
}
+/*
+ * 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;
+}
+
+/* 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
windowlink_handler(TextNode * node)
{
@@ -456,14 +387,6 @@ windowlink_handler(TextNode * node)
/* 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)
{
@@ -484,86 +407,36 @@ lispwindowlink_handler(HyperLink * link)
}
}
-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)
+static void
+create_window(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);
+ XWindowAttributes wa;
- page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, gWindow->page->helppage);
+ XGetWindowAttributes(gXDisplay, gWindow->fMainWindow, &wa);
- if (page)
- make_window_link(gWindow->page->helppage);
- else
- BeepAtTheUser();
-}
+ gWindow->width = wa.width;
+ gWindow->height = wa.height;
+ display_page(gWindow->page);
+ gWindow->fWindowHashTable = gWindow->page->fLinkHashTable;
-static HyperLink *
-findButtonInList(HDWindow * window, int x, int y)
-{
- ButtonList *bl;
+ /* 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);
- 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;
+/*
+ * These are macros for taking care of the downlink stack, and the memolink
+ * stack.
+ */
- l1 = (HyperLink *) hash_find(gWindow->fWindowHashTable, (char *)&(event->window));
- if (l1)
- return l1;
- l2 = findButtonInList(gWindow, event->x, event->y);
- return l2;
-}
+#define NotSpecial(t) \
+ ((t == openaxiom_Quitbutton_token || t == openaxiom_Returnbutton_token \
+ || t == openaxiom_Upbutton_token || t == UnknownPage \
+ || t == UlUnknownPage || t == ErrorPage) \
+ ?(0):(1))
/*
* Handle a button pressed event. window is the subwindow in which the event
@@ -736,6 +609,190 @@ handle_button(int button, XButtonEvent * 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;
+ }
+
+}
+
+/*
+ * 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();
+}
+
+
+
+void
+make_window_link(char *name)
+{
+ if (init_top_window(name) != -1)
+{}/* gWindow->fWindowHashTable = gWindow->page->fLinkHashTable; */
+}
+
+
+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();
+}
+
+
void
exitHyperDoc(void)
{
@@ -776,71 +833,6 @@ exitHyperDoc(void)
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)
{
@@ -963,37 +955,6 @@ get_new_window(void)
}
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
@@ -1019,42 +980,83 @@ init_cursor_states(void)
}
-static void
-make_busy_cursor(HDWindow *window)
-{
- change_cursor(gBusyCursor, window);
-}
-
-static void
-make_busy_cursors(void)
-{
- hash_map(&gSessionHashTable, (MappableFunction)make_busy_cursor);
-}
+/*
+ * 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
+ */
-static int
-HyperDocErrorHandler(Display *display, XErrorEvent *xe)
+void
+mainEventLoop(void)
{
- 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);
+ XEvent event;
+ int Xcon;
+ fd_set rd, dum1, dum2;
+ motion = 0;
+ gActiveWindow = -1;
+ set_error_handlers();
+ Xcon = ConnectionNumber(gXDisplay);
- if (xe->request_code != 15)
- exit(-1);
- }
- return(0);
-}
+ while (1) {
+/* fprintf(stderr,"event:mainEventLoop: loop top\n");*/
+ while (gSessionHashTable.num_entries == 0)
+ pause();
+ /* XFlush(gXDisplay); */
+ if (!motion)
+ init_cursor_states();
+ motion = 0;
-static void
-set_error_handlers(void)
-{
- XSetErrorHandler(HyperDocErrorHandler);
+ 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, &rd, &dum1, &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);
+ }
+ }
}