comparison src/macmenu.c @ 83474:d08a7ef0cb8a

Merged from emacs@sv.gnu.org Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-91 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-92 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-93 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-94 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-95 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-96 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-97 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-98 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-99 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-100 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-101 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-102 Merge from erc--emacs--0 * emacs@sv.gnu.org/emacs--devo--0--patch-103 Update from CVS: src/regex.c (extend_range_table_work_area): Fix typo. * emacs@sv.gnu.org/emacs--devo--0--patch-104 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-30 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-31 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-32 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-33 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-34 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-35 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-36 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-514
author Karoly Lorentey <lorentey@elte.hu>
date Mon, 20 Feb 2006 16:30:15 +0000
parents 03e41ed4f4d9
children 53d05914b117 d1c5430c5bff
comparison
equal deleted inserted replaced
83473:428d132b4028 83474:d08a7ef0cb8a
187 static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 187 static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
188 int, int)); 188 int, int));
189 static void list_of_panes P_ ((Lisp_Object)); 189 static void list_of_panes P_ ((Lisp_Object));
190 static void list_of_items P_ ((Lisp_Object)); 190 static void list_of_items P_ ((Lisp_Object));
191 191
192 static void fill_submenu (MenuHandle, widget_value *); 192 static int fill_menu P_ ((MenuHandle, widget_value *, int));
193 static void fill_menubar (widget_value *); 193 static void fill_menubar P_ ((widget_value *, int));
194 static void dispose_menus P_ ((int));
194 195
195 196
196 /* This holds a Lisp vector that holds the results of decoding 197 /* This holds a Lisp vector that holds the results of decoding
197 the keymaps or alist-of-alists that specify a menu. 198 the keymaps or alist-of-alists that specify a menu.
198 199
244 excluding those within submenus. */ 245 excluding those within submenus. */
245 static int menu_items_n_panes; 246 static int menu_items_n_panes;
246 247
247 /* Current depth within submenus. */ 248 /* Current depth within submenus. */
248 static int menu_items_submenu_depth; 249 static int menu_items_submenu_depth;
249
250 /* Flag which when set indicates a dialog or menu has been posted by
251 Xt on behalf of one of the widget sets. */
252 static int popup_activated_flag;
253
254 /* Index of the next submenu */
255 static int submenu_id;
256
257 static int next_menubar_widget_id;
258 250
259 /* This is set nonzero after the user activates the menu bar, and set 251 /* This is set nonzero after the user activates the menu bar, and set
260 to zero again after the menu bars are redisplayed by prepare_menu_bar. 252 to zero again after the menu bars are redisplayed by prepare_menu_bar.
261 While it is nonzero, all calls to set_frame_menubar go deep. 253 While it is nonzero, all calls to set_frame_menubar go deep.
262 254
1438 typesList, menu_handle, NULL); 1430 typesList, menu_handle, NULL);
1439 if (menu_handle) break; 1431 if (menu_handle) break;
1440 menu = GetMenuHandle (++i); 1432 menu = GetMenuHandle (++i);
1441 } 1433 }
1442 1434
1443 i = menu_handle ? MIN_POPUP_SUBMENU_ID : MIN_SUBMENU_ID; 1435 i = menu_handle ? MIN_POPUP_SUBMENU_ID : MIN_SUBMENU_ID;
1444 menu = GetMenuHandle (i); 1436 menu = GetMenuHandle (i);
1445 while (menu != NULL) 1437 while (menu != NULL)
1446 { 1438 {
1447 InstallMenuEventHandler (menu, menu_quit_handler, 1439 InstallMenuEventHandler (menu, menu_quit_handler,
1448 GetEventTypeCount (typesList), 1440 GetEventTypeCount (typesList),
1677 BLOCK_INPUT; 1669 BLOCK_INPUT;
1678 1670
1679 /* Non-null value to indicate menubar has already been "created". */ 1671 /* Non-null value to indicate menubar has already been "created". */
1680 f->output_data.mac->menubar_widget = 1; 1672 f->output_data.mac->menubar_widget = 1;
1681 1673
1682 { 1674 fill_menubar (first_wv->contents, deep_p);
1683 int i = MIN_MENU_ID;
1684 MenuHandle menu = GetMenuHandle (i);
1685 while (menu != NULL)
1686 {
1687 DeleteMenu (i);
1688 DisposeMenu (menu);
1689 menu = GetMenuHandle (++i);
1690 }
1691
1692 i = MIN_SUBMENU_ID;
1693 menu = GetMenuHandle (i);
1694 while (menu != NULL)
1695 {
1696 DeleteMenu (i);
1697 DisposeMenu (menu);
1698 menu = GetMenuHandle (++i);
1699 }
1700 }
1701
1702 fill_menubar (first_wv->contents);
1703 1675
1704 /* Add event handler so we can detect C-g. */ 1676 /* Add event handler so we can detect C-g. */
1705 install_menu_quit_handler (NULL); 1677 install_menu_quit_handler (NULL);
1706 free_menubar_widget_value_tree (first_wv); 1678 free_menubar_widget_value_tree (first_wv);
1707 1679
1708 UNBLOCK_INPUT; 1680 UNBLOCK_INPUT;
1709 } 1681 }
1710
1711 /* Called from Fx_create_frame to create the initial menubar of a frame
1712 before it is mapped, so that the window is mapped with the menubar already
1713 there instead of us tacking it on later and thrashing the window after it
1714 is visible. */
1715
1716 void
1717 initialize_frame_menubar (f)
1718 FRAME_PTR f;
1719 {
1720 /* This function is called before the first chance to redisplay
1721 the frame. It has to be, so the frame will have the right size. */
1722 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
1723 set_frame_menubar (f, 1, 1);
1724 }
1725
1726 1682
1727 /* Get rid of the menu bar of frame F, and free its storage. 1683 /* Get rid of the menu bar of frame F, and free its storage.
1728 This is used when deleting a frame, and when turning off the menu bar. */ 1684 This is used when deleting a frame, and when turning off the menu bar. */
1729 1685
1730 void 1686 void
1737 1693
1738 static Lisp_Object 1694 static Lisp_Object
1739 pop_down_menu (arg) 1695 pop_down_menu (arg)
1740 Lisp_Object arg; 1696 Lisp_Object arg;
1741 { 1697 {
1742 struct Lisp_Save_Value *p1 = XSAVE_VALUE (Fcar (arg)); 1698 struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
1743 struct Lisp_Save_Value *p2 = XSAVE_VALUE (Fcdr (arg)); 1699 FRAME_PTR f = p->pointer;
1744 1700 MenuHandle menu = GetMenuHandle (POPUP_SUBMENU_ID);
1745 FRAME_PTR f = p1->pointer;
1746 MenuHandle *menu = p2->pointer;
1747 1701
1748 BLOCK_INPUT; 1702 BLOCK_INPUT;
1749 1703
1750 /* Must reset this manually because the button release event is not 1704 /* Must reset this manually because the button release event is not
1751 passed to Emacs event loop. */ 1705 passed to Emacs event loop. */
1752 FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0; 1706 FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0;
1753 1707
1754 /* delete all menus */ 1708 /* delete all menus */
1755 { 1709 dispose_menus (MIN_POPUP_SUBMENU_ID);
1756 int i = MIN_POPUP_SUBMENU_ID;
1757 MenuHandle submenu = GetMenuHandle (i);
1758 while (submenu != NULL)
1759 {
1760 DeleteMenu (i);
1761 DisposeMenu (submenu);
1762 submenu = GetMenuHandle (++i);
1763 }
1764 }
1765
1766 DeleteMenu (POPUP_SUBMENU_ID); 1710 DeleteMenu (POPUP_SUBMENU_ID);
1767 DisposeMenu (*menu); 1711 DisposeMenu (menu);
1768 1712
1769 UNBLOCK_INPUT; 1713 UNBLOCK_INPUT;
1770 1714
1771 return Qnil; 1715 return Qnil;
1772 } 1716 }
1996 first_wv->contents = wv_title; 1940 first_wv->contents = wv_title;
1997 } 1941 }
1998 1942
1999 /* Actually create the menu. */ 1943 /* Actually create the menu. */
2000 menu = NewMenu (POPUP_SUBMENU_ID, "\p"); 1944 menu = NewMenu (POPUP_SUBMENU_ID, "\p");
2001 submenu_id = MIN_POPUP_SUBMENU_ID; 1945 InsertMenu (menu, -1);
2002 fill_submenu (menu, first_wv->contents); 1946 fill_menu (menu, first_wv->contents, MIN_POPUP_SUBMENU_ID);
2003 1947
2004 /* Free the widget_value objects we used to specify the 1948 /* Free the widget_value objects we used to specify the
2005 contents. */ 1949 contents. */
2006 free_menubar_widget_value_tree (first_wv); 1950 free_menubar_widget_value_tree (first_wv);
2007 1951
2014 1958
2015 /* No selection has been chosen yet. */ 1959 /* No selection has been chosen yet. */
2016 menu_item_choice = 0; 1960 menu_item_choice = 0;
2017 menu_item_selection = 0; 1961 menu_item_selection = 0;
2018 1962
2019 InsertMenu (menu, -1); 1963 record_unwind_protect (pop_down_menu, make_save_value (f, 0));
2020
2021 record_unwind_protect (pop_down_menu,
2022 Fcons (make_save_value (f, 0),
2023 make_save_value (&menu, 0)));
2024 1964
2025 /* Add event handler so we can detect C-g. */ 1965 /* Add event handler so we can detect C-g. */
2026 install_menu_quit_handler (menu); 1966 install_menu_quit_handler (menu);
2027 1967
2028 /* Display the menu. */ 1968 /* Display the menu. */
2419 them like normal separators. */ 2359 them like normal separators. */
2420 return (*name == '\0' || start + 2 == name); 2360 return (*name == '\0' || start + 2 == name);
2421 } 2361 }
2422 2362
2423 static void 2363 static void
2424 add_menu_item (MenuHandle menu, widget_value *wv, int submenu, 2364 add_menu_item (menu, pos, wv)
2425 int force_disable) 2365 MenuHandle menu;
2366 int pos;
2367 widget_value *wv;
2426 { 2368 {
2427 #if TARGET_API_MAC_CARBON 2369 #if TARGET_API_MAC_CARBON
2428 CFStringRef item_name; 2370 CFStringRef item_name;
2429 #else 2371 #else
2430 Str255 item_name; 2372 Str255 item_name;
2431 #endif 2373 #endif
2432 int pos;
2433 2374
2434 if (name_is_separator (wv->name)) 2375 if (name_is_separator (wv->name))
2435 AppendMenu (menu, "\p-"); 2376 AppendMenu (menu, "\p-");
2436 else 2377 else
2437 { 2378 {
2438 AppendMenu (menu, "\pX"); 2379 AppendMenu (menu, "\pX");
2439 2380
2440 #if TARGET_API_MAC_CARBON 2381 #if TARGET_API_MAC_CARBON
2441 pos = CountMenuItems (menu);
2442
2443 item_name = cfstring_create_with_utf8_cstring (wv->name); 2382 item_name = cfstring_create_with_utf8_cstring (wv->name);
2444 2383
2445 if (wv->key != NULL) 2384 if (wv->key != NULL)
2446 { 2385 {
2447 CFStringRef name, key; 2386 CFStringRef name, key;
2455 } 2394 }
2456 2395
2457 SetMenuItemTextWithCFString (menu, pos, item_name); 2396 SetMenuItemTextWithCFString (menu, pos, item_name);
2458 CFRelease (item_name); 2397 CFRelease (item_name);
2459 2398
2460 if (wv->enabled && !force_disable) 2399 if (wv->enabled)
2461 EnableMenuItem (menu, pos); 2400 EnableMenuItem (menu, pos);
2462 else 2401 else
2463 DisableMenuItem (menu, pos); 2402 DisableMenuItem (menu, pos);
2464 #else /* ! TARGET_API_MAC_CARBON */ 2403 #else /* ! TARGET_API_MAC_CARBON */
2465 pos = CountMItems (menu);
2466
2467 item_name[sizeof (item_name) - 1] = '\0'; 2404 item_name[sizeof (item_name) - 1] = '\0';
2468 strncpy (item_name, wv->name, sizeof (item_name) - 1); 2405 strncpy (item_name, wv->name, sizeof (item_name) - 1);
2469 if (wv->key != NULL) 2406 if (wv->key != NULL)
2470 { 2407 {
2471 int len = strlen (item_name); 2408 int len = strlen (item_name);
2475 strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len); 2412 strncpy (item_name + len, wv->key, sizeof (item_name) - 1 - len);
2476 } 2413 }
2477 c2pstr (item_name); 2414 c2pstr (item_name);
2478 SetMenuItemText (menu, pos, item_name); 2415 SetMenuItemText (menu, pos, item_name);
2479 2416
2480 if (wv->enabled && !force_disable) 2417 if (wv->enabled)
2481 EnableItem (menu, pos); 2418 EnableItem (menu, pos);
2482 else 2419 else
2483 DisableItem (menu, pos); 2420 DisableItem (menu, pos);
2484 #endif /* ! TARGET_API_MAC_CARBON */ 2421 #endif /* ! TARGET_API_MAC_CARBON */
2485 2422
2486 /* Draw radio buttons and tickboxes. */ 2423 /* Draw radio buttons and tickboxes. */
2487 {
2488 if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE || 2424 if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
2489 wv->button_type == BUTTON_TYPE_RADIO)) 2425 wv->button_type == BUTTON_TYPE_RADIO))
2490 SetItemMark (menu, pos, checkMark); 2426 SetItemMark (menu, pos, checkMark);
2491 else 2427 else
2492 SetItemMark (menu, pos, noMark); 2428 SetItemMark (menu, pos, noMark);
2493 }
2494 2429
2495 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data); 2430 SetMenuItemRefCon (menu, pos, (UInt32) wv->call_data);
2496 } 2431 }
2497 2432 }
2498 if (submenu != 0) 2433
2499 SetMenuItemHierarchicalID (menu, pos, submenu); 2434 /* Construct native Mac OS menu based on widget_value tree. */
2435
2436 static int
2437 fill_menu (menu, wv, submenu_id)
2438 MenuHandle menu;
2439 widget_value *wv;
2440 int submenu_id;
2441 {
2442 int pos;
2443
2444 for (pos = 1; wv != NULL; wv = wv->next, pos++)
2445 {
2446 add_menu_item (menu, pos, wv);
2447 if (wv->contents)
2448 {
2449 MenuHandle submenu = NewMenu (submenu_id, "\pX");
2450
2451 InsertMenu (submenu, -1);
2452 SetMenuItemHierarchicalID (menu, pos, submenu_id);
2453 submenu_id = fill_menu (submenu, wv->contents, submenu_id + 1);
2454 }
2455 }
2456
2457 return submenu_id;
2500 } 2458 }
2501 2459
2502 /* Construct native Mac OS menubar based on widget_value tree. */ 2460 /* Construct native Mac OS menubar based on widget_value tree. */
2503 2461
2504 static void 2462 static void
2505 fill_submenu (MenuHandle menu, widget_value *wv) 2463 fill_menubar (wv, deep_p)
2506 { 2464 widget_value *wv;
2507 for ( ; wv != NULL; wv = wv->next) 2465 int deep_p;
2508 if (wv->contents) 2466 {
2509 { 2467 int id, submenu_id;
2510 int cur_submenu = submenu_id++; 2468 MenuHandle menu;
2511 MenuHandle submenu = NewMenu (cur_submenu, "\pX"); 2469 Str255 title;
2512 fill_submenu (submenu, wv->contents); 2470 #if !TARGET_API_MAC_CARBON
2513 InsertMenu (submenu, -1); 2471 int title_changed_p = 0;
2514 add_menu_item (menu, wv, cur_submenu, 0); 2472 #endif
2515 } 2473
2516 else 2474 /* Clean up the menu bar when filled by the entire menu trees. */
2517 add_menu_item (menu, wv, 0, 0); 2475 if (deep_p)
2518 } 2476 {
2519 2477 dispose_menus (MIN_MENU_ID);
2520 2478 dispose_menus (MIN_SUBMENU_ID);
2521 /* Construct native Mac OS menu based on widget_value tree. */ 2479 #if !TARGET_API_MAC_CARBON
2480 title_changed_p = 1;
2481 #endif
2482 }
2483
2484 /* Fill menu bar titles and submenus. Reuse the existing menu bar
2485 titles as much as possible to minimize redraw (if !deep_p). */
2486 submenu_id = MIN_SUBMENU_ID;
2487 for (id = MIN_MENU_ID; wv != NULL; wv = wv->next, id++)
2488 {
2489 strncpy (title, wv->name, 255);
2490 title[255] = '\0';
2491 c2pstr (title);
2492
2493 menu = GetMenuHandle (id);
2494 if (menu)
2495 {
2496 #if TARGET_API_MAC_CARBON
2497 Str255 old_title;
2498
2499 GetMenuTitle (menu, old_title);
2500 if (!EqualString (title, old_title, false, false))
2501 SetMenuTitle (menu, title);
2502 #else /* !TARGET_API_MAC_CARBON */
2503 if (!EqualString (title, (*menu)->menuData, false, false))
2504 {
2505 DeleteMenu (id);
2506 DisposeMenu (menu);
2507 menu = NewMenu (id, title);
2508 InsertMenu (menu, GetMenuHandle (id + 1) ? id + 1 : 0);
2509 title_changed_p = 1;
2510 }
2511 #endif /* !TARGET_API_MAC_CARBON */
2512 }
2513 else
2514 {
2515 menu = NewMenu (id, title);
2516 InsertMenu (menu, 0);
2517 #if !TARGET_API_MAC_CARBON
2518 title_changed_p = 1;
2519 #endif
2520 }
2521
2522 if (wv->contents)
2523 submenu_id = fill_menu (menu, wv->contents, submenu_id);
2524 }
2525
2526 if (GetMenuHandle (id))
2527 {
2528 dispose_menus (id);
2529 #if !TARGET_API_MAC_CARBON
2530 title_changed_p = 1;
2531 #endif
2532 }
2533
2534 #if !TARGET_API_MAC_CARBON
2535 if (title_changed_p)
2536 InvalMenuBar ();
2537 #endif
2538 }
2522 2539
2523 static void 2540 static void
2524 fill_menu (MenuHandle menu, widget_value *wv) 2541 dispose_menus (id)
2525 { 2542 int id;
2526 for ( ; wv != NULL; wv = wv->next) 2543 {
2527 if (wv->contents) 2544 MenuHandle menu;
2528 { 2545
2529 int cur_submenu = submenu_id++; 2546 while ((menu = GetMenuHandle (id)) != NULL)
2530 MenuHandle submenu = NewMenu (cur_submenu, "\pX"); 2547 {
2531 fill_submenu (submenu, wv->contents); 2548 DeleteMenu (id);
2532 InsertMenu (submenu, -1); 2549 DisposeMenu (menu);
2533 add_menu_item (menu, wv, cur_submenu, 0); 2550 id++;
2534 }
2535 else
2536 add_menu_item (menu, wv, 0, 0);
2537 }
2538
2539 /* Construct native Mac OS menubar based on widget_value tree. */
2540
2541 static void
2542 fill_menubar (widget_value *wv)
2543 {
2544 int id;
2545
2546 submenu_id = MIN_SUBMENU_ID;
2547
2548 for (id = MIN_MENU_ID; wv != NULL; wv = wv->next, id++)
2549 {
2550 MenuHandle menu;
2551 Str255 title;
2552
2553 strncpy (title, wv->name, 255);
2554 title[255] = 0;
2555 c2pstr (title);
2556 menu = NewMenu (id, title);
2557
2558 if (wv->contents)
2559 fill_menu (menu, wv->contents);
2560
2561 InsertMenu (menu, 0);
2562 } 2551 }
2563 } 2552 }
2564 2553
2565 #endif /* HAVE_MENUS */ 2554 #endif /* HAVE_MENUS */
2566 2555