changeset 69651:b69c19d38ce9

(enum mac_menu_kind): New enum. (min_menu_id): New variable. (POPUP_SUBMENU_ID, MIN_POPUP_SUBMENU_ID, MIN_MENU_ID) (MIN_SUBMENU_ID): Remove defines. All uses are replaced with min_menu_id and enumerators in enum mac_menu_kind. (fill_menu, dispose_menus, install_menu_quit_handler): New arg KIND. All uses changed. Add range check for menu ID. (fill_menubar): Add range check for menu ID. [HAVE_CANCELMENUTRACKING] (menu_quit_handler): Check error code of GetEventParameter. (set_frame_menubar, mac_menu_show): Call install_menu_quit_handler for each menu kind.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Fri, 24 Mar 2006 08:11:34 +0000
parents de8b61c18c11
children b2bd6986d8af
files src/macmenu.c
diffstat 1 files changed, 70 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/src/macmenu.c	Thu Mar 23 23:52:11 2006 +0000
+++ b/src/macmenu.c	Fri Mar 24 08:11:34 2006 +0000
@@ -62,10 +62,17 @@
 
 #include "dispextern.h"
 
-#define POPUP_SUBMENU_ID 235
-#define MIN_POPUP_SUBMENU_ID 512
-#define MIN_MENU_ID 256
-#define MIN_SUBMENU_ID 1
+enum mac_menu_kind {		/* Menu ID range  */
+  MAC_MENU_APPLE,		/* 0 (Reserved by Apple) */
+  MAC_MENU_MENU_BAR,		/* 1 .. 234       */
+  MAC_MENU_POPUP,		/* 235            */
+  MAC_MENU_DRIVER,		/* 236 .. 255 (Reserved) */
+  MAC_MENU_MENU_BAR_SUB,	/* 256 .. 16383   */
+  MAC_MENU_POPUP_SUB,		/* 16384 .. 32767 */
+  MAC_MENU_END			/* 32768          */
+};
+
+static const min_menu_id[] = {0, 1, 235, 236, 256, 16384, 32768};
 
 #define DIALOG_WINDOW_RESOURCE 130
 
@@ -189,9 +196,9 @@
 static void list_of_panes P_ ((Lisp_Object));
 static void list_of_items P_ ((Lisp_Object));
 
-static int fill_menu P_ ((MenuHandle, widget_value *, int));
+static int fill_menu P_ ((MenuHandle, widget_value *, enum mac_menu_kind, int));
 static void fill_menubar P_ ((widget_value *, int));
-static void dispose_menus P_ ((int));
+static void dispose_menus P_ ((enum mac_menu_kind, int));
 
 
 /* This holds a Lisp vector that holds the results of decoding
@@ -1387,19 +1394,21 @@
      EventRef theEvent;
      void* userData;
 {
+  OSStatus err;
   UInt32 keyCode;
   UInt32 keyModifiers;
   extern int mac_quit_char_modifiers;
   extern int mac_quit_char_keycode;
 
-  GetEventParameter (theEvent, kEventParamKeyCode,
-                     typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
-
-  GetEventParameter (theEvent, kEventParamKeyModifiers,
-                     typeUInt32, NULL, sizeof(UInt32),
-                     NULL, &keyModifiers);
-
-  if (keyCode == mac_quit_char_keycode
+  err = GetEventParameter (theEvent, kEventParamKeyCode,
+			   typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
+
+  if (err == noErr)
+    err = GetEventParameter (theEvent, kEventParamKeyModifiers,
+			     typeUInt32, NULL, sizeof(UInt32),
+			     NULL, &keyModifiers);
+
+  if (err == noErr && keyCode == mac_quit_char_keycode
       && keyModifiers == mac_quit_char_modifiers)
     {
       MenuRef menu = userData != 0
@@ -1414,35 +1423,29 @@
 }
 #endif /* HAVE_CANCELMENUTRACKING */
 
