]> code.delx.au - gnu-emacs/blobdiff - oldXMenu/Activate.c
(gnus-article-mime-handles): Add defvar.
[gnu-emacs] / oldXMenu / Activate.c
index 2c36cc850337731cfbd36a5f52b8f3bd5435c652..d03534e144ac332650469b08f471e7933ed8bce0 100644 (file)
@@ -1,5 +1,5 @@
-/* $Header: /gd/gnu/cvsroot/emacs/oldXMenu/Activate.c,v 1.2 2000/01/27 15:31:20 gerd 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.
 
 #include <config.h>
 #include "XMenuInt.h"
+#include <X11/keysym.h>
+
+/* 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,11 +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,
                               cur_p->serial, cur_s->serial);
-               
+
                /*
                 * If the pane we are in is active and the
                 * selection entered is active then activate
@@ -370,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
@@ -385,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.
@@ -396,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;
@@ -429,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.
@@ -456,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);
       }
@@ -465,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.
      */
@@ -486,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.
      */
@@ -541,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.
      */
@@ -549,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) */