Mercurial > emacs
comparison src/macmenu.c @ 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 | 53d05914b117 |
| children | adc2f96580af e6bf73e43cf4 |
comparison
equal
deleted
inserted
replaced
| 69650:de8b61c18c11 | 69651:b69c19d38ce9 |
|---|---|
| 60 #include <sys/types.h> | 60 #include <sys/types.h> |
| 61 #endif | 61 #endif |
| 62 | 62 |
| 63 #include "dispextern.h" | 63 #include "dispextern.h" |
| 64 | 64 |
| 65 #define POPUP_SUBMENU_ID 235 | 65 enum mac_menu_kind { /* Menu ID range */ |
| 66 #define MIN_POPUP_SUBMENU_ID 512 | 66 MAC_MENU_APPLE, /* 0 (Reserved by Apple) */ |
| 67 #define MIN_MENU_ID 256 | 67 MAC_MENU_MENU_BAR, /* 1 .. 234 */ |
| 68 #define MIN_SUBMENU_ID 1 | 68 MAC_MENU_POPUP, /* 235 */ |
| 69 MAC_MENU_DRIVER, /* 236 .. 255 (Reserved) */ | |
| 70 MAC_MENU_MENU_BAR_SUB, /* 256 .. 16383 */ | |
| 71 MAC_MENU_POPUP_SUB, /* 16384 .. 32767 */ | |
| 72 MAC_MENU_END /* 32768 */ | |
| 73 }; | |
| 74 | |
| 75 static const min_menu_id[] = {0, 1, 235, 236, 256, 16384, 32768}; | |
| 69 | 76 |
| 70 #define DIALOG_WINDOW_RESOURCE 130 | 77 #define DIALOG_WINDOW_RESOURCE 130 |
| 71 | 78 |
| 72 #define HAVE_DIALOGS 1 | 79 #define HAVE_DIALOGS 1 |
| 73 | 80 |
| 187 static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 194 static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| 188 int, int)); | 195 int, int)); |
| 189 static void list_of_panes P_ ((Lisp_Object)); | 196 static void list_of_panes P_ ((Lisp_Object)); |
| 190 static void list_of_items P_ ((Lisp_Object)); | 197 static void list_of_items P_ ((Lisp_Object)); |
| 191 | 198 |
| 192 static int fill_menu P_ ((MenuHandle, widget_value *, int)); | 199 static int fill_menu P_ ((MenuHandle, widget_value *, enum mac_menu_kind, int)); |
| 193 static void fill_menubar P_ ((widget_value *, int)); | 200 static void fill_menubar P_ ((widget_value *, int)); |
| 194 static void dispose_menus P_ ((int)); | 201 static void dispose_menus P_ ((enum mac_menu_kind, int)); |
| 195 | 202 |
| 196 | 203 |
| 197 /* This holds a Lisp vector that holds the results of decoding | 204 /* This holds a Lisp vector that holds the results of decoding |
| 198 the keymaps or alist-of-alists that specify a menu. | 205 the keymaps or alist-of-alists that specify a menu. |
| 199 | 206 |
| 1385 menu_quit_handler (nextHandler, theEvent, userData) | 1392 menu_quit_handler (nextHandler, theEvent, userData) |
| 1386 EventHandlerCallRef nextHandler; | 1393 EventHandlerCallRef nextHandler; |
| 1387 EventRef theEvent; | 1394 EventRef theEvent; |
| 1388 void* userData; | 1395 void* userData; |
| 1389 { | 1396 { |
| 1397 OSStatus err; | |
| 1390 UInt32 keyCode; | 1398 UInt32 keyCode; |
| 1391 UInt32 keyModifiers; | 1399 UInt32 keyModifiers; |
| 1392 extern int mac_quit_char_modifiers; | 1400 extern int mac_quit_char_modifiers; |
| 1393 extern int mac_quit_char_keycode; | 1401 extern int mac_quit_char_keycode; |
| 1394 | 1402 |
| 1395 GetEventParameter (theEvent, kEventParamKeyCode, | 1403 err = GetEventParameter (theEvent, kEventParamKeyCode, |
| 1396 typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); | 1404 typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); |
| 1397 | 1405 |
| 1398 GetEventParameter (theEvent, kEventParamKeyModifiers, | 1406 if (err == noErr) |
| 1399 typeUInt32, NULL, sizeof(UInt32), | 1407 err = GetEventParameter (theEvent, kEventParamKeyModifiers, |
| 1400 NULL, &keyModifiers); | 1408 typeUInt32, NULL, sizeof(UInt32), |
| 1401 | 1409 NULL, &keyModifiers); |
| 1402 if (keyCode == mac_quit_char_keycode | 1410 |
| 1411 if (err == noErr && keyCode == mac_quit_char_keycode | |
| 1403 && keyModifiers == mac_quit_char_modifiers) | 1412 && keyModifiers == mac_quit_char_modifiers) |
| 1404 { | 1413 { |
| 1405 MenuRef menu = userData != 0 | 1414 MenuRef menu = userData != 0 |
| 1406 ? (MenuRef)userData : AcquireRootMenu (); | 1415 ? (MenuRef)userData : AcquireRootMenu (); |
| 1407 | 1416 |
| 1412 | 1421 |
| 1413 return CallNextEventHandler (nextHandler, theEvent); | 1422 return CallNextEventHandler (nextHandler, theEvent); |
| 1414 } | 1423 } |
| 1415 #endif /* HAVE_CANCELMENUTRACKING */ | 1424 #endif /* HAVE_CANCELMENUTRACKING */ |
| 1416 | 1425 |
| 1417 /* Add event handler for MENU_HANDLE so we can detect C-g. | 1426 /* Add event handler to all menus that belong to KIND so we can detect C-g. |
| 1418 If MENU_HANDLE is NULL, install handler for all menus in the menu bar. | 1427 MENU_HANDLE is the root menu of the tracking session to dismiss |
| 1428 when C-g is detected. NULL means the menu bar. | |
| 1419 If CancelMenuTracking isn't available, do nothing. */ | 1429 If CancelMenuTracking isn't available, do nothing. */ |
| 1420 | 1430 |
| 1421 static void | 1431 static void |
| 1422 install_menu_quit_handler (MenuHandle menu_handle) | 1432 install_menu_quit_handler (kind, menu_handle) |
| 1433 enum mac_menu_kind kind; | |
| 1434 MenuHandle menu_handle; | |
| 1423 { | 1435 { |
| 1424 #ifdef HAVE_CANCELMENUTRACKING | 1436 #ifdef HAVE_CANCELMENUTRACKING |
| 1425 EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; | 1437 EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; |
| 1426 int i = MIN_MENU_ID; | 1438 int id; |
| 1427 MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i); | 1439 |
| 1428 | 1440 for (id = min_menu_id[kind]; id < min_menu_id[kind + 1]; id++) |
| 1429 while (menu != NULL) | 1441 { |
| 1430 { | 1442 MenuHandle menu = GetMenuHandle (id); |
| 1443 | |
| 1444 if (menu == NULL) | |
| 1445 break; | |
| 1431 InstallMenuEventHandler (menu, menu_quit_handler, | 1446 InstallMenuEventHandler (menu, menu_quit_handler, |
| 1432 GetEventTypeCount (typesList), | 1447 GetEventTypeCount (typesList), |
| 1433 typesList, menu_handle, NULL); | 1448 typesList, menu_handle, NULL); |
| 1434 if (menu_handle) break; | |
| 1435 menu = GetMenuHandle (++i); | |
| 1436 } | |
| 1437 | |
| 1438 i = menu_handle ? MIN_POPUP_SUBMENU_ID : MIN_SUBMENU_ID; | |
| 1439 menu = GetMenuHandle (i); | |
| 1440 while (menu != NULL) | |
| 1441 { | |
| 1442 InstallMenuEventHandler (menu, menu_quit_handler, | |
| 1443 GetEventTypeCount (typesList), | |
| 1444 typesList, menu_handle, NULL); | |
| 1445 menu = GetMenuHandle (++i); | |
| 1446 } | 1449 } |
| 1447 #endif /* HAVE_CANCELMENUTRACKING */ | 1450 #endif /* HAVE_CANCELMENUTRACKING */ |
| 1448 } | 1451 } |
| 1449 | 1452 |
| 1450 /* Set the contents of the menubar widgets of frame F. | 1453 /* Set the contents of the menubar widgets of frame F. |
| 1675 f->output_data.mac->menubar_widget = 1; | 1678 f->output_data.mac->menubar_widget = 1; |
| 1676 | 1679 |
| 1677 fill_menubar (first_wv->contents, deep_p); | 1680 fill_menubar (first_wv->contents, deep_p); |
| 1678 | 1681 |
| 1679 /* Add event handler so we can detect C-g. */ | 1682 /* Add event handler so we can detect C-g. */ |
| 1680 install_menu_quit_handler (NULL); | 1683 install_menu_quit_handler (MAC_MENU_MENU_BAR, NULL); |
| 1684 install_menu_quit_handler (MAC_MENU_MENU_BAR_SUB, NULL); | |
| 1681 free_menubar_widget_value_tree (first_wv); | 1685 free_menubar_widget_value_tree (first_wv); |
| 1682 | 1686 |
| 1683 UNBLOCK_INPUT; | 1687 UNBLOCK_INPUT; |
| 1684 } | 1688 } |
| 1685 | 1689 |
| 1698 pop_down_menu (arg) | 1702 pop_down_menu (arg) |
| 1699 Lisp_Object arg; | 1703 Lisp_Object arg; |
| 1700 { | 1704 { |
| 1701 struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 1705 struct Lisp_Save_Value *p = XSAVE_VALUE (arg); |
| 1702 FRAME_PTR f = p->pointer; | 1706 FRAME_PTR f = p->pointer; |
| 1703 MenuHandle menu = GetMenuHandle (POPUP_SUBMENU_ID); | 1707 MenuHandle menu = GetMenuHandle (min_menu_id[MAC_MENU_POPUP]); |
| 1704 | 1708 |
| 1705 BLOCK_INPUT; | 1709 BLOCK_INPUT; |
| 1706 | 1710 |
| 1707 /* Must reset this manually because the button release event is not | 1711 /* Must reset this manually because the button release event is not |
| 1708 passed to Emacs event loop. */ | 1712 passed to Emacs event loop. */ |
| 1709 FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0; | 1713 FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0; |
| 1710 | 1714 |
| 1711 /* delete all menus */ | 1715 /* delete all menus */ |
| 1712 dispose_menus (MIN_POPUP_SUBMENU_ID); | 1716 dispose_menus (MAC_MENU_POPUP_SUB, 0); |
| 1713 DeleteMenu (POPUP_SUBMENU_ID); | 1717 DeleteMenu (min_menu_id[MAC_MENU_POPUP]); |
| 1714 DisposeMenu (menu); | 1718 DisposeMenu (menu); |
| 1715 | 1719 |
| 1716 UNBLOCK_INPUT; | 1720 UNBLOCK_INPUT; |
| 1717 | 1721 |
| 1718 return Qnil; | 1722 return Qnil; |
| 1942 wv_title->next = wv_sep; | 1946 wv_title->next = wv_sep; |
| 1943 first_wv->contents = wv_title; | 1947 first_wv->contents = wv_title; |
| 1944 } | 1948 } |
| 1945 | 1949 |
| 1946 /* Actually create the menu. */ | 1950 /* Actually create the menu. */ |
| 1947 menu = NewMenu (POPUP_SUBMENU_ID, "\p"); | 1951 menu = NewMenu (min_menu_id[MAC_MENU_POPUP], "\p"); |
| 1948 InsertMenu (menu, -1); | 1952 InsertMenu (menu, -1); |
| 1949 fill_menu (menu, first_wv->contents, MIN_POPUP_SUBMENU_ID); | 1953 fill_menu (menu, first_wv->contents, MAC_MENU_POPUP_SUB, |
| 1954 min_menu_id[MAC_MENU_POPUP_SUB]); | |
| 1950 | 1955 |
| 1951 /* Free the widget_value objects we used to specify the | 1956 /* Free the widget_value objects we used to specify the |
| 1952 contents. */ | 1957 contents. */ |
| 1953 free_menubar_widget_value_tree (first_wv); | 1958 free_menubar_widget_value_tree (first_wv); |
| 1954 | 1959 |
| 1964 menu_item_selection = 0; | 1969 menu_item_selection = 0; |
| 1965 | 1970 |
| 1966 record_unwind_protect (pop_down_menu, make_save_value (f, 0)); | 1971 record_unwind_protect (pop_down_menu, make_save_value (f, 0)); |
| 1967 | 1972 |
| 1968 /* Add event handler so we can detect C-g. */ | 1973 /* Add event handler so we can detect C-g. */ |
| 1969 install_menu_quit_handler (menu); | 1974 install_menu_quit_handler (MAC_MENU_POPUP, menu); |
| 1975 install_menu_quit_handler (MAC_MENU_POPUP_SUB, menu); | |
| 1970 | 1976 |
| 1971 /* Display the menu. */ | 1977 /* Display the menu. */ |
| 1972 menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0); | 1978 menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0); |
| 1973 menu_item_selection = LoWord (menu_item_choice); | 1979 menu_item_selection = LoWord (menu_item_choice); |
| 1974 | 1980 |
| 2435 } | 2441 } |
| 2436 | 2442 |
| 2437 /* Construct native Mac OS menu based on widget_value tree. */ | 2443 /* Construct native Mac OS menu based on widget_value tree. */ |
| 2438 | 2444 |
| 2439 static int | 2445 static int |
| 2440 fill_menu (menu, wv, submenu_id) | 2446 fill_menu (menu, wv, kind, submenu_id) |
| 2441 MenuHandle menu; | 2447 MenuHandle menu; |
| 2442 widget_value *wv; | 2448 widget_value *wv; |
| 2449 enum mac_menu_kind kind; | |
| 2443 int submenu_id; | 2450 int submenu_id; |
| 2444 { | 2451 { |
| 2445 int pos; | 2452 int pos; |
| 2446 | 2453 |
| 2447 for (pos = 1; wv != NULL; wv = wv->next, pos++) | 2454 for (pos = 1; wv != NULL; wv = wv->next, pos++) |
| 2448 { | 2455 { |
| 2449 add_menu_item (menu, pos, wv); | 2456 add_menu_item (menu, pos, wv); |
| 2450 if (wv->contents) | 2457 if (wv->contents && submenu_id < min_menu_id[kind + 1]) |
| 2451 { | 2458 { |
| 2452 MenuHandle submenu = NewMenu (submenu_id, "\pX"); | 2459 MenuHandle submenu = NewMenu (submenu_id, "\pX"); |
| 2453 | 2460 |
| 2454 InsertMenu (submenu, -1); | 2461 InsertMenu (submenu, -1); |
| 2455 SetMenuItemHierarchicalID (menu, pos, submenu_id); | 2462 SetMenuItemHierarchicalID (menu, pos, submenu_id); |
| 2456 submenu_id = fill_menu (submenu, wv->contents, submenu_id + 1); | 2463 submenu_id = fill_menu (submenu, wv->contents, kind, submenu_id + 1); |
| 2457 } | 2464 } |
| 2458 } | 2465 } |
| 2459 | 2466 |
| 2460 return submenu_id; | 2467 return submenu_id; |
| 2461 } | 2468 } |
| 2475 #endif | 2482 #endif |
| 2476 | 2483 |
| 2477 /* Clean up the menu bar when filled by the entire menu trees. */ | 2484 /* Clean up the menu bar when filled by the entire menu trees. */ |
| 2478 if (deep_p) | 2485 if (deep_p) |
| 2479 { | 2486 { |
| 2480 dispose_menus (MIN_MENU_ID); | 2487 dispose_menus (MAC_MENU_MENU_BAR, 0); |
| 2481 dispose_menus (MIN_SUBMENU_ID); | 2488 dispose_menus (MAC_MENU_MENU_BAR_SUB, 0); |
| 2482 #if !TARGET_API_MAC_CARBON | 2489 #if !TARGET_API_MAC_CARBON |
| 2483 title_changed_p = 1; | 2490 title_changed_p = 1; |
| 2484 #endif | 2491 #endif |
| 2485 } | 2492 } |
| 2486 | 2493 |
| 2487 /* Fill menu bar titles and submenus. Reuse the existing menu bar | 2494 /* Fill menu bar titles and submenus. Reuse the existing menu bar |
| 2488 titles as much as possible to minimize redraw (if !deep_p). */ | 2495 titles as much as possible to minimize redraw (if !deep_p). */ |
| 2489 submenu_id = MIN_SUBMENU_ID; | 2496 submenu_id = min_menu_id[MAC_MENU_MENU_BAR_SUB]; |
| 2490 for (id = MIN_MENU_ID; wv != NULL; wv = wv->next, id++) | 2497 for (id = min_menu_id[MAC_MENU_MENU_BAR]; |
| 2498 wv != NULL && id < min_menu_id[MAC_MENU_MENU_BAR + 1]; | |
| 2499 wv = wv->next, id++) | |
| 2491 { | 2500 { |
| 2492 strncpy (title, wv->name, 255); | 2501 strncpy (title, wv->name, 255); |
| 2493 title[255] = '\0'; | 2502 title[255] = '\0'; |
| 2494 c2pstr (title); | 2503 c2pstr (title); |
| 2495 | 2504 |
| 2521 title_changed_p = 1; | 2530 title_changed_p = 1; |
| 2522 #endif | 2531 #endif |
| 2523 } | 2532 } |
| 2524 | 2533 |
| 2525 if (wv->contents) | 2534 if (wv->contents) |
| 2526 submenu_id = fill_menu (menu, wv->contents, submenu_id); | 2535 submenu_id = fill_menu (menu, wv->contents, MAC_MENU_MENU_BAR_SUB, |
| 2527 } | 2536 submenu_id); |
| 2528 | 2537 } |
| 2529 if (GetMenuHandle (id)) | 2538 |
| 2530 { | 2539 if (id < min_menu_id[MAC_MENU_MENU_BAR + 1] && GetMenuHandle (id)) |
| 2531 dispose_menus (id); | 2540 { |
| 2541 dispose_menus (MAC_MENU_MENU_BAR, id); | |
| 2532 #if !TARGET_API_MAC_CARBON | 2542 #if !TARGET_API_MAC_CARBON |
| 2533 title_changed_p = 1; | 2543 title_changed_p = 1; |
| 2534 #endif | 2544 #endif |
| 2535 } | 2545 } |
| 2536 | 2546 |
| 2538 if (title_changed_p) | 2548 if (title_changed_p) |
| 2539 InvalMenuBar (); | 2549 InvalMenuBar (); |
| 2540 #endif | 2550 #endif |
| 2541 } | 2551 } |
| 2542 | 2552 |
| 2553 /* Dispose of menus that belong to KIND, and remove them from the menu | |
| 2554 list. ID is the lower bound of menu IDs that will be processed. */ | |
| 2555 | |
| 2543 static void | 2556 static void |
| 2544 dispose_menus (id) | 2557 dispose_menus (kind, id) |
| 2558 enum mac_menu_kind kind; | |
| 2545 int id; | 2559 int id; |
| 2546 { | 2560 { |
| 2547 MenuHandle menu; | 2561 for (id = max (id, min_menu_id[kind]); id < min_menu_id[kind + 1]; id++) |
| 2548 | 2562 { |
| 2549 while ((menu = GetMenuHandle (id)) != NULL) | 2563 MenuHandle menu = GetMenuHandle (id); |
| 2550 { | 2564 |
| 2565 if (menu == NULL) | |
| 2566 break; | |
| 2551 DeleteMenu (id); | 2567 DeleteMenu (id); |
| 2552 DisposeMenu (menu); | 2568 DisposeMenu (menu); |
| 2553 id++; | |
| 2554 } | 2569 } |
| 2555 } | 2570 } |
| 2556 | 2571 |
| 2557 #endif /* HAVE_MENUS */ | 2572 #endif /* HAVE_MENUS */ |
| 2558 | 2573 |
