diff options
| author | YAMAMOTO Mitsuharu | 2005-12-21 12:31:02 +0000 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2005-12-21 12:31:02 +0000 |
| commit | 4036ffb904fd5a68a739297f7d4a30cdfc2f6f97 (patch) | |
| tree | 0e9f652a053cc70b1fff985340d11fa6057374c4 /src/macmenu.c | |
| parent | 3150fbfcca4b29a5408c9be07c14d8edc3debbca (diff) | |
| download | emacs-4036ffb904fd5a68a739297f7d4a30cdfc2f6f97.tar.gz emacs-4036ffb904fd5a68a739297f7d4a30cdfc2f6f97.zip | |
(Qmac_apple_event): Add extern.
(set_frame_menubar, mac_menu_show keymp_panes)
(single_keymap_panes, list_of_panes, list_of_item)
(single_menu_item): Add argument types to prototypes.
(mac_dialog_show) [HAVE_DIALOGS]: Likewise.
(struct skp): New struct (from xmenu.c).
(single_keymap_panes, single_menu_item, list_of_panes)
(list_of_item): Sync with xmenu.c.
(Fx_popup_menu, Fx_popup_dialog): Likewise. Don't get window from
POSITION if it is mac-apple-event event.
(menubar_selection_callback): Don't use menu_command_in_progress.
(set_frame_menubar): First parse all submenus, then make
widget_value trees from them. Don't allocate any widget_value
objects until we are done with the parsing.
(parse_single_submenu, digest_single_submenu): New functions.
(single_submenu): Function deleted, replaced by those two.
(install_menu_quit_handler) [HAVE_CANCELMENUTRACKING]: Don't
create or dispose of EventHandlerUPP. Install hander to all submenus.
(mac_menu_show) [!HAVE_MULTILINGUAL_MENU]: Use ENCODE_MENU_STRING
instead of ENCODE_SYSTEM.
(free_frame_menubar, fill_submenu, fill_menu): Don't use NULL for
integer values.
[HAVE_DIALOGS] (mac_dialog_show): Sync with xdialog_show (in xmenu.c).
(add_menu_item) [TARGET_API_MAC_CARBON]: Use CFString functions to
format menu item string. Don't use NULL for integer value.
Diffstat (limited to 'src/macmenu.c')
| -rw-r--r-- | src/macmenu.c | 445 |
1 files changed, 258 insertions, 187 deletions
diff --git a/src/macmenu.c b/src/macmenu.c index 064cec57486..1b132407df7 100644 --- a/src/macmenu.c +++ b/src/macmenu.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Menu support for GNU Emacs on the for Mac OS. | 1 | /* Menu support for GNU Emacs on Mac OS. |
| 2 | Copyright (C) 2000, 2001, 2002, 2003, 2004, | 2 | Copyright (C) 2000, 2001, 2002, 2003, 2004, |
| 3 | 2005 Free Software Foundation, Inc. | 3 | 2005 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 24 | #include <config.h> | 24 | #include <config.h> |
| 25 | 25 | ||
| 26 | #include <stdio.h> | 26 | #include <stdio.h> |
| 27 | |||
| 27 | #include "lisp.h" | 28 | #include "lisp.h" |
| 28 | #include "termhooks.h" | 29 | #include "termhooks.h" |
| 29 | #include "keyboard.h" | 30 | #include "keyboard.h" |
| @@ -154,7 +155,7 @@ Lisp_Object Vmenu_updating_frame; | |||
| 154 | 155 | ||
| 155 | Lisp_Object Qdebug_on_next_call; | 156 | Lisp_Object Qdebug_on_next_call; |
| 156 | 157 | ||
| 157 | extern Lisp_Object Qmenu_bar; | 158 | extern Lisp_Object Qmenu_bar, Qmac_apple_event; |
| 158 | 159 | ||
| 159 | extern Lisp_Object QCtoggle, QCradio; | 160 | extern Lisp_Object QCtoggle, QCradio; |
| 160 | 161 | ||
| @@ -165,27 +166,28 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; | |||
| 165 | 166 | ||
| 166 | extern Lisp_Object Qmenu_bar_update_hook; | 167 | extern Lisp_Object Qmenu_bar_update_hook; |
| 167 | 168 | ||
| 169 | void set_frame_menubar P_ ((FRAME_PTR, int, int)); | ||
| 170 | |||
| 168 | #if TARGET_API_MAC_CARBON | 171 | #if TARGET_API_MAC_CARBON |
| 169 | #define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) | 172 | #define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) |
| 170 | #else | 173 | #else |
| 171 | #define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str) | 174 | #define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str) |
| 172 | #endif | 175 | #endif |
| 173 | 176 | ||
| 174 | void set_frame_menubar (); | ||
| 175 | |||
| 176 | static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 177 | static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| 177 | Lisp_Object, Lisp_Object, Lisp_Object, | 178 | Lisp_Object, Lisp_Object, Lisp_Object, |
| 178 | Lisp_Object, Lisp_Object)); | 179 | Lisp_Object, Lisp_Object)); |
| 179 | #ifdef HAVE_DIALOGS | 180 | #ifdef HAVE_DIALOGS |
| 180 | static Lisp_Object mac_dialog_show (); | 181 | static Lisp_Object mac_dialog_show P_ ((FRAME_PTR, int, Lisp_Object, |
| 182 | Lisp_Object, char **)); | ||
| 181 | #endif | 183 | #endif |
| 182 | static Lisp_Object mac_menu_show (); | 184 | static Lisp_Object mac_menu_show P_ ((struct frame *, int, int, int, int, |
| 183 | 185 | Lisp_Object, char **)); | |
| 184 | static void keymap_panes (); | 186 | static void keymap_panes P_ ((Lisp_Object *, int, int)); |
| 185 | static void single_keymap_panes (); | 187 | static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| 186 | static void single_menu_item (); | 188 | int, int)); |
| 187 | static void list_of_panes (); | 189 | static void list_of_panes P_ ((Lisp_Object)); |
| 188 | static void list_of_items (); | 190 | static void list_of_items P_ ((Lisp_Object)); |
| 189 | 191 | ||
| 190 | static void fill_submenu (MenuHandle, widget_value *); | 192 | static void fill_submenu (MenuHandle, widget_value *); |
| 191 | static void fill_menubar (widget_value *); | 193 | static void fill_menubar (widget_value *); |
| @@ -280,8 +282,7 @@ init_menu_items () | |||
| 280 | menu_items_submenu_depth = 0; | 282 | menu_items_submenu_depth = 0; |
| 281 | } | 283 | } |
| 282 | 284 | ||
| 283 | /* Call at the end of generating the data in menu_items. | 285 | /* Call at the end of generating the data in menu_items. */ |
| 284 | This fills in the number of items in the last pane. */ | ||
| 285 | 286 | ||
| 286 | static void | 287 | static void |
| 287 | finish_menu_items () | 288 | finish_menu_items () |
| @@ -415,11 +416,21 @@ keymap_panes (keymaps, nmaps, notreal) | |||
| 415 | P is the number of panes we have made so far. */ | 416 | P is the number of panes we have made so far. */ |
| 416 | for (mapno = 0; mapno < nmaps; mapno++) | 417 | for (mapno = 0; mapno < nmaps; mapno++) |
| 417 | single_keymap_panes (keymaps[mapno], | 418 | single_keymap_panes (keymaps[mapno], |
| 418 | Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10); | 419 | Fkeymap_prompt (keymaps[mapno]), Qnil, notreal, 10); |
| 419 | 420 | ||
| 420 | finish_menu_items (); | 421 | finish_menu_items (); |
| 421 | } | 422 | } |
| 422 | 423 | ||
| 424 | /* Args passed between single_keymap_panes and single_menu_item. */ | ||
| 425 | struct skp | ||
| 426 | { | ||
| 427 | Lisp_Object pending_maps; | ||
| 428 | int maxdepth, notreal; | ||
| 429 | }; | ||
| 430 | |||
| 431 | static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | ||
| 432 | void *)); | ||
| 433 | |||
| 423 | /* This is a recursive subroutine of keymap_panes. | 434 | /* This is a recursive subroutine of keymap_panes. |
| 424 | It handles one keymap, KEYMAP. | 435 | It handles one keymap, KEYMAP. |
| 425 | The other arguments are passed along | 436 | The other arguments are passed along |
| @@ -437,89 +448,71 @@ single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth) | |||
| 437 | int notreal; | 448 | int notreal; |
| 438 | int maxdepth; | 449 | int maxdepth; |
| 439 | { | 450 | { |
| 440 | Lisp_Object pending_maps = Qnil; | 451 | struct skp skp; |
| 441 | Lisp_Object tail, item; | 452 | struct gcpro gcpro1; |
| 442 | struct gcpro gcpro1, gcpro2; | 453 | |
| 454 | skp.pending_maps = Qnil; | ||
| 455 | skp.maxdepth = maxdepth; | ||
| 456 | skp.notreal = notreal; | ||
| 443 | 457 | ||
| 444 | if (maxdepth <= 0) | 458 | if (maxdepth <= 0) |
| 445 | return; | 459 | return; |
| 446 | 460 | ||
| 447 | push_menu_pane (pane_name, prefix); | 461 | push_menu_pane (pane_name, prefix); |
| 448 | 462 | ||
| 449 | for (tail = keymap; CONSP (tail); tail = XCDR (tail)) | 463 | GCPRO1 (skp.pending_maps); |
| 450 | { | 464 | map_keymap (keymap, single_menu_item, Qnil, &skp, 1); |
| 451 | GCPRO2 (keymap, pending_maps); | 465 | UNGCPRO; |
| 452 | /* Look at each key binding, and if it is a menu item add it | ||
| 453 | to this menu. */ | ||
| 454 | item = XCAR (tail); | ||
| 455 | if (CONSP (item)) | ||
| 456 | single_menu_item (XCAR (item), XCDR (item), | ||
| 457 | &pending_maps, notreal, maxdepth); | ||
| 458 | else if (VECTORP (item)) | ||
| 459 | { | ||
| 460 | /* Loop over the char values represented in the vector. */ | ||
| 461 | int len = XVECTOR (item)->size; | ||
| 462 | int c; | ||
| 463 | for (c = 0; c < len; c++) | ||
| 464 | { | ||
| 465 | Lisp_Object character; | ||
| 466 | XSETFASTINT (character, c); | ||
| 467 | single_menu_item (character, XVECTOR (item)->contents[c], | ||
| 468 | &pending_maps, notreal, maxdepth); | ||
| 469 | } | ||
| 470 | } | ||
| 471 | UNGCPRO; | ||
| 472 | } | ||
| 473 | 466 | ||
| 474 | /* Process now any submenus which want to be panes at this level. */ | 467 | /* Process now any submenus which want to be panes at this level. */ |
| 475 | while (!NILP (pending_maps)) | 468 | while (CONSP (skp.pending_maps)) |
| 476 | { | 469 | { |
| 477 | Lisp_Object elt, eltcdr, string; | 470 | Lisp_Object elt, eltcdr, string; |
| 478 | elt = Fcar (pending_maps); | 471 | elt = XCAR (skp.pending_maps); |
| 479 | eltcdr = XCDR (elt); | 472 | eltcdr = XCDR (elt); |
| 480 | string = XCAR (eltcdr); | 473 | string = XCAR (eltcdr); |
| 481 | /* We no longer discard the @ from the beginning of the string here. | 474 | /* We no longer discard the @ from the beginning of the string here. |
| 482 | Instead, we do this in mac_menu_show. */ | 475 | Instead, we do this in mac_menu_show. */ |
| 483 | single_keymap_panes (Fcar (elt), string, | 476 | single_keymap_panes (Fcar (elt), string, |
| 484 | XCDR (eltcdr), notreal, maxdepth - 1); | 477 | XCDR (eltcdr), notreal, maxdepth - 1); |
| 485 | pending_maps = Fcdr (pending_maps); | 478 | skp.pending_maps = XCDR (skp.pending_maps); |
| 486 | } | 479 | } |
| 487 | } | 480 | } |
| 488 | 481 | ||
| 489 | /* This is a subroutine of single_keymap_panes that handles one | 482 | /* This is a subroutine of single_keymap_panes that handles one |
| 490 | keymap entry. | 483 | keymap entry. |
| 491 | KEY is a key in a keymap and ITEM is its binding. | 484 | KEY is a key in a keymap and ITEM is its binding. |
| 492 | PENDING_MAPS_PTR points to a list of keymaps waiting to be made into | 485 | SKP->PENDING_MAPS_PTR is a list of keymaps waiting to be made into |
| 493 | separate panes. | 486 | separate panes. |
| 494 | If NOTREAL is nonzero, only check for equivalent key bindings, don't | 487 | If SKP->NOTREAL is nonzero, only check for equivalent key bindings, don't |
| 495 | evaluate expressions in menu items and don't make any menu. | 488 | evaluate expressions in menu items and don't make any menu. |
| 496 | If we encounter submenus deeper than MAXDEPTH levels, ignore them. */ | 489 | If we encounter submenus deeper than SKP->MAXDEPTH levels, ignore them. */ |
| 497 | 490 | ||
| 498 | static void | 491 | static void |
| 499 | single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth) | 492 | single_menu_item (key, item, dummy, skp_v) |
| 500 | Lisp_Object key, item; | 493 | Lisp_Object key, item, dummy; |
| 501 | Lisp_Object *pending_maps_ptr; | 494 | void *skp_v; |
| 502 | int maxdepth, notreal; | ||
| 503 | { | 495 | { |
| 504 | Lisp_Object map, item_string, enabled; | 496 | Lisp_Object map, item_string, enabled; |
| 505 | struct gcpro gcpro1, gcpro2; | 497 | struct gcpro gcpro1, gcpro2; |
| 506 | int res; | 498 | int res; |
| 499 | struct skp *skp = skp_v; | ||
| 507 | 500 | ||
| 508 | /* Parse the menu item and leave the result in item_properties. */ | 501 | /* Parse the menu item and leave the result in item_properties. */ |
| 509 | GCPRO2 (key, item); | 502 | GCPRO2 (key, item); |
| 510 | res = parse_menu_item (item, notreal, 0); | 503 | res = parse_menu_item (item, skp->notreal, 0); |
| 511 | UNGCPRO; | 504 | UNGCPRO; |
| 512 | if (!res) | 505 | if (!res) |
| 513 | return; /* Not a menu item. */ | 506 | return; /* Not a menu item. */ |
| 514 | 507 | ||
| 515 | map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; | 508 | map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; |
| 516 | 509 | ||
| 517 | if (notreal) | 510 | if (skp->notreal) |
| 518 | { | 511 | { |
| 519 | /* We don't want to make a menu, just traverse the keymaps to | 512 | /* We don't want to make a menu, just traverse the keymaps to |
| 520 | precompute equivalent key bindings. */ | 513 | precompute equivalent key bindings. */ |
| 521 | if (!NILP (map)) | 514 | if (!NILP (map)) |
| 522 | single_keymap_panes (map, Qnil, key, 1, maxdepth - 1); | 515 | single_keymap_panes (map, Qnil, key, 1, skp->maxdepth - 1); |
| 523 | return; | 516 | return; |
| 524 | } | 517 | } |
| 525 | 518 | ||
| @@ -530,8 +523,8 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth) | |||
| 530 | { | 523 | { |
| 531 | if (!NILP (enabled)) | 524 | if (!NILP (enabled)) |
| 532 | /* An enabled separate pane. Remember this to handle it later. */ | 525 | /* An enabled separate pane. Remember this to handle it later. */ |
| 533 | *pending_maps_ptr = Fcons (Fcons (map, Fcons (item_string, key)), | 526 | skp->pending_maps = Fcons (Fcons (map, Fcons (item_string, key)), |
| 534 | *pending_maps_ptr); | 527 | skp->pending_maps); |
| 535 | return; | 528 | return; |
| 536 | } | 529 | } |
| 537 | 530 | ||
| @@ -539,14 +532,14 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth) | |||
| 539 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], | 532 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], |
| 540 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], | 533 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], |
| 541 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], | 534 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], |
| 542 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], | 535 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], |
| 543 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); | 536 | XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); |
| 544 | 537 | ||
| 545 | /* Display a submenu using the toolkit. */ | 538 | /* Display a submenu using the toolkit. */ |
| 546 | if (! (NILP (map) || NILP (enabled))) | 539 | if (! (NILP (map) || NILP (enabled))) |
| 547 | { | 540 | { |
| 548 | push_submenu_start (); | 541 | push_submenu_start (); |
| 549 | single_keymap_panes (map, Qnil, key, 0, maxdepth - 1); | 542 | single_keymap_panes (map, Qnil, key, 0, skp->maxdepth - 1); |
| 550 | push_submenu_end (); | 543 | push_submenu_end (); |
| 551 | } | 544 | } |
| 552 | } | 545 | } |
| @@ -563,13 +556,13 @@ list_of_panes (menu) | |||
| 563 | 556 | ||
| 564 | init_menu_items (); | 557 | init_menu_items (); |
| 565 | 558 | ||
| 566 | for (tail = menu; !NILP (tail); tail = Fcdr (tail)) | 559 | for (tail = menu; CONSP (tail); tail = XCDR (tail)) |
| 567 | { | 560 | { |
| 568 | Lisp_Object elt, pane_name, pane_data; | 561 | Lisp_Object elt, pane_name, pane_data; |
| 569 | elt = Fcar (tail); | 562 | elt = XCAR (tail); |
| 570 | pane_name = Fcar (elt); | 563 | pane_name = Fcar (elt); |
| 571 | CHECK_STRING (pane_name); | 564 | CHECK_STRING (pane_name); |
| 572 | push_menu_pane (pane_name, Qnil); | 565 | push_menu_pane (ENCODE_MENU_STRING (pane_name), Qnil); |
| 573 | pane_data = Fcdr (elt); | 566 | pane_data = Fcdr (elt); |
| 574 | CHECK_CONS (pane_data); | 567 | CHECK_CONS (pane_data); |
| 575 | list_of_items (pane_data); | 568 | list_of_items (pane_data); |
| @@ -586,20 +579,22 @@ list_of_items (pane) | |||
| 586 | { | 579 | { |
| 587 | Lisp_Object tail, item, item1; | 580 | Lisp_Object tail, item, item1; |
| 588 | 581 | ||
| 589 | for (tail = pane; !NILP (tail); tail = Fcdr (tail)) | 582 | for (tail = pane; CONSP (tail); tail = XCDR (tail)) |
| 590 | { | 583 | { |
| 591 | item = Fcar (tail); | 584 | item = XCAR (tail); |
| 592 | if (STRINGP (item)) | 585 | if (STRINGP (item)) |
| 593 | push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil, Qnil); | 586 | push_menu_item (ENCODE_MENU_STRING (item), Qnil, Qnil, Qt, |
| 594 | else if (NILP (item)) | 587 | Qnil, Qnil, Qnil, Qnil); |
| 595 | push_left_right_boundary (); | 588 | else if (CONSP (item)) |
| 596 | else | ||
| 597 | { | 589 | { |
| 598 | CHECK_CONS (item); | 590 | item1 = XCAR (item); |
| 599 | item1 = Fcar (item); | ||
| 600 | CHECK_STRING (item1); | 591 | CHECK_STRING (item1); |
| 601 | push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil, Qnil); | 592 | push_menu_item (ENCODE_MENU_STRING (item1), Qt, XCDR (item), |
| 593 | Qt, Qnil, Qnil, Qnil, Qnil); | ||
| 602 | } | 594 | } |
| 595 | else | ||
| 596 | push_left_right_boundary (); | ||
| 597 | |||
| 603 | } | 598 | } |
| 604 | } | 599 | } |
| 605 | 600 | ||
| @@ -659,15 +654,14 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 659 | Lisp_Object keymap, tem; | 654 | Lisp_Object keymap, tem; |
| 660 | int xpos = 0, ypos = 0; | 655 | int xpos = 0, ypos = 0; |
| 661 | Lisp_Object title; | 656 | Lisp_Object title; |
| 662 | char *error_name; | 657 | char *error_name = NULL; |
| 663 | Lisp_Object selection; | 658 | Lisp_Object selection; |
| 664 | FRAME_PTR f = NULL; | 659 | FRAME_PTR f = NULL; |
| 665 | Lisp_Object x, y, window; | 660 | Lisp_Object x, y, window; |
| 666 | int keymaps = 0; | 661 | int keymaps = 0; |
| 667 | int for_click = 0; | 662 | int for_click = 0; |
| 668 | struct gcpro gcpro1; | ||
| 669 | int specpdl_count = SPECPDL_INDEX (); | 663 | int specpdl_count = SPECPDL_INDEX (); |
| 670 | 664 | struct gcpro gcpro1; | |
| 671 | 665 | ||
| 672 | #ifdef HAVE_MENUS | 666 | #ifdef HAVE_MENUS |
| 673 | if (! NILP (position)) | 667 | if (! NILP (position)) |
| @@ -677,7 +671,8 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 677 | /* Decode the first argument: find the window and the coordinates. */ | 671 | /* Decode the first argument: find the window and the coordinates. */ |
| 678 | if (EQ (position, Qt) | 672 | if (EQ (position, Qt) |
| 679 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) | 673 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) |
| 680 | || EQ (XCAR (position), Qtool_bar)))) | 674 | || EQ (XCAR (position), Qtool_bar) |
| 675 | || EQ (XCAR (position), Qmac_apple_event)))) | ||
| 681 | { | 676 | { |
| 682 | /* Use the mouse's current position. */ | 677 | /* Use the mouse's current position. */ |
| 683 | FRAME_PTR new_f = SELECTED_FRAME (); | 678 | FRAME_PTR new_f = SELECTED_FRAME (); |
| @@ -703,8 +698,8 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 703 | if (CONSP (tem)) | 698 | if (CONSP (tem)) |
| 704 | { | 699 | { |
| 705 | window = Fcar (Fcdr (position)); | 700 | window = Fcar (Fcdr (position)); |
| 706 | x = Fcar (tem); | 701 | x = XCAR (tem); |
| 707 | y = Fcar (Fcdr (tem)); | 702 | y = Fcar (XCDR (tem)); |
| 708 | } | 703 | } |
| 709 | else | 704 | else |
| 710 | { | 705 | { |
| @@ -788,11 +783,11 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 788 | 783 | ||
| 789 | /* The first keymap that has a prompt string | 784 | /* The first keymap that has a prompt string |
| 790 | supplies the menu title. */ | 785 | supplies the menu title. */ |
| 791 | for (tem = menu, i = 0; CONSP (tem); tem = Fcdr (tem)) | 786 | for (tem = menu, i = 0; CONSP (tem); tem = XCDR (tem)) |
| 792 | { | 787 | { |
| 793 | Lisp_Object prompt; | 788 | Lisp_Object prompt; |
| 794 | 789 | ||
| 795 | maps[i++] = keymap = get_keymap (Fcar (tem), 1, 0); | 790 | maps[i++] = keymap = get_keymap (XCAR (tem), 1, 0); |
| 796 | 791 | ||
| 797 | prompt = Fkeymap_prompt (keymap); | 792 | prompt = Fkeymap_prompt (keymap); |
| 798 | if (NILP (title) && !NILP (prompt)) | 793 | if (NILP (title) && !NILP (prompt)) |
| @@ -879,7 +874,8 @@ for instance using the window manager, then this produces a quit and | |||
| 879 | /* Decode the first argument: find the window or frame to use. */ | 874 | /* Decode the first argument: find the window or frame to use. */ |
| 880 | if (EQ (position, Qt) | 875 | if (EQ (position, Qt) |
| 881 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) | 876 | || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) |
| 882 | || EQ (XCAR (position), Qtool_bar)))) | 877 | || EQ (XCAR (position), Qtool_bar) |
| 878 | || EQ (XCAR (position), Qmac_apple_event)))) | ||
| 883 | { | 879 | { |
| 884 | #if 0 /* Using the frame the mouse is on may not be right. */ | 880 | #if 0 /* Using the frame the mouse is on may not be right. */ |
| 885 | /* Use the mouse's current position. */ | 881 | /* Use the mouse's current position. */ |
| @@ -947,6 +943,7 @@ for instance using the window manager, then this produces a quit and | |||
| 947 | Lisp_Object title; | 943 | Lisp_Object title; |
| 948 | char *error_name; | 944 | char *error_name; |
| 949 | Lisp_Object selection; | 945 | Lisp_Object selection; |
| 946 | int specpdl_count = SPECPDL_INDEX (); | ||
| 950 | 947 | ||
| 951 | /* Decode the dialog items from what was specified. */ | 948 | /* Decode the dialog items from what was specified. */ |
| 952 | title = Fcar (contents); | 949 | title = Fcar (contents); |
| @@ -955,11 +952,11 @@ for instance using the window manager, then this produces a quit and | |||
| 955 | list_of_panes (Fcons (contents, Qnil)); | 952 | list_of_panes (Fcons (contents, Qnil)); |
| 956 | 953 | ||
| 957 | /* Display them in a dialog box. */ | 954 | /* Display them in a dialog box. */ |
| 955 | record_unwind_protect (cleanup_popup_menu, Qnil); | ||
| 958 | BLOCK_INPUT; | 956 | BLOCK_INPUT; |
| 959 | selection = mac_dialog_show (f, 0, title, header, &error_name); | 957 | selection = mac_dialog_show (f, 0, title, header, &error_name); |
| 960 | UNBLOCK_INPUT; | 958 | UNBLOCK_INPUT; |
| 961 | 959 | unbind_to (specpdl_count, Qnil); | |
| 962 | discard_menu_items (); | ||
| 963 | 960 | ||
| 964 | if (error_name) error (error_name); | 961 | if (error_name) error (error_name); |
| 965 | return selection; | 962 | return selection; |
| @@ -971,13 +968,14 @@ for instance using the window manager, then this produces a quit and | |||
| 971 | This is called from keyboard.c when it gets the | 968 | This is called from keyboard.c when it gets the |
| 972 | MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue. | 969 | MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue. |
| 973 | 970 | ||
| 974 | To activate the menu bar, we signal to the input thread that it can | 971 | To activate the menu bar, we use the button-press event location |
| 975 | return from the WM_INITMENU message, allowing the normal Windows | 972 | that was saved in saved_menu_event_location. |
| 976 | processing of the menus. | ||
| 977 | 973 | ||
| 978 | But first we recompute the menu bar contents (the whole tree). | 974 | But first we recompute the menu bar contents (the whole tree). |
| 979 | 975 | ||
| 980 | This way we can safely execute Lisp code. */ | 976 | The reason for saving the button event until here, instead of |
| 977 | passing it to the toolkit right away, is that we can safely | ||
| 978 | execute Lisp code. */ | ||
| 981 | 979 | ||
| 982 | void | 980 | void |
| 983 | x_activate_menubar (f) | 981 | x_activate_menubar (f) |
| @@ -1074,14 +1072,12 @@ menubar_selection_callback (FRAME_PTR f, int client_data) | |||
| 1074 | buf.arg = entry; | 1072 | buf.arg = entry; |
| 1075 | kbd_buffer_store_event (&buf); | 1073 | kbd_buffer_store_event (&buf); |
| 1076 | 1074 | ||
| 1077 | f->output_data.mac->menu_command_in_progress = 0; | ||
| 1078 | f->output_data.mac->menubar_active = 0; | 1075 | f->output_data.mac->menubar_active = 0; |
| 1079 | return; | 1076 | return; |
| 1080 | } | 1077 | } |
| 1081 | i += MENU_ITEMS_ITEM_LENGTH; | 1078 | i += MENU_ITEMS_ITEM_LENGTH; |
| 1082 | } | 1079 | } |
| 1083 | } | 1080 | } |
| 1084 | f->output_data.mac->menu_command_in_progress = 0; | ||
| 1085 | f->output_data.mac->menubar_active = 0; | 1081 | f->output_data.mac->menubar_active = 0; |
| 1086 | } | 1082 | } |
| 1087 | 1083 | ||
| @@ -1127,22 +1123,18 @@ free_menubar_widget_value_tree (wv) | |||
| 1127 | UNBLOCK_INPUT; | 1123 | UNBLOCK_INPUT; |
| 1128 | } | 1124 | } |
| 1129 | 1125 | ||
| 1130 | /* Return a tree of widget_value structures for a menu bar item | 1126 | /* Set up data in menu_items for a menu bar item |
| 1131 | whose event type is ITEM_KEY (with string ITEM_NAME) | 1127 | whose event type is ITEM_KEY (with string ITEM_NAME) |
| 1132 | and whose contents come from the list of keymaps MAPS. */ | 1128 | and whose contents come from the list of keymaps MAPS. */ |
| 1133 | 1129 | ||
| 1134 | static widget_value * | 1130 | static int |
| 1135 | single_submenu (item_key, item_name, maps) | 1131 | parse_single_submenu (item_key, item_name, maps) |
| 1136 | Lisp_Object item_key, item_name, maps; | 1132 | Lisp_Object item_key, item_name, maps; |
| 1137 | { | 1133 | { |
| 1138 | widget_value *wv, *prev_wv, *save_wv, *first_wv; | ||
| 1139 | int i; | ||
| 1140 | int submenu_depth = 0; | ||
| 1141 | Lisp_Object length; | 1134 | Lisp_Object length; |
| 1142 | int len; | 1135 | int len; |
| 1143 | Lisp_Object *mapvec; | 1136 | Lisp_Object *mapvec; |
| 1144 | widget_value **submenu_stack; | 1137 | int i; |
| 1145 | int previous_items = menu_items_used; | ||
| 1146 | int top_level_items = 0; | 1138 | int top_level_items = 0; |
| 1147 | 1139 | ||
| 1148 | length = Flength (maps); | 1140 | length = Flength (maps); |
| @@ -1156,28 +1148,44 @@ single_submenu (item_key, item_name, maps) | |||
| 1156 | maps = Fcdr (maps); | 1148 | maps = Fcdr (maps); |
| 1157 | } | 1149 | } |
| 1158 | 1150 | ||
| 1159 | menu_items_n_panes = 0; | ||
| 1160 | |||
| 1161 | /* Loop over the given keymaps, making a pane for each map. | 1151 | /* Loop over the given keymaps, making a pane for each map. |
| 1162 | But don't make a pane that is empty--ignore that map instead. */ | 1152 | But don't make a pane that is empty--ignore that map instead. */ |
| 1163 | for (i = 0; i < len; i++) | 1153 | for (i = 0; i < len; i++) |
| 1164 | { | 1154 | { |
| 1165 | if (SYMBOLP (mapvec[i]) | 1155 | if (!KEYMAPP (mapvec[i])) |
| 1166 | || (CONSP (mapvec[i]) && !KEYMAPP (mapvec[i]))) | ||
| 1167 | { | 1156 | { |
| 1168 | /* Here we have a command at top level in the menu bar | 1157 | /* Here we have a command at top level in the menu bar |
| 1169 | as opposed to a submenu. */ | 1158 | as opposed to a submenu. */ |
| 1170 | top_level_items = 1; | 1159 | top_level_items = 1; |
| 1171 | push_menu_pane (Qnil, Qnil); | 1160 | push_menu_pane (Qnil, Qnil); |
| 1172 | push_menu_item (item_name, Qt, item_key, mapvec[i], | 1161 | push_menu_item (item_name, Qt, item_key, mapvec[i], |
| 1173 | Qnil, Qnil, Qnil, Qnil); | 1162 | Qnil, Qnil, Qnil, Qnil); |
| 1174 | } | 1163 | } |
| 1175 | else | 1164 | else |
| 1176 | single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); | 1165 | { |
| 1166 | Lisp_Object prompt; | ||
| 1167 | prompt = Fkeymap_prompt (mapvec[i]); | ||
| 1168 | single_keymap_panes (mapvec[i], | ||
| 1169 | !NILP (prompt) ? prompt : item_name, | ||
| 1170 | item_key, 0, 10); | ||
| 1171 | } | ||
| 1177 | } | 1172 | } |
| 1178 | 1173 | ||
| 1179 | /* Create a tree of widget_value objects | 1174 | return top_level_items; |
| 1180 | representing the panes and their items. */ | 1175 | } |
| 1176 | |||
| 1177 | /* Create a tree of widget_value objects | ||
| 1178 | representing the panes and items | ||
| 1179 | in menu_items starting at index START, up to index END. */ | ||
| 1180 | |||
| 1181 | static widget_value * | ||
| 1182 | digest_single_submenu (start, end, top_level_items) | ||
| 1183 | int start, end, top_level_items; | ||
| 1184 | { | ||
| 1185 | widget_value *wv, *prev_wv, *save_wv, *first_wv; | ||
| 1186 | int i; | ||
| 1187 | int submenu_depth = 0; | ||
| 1188 | widget_value **submenu_stack; | ||
| 1181 | 1189 | ||
| 1182 | submenu_stack | 1190 | submenu_stack |
| 1183 | = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); | 1191 | = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); |
| @@ -1191,12 +1199,12 @@ single_submenu (item_key, item_name, maps) | |||
| 1191 | save_wv = 0; | 1199 | save_wv = 0; |
| 1192 | prev_wv = 0; | 1200 | prev_wv = 0; |
| 1193 | 1201 | ||
| 1194 | /* Loop over all panes and items made during this call | 1202 | /* Loop over all panes and items made by the preceding call |
| 1195 | and construct a tree of widget_value objects. | 1203 | to parse_single_submenu and construct a tree of widget_value objects. |
| 1196 | Ignore the panes and items made by previous calls to | 1204 | Ignore the panes and items used by previous calls to |
| 1197 | single_submenu, even though those are also in menu_items. */ | 1205 | digest_single_submenu, even though those are also in menu_items. */ |
| 1198 | i = previous_items; | 1206 | i = start; |
| 1199 | while (i < menu_items_used) | 1207 | while (i < end) |
| 1200 | { | 1208 | { |
| 1201 | if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) | 1209 | if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) |
| 1202 | { | 1210 | { |
| @@ -1230,7 +1238,7 @@ single_submenu (item_key, item_name, maps) | |||
| 1230 | #ifndef HAVE_MULTILINGUAL_MENU | 1238 | #ifndef HAVE_MULTILINGUAL_MENU |
| 1231 | if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) | 1239 | if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) |
| 1232 | { | 1240 | { |
| 1233 | pane_name = ENCODE_SYSTEM (pane_name); | 1241 | pane_name = ENCODE_MENU_STRING (pane_name); |
| 1234 | AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; | 1242 | AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; |
| 1235 | } | 1243 | } |
| 1236 | #endif | 1244 | #endif |
| @@ -1266,7 +1274,7 @@ single_submenu (item_key, item_name, maps) | |||
| 1266 | { | 1274 | { |
| 1267 | /* Create a new item within current pane. */ | 1275 | /* Create a new item within current pane. */ |
| 1268 | Lisp_Object item_name, enable, descrip, def, type, selected; | 1276 | Lisp_Object item_name, enable, descrip, def, type, selected; |
| 1269 | Lisp_Object help; | 1277 | Lisp_Object help; |
| 1270 | 1278 | ||
| 1271 | item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); | 1279 | item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); |
| 1272 | enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); | 1280 | enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); |
| @@ -1277,13 +1285,13 @@ single_submenu (item_key, item_name, maps) | |||
| 1277 | help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); | 1285 | help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); |
| 1278 | 1286 | ||
| 1279 | #ifndef HAVE_MULTILINGUAL_MENU | 1287 | #ifndef HAVE_MULTILINGUAL_MENU |
| 1280 | if (STRING_MULTIBYTE (item_name)) | 1288 | if (STRING_MULTIBYTE (item_name)) |
| 1281 | { | 1289 | { |
| 1282 | item_name = ENCODE_MENU_STRING (item_name); | 1290 | item_name = ENCODE_MENU_STRING (item_name); |
| 1283 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; | 1291 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
| 1284 | } | 1292 | } |
| 1285 | 1293 | ||
| 1286 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) | 1294 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
| 1287 | { | 1295 | { |
| 1288 | descrip = ENCODE_MENU_STRING (descrip); | 1296 | descrip = ENCODE_MENU_STRING (descrip); |
| 1289 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; | 1297 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
| @@ -1315,7 +1323,7 @@ single_submenu (item_key, item_name, maps) | |||
| 1315 | abort (); | 1323 | abort (); |
| 1316 | 1324 | ||
| 1317 | wv->selected = !NILP (selected); | 1325 | wv->selected = !NILP (selected); |
| 1318 | if (!STRINGP (help)) | 1326 | if (! STRINGP (help)) |
| 1319 | help = Qnil; | 1327 | help = Qnil; |
| 1320 | 1328 | ||
| 1321 | wv->help = help; | 1329 | wv->help = help; |
| @@ -1337,6 +1345,7 @@ single_submenu (item_key, item_name, maps) | |||
| 1337 | 1345 | ||
| 1338 | return first_wv; | 1346 | return first_wv; |
| 1339 | } | 1347 | } |
| 1348 | |||
| 1340 | /* Walk through the widget_value tree starting at FIRST_WV and update | 1349 | /* Walk through the widget_value tree starting at FIRST_WV and update |
| 1341 | the char * pointers from the corresponding lisp values. | 1350 | the char * pointers from the corresponding lisp values. |
| 1342 | We do this after building the whole tree, since GC may happen while the | 1351 | We do this after building the whole tree, since GC may happen while the |
| @@ -1418,20 +1427,28 @@ static void | |||
| 1418 | install_menu_quit_handler (MenuHandle menu_handle) | 1427 | install_menu_quit_handler (MenuHandle menu_handle) |
| 1419 | { | 1428 | { |
| 1420 | #ifdef HAVE_CANCELMENUTRACKING | 1429 | #ifdef HAVE_CANCELMENUTRACKING |
| 1421 | EventHandlerUPP handler = NewEventHandlerUPP(menu_quit_handler); | ||
| 1422 | UInt32 numTypes = 1; | ||
| 1423 | EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; | 1430 | EventTypeSpec typesList[] = { { kEventClassKeyboard, kEventRawKeyDown } }; |
| 1424 | int i = MIN_MENU_ID; | 1431 | int i = MIN_MENU_ID; |
| 1425 | MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i); | 1432 | MenuHandle menu = menu_handle ? menu_handle : GetMenuHandle (i); |
| 1426 | 1433 | ||
| 1427 | while (menu != NULL) | 1434 | while (menu != NULL) |
| 1428 | { | 1435 | { |
| 1429 | InstallMenuEventHandler (menu, handler, GetEventTypeCount (typesList), | 1436 | InstallMenuEventHandler (menu, menu_quit_handler, |
| 1437 | GetEventTypeCount (typesList), | ||
| 1430 | typesList, menu_handle, NULL); | 1438 | typesList, menu_handle, NULL); |
| 1431 | if (menu_handle) break; | 1439 | if (menu_handle) break; |
| 1432 | menu = GetMenuHandle (++i); | 1440 | menu = GetMenuHandle (++i); |
| 1433 | } | 1441 | } |
| 1434 | DisposeEventHandlerUPP (handler); | 1442 | |
| 1443 | i = menu_handle ? MIN_POPUP_SUBMENU_ID : MIN_SUBMENU_ID; | ||
| 1444 | menu = GetMenuHandle (i); | ||
| 1445 | while (menu != NULL) | ||
| 1446 | { | ||
| 1447 | InstallMenuEventHandler (menu, menu_quit_handler, | ||
| 1448 | GetEventTypeCount (typesList), | ||
| 1449 | typesList, menu_handle, NULL); | ||
| 1450 | menu = GetMenuHandle (++i); | ||
| 1451 | } | ||
| 1435 | #endif /* HAVE_CANCELMENUTRACKING */ | 1452 | #endif /* HAVE_CANCELMENUTRACKING */ |
| 1436 | } | 1453 | } |
| 1437 | 1454 | ||
| @@ -1448,7 +1465,9 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1448 | int menubar_widget = f->output_data.mac->menubar_widget; | 1465 | int menubar_widget = f->output_data.mac->menubar_widget; |
| 1449 | Lisp_Object items; | 1466 | Lisp_Object items; |
| 1450 | widget_value *wv, *first_wv, *prev_wv = 0; | 1467 | widget_value *wv, *first_wv, *prev_wv = 0; |
| 1451 | int i; | 1468 | int i, last_i = 0; |
| 1469 | int *submenu_start, *submenu_end; | ||
| 1470 | int *submenu_top_level_items, *submenu_n_panes; | ||
| 1452 | 1471 | ||
| 1453 | /* We must not change the menubar when actually in use. */ | 1472 | /* We must not change the menubar when actually in use. */ |
| 1454 | if (f->output_data.mac->menubar_active) | 1473 | if (f->output_data.mac->menubar_active) |
| @@ -1461,14 +1480,6 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1461 | else if (pending_menu_activation && !deep_p) | 1480 | else if (pending_menu_activation && !deep_p) |
| 1462 | deep_p = 1; | 1481 | deep_p = 1; |
| 1463 | 1482 | ||
| 1464 | wv = xmalloc_widget_value (); | ||
| 1465 | wv->name = "menubar"; | ||
| 1466 | wv->value = 0; | ||
| 1467 | wv->enabled = 1; | ||
| 1468 | wv->button_type = BUTTON_TYPE_NONE; | ||
| 1469 | wv->help = Qnil; | ||
| 1470 | first_wv = wv; | ||
| 1471 | |||
| 1472 | if (deep_p) | 1483 | if (deep_p) |
| 1473 | { | 1484 | { |
| 1474 | /* Make a widget-value tree representing the entire menu trees. */ | 1485 | /* Make a widget-value tree representing the entire menu trees. */ |
| @@ -1503,6 +1514,7 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1503 | 1514 | ||
| 1504 | /* Run the Lucid hook. */ | 1515 | /* Run the Lucid hook. */ |
| 1505 | safe_run_hooks (Qactivate_menubar_hook); | 1516 | safe_run_hooks (Qactivate_menubar_hook); |
| 1517 | |||
| 1506 | /* If it has changed current-menubar from previous value, | 1518 | /* If it has changed current-menubar from previous value, |
| 1507 | really recompute the menubar from the value. */ | 1519 | really recompute the menubar from the value. */ |
| 1508 | if (! NILP (Vlucid_menu_bar_dirty_flag)) | 1520 | if (! NILP (Vlucid_menu_bar_dirty_flag)) |
| @@ -1517,21 +1529,56 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1517 | bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, | 1529 | bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, |
| 1518 | previous_menu_items_used * sizeof (Lisp_Object)); | 1530 | previous_menu_items_used * sizeof (Lisp_Object)); |
| 1519 | 1531 | ||
| 1520 | /* Fill in the current menu bar contents. */ | 1532 | /* Fill in menu_items with the current menu bar contents. |
| 1533 | This can evaluate Lisp code. */ | ||
| 1521 | menu_items = f->menu_bar_vector; | 1534 | menu_items = f->menu_bar_vector; |
| 1522 | menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; | 1535 | menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; |
| 1536 | submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); | ||
| 1537 | submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); | ||
| 1538 | submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int)); | ||
| 1539 | submenu_top_level_items | ||
| 1540 | = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); | ||
| 1523 | init_menu_items (); | 1541 | init_menu_items (); |
| 1524 | for (i = 0; i < XVECTOR (items)->size; i += 4) | 1542 | for (i = 0; i < XVECTOR (items)->size; i += 4) |
| 1525 | { | 1543 | { |
| 1526 | Lisp_Object key, string, maps; | 1544 | Lisp_Object key, string, maps; |
| 1527 | 1545 | ||
| 1546 | last_i = i; | ||
| 1547 | |||
| 1528 | key = XVECTOR (items)->contents[i]; | 1548 | key = XVECTOR (items)->contents[i]; |
| 1529 | string = XVECTOR (items)->contents[i + 1]; | 1549 | string = XVECTOR (items)->contents[i + 1]; |
| 1530 | maps = XVECTOR (items)->contents[i + 2]; | 1550 | maps = XVECTOR (items)->contents[i + 2]; |
| 1531 | if (NILP (string)) | 1551 | if (NILP (string)) |
| 1532 | break; | 1552 | break; |
| 1533 | 1553 | ||
| 1534 | wv = single_submenu (key, string, maps); | 1554 | submenu_start[i] = menu_items_used; |
| 1555 | |||
| 1556 | menu_items_n_panes = 0; | ||
| 1557 | submenu_top_level_items[i] | ||
| 1558 | = parse_single_submenu (key, string, maps); | ||
| 1559 | submenu_n_panes[i] = menu_items_n_panes; | ||
| 1560 | |||
| 1561 | submenu_end[i] = menu_items_used; | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | finish_menu_items (); | ||
| 1565 | |||
| 1566 | /* Convert menu_items into widget_value trees | ||
| 1567 | to display the menu. This cannot evaluate Lisp code. */ | ||
| 1568 | |||
| 1569 | wv = xmalloc_widget_value (); | ||
| 1570 | wv->name = "menubar"; | ||
| 1571 | wv->value = 0; | ||
| 1572 | wv->enabled = 1; | ||
| 1573 | wv->button_type = BUTTON_TYPE_NONE; | ||
| 1574 | wv->help = Qnil; | ||
| 1575 | first_wv = wv; | ||
| 1576 | |||
| 1577 | for (i = 0; i < last_i; i += 4) | ||
| 1578 | { | ||
| 1579 | menu_items_n_panes = submenu_n_panes[i]; | ||
| 1580 | wv = digest_single_submenu (submenu_start[i], submenu_end[i], | ||
| 1581 | submenu_top_level_items[i]); | ||
| 1535 | if (prev_wv) | 1582 | if (prev_wv) |
| 1536 | prev_wv->next = wv; | 1583 | prev_wv->next = wv; |
| 1537 | else | 1584 | else |
| @@ -1542,8 +1589,6 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1542 | prev_wv = wv; | 1589 | prev_wv = wv; |
| 1543 | } | 1590 | } |
| 1544 | 1591 | ||
| 1545 | finish_menu_items (); | ||
| 1546 | |||
| 1547 | set_buffer_internal_1 (prev); | 1592 | set_buffer_internal_1 (prev); |
| 1548 | unbind_to (specpdl_count, Qnil); | 1593 | unbind_to (specpdl_count, Qnil); |
| 1549 | 1594 | ||
| @@ -1552,22 +1597,18 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1552 | 1597 | ||
| 1553 | for (i = 0; i < previous_menu_items_used; i++) | 1598 | for (i = 0; i < previous_menu_items_used; i++) |
| 1554 | if (menu_items_used == i | 1599 | if (menu_items_used == i |
| 1555 | || (NILP (Fequal (previous_items[i], | 1600 | || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) |
| 1556 | XVECTOR (menu_items)->contents[i])))) | ||
| 1557 | break; | 1601 | break; |
| 1558 | if (i == menu_items_used && i == previous_menu_items_used && i != 0) | 1602 | if (i == menu_items_used && i == previous_menu_items_used && i != 0) |
| 1559 | { | 1603 | { |
| 1560 | free_menubar_widget_value_tree (first_wv); | 1604 | free_menubar_widget_value_tree (first_wv); |
| 1561 | menu_items = Qnil; | 1605 | discard_menu_items (); |
| 1562 | 1606 | ||
| 1563 | return; | 1607 | return; |
| 1564 | } | 1608 | } |
| 1565 | 1609 | ||
| 1566 | /* Now GC cannot happen during the lifetime of the widget_value, | 1610 | /* Now GC cannot happen during the lifetime of the widget_value, |
| 1567 | so it's safe to store data from a Lisp_String, as long as | 1611 | so it's safe to store data from a Lisp_String. */ |
| 1568 | local copies are made when the actual menu is created. | ||
| 1569 | Windows takes care of this for normal string items, but | ||
| 1570 | not for owner-drawn items or additional item-info. */ | ||
| 1571 | wv = first_wv->contents; | 1612 | wv = first_wv->contents; |
| 1572 | for (i = 0; i < XVECTOR (items)->size; i += 4) | 1613 | for (i = 0; i < XVECTOR (items)->size; i += 4) |
| 1573 | { | 1614 | { |
| @@ -1582,13 +1623,21 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1582 | 1623 | ||
| 1583 | f->menu_bar_vector = menu_items; | 1624 | f->menu_bar_vector = menu_items; |
| 1584 | f->menu_bar_items_used = menu_items_used; | 1625 | f->menu_bar_items_used = menu_items_used; |
| 1585 | menu_items = Qnil; | 1626 | discard_menu_items (); |
| 1586 | } | 1627 | } |
| 1587 | else | 1628 | else |
| 1588 | { | 1629 | { |
| 1589 | /* Make a widget-value tree containing | 1630 | /* Make a widget-value tree containing |
| 1590 | just the top level menu bar strings. */ | 1631 | just the top level menu bar strings. */ |
| 1591 | 1632 | ||
| 1633 | wv = xmalloc_widget_value (); | ||
| 1634 | wv->name = "menubar"; | ||
| 1635 | wv->value = 0; | ||
| 1636 | wv->enabled = 1; | ||
| 1637 | wv->button_type = BUTTON_TYPE_NONE; | ||
| 1638 | wv->help = Qnil; | ||
| 1639 | first_wv = wv; | ||
| 1640 | |||
| 1592 | items = FRAME_MENU_BAR_ITEMS (f); | 1641 | items = FRAME_MENU_BAR_ITEMS (f); |
| 1593 | for (i = 0; i < XVECTOR (items)->size; i += 4) | 1642 | for (i = 0; i < XVECTOR (items)->size; i += 4) |
| 1594 | { | 1643 | { |
| @@ -1676,6 +1725,7 @@ initialize_frame_menubar (f) | |||
| 1676 | set_frame_menubar (f, 1, 1); | 1725 | set_frame_menubar (f, 1, 1); |
| 1677 | } | 1726 | } |
| 1678 | 1727 | ||
| 1728 | |||
| 1679 | /* Get rid of the menu bar of frame F, and free its storage. | 1729 | /* Get rid of the menu bar of frame F, and free its storage. |
| 1680 | This is used when deleting a frame, and when turning off the menu bar. */ | 1730 | This is used when deleting a frame, and when turning off the menu bar. */ |
| 1681 | 1731 | ||
| @@ -1683,7 +1733,7 @@ void | |||
| 1683 | free_frame_menubar (f) | 1733 | free_frame_menubar (f) |
| 1684 | FRAME_PTR f; | 1734 | FRAME_PTR f; |
| 1685 | { | 1735 | { |
| 1686 | f->output_data.mac->menubar_widget = NULL; | 1736 | f->output_data.mac->menubar_widget = 0; |
| 1687 | } | 1737 | } |
| 1688 | 1738 | ||
| 1689 | 1739 | ||
| @@ -1760,6 +1810,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1760 | Lisp_Object *subprefix_stack | 1810 | Lisp_Object *subprefix_stack |
| 1761 | = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); | 1811 | = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); |
| 1762 | int submenu_depth = 0; | 1812 | int submenu_depth = 0; |
| 1813 | |||
| 1763 | int first_pane; | 1814 | int first_pane; |
| 1764 | int specpdl_count = SPECPDL_INDEX (); | 1815 | int specpdl_count = SPECPDL_INDEX (); |
| 1765 | 1816 | ||
| @@ -1813,12 +1864,14 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1813 | /* Create a new pane. */ | 1864 | /* Create a new pane. */ |
| 1814 | Lisp_Object pane_name, prefix; | 1865 | Lisp_Object pane_name, prefix; |
| 1815 | char *pane_string; | 1866 | char *pane_string; |
| 1867 | |||
| 1816 | pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); | 1868 | pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); |
| 1817 | prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); | 1869 | prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); |
| 1870 | |||
| 1818 | #ifndef HAVE_MULTILINGUAL_MENU | 1871 | #ifndef HAVE_MULTILINGUAL_MENU |
| 1819 | if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) | 1872 | if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) |
| 1820 | { | 1873 | { |
| 1821 | pane_name = ENCODE_SYSTEM (pane_name); | 1874 | pane_name = ENCODE_MENU_STRING (pane_name); |
| 1822 | AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; | 1875 | AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; |
| 1823 | } | 1876 | } |
| 1824 | #endif | 1877 | #endif |
| @@ -1861,14 +1914,13 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1861 | { | 1914 | { |
| 1862 | /* Create a new item within current pane. */ | 1915 | /* Create a new item within current pane. */ |
| 1863 | Lisp_Object item_name, enable, descrip, def, type, selected, help; | 1916 | Lisp_Object item_name, enable, descrip, def, type, selected, help; |
| 1864 | |||
| 1865 | item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); | 1917 | item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); |
| 1866 | enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); | 1918 | enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); |
| 1867 | descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); | 1919 | descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); |
| 1868 | def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); | 1920 | def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); |
| 1869 | type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE); | 1921 | type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE); |
| 1870 | selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED); | 1922 | selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED); |
| 1871 | help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); | 1923 | help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); |
| 1872 | 1924 | ||
| 1873 | #ifndef HAVE_MULTILINGUAL_MENU | 1925 | #ifndef HAVE_MULTILINGUAL_MENU |
| 1874 | if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) | 1926 | if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) |
| @@ -1876,8 +1928,9 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1876 | item_name = ENCODE_MENU_STRING (item_name); | 1928 | item_name = ENCODE_MENU_STRING (item_name); |
| 1877 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; | 1929 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
| 1878 | } | 1930 | } |
| 1931 | |||
| 1879 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) | 1932 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
| 1880 | { | 1933 | { |
| 1881 | descrip = ENCODE_MENU_STRING (descrip); | 1934 | descrip = ENCODE_MENU_STRING (descrip); |
| 1882 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; | 1935 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
| 1883 | } | 1936 | } |
| @@ -1907,7 +1960,8 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1907 | abort (); | 1960 | abort (); |
| 1908 | 1961 | ||
| 1909 | wv->selected = !NILP (selected); | 1962 | wv->selected = !NILP (selected); |
| 1910 | if (!STRINGP (help)) | 1963 | |
| 1964 | if (! STRINGP (help)) | ||
| 1911 | help = Qnil; | 1965 | help = Qnil; |
| 1912 | 1966 | ||
| 1913 | wv->help = help; | 1967 | wv->help = help; |
| @@ -1934,6 +1988,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1934 | if (STRING_MULTIBYTE (title)) | 1988 | if (STRING_MULTIBYTE (title)) |
| 1935 | title = ENCODE_MENU_STRING (title); | 1989 | title = ENCODE_MENU_STRING (title); |
| 1936 | #endif | 1990 | #endif |
| 1991 | |||
| 1937 | wv_title->name = (char *) SDATA (title); | 1992 | wv_title->name = (char *) SDATA (title); |
| 1938 | wv_title->enabled = FALSE; | 1993 | wv_title->enabled = FALSE; |
| 1939 | wv_title->title = TRUE; | 1994 | wv_title->title = TRUE; |
| @@ -1957,7 +2012,6 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1957 | pos.v = y; | 2012 | pos.v = y; |
| 1958 | 2013 | ||
| 1959 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); | 2014 | SetPortWindowPort (FRAME_MAC_WINDOW (f)); |
| 1960 | |||
| 1961 | LocalToGlobal (&pos); | 2015 | LocalToGlobal (&pos); |
| 1962 | 2016 | ||
| 1963 | /* No selection has been chosen yet. */ | 2017 | /* No selection has been chosen yet. */ |
| @@ -2167,11 +2221,11 @@ static char * button_names [] = { | |||
| 2167 | "button6", "button7", "button8", "button9", "button10" }; | 2221 | "button6", "button7", "button8", "button9", "button10" }; |
| 2168 | 2222 | ||
| 2169 | static Lisp_Object | 2223 | static Lisp_Object |
| 2170 | mac_dialog_show (f, keymaps, title, header, error) | 2224 | mac_dialog_show (f, keymaps, title, header, error_name) |
| 2171 | FRAME_PTR f; | 2225 | FRAME_PTR f; |
| 2172 | int keymaps; | 2226 | int keymaps; |
| 2173 | Lisp_Object title, header; | 2227 | Lisp_Object title, header; |
| 2174 | char **error; | 2228 | char **error_name; |
| 2175 | { | 2229 | { |
| 2176 | int i, nb_buttons=0; | 2230 | int i, nb_buttons=0; |
| 2177 | char dialog_name[6]; | 2231 | char dialog_name[6]; |
| @@ -2184,11 +2238,11 @@ mac_dialog_show (f, keymaps, title, header, error) | |||
| 2184 | /* 1 means we've seen the boundary between left-hand elts and right-hand. */ | 2238 | /* 1 means we've seen the boundary between left-hand elts and right-hand. */ |
| 2185 | int boundary_seen = 0; | 2239 | int boundary_seen = 0; |
| 2186 | 2240 | ||
| 2187 | *error = NULL; | 2241 | *error_name = NULL; |
| 2188 | 2242 | ||
| 2189 | if (menu_items_n_panes > 1) | 2243 | if (menu_items_n_panes > 1) |
| 2190 | { | 2244 | { |
| 2191 | *error = "Multiple panes in dialog box"; | 2245 | *error_name = "Multiple panes in dialog box"; |
| 2192 | return Qnil; | 2246 | return Qnil; |
| 2193 | } | 2247 | } |
| 2194 | 2248 | ||
| @@ -2216,18 +2270,16 @@ mac_dialog_show (f, keymaps, title, header, error) | |||
| 2216 | { | 2270 | { |
| 2217 | 2271 | ||
| 2218 | /* Create a new item within current pane. */ | 2272 | /* Create a new item within current pane. */ |
| 2219 | Lisp_Object item_name, enable, descrip, help; | 2273 | Lisp_Object item_name, enable, descrip; |
| 2220 | |||
| 2221 | item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; | 2274 | item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; |
| 2222 | enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; | 2275 | enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; |
| 2223 | descrip | 2276 | descrip |
| 2224 | = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; | 2277 | = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; |
| 2225 | help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP]; | ||
| 2226 | 2278 | ||
| 2227 | if (NILP (item_name)) | 2279 | if (NILP (item_name)) |
| 2228 | { | 2280 | { |
| 2229 | free_menubar_widget_value_tree (first_wv); | 2281 | free_menubar_widget_value_tree (first_wv); |
| 2230 | *error = "Submenu in dialog items"; | 2282 | *error_name = "Submenu in dialog items"; |
| 2231 | return Qnil; | 2283 | return Qnil; |
| 2232 | } | 2284 | } |
| 2233 | if (EQ (item_name, Qquote)) | 2285 | if (EQ (item_name, Qquote)) |
| @@ -2241,7 +2293,7 @@ mac_dialog_show (f, keymaps, title, header, error) | |||
| 2241 | if (nb_buttons >= 9) | 2293 | if (nb_buttons >= 9) |
| 2242 | { | 2294 | { |
| 2243 | free_menubar_widget_value_tree (first_wv); | 2295 | free_menubar_widget_value_tree (first_wv); |
| 2244 | *error = "Too many dialog items"; | 2296 | *error_name = "Too many dialog items"; |
| 2245 | return Qnil; | 2297 | return Qnil; |
| 2246 | } | 2298 | } |
| 2247 | 2299 | ||
| @@ -2304,8 +2356,8 @@ mac_dialog_show (f, keymaps, title, header, error) | |||
| 2304 | /* Free the widget_value objects we used to specify the contents. */ | 2356 | /* Free the widget_value objects we used to specify the contents. */ |
| 2305 | free_menubar_widget_value_tree (first_wv); | 2357 | free_menubar_widget_value_tree (first_wv); |
| 2306 | 2358 | ||
| 2307 | /* Find the selected item, and its pane, to return the proper | 2359 | /* Find the selected item, and its pane, to return |
| 2308 | value. */ | 2360 | the proper value. */ |
| 2309 | if (menu_item_selection != 0) | 2361 | if (menu_item_selection != 0) |
| 2310 | { | 2362 | { |
| 2311 | Lisp_Object prefix; | 2363 | Lisp_Object prefix; |
| @@ -2322,6 +2374,12 @@ mac_dialog_show (f, keymaps, title, header, error) | |||
| 2322 | = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; | 2374 | = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; |
| 2323 | i += MENU_ITEMS_PANE_LENGTH; | 2375 | i += MENU_ITEMS_PANE_LENGTH; |
| 2324 | } | 2376 | } |
| 2377 | else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) | ||
| 2378 | { | ||
| 2379 | /* This is the boundary between left-side elts and | ||
| 2380 | right-side elts. */ | ||
| 2381 | ++i; | ||
| 2382 | } | ||
| 2325 | else | 2383 | else |
| 2326 | { | 2384 | { |
| 2327 | entry | 2385 | entry |
| @@ -2340,6 +2398,9 @@ mac_dialog_show (f, keymaps, title, header, error) | |||
| 2340 | } | 2398 | } |
| 2341 | } | 2399 | } |
| 2342 | } | 2400 | } |
| 2401 | else | ||
| 2402 | /* Make "Cancel" equivalent to C-g. */ | ||
| 2403 | Fsignal (Qquit, Qnil); | ||
| 2343 | 2404 | ||
| 2344 | return Qnil; | 2405 | return Qnil; |
| 2345 | } | 2406 | } |
| @@ -2365,7 +2426,11 @@ static void | |||
| 2365 | add_menu_item (MenuHandle menu, widget_value *wv, int submenu, | 2426 | add_menu_item (MenuHandle menu, widget_value *wv, int submenu, |
| 2366 | int force_disable) | 2427 | int force_disable) |
| 2367 | { | 2428 | { |
| 2429 | #if TARGET_API_MAC_CARBON | ||
| 2430 | CFStringRef item_name; | ||
| 2431 | #else | ||
| 2368 | Str255 item_name; | 2432 | Str255 item_name; |
| 2433 | #endif | ||
| 2369 | int pos; | 2434 | int pos; |
| 2370 | 2435 | ||
| 2371 | if (name_is_separator (wv->name)) | 2436 | if (name_is_separator (wv->name)) |
| @@ -2376,42 +2441,49 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu, | |||
| 2376 | 2441 | ||
| 2377 | #if TARGET_API_MAC_CARBON | 2442 | #if TARGET_API_MAC_CARBON |
| 2378 | pos = CountMenuItems (menu); | 2443 | pos = CountMenuItems (menu); |
| 2379 | #else | ||
| 2380 | pos = CountMItems (menu); | ||
| 2381 | #endif | ||
| 2382 | 2444 | ||
| 2383 | strcpy (item_name, ""); | 2445 | item_name = cfstring_create_with_utf8_cstring (wv->name); |
| 2384 | strncat (item_name, wv->name, 255); | 2446 | |
| 2385 | if (wv->key != NULL) | 2447 | if (wv->key != NULL) |
| 2386 | { | 2448 | { |
| 2387 | strncat (item_name, " ", 255); | 2449 | CFStringRef name, key; |
| 2388 | strncat (item_name, wv->key, 255); | 2450 | |
| 2451 | name = item_name; | ||
| 2452 | key = cfstring_create_with_utf8_cstring (wv->key); | ||
| 2453 | item_name = CFStringCreateWithFormat (NULL, NULL, CFSTR ("%@ %@"), | ||
| 2454 | name, key); | ||
| 2455 | CFRelease (name); | ||
| 2456 | CFRelease (key); | ||
| 2389 | } | 2457 | } |
| 2390 | item_name[255] = 0; | ||
| 2391 | #if TARGET_API_MAC_CARBON | ||
| 2392 | { | ||
| 2393 | CFStringRef string = cfstring_create_with_utf8_cstring (item_name); | ||
| 2394 | 2458 | ||
| 2395 | SetMenuItemTextWithCFString (menu, pos, string); | 2459 | SetMenuItemTextWithCFString (menu, pos, item_name); |
| 2396 | CFRelease (string); | 2460 | CFRelease (item_name); |
| 2397 | } | 2461 | |
| 2398 | #else | 2462 | if (wv->enabled && !force_disable) |
| 2463 | EnableMenuItem (menu, pos); | ||
| 2464 | else | ||
| 2465 | DisableMenuItem (menu, pos); | ||
| 2466 | #else /* ! TARGET_API_MAC_CARBON */ | ||
| 2467 | pos = CountMItems (menu); | ||
| 2468 | |||
| 2469 | item_name[sizeof (item_name) - 1] = '\0'; | ||
| 2470 | strncpy (item_name, wv->name, sizeof (item_name) - 1); | ||
| 2471 | if (wv->key != NULL) | ||
| 2472 | { | ||
| 2473 | int len = strlen (item_name); | ||
| 2474 | |||
| 2475 | strncpy (item_name + len, " ", sizeof (item_name) - 1 - len); | ||
| 2476 | len = strlen (item_name); | ||
| 2477 | strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len); | ||
| 2478 | } | ||
| 2399 | c2pstr (item_name); | 2479 | c2pstr (item_name); |
| 2400 | SetMenuItemText (menu, pos, item_name); | 2480 | SetMenuItemText (menu, pos, item_name); |
| 2401 | #endif | ||
| 2402 | 2481 | ||
| 2403 | if (wv->enabled && !force_disable) | 2482 | if (wv->enabled && !force_disable) |
| 2404 | #if TARGET_API_MAC_CARBON | ||
| 2405 | EnableMenuItem (menu, pos); | ||
| 2406 | #else | ||
| 2407 | EnableItem (menu, pos); | 2483 | EnableItem (menu, pos); |
| 2408 | #endif | ||
| 2409 | else | 2484 | else |
| 2410 | #if TARGET_API_MAC_CARBON | ||
| 2411 | DisableMenuItem (menu, pos); | ||
| 2412 | #else | ||
| 2413 | DisableItem (menu, pos); | 2485 | DisableItem (menu, pos); |
| 2414 | #endif | 2486 | #endif /* ! TARGET_API_MAC_CARBON */ |
| 2415 | 2487 | ||
| 2416 | /* Draw radio buttons and tickboxes. */ | 2488 | /* Draw radio buttons and tickboxes. */ |
| 2417 | { | 2489 | { |
| @@ -2425,7 +2497,7 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu, | |||
| 2425 | SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); | 2497 | SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); |
| 2426 | } | 2498 | } |
| 2427 | 2499 | ||
| 2428 | if (submenu != NULL) | 2500 | if (submenu != 0) |
| 2429 | SetMenuItemHierarchicalID (menu, pos, submenu); | 2501 | SetMenuItemHierarchicalID (menu, pos, submenu); |
| 2430 | } | 2502 | } |
| 2431 | 2503 | ||
| @@ -2444,7 +2516,7 @@ fill_submenu (MenuHandle menu, widget_value *wv) | |||
| 2444 | add_menu_item (menu, wv, cur_submenu, 0); | 2516 | add_menu_item (menu, wv, cur_submenu, 0); |
| 2445 | } | 2517 | } |
| 2446 | else | 2518 | else |
| 2447 | add_menu_item (menu, wv, NULL, 0); | 2519 | add_menu_item (menu, wv, 0, 0); |
| 2448 | } | 2520 | } |
| 2449 | 2521 | ||
| 2450 | 2522 | ||
| @@ -2463,7 +2535,7 @@ fill_menu (MenuHandle menu, widget_value *wv) | |||
| 2463 | add_menu_item (menu, wv, cur_submenu, 0); | 2535 | add_menu_item (menu, wv, cur_submenu, 0); |
| 2464 | } | 2536 | } |
| 2465 | else | 2537 | else |
| 2466 | add_menu_item (menu, wv, NULL, 0); | 2538 | add_menu_item (menu, wv, 0, 0); |
| 2467 | } | 2539 | } |
| 2468 | 2540 | ||
| 2469 | /* Construct native Mac OS menubar based on widget_value tree. */ | 2541 | /* Construct native Mac OS menubar based on widget_value tree. */ |
| @@ -2493,7 +2565,6 @@ fill_menubar (widget_value *wv) | |||
| 2493 | } | 2565 | } |
| 2494 | 2566 | ||
| 2495 | #endif /* HAVE_MENUS */ | 2567 | #endif /* HAVE_MENUS */ |
| 2496 | |||
| 2497 | 2568 | ||
| 2498 | void | 2569 | void |
| 2499 | syms_of_macmenu () | 2570 | syms_of_macmenu () |