-/* Add event handler for MENU_HANDLE so we can detect C-g.
-   If MENU_HANDLE is NULL, install handler for all menus in the menu bar.
+/* Add event handler to all menus that belong to KIND so we can detect C-g.
+   MENU_HANDLE is the root menu of the tracking session to dismiss
+   when C-g is detected.  NULL means the menu bar.
    If CancelMenuTracking isn't available, do nothing.  */
 
 static void
-install_menu_quit_handler (MenuHandle menu_handle)
+install_menu_quit_handler (kind, menu_handle)
+     enum mac_menu_kind kind;
+     MenuHandle menu_handle;
 {
 #ifdef HAVE_CANCELMENUTRACKING
   EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } };
-  int i = MIN_MENU_ID;
-  MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i);
-
-  while (menu != NULL)
+  int id;
+
+  for (id = min_menu_id[kind]; id < min_menu_id[kind + 1]; id++)
     {
+      MenuHandle menu = GetMenuHandle (id);
+
+      if (menu == NULL)
+	break;
       InstallMenuEventHandler (menu, menu_quit_handler,
 			       GetEventTypeCount (typesList),
                                typesList, menu_handle, NULL);
-      if (menu_handle) break;
-      menu = GetMenuHandle (++i);
-    }
-
-  i = menu_handle ? MIN_POPUP_SUBMENU_ID : MIN_SUBMENU_ID;
-  menu = GetMenuHandle (i);
-  while (menu != NULL)
-    {
-      InstallMenuEventHandler (menu, menu_quit_handler,
-			       GetEventTypeCount (typesList),
-                               typesList, menu_handle, NULL);
-      menu = GetMenuHandle (++i);
     }
 #endif /* HAVE_CANCELMENUTRACKING */
 }
@@ -1677,7 +1680,8 @@
   fill_menubar (first_wv->contents, deep_p);
 
   /* Add event handler so we can detect C-g. */
-  install_menu_quit_handler (NULL);
+  install_menu_quit_handler (MAC_MENU_MENU_BAR, NULL);
+  install_menu_quit_handler (MAC_MENU_MENU_BAR_SUB, NULL);
   free_menubar_widget_value_tree (first_wv);
 
   UNBLOCK_INPUT;
@@ -1700,7 +1704,7 @@
 {
   struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
   FRAME_PTR f = p->pointer;
-  MenuHandle menu = GetMenuHandle (POPUP_SUBMENU_ID);
+  MenuHandle menu = GetMenuHandle (min_menu_id[MAC_MENU_POPUP]);
 
   BLOCK_INPUT;
 
@@ -1709,8 +1713,8 @@
   FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0;
 
   /* delete all menus */
-  dispose_menus (MIN_POPUP_SUBMENU_ID);
-  DeleteMenu (POPUP_SUBMENU_ID);
+  dispose_menus (MAC_MENU_POPUP_SUB, 0);
+  DeleteMenu (min_menu_id[MAC_MENU_POPUP]);
   DisposeMenu (menu);
 
   UNBLOCK_INPUT;
@@ -1944,9 +1948,10 @@
     }
 
   /* Actually create the menu.  */
-  menu = NewMenu (POPUP_SUBMENU_ID, "\p");
+  menu = NewMenu (min_menu_id[MAC_MENU_POPUP], "\p");
   InsertMenu (menu, -1);
-  fill_menu (menu, first_wv->contents, MIN_POPUP_SUBMENU_ID);
+  fill_menu (menu, first_wv->contents, MAC_MENU_POPUP_SUB,
+	     min_menu_id[MAC_MENU_POPUP_SUB]);
 
   /* Free the widget_value objects we used to specify the
      contents.  */
@@ -1966,7 +1971,8 @@
   record_unwind_protect (pop_down_menu, make_save_value (f, 0));
 
   /* Add event handler so we can detect C-g. */
