diff options
author | dos-reis <gdr@axiomatics.org> | 2010-07-29 19:52:43 +0000 |
---|---|---|
committer | dos-reis <gdr@axiomatics.org> | 2010-07-29 19:52:43 +0000 |
commit | 1b7a0340896d0fb7b2d99ba9c1358cac9f7b03d3 (patch) | |
tree | e0776cb40c64012874aee5767f27ee183d3ea537 /src/hyper/event.c | |
parent | 17004f202c892fd4d933b94c6b7441c45a06e80b (diff) | |
download | open-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.c | 968 |
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); + } + } } |