1356 |
} |
} |
1357 |
|
|
1358 |
|
|
1359 |
|
/* Event handler function that pops down a menu on C-g. We can only pop |
1360 |
|
down menus if CancelMenuTracking is present (OSX 10.3 or later). */ |
1361 |
|
|
1362 |
|
#ifdef HAVE_CANCELMENUTRACKING |
1363 |
|
static pascal OSStatus |
1364 |
|
menu_quit_handler (nextHandler, theEvent, userData) |
1365 |
|
EventHandlerCallRef nextHandler; |
1366 |
|
EventRef theEvent; |
1367 |
|
void* userData; |
1368 |
|
{ |
1369 |
|
UInt32 keyCode; |
1370 |
|
UInt32 keyModifiers; |
1371 |
|
extern int mac_quit_char_modifiers; |
1372 |
|
extern int mac_quit_char_keycode; |
1373 |
|
|
1374 |
|
GetEventParameter (theEvent, kEventParamKeyCode, |
1375 |
|
typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); |
1376 |
|
|
1377 |
|
GetEventParameter (theEvent, kEventParamKeyModifiers, |
1378 |
|
typeUInt32, NULL, sizeof(UInt32), |
1379 |
|
NULL, &keyModifiers); |
1380 |
|
|
1381 |
|
if (keyCode == mac_quit_char_keycode |
1382 |
|
&& keyModifiers == mac_quit_char_modifiers) |
1383 |
|
{ |
1384 |
|
MenuRef menu = userData != 0 |
1385 |
|
? (MenuRef)userData : AcquireRootMenu (); |
1386 |
|
|
1387 |
|
CancelMenuTracking (menu, true, 0); |
1388 |
|
if (!userData) ReleaseMenu (menu); |
1389 |
|
return noErr; |
1390 |
|
} |
1391 |
|
|
1392 |
|
return CallNextEventHandler (nextHandler, theEvent); |
1393 |
|
} |
1394 |
|
#endif /* HAVE_CANCELMENUTRACKING */ |
1395 |
|
|
1396 |
|
/* Add event handler for MENU_HANDLE so we can detect C-g. |
1397 |
|
If MENU_HANDLE is NULL, install handler for all menus in the menu bar. |
1398 |
|
If CancelMenuTracking isn't available, do nothing. */ |
1399 |
|
|
1400 |
|
static void |
1401 |
|
install_menu_quit_handler (MenuHandle menu_handle) |
1402 |
|
{ |
1403 |
|
#ifdef HAVE_CANCELMENUTRACKING |
1404 |
|
EventHandlerUPP handler = NewEventHandlerUPP(menu_quit_handler); |
1405 |
|
UInt32 numTypes = 1; |
1406 |
|
EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; |
1407 |
|
int i = MIN_MENU_ID; |
1408 |
|
MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i); |
1409 |
|
|
1410 |
|
while (menu != NULL) |
1411 |
|
{ |
1412 |
|
InstallMenuEventHandler (menu, handler, GetEventTypeCount (typesList), |
1413 |
|
typesList, menu_handle, NULL); |
1414 |
|
if (menu_handle) break; |
1415 |
|
menu = GetMenuHandle (++i); |
1416 |
|
} |
1417 |
|
DisposeEventHandlerUPP (handler); |
1418 |
|
#endif /* HAVE_CANCELMENUTRACKING */ |
1419 |
|
} |
1420 |
|
|
1421 |
/* Set the contents of the menubar widgets of frame F. |
/* Set the contents of the menubar widgets of frame F. |
1422 |
The argument FIRST_TIME is currently ignored; |
The argument FIRST_TIME is currently ignored; |
1423 |
it is set the first time this is called, from initialize_frame_menubar. */ |
it is set the first time this is called, from initialize_frame_menubar. */ |
1637 |
|
|
1638 |
DrawMenuBar (); |
DrawMenuBar (); |
1639 |
|
|
1640 |
|
/* Add event handler so we can detect C-g. */ |
1641 |
|
install_menu_quit_handler (NULL); |
1642 |
free_menubar_widget_value_tree (first_wv); |
free_menubar_widget_value_tree (first_wv); |
1643 |
|
|
1644 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
1670 |
} |
} |
1671 |
|
|
1672 |
|
|
1673 |
/* mac_menu_show actually displays a menu using the panes and items in |
static Lisp_Object |
1674 |
|
pop_down_menu (arg) |
1675 |
|
Lisp_Object arg; |
1676 |
|
{ |
1677 |
|
struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg)); |
1678 |
|
struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg)); |
1679 |
|
|
1680 |
|
FRAME_PTR f = p1->pointer; |
1681 |
|
MenuHandle *menu = p2->pointer; |
1682 |
|
|
1683 |
|
BLOCK_INPUT; |
1684 |
|
|
1685 |
|
/* Must reset this manually because the button release event is not |
1686 |
|
passed to Emacs event loop. */ |
1687 |
|
FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0; |
1688 |
|
|
1689 |
|
/* delete all menus */ |
1690 |
|
{ |
1691 |
|
int i = MIN_POPUP_SUBMENU_ID; |
1692 |
|
MenuHandle submenu = GetMenuHandle (i); |
1693 |
|
while (submenu != NULL) |
1694 |
|
{ |
1695 |
|
DeleteMenu (i); |
1696 |
|
DisposeMenu (submenu); |
1697 |
|
submenu = GetMenuHandle (++i); |
1698 |
|
} |
1699 |
|
} |
1700 |
|
|
1701 |
|
DeleteMenu (POPUP_SUBMENU_ID); |
1702 |
|
DisposeMenu (*menu); |
1703 |
|
|
1704 |
|
UNBLOCK_INPUT; |
1705 |
|
|
1706 |
|
return Qnil; |
1707 |
|
} |
1708 |
|
|
1709 |
|
/* Mac_menu_show actually displays a menu using the panes and items in |
1710 |
menu_items and returns the value selected from it; we assume input |
menu_items and returns the value selected from it; we assume input |
1711 |
is blocked by the caller. */ |
is blocked by the caller. */ |
1712 |
|
|
1744 |
= (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); |
= (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); |
1745 |
int submenu_depth = 0; |
int submenu_depth = 0; |
1746 |
int first_pane; |
int first_pane; |
1747 |
|
int specpdl_count = SPECPDL_INDEX (); |
1748 |
|
|
1749 |
*error = NULL; |
*error = NULL; |
1750 |
|
|
1918 |
title = ENCODE_MENU_STRING (title); |
title = ENCODE_MENU_STRING (title); |
1919 |
#endif |
#endif |
1920 |
wv_title->name = (char *) SDATA (title); |
wv_title->name = (char *) SDATA (title); |
1921 |
wv_title->enabled = TRUE; |
wv_title->enabled = FALSE; |
1922 |
wv_title->title = TRUE; |
wv_title->title = TRUE; |
1923 |
wv_title->button_type = BUTTON_TYPE_NONE; |
wv_title->button_type = BUTTON_TYPE_NONE; |
1924 |
wv_title->help = Qnil; |
wv_title->help = Qnil; |
1931 |
submenu_id = MIN_POPUP_SUBMENU_ID; |
submenu_id = MIN_POPUP_SUBMENU_ID; |
1932 |
fill_submenu (menu, first_wv->contents); |
fill_submenu (menu, first_wv->contents); |
1933 |
|
|
1934 |
|
/* Free the widget_value objects we used to specify the |
1935 |
|
contents. */ |
1936 |
|
free_menubar_widget_value_tree (first_wv); |
1937 |
|
|
1938 |
/* Adjust coordinates to be root-window-relative. */ |
/* Adjust coordinates to be root-window-relative. */ |
1939 |
pos.h = x; |
pos.h = x; |
1940 |
pos.v = y; |
pos.v = y; |
1949 |
|
|
1950 |
InsertMenu (menu, -1); |
InsertMenu (menu, -1); |
1951 |
|
|
1952 |
|
record_unwind_protect (pop_down_menu, |
1953 |
|
Fcons (make_save_value (f, 0), |
1954 |
|
make_save_value (&menu, 0))); |
1955 |
|
|
1956 |
|
/* Add event handler so we can detect C-g. */ |
1957 |
|
install_menu_quit_handler (menu); |
1958 |
|
|
1959 |
/* Display the menu. */ |
/* Display the menu. */ |
1960 |
menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0); |
menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0); |
1961 |
menu_item_selection = LoWord (menu_item_choice); |
menu_item_selection = LoWord (menu_item_choice); |
1962 |
|
|
1963 |
/* Get the refcon to find the correct item*/ |
/* Get the refcon to find the correct item */ |
1964 |
if (menu_item_selection) |
if (menu_item_selection) |
1965 |
{ |
{ |
1966 |
MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice)); |
MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice)); |
1968 |
GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon); |
GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon); |
1969 |
} |
} |
1970 |
} |
} |
1971 |
|
else if (! for_click) |
1972 |
#if 0 |
/* Make "Cancel" equivalent to C-g unless this menu was popped up by |
1973 |
/* Clean up extraneous mouse events which might have been generated |
a mouse press. */ |
1974 |
during the call. */ |
Fsignal (Qquit, Qnil); |
|
discard_mouse_events (); |
|
|
#endif |
|
|
|
|
|
/* Must reset this manually because the button release event is not |
|
|
passed to Emacs event loop. */ |
|
|
FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0; |
|
|
|
|
|
/* Free the widget_value objects we used to specify the |
|
|
contents. */ |
|
|
free_menubar_widget_value_tree (first_wv); |
|
|
|
|
|
/* delete all menus */ |
|
|
{ |
|
|
int i = MIN_POPUP_SUBMENU_ID; |
|
|
MenuHandle submenu = GetMenuHandle (i); |
|
|
while (submenu != NULL) |
|
|
{ |
|
|
DeleteMenu (i); |
|
|
DisposeMenu (submenu); |
|
|
submenu = GetMenuHandle (++i); |
|
|
} |
|
|
} |
|
|
|
|
|
DeleteMenu (POPUP_SUBMENU_ID); |
|
|
DisposeMenu (menu); |
|
1975 |
|
|
1976 |
/* Find the selected item, and its pane, to return |
/* Find the selected item, and its pane, to return |
1977 |
the proper value. */ |
the proper value. */ |
2031 |
/* Make "Cancel" equivalent to C-g. */ |
/* Make "Cancel" equivalent to C-g. */ |
2032 |
Fsignal (Qquit, Qnil); |
Fsignal (Qquit, Qnil); |
2033 |
|
|
2034 |
|
unbind_to (specpdl_count, Qnil); |
2035 |
|
|
2036 |
return Qnil; |
return Qnil; |
2037 |
} |
} |
2038 |
|
|