X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f9a70a31718a329d98272bbba17184c295994023..70482877f532d75f7fc038e5299ad66de7da3378:/oldXMenu/Activate.c diff --git a/oldXMenu/Activate.c b/oldXMenu/Activate.c index 5774176e82..d03534e144 100644 --- a/oldXMenu/Activate.c +++ b/oldXMenu/Activate.c @@ -1,5 +1,5 @@ -/* $Header: /gd/gnu/cvsroot/emacs/oldXMenu/Activate.c,v 1.1 1999/10/03 19:34:50 fx Exp $ */ /* Copyright Massachusetts Institute of Technology 1985 */ +/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. */ #include "copyright.h" @@ -28,7 +28,7 @@ * * 1) If at any time an error occurs the data * pointer is left untouched and XM_FAILURE - * is returned. + * is returned. * * 2) When a selection request is received (i.e., * when the specified mouse event occurs) the @@ -42,7 +42,7 @@ * will be left untouched and XM_NO_SELECT will * be returned. * - * 4) If the selection that was current at the time + * 4) If the selection that was current at the time * a selection request is made is not an active * selection the data pointer will be left * untouched and XM_IA_SELECT will be returned. @@ -82,6 +82,24 @@ #include #include "XMenuInt.h" +#include + +/* For debug, set this to 0 to not grab the keyboard on menu popup */ +int x_menu_grab_keyboard = 1; + +typedef void (*Wait_func)(); + +static Wait_func wait_func; +static void* wait_data; + +void +XMenuActivateSetWaitFunction (func, data) + Wait_func func; + void *data; +{ + wait_func = func; + wait_data = data; +} int XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, @@ -115,6 +133,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, Window root, child; int root_x, root_y, win_x, win_y; unsigned int mask; + KeySym keysym; /* * Define and allocate a foreign event queue to hold events @@ -128,7 +147,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, XMEventQue *feq = NULL; /* Foreign event queue. */ XMEventQue *feq_tmp; /* Foreign event queue temporary. */ - + /* * If there are no panes in the menu then return failure * because the menu is not initialized. @@ -159,14 +178,14 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, * Compute origin of menu so that cursor is in * Correct pane and selection. */ - _XMTransToOrigin(display, - menu, - cur_p, cur_s, - x_pos, y_pos, + _XMTransToOrigin(display, + menu, + cur_p, cur_s, + x_pos, y_pos, &orig_x, &orig_y); menu->x_pos = orig_x; /* Store X and Y coords of menu. */ menu->y_pos = orig_y; - + if (XMenuRecompute(display, menu) == XM_FAILURE) { return(XM_FAILURE); } @@ -209,11 +228,11 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, * not provided an event handler. */ XSync(display, 0); - + /* * Grab the mouse for menu input. */ - + status = XGrabPointer( display, menu->parent, @@ -225,6 +244,18 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, menu->mouse_cursor, CurrentTime ); + if (status == Success && x_menu_grab_keyboard) + { + status = XGrabKeyboard (display, + menu->parent, + False, + GrabModeAsync, + GrabModeAsync, + CurrentTime); + if (status != Success) + XUngrabPointer(display, CurrentTime); + } + if (status == _X_FAILURE) { _XMErrorCode = XME_GRAB_MOUSE; return(XM_FAILURE); @@ -235,7 +266,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, */ XMapWindow(display, cur_p->window); for (p_ptr = menu->p_list->next; - p_ptr != cur_p; + p_ptr != cur_p; p_ptr = p_ptr->next) XMapWindow(display, p_ptr->window); for (p_ptr = cur_p->next; @@ -245,18 +276,19 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, XRaiseWindow(display, cur_p->window); /* Make sure current */ /* pane is on top. */ - + cur_s = NULL; /* Clear current selection. */ /* * Begin event processing loop. */ while (1) { + if (wait_func) (*wait_func) (wait_data); XNextEvent(display, &event); /* Get next event. */ switch (event.type) { /* Dispatch on the event type. */ case Expose: event_xmp = (XMPane *)XLookUpAssoc(display, - menu->assoc_tab, + menu->assoc_tab, event.xexpose.window); if (event_xmp == NULL) { /* @@ -277,7 +309,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, } if (event_xmp->activated) { XSetWindowBackground(display, - event_xmp->window, + event_xmp->window, menu->bkgnd_color); } else { @@ -288,13 +320,13 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, _XMRefreshPane(display, menu, event_xmp); break; case EnterNotify: - /* + /* * First wait a small period of time, and see * if another EnterNotify event follows hard on the * heels of this one. i.e., the user is simply * "passing through". If so, ignore this one. */ - + event_xmw = (XMWindow *)XLookUpAssoc(display, menu->assoc_tab, event.xcrossing.window); @@ -309,10 +341,11 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, if(peek_event.type == LeaveNotify) { break; } - } + } cur_s = (XMSelect *)event_xmw; - help_callback (cur_s->help_string); - + help_callback (cur_s->help_string, + cur_p->serial, cur_s->serial); + /* * If the pane we are in is active and the * selection entered is active then activate @@ -369,7 +402,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, * take it from here. -- caveh@eng.sun.com. */ XSetWindowBackground(display, - event_xmp->window, + event_xmp->window, menu->bkgnd_color); _XMRefreshPane(display, menu, event_xmp); #endif @@ -384,7 +417,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, ); if (event_xmw == NULL) break; if(cur_s == NULL) break; - + /* * If the current selection was activated then * deactivate it. @@ -395,7 +428,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, } cur_s = NULL; break; - + case ButtonPress: case ButtonRelease: *p_num = cur_p->serial; @@ -428,6 +461,18 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, } selection = True; break; + case KeyPress: + case KeyRelease: + keysym = XLookupKeysym (&event.xkey, 0); + + /* Pop down on C-g and Escape. */ + if ((keysym == XK_g && (event.xkey.state & ControlMask) != 0) + || keysym == XK_Escape) /* Any escape, ignore modifiers. */ + { + ret_val = XM_NO_SELECT; + selection = True; + } + break; default: /* * If AEQ mode is enabled then queue the event. @@ -455,7 +500,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, */ for ( p_ptr = menu->p_list->next; p_ptr != menu->p_list; - p_ptr = p_ptr->next) + p_ptr = p_ptr->next) { XUnmapWindow(display, p_ptr->window); } @@ -464,8 +509,9 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, * Ungrab the mouse. */ XUngrabPointer(display, CurrentTime); + XUngrabKeyboard(display, CurrentTime); - /* + /* * Restore bits under where the menu was if we managed * to save them and free the pixmap. */ @@ -485,7 +531,7 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, * Synchronize the X buffers and the X event queue. */ XSync(display, 0); - + /* * Dispatch any events remaining on the queue. */ @@ -540,7 +586,9 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, feq = feq_tmp->next; free((char *)feq_tmp); } - + + wait_func = 0; + /* * Return successfully. */ @@ -548,3 +596,6 @@ XMenuActivate(display, menu, p_num, s_num, x_pos, y_pos, event_mask, data, return(ret_val); } + +/* arch-tag: 6b90b578-ecea-4328-b460-a0c96963f872 + (do not change this comment) */