-  install_menu_quit_handler (menu);
+  install_menu_quit_handler (MAC_MENU_POPUP, menu);
+  install_menu_quit_handler (MAC_MENU_POPUP_SUB, menu);
 
   /* Display the menu.  */
   menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0);
@@ -2437,9 +2443,10 @@
 /* Construct native Mac OS menu based on widget_value tree.  */
 
 static int
-fill_menu (menu, wv, submenu_id)
+fill_menu (menu, wv, kind, submenu_id)
      MenuHandle menu;
      widget_value *wv;
+     enum mac_menu_kind kind;
      int submenu_id;
 {
   int pos;
@@ -2447,13 +2454,13 @@
   for (pos = 1; wv != NULL; wv = wv->next, pos++)
     {
       add_menu_item (menu, pos, wv);
-      if (wv->contents)
+      if (wv->contents && submenu_id < min_menu_id[kind + 1])
 	{
 	  MenuHandle submenu = NewMenu (submenu_id, "\pX");
 
 	  InsertMenu (submenu, -1);
 	  SetMenuItemHierarchicalID (menu, pos, submenu_id);
-	  submenu_id = fill_menu (submenu, wv->contents, submenu_id + 1);
+	  submenu_id = fill_menu (submenu, wv->contents, kind, submenu_id + 1);
 	}
     }
 
@@ -2477,8 +2484,8 @@
   /* Clean up the menu bar when filled by the entire menu trees.  */
   if (deep_p)
     {
-      dispose_menus (MIN_MENU_ID);
-      dispose_menus (MIN_SUBMENU_ID);
+      dispose_menus (MAC_MENU_MENU_BAR, 0);
+      dispose_menus (MAC_MENU_MENU_BAR_SUB, 0);
 #if !TARGET_API_MAC_CARBON
       title_changed_p = 1;
 #endif
@@ -2486,8 +2493,10 @@
 
   /* Fill menu bar titles and submenus.  Reuse the existing menu bar
      titles as much as possible to minimize redraw (if !deep_p).  */
-  submenu_id = MIN_SUBMENU_ID;
-  for (id = MIN_MENU_ID; wv != NULL; wv = wv->next, id++)
+  submenu_id = min_menu_id[MAC_MENU_MENU_BAR_SUB];
+  for (id = min_menu_id[MAC_MENU_MENU_BAR];
+       wv != NULL && id < min_menu_id[MAC_MENU_MENU_BAR + 1];
+       wv = wv->next, id++)
     {
       strncpy (title, wv->name, 255);
       title[255] = '\0';
@@ -2523,12 +2532,13 @@
 	}
 
       if (wv->contents)
-        submenu_id = fill_menu (menu, wv->contents, submenu_id);
+        submenu_id = fill_menu (menu, wv->contents, MAC_MENU_MENU_BAR_SUB,
+				submenu_id);
     }
 
-  if (GetMenuHandle (id))
+  if (id < min_menu_id[MAC_MENU_MENU_BAR + 1] && GetMenuHandle (id))
     {
-      dispose_menus (id);
+      dispose_menus (MAC_MENU_MENU_BAR, id);
 #if !TARGET_API_MAC_CARBON
       title_changed_p = 1;
 #endif
@@ -2540,17 +2550,22 @@
 #endif
 }
 
+/* Dispose of menus that belong to KIND, and remove them from the menu
+   list.  ID is the lower bound of menu IDs that will be processed.  */
+
 static void
-dispose_menus (id)
+dispose_menus (kind, id)
+     enum mac_menu_kind kind;
      int id;
 {
-  MenuHandle menu;
-
-  while ((menu = GetMenuHandle (id)) != NULL)
+  for (id = max (id, min_menu_id[kind]); id < min_menu_id[kind + 1]; id++)
     {
+      MenuHandle menu = GetMenuHandle (id);
+
+      if (menu == NULL)
+	break;
       DeleteMenu (id);
       DisposeMenu (menu);
-      id++;
     }
 }