aboutsummaryrefslogtreecommitdiffstats
path: root/src/macmenu.c
diff options
context:
space:
mode:
authorMiles Bader2007-01-26 06:16:11 +0000
committerMiles Bader2007-01-26 06:16:11 +0000
commitc0466914ba3ad88c402b0301646b4b5db8aeb913 (patch)
tree964d8df324ab5f46872dfedc92ccea9fe50a1441 /src/macmenu.c
parentc97a3f22ed5841f1c8bcdbb80df2bd49635c6a56 (diff)
parent58f8a3f97bd49484d0eb4f83a70662ded0daf9cc (diff)
downloademacs-c0466914ba3ad88c402b0301646b4b5db8aeb913.tar.gz
emacs-c0466914ba3ad88c402b0301646b4b5db8aeb913.zip
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 586-614) - Update from CVS - Update from erc--emacs--22 - Merge from gnus--rel--5.10 - Merge from erc--main--0 - Make byte compiler correctly write circular constants * gnus--rel--5.10 (patch 186-196) - Update from CVS - Merge from emacs--devo--0 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-162
Diffstat (limited to 'src/macmenu.c')
-rw-r--r--src/macmenu.c595
1 files changed, 585 insertions, 10 deletions
diff --git a/src/macmenu.c b/src/macmenu.c
index 14bfe92cb25..3ea09412650 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -1,6 +1,6 @@
1/* Menu support for GNU Emacs on 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, 2006 Free Software Foundation, Inc. 3 2005, 2006, 2007 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -77,10 +77,11 @@ static const int min_menu_id[] = {0, 1, 234, 235, 236, 256, 16384, 32768};
77 77
78#define DIALOG_WINDOW_RESOURCE 130 78#define DIALOG_WINDOW_RESOURCE 130
79 79
80#if TARGET_API_MAC_CARBON
80#define HAVE_DIALOGS 1 81#define HAVE_DIALOGS 1
82#endif
81 83
82#undef HAVE_MULTILINGUAL_MENU 84#undef HAVE_MULTILINGUAL_MENU
83#undef HAVE_DIALOGS /* TODO: Implement native dialogs. */
84 85
85/******************************************************************/ 86/******************************************************************/
86/* Definitions copied from lwlib.h */ 87/* Definitions copied from lwlib.h */
@@ -876,6 +877,32 @@ no quit occurs and `x-popup-menu' returns nil. */)
876 877
877#ifdef HAVE_MENUS 878#ifdef HAVE_MENUS
878 879
880/* Regard ESC and C-g as Cancel even without the Cancel button. */
881
882#ifdef MAC_OSX
883static Boolean
884mac_dialog_modal_filter (dialog, event, item_hit)
885 DialogRef dialog;
886 EventRecord *event;
887 DialogItemIndex *item_hit;
888{
889 Boolean result;
890
891 result = StdFilterProc (dialog, event, item_hit);
892 if (result == false
893 && (event->what == keyDown || event->what == autoKey)
894 && ((event->message & charCodeMask) == kEscapeCharCode
895 || mac_quit_char_key_p (event->modifiers,
896 (event->message & keyCodeMask) >> 8)))
897 {
898 *item_hit = kStdCancelItemIndex;
899 return true;
900 }
901
902 return result;
903}
904#endif
905
879DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0, 906DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
880 doc: /* Pop up a dialog box and return user's selection. 907 doc: /* Pop up a dialog box and return user's selection.
881POSITION specifies which frame to use. 908POSITION specifies which frame to use.
@@ -961,6 +988,96 @@ for instance using the window manager, then this produces a quit and
961 but I don't want to make one now. */ 988 but I don't want to make one now. */
962 CHECK_WINDOW (window); 989 CHECK_WINDOW (window);
963 990
991#ifdef MAC_OSX
992 /* Special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p. */
993 if (EQ (position, Qt)
994 && STRINGP (Fcar (contents))
995 && ((!NILP (Fequal (XCDR (contents),
996 Fcons (Fcons (build_string ("OK"), Qt), Qnil)))
997 && EQ (header, Qt))
998 || (!NILP (Fequal (XCDR (contents),
999 Fcons (Fcons (build_string ("Yes"), Qt),
1000 Fcons (Fcons (build_string ("No"), Qnil),
1001 Qnil))))
1002 && NILP (header))))
1003 {
1004 OSStatus err = noErr;
1005 AlertStdCFStringAlertParamRec param;
1006 CFStringRef error_string, explanation_string;
1007 DialogRef alert;
1008 DialogItemIndex item_hit;
1009 Lisp_Object tem;
1010
1011 tem = Fstring_match (concat3 (build_string ("\\("),
1012 call0 (intern ("sentence-end")),
1013 build_string ("\\)\n")),
1014 XCAR (contents), Qnil);
1015 BLOCK_INPUT;
1016 if (NILP (tem))
1017 {
1018 error_string = cfstring_create_with_string (XCAR (contents));
1019 if (error_string == NULL)
1020 err = memFullErr;
1021 explanation_string = NULL;
1022 }
1023 else
1024 {
1025 tem = Fmatch_end (make_number (1));
1026 error_string =
1027 cfstring_create_with_string (Fsubstring (XCAR (contents),
1028 make_number (0), tem));
1029 if (error_string == NULL)
1030 err = memFullErr;
1031 else
1032 {
1033 XSETINT (tem, XINT (tem) + 1);
1034 explanation_string =
1035 cfstring_create_with_string (Fsubstring (XCAR (contents),
1036 tem, Qnil));
1037 if (explanation_string == NULL)
1038 {
1039 CFRelease (error_string);
1040 err = memFullErr;
1041 }
1042 }
1043 }
1044 if (err == noErr)
1045 err = GetStandardAlertDefaultParams (&param,
1046 kStdCFStringAlertVersionOne);
1047 if (err == noErr)
1048 {
1049 param.movable = true;
1050 param.position = kWindowAlertPositionParentWindow;
1051 if (NILP (header))
1052 {
1053 param.defaultText = CFSTR ("Yes");
1054 param.otherText = CFSTR ("No");
1055#if 0
1056 param.cancelText = CFSTR ("Cancel");
1057 param.cancelButton = kAlertStdAlertCancelButton;
1058#endif
1059 }
1060 err = CreateStandardAlert (kAlertNoteAlert, error_string,
1061 explanation_string, &param, &alert);
1062 CFRelease (error_string);
1063 if (explanation_string)
1064 CFRelease (explanation_string);
1065 }
1066 if (err == noErr)
1067 err = RunStandardAlert (alert, mac_dialog_modal_filter, &item_hit);
1068 UNBLOCK_INPUT;
1069
1070 if (err == noErr)
1071 {
1072 if (item_hit == kStdCancelItemIndex)
1073 Fsignal (Qquit, Qnil);
1074 else if (item_hit == kStdOkItemIndex)
1075 return Qt;
1076 else
1077 return Qnil;
1078 }
1079 }
1080#endif
964#ifndef HAVE_DIALOGS 1081#ifndef HAVE_DIALOGS
965 /* Display a menu with these alternatives 1082 /* Display a menu with these alternatives
966 in the middle of frame F. */ 1083 in the middle of frame F. */
@@ -1450,6 +1567,80 @@ update_submenu_strings (first_wv)
1450} 1567}
1451 1568
1452 1569
1570#if TARGET_API_MAC_CARBON
1571extern Lisp_Object Vshow_help_function;
1572
1573static Lisp_Object
1574restore_show_help_function (old_show_help_function)
1575 Lisp_Object old_show_help_function;
1576{
1577 Vshow_help_function = old_show_help_function;
1578
1579 return Qnil;
1580}
1581
1582static pascal OSStatus
1583menu_target_item_handler (next_handler, event, data)
1584 EventHandlerCallRef next_handler;
1585 EventRef event;
1586 void *data;
1587{
1588 OSStatus err, result;
1589 MenuRef menu;
1590 MenuItemIndex menu_item;
1591 Lisp_Object help;
1592 GrafPtr port;
1593 int specpdl_count = SPECPDL_INDEX ();
1594
1595 result = CallNextEventHandler (next_handler, event);
1596
1597 err = GetEventParameter (event, kEventParamDirectObject, typeMenuRef,
1598 NULL, sizeof (MenuRef), NULL, &menu);
1599 if (err == noErr)
1600 err = GetEventParameter (event, kEventParamMenuItemIndex,
1601 typeMenuItemIndex, NULL,
1602 sizeof (MenuItemIndex), NULL, &menu_item);
1603 if (err == noErr)
1604 err = GetMenuItemProperty (menu, menu_item,
1605 MAC_EMACS_CREATOR_CODE, 'help',
1606 sizeof (Lisp_Object), NULL, &help);
1607 if (err != noErr)
1608 help = Qnil;
1609
1610 /* Temporarily bind Vshow_help_function to Qnil because we don't
1611 want tooltips during menu tracking. */
1612 record_unwind_protect (restore_show_help_function, Vshow_help_function);
1613 Vshow_help_function = Qnil;
1614 GetPort (&port);
1615 show_help_echo (help, Qnil, Qnil, Qnil, 1);
1616 SetPort (port);
1617 unbind_to (specpdl_count, Qnil);
1618
1619 return err == noErr ? noErr : result;
1620}
1621#endif
1622
1623OSStatus
1624install_menu_target_item_handler (window)
1625 WindowPtr window;
1626{
1627 OSStatus err = noErr;
1628#if TARGET_API_MAC_CARBON
1629 static const EventTypeSpec specs[] =
1630 {{kEventClassMenu, kEventMenuTargetItem}};
1631 static EventHandlerUPP menu_target_item_handlerUPP = NULL;
1632
1633 if (menu_target_item_handlerUPP == NULL)
1634 menu_target_item_handlerUPP =
1635 NewEventHandlerUPP (menu_target_item_handler);
1636
1637 err = InstallWindowEventHandler (window, menu_target_item_handlerUPP,
1638 GetEventTypeCount (specs), specs,
1639 NULL, NULL);
1640#endif
1641 return err;
1642}
1643
1453/* Event handler function that pops down a menu on C-g. We can only pop 1644/* Event handler function that pops down a menu on C-g. We can only pop
1454 down menus if CancelMenuTracking is present (OSX 10.3 or later). */ 1645 down menus if CancelMenuTracking is present (OSX 10.3 or later). */
1455 1646
@@ -1463,8 +1654,6 @@ menu_quit_handler (nextHandler, theEvent, userData)
1463 OSStatus err; 1654 OSStatus err;
1464 UInt32 keyCode; 1655 UInt32 keyCode;
1465 UInt32 keyModifiers; 1656 UInt32 keyModifiers;
1466 extern int mac_quit_char_modifiers;
1467 extern int mac_quit_char_keycode;
1468 1657
1469 err = GetEventParameter (theEvent, kEventParamKeyCode, 1658 err = GetEventParameter (theEvent, kEventParamKeyCode,
1470 typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); 1659 typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
@@ -1474,8 +1663,7 @@ menu_quit_handler (nextHandler, theEvent, userData)
1474 typeUInt32, NULL, sizeof(UInt32), 1663 typeUInt32, NULL, sizeof(UInt32),
1475 NULL, &keyModifiers); 1664 NULL, &keyModifiers);
1476 1665
1477 if (err == noErr && keyCode == mac_quit_char_keycode 1666 if (err == noErr && mac_quit_char_key_p (keyModifiers, keyCode))
1478 && keyModifiers == mac_quit_char_modifiers)
1479 { 1667 {
1480 MenuRef menu = userData != 0 1668 MenuRef menu = userData != 0
1481 ? (MenuRef)userData : AcquireRootMenu (); 1669 ? (MenuRef)userData : AcquireRootMenu ();
@@ -2132,8 +2320,390 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error)
2132 2320
2133 2321
2134#ifdef HAVE_DIALOGS 2322#ifdef HAVE_DIALOGS
2135/* Construct native Mac OS menubar based on widget_value tree. */ 2323/* Construct native Mac OS dialog based on widget_value tree. */
2324
2325#if TARGET_API_MAC_CARBON
2326
2327static pascal OSStatus
2328mac_handle_dialog_event (next_handler, event, data)
2329 EventHandlerCallRef next_handler;
2330 EventRef event;
2331 void *data;
2332{
2333 OSStatus err;
2334 WindowRef window = (WindowRef) data;
2335
2336 switch (GetEventClass (event))
2337 {
2338 case kEventClassCommand:
2339 {
2340 HICommand command;
2341
2342 err = GetEventParameter (event, kEventParamDirectObject,
2343 typeHICommand, NULL, sizeof (HICommand),
2344 NULL, &command);
2345 if (err == noErr)
2346 if ((command.commandID & ~0xffff) == 'Bt\0\0')
2347 {
2348 SetWRefCon (window, command.commandID);
2349 err = QuitAppModalLoopForWindow (window);
2350
2351 return err == noErr ? noErr : eventNotHandledErr;
2352 }
2353
2354 return CallNextEventHandler (next_handler, event);
2355 }
2356 break;
2357
2358 case kEventClassKeyboard:
2359 {
2360 OSStatus result;
2361 char char_code;
2362
2363 result = CallNextEventHandler (next_handler, event);
2364 if (result == noErr)
2365 return noErr;
2366
2367 err = GetEventParameter (event, kEventParamKeyMacCharCodes,
2368 typeChar, NULL, sizeof (char),
2369 NULL, &char_code);
2370 if (err == noErr)
2371 switch (char_code)
2372 {
2373 case kEscapeCharCode:
2374 err = QuitAppModalLoopForWindow (window);
2375 break;
2376
2377 default:
2378 {
2379 UInt32 modifiers, key_code;
2380
2381 err = GetEventParameter (event, kEventParamKeyModifiers,
2382 typeUInt32, NULL, sizeof (UInt32),
2383 NULL, &modifiers);
2384 if (err == noErr)
2385 err = GetEventParameter (event, kEventParamKeyCode,
2386 typeUInt32, NULL, sizeof (UInt32),
2387 NULL, &key_code);
2388 if (err == noErr)
2389 if (mac_quit_char_key_p (modifiers, key_code))
2390 err = QuitAppModalLoopForWindow (window);
2391 else
2392 err = eventNotHandledErr;
2393 }
2394 break;
2395 }
2396
2397 return err == noErr ? noErr : result;
2398 }
2399 break;
2400
2401 default:
2402 abort ();
2403 }
2404}
2405
2406static OSStatus
2407install_dialog_event_handler (window)
2408 WindowRef window;
2409{
2410 static const EventTypeSpec specs[] =
2411 {{kEventClassCommand, kEventCommandProcess},
2412 {kEventClassKeyboard, kEventRawKeyDown}};
2413 static EventHandlerUPP handle_dialog_eventUPP = NULL;
2414
2415 if (handle_dialog_eventUPP == NULL)
2416 handle_dialog_eventUPP = NewEventHandlerUPP (mac_handle_dialog_event);
2417 return InstallWindowEventHandler (window, handle_dialog_eventUPP,
2418 GetEventTypeCount (specs), specs,
2419 window, NULL);
2420}
2421
2422#define DIALOG_LEFT_MARGIN (112)
2423#define DIALOG_TOP_MARGIN (24)
2424#define DIALOG_RIGHT_MARGIN (24)
2425#define DIALOG_BOTTOM_MARGIN (20)
2426#define DIALOG_MIN_INNER_WIDTH (338)
2427#define DIALOG_MAX_INNER_WIDTH (564)
2428#define DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE (12)
2429#define DIALOG_BUTTON_BUTTON_VERTICAL_SPACE (12)
2430#define DIALOG_BUTTON_MIN_WIDTH (68)
2431#define DIALOG_TEXT_MIN_HEIGHT (50)
2432#define DIALOG_TEXT_BUTTONS_VERTICAL_SPACE (10)
2433#define DIALOG_ICON_WIDTH (64)
2434#define DIALOG_ICON_HEIGHT (64)
2435#define DIALOG_ICON_LEFT_MARGIN (24)
2436#define DIALOG_ICON_TOP_MARGIN (15)
2437
2438static int
2439create_and_show_dialog (f, first_wv)
2440 FRAME_PTR f;
2441 widget_value *first_wv;
2442{
2443 OSStatus err;
2444 char *dialog_name, *message;
2445 int nb_buttons, first_group_count, i, result = 0;
2446 widget_value *wv;
2447 short buttons_height, text_height, inner_width, inner_height;
2448 Rect empty_rect, *rects;
2449 WindowRef window = NULL;
2450 ControlRef *buttons, default_button = NULL, text;
2451
2452 dialog_name = first_wv->name;
2453 nb_buttons = dialog_name[1] - '0';
2454 first_group_count = nb_buttons - (dialog_name[4] - '0');
2455
2456 wv = first_wv->contents;
2457 message = wv->value;
2136 2458
2459 wv = wv->next;
2460 SetRect (&empty_rect, 0, 0, 0, 0);
2461
2462 /* Create dialog window. */
2463 err = CreateNewWindow (kMovableModalWindowClass,
2464 kWindowStandardHandlerAttribute,
2465 &empty_rect, &window);
2466 if (err == noErr)
2467 err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
2468 true);
2469 if (err == noErr)
2470 err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q'
2471 ? CFSTR ("Question")
2472 : CFSTR ("Information")));
2473
2474 /* Create button controls and measure their optimal bounds. */
2475 if (err == noErr)
2476 {
2477 buttons = alloca (sizeof (ControlRef) * nb_buttons);
2478 rects = alloca (sizeof (Rect) * nb_buttons);
2479 for (i = 0; i < nb_buttons; i++)
2480 {
2481 CFStringRef label = cfstring_create_with_utf8_cstring (wv->value);
2482
2483 if (label == NULL)
2484 err = memFullErr;
2485 else
2486 {
2487 err = CreatePushButtonControl (window, &empty_rect,
2488 label, &buttons[i]);
2489 CFRelease (label);
2490 }
2491 if (err == noErr)
2492 {
2493 if (!wv->enabled)
2494 {
2495#ifdef MAC_OSX
2496 err = DisableControl (buttons[i]);
2497#else
2498 err = DeactivateControl (buttons[i]);
2499#endif
2500 }
2501 else if (default_button == NULL)
2502 default_button = buttons[i];
2503 }
2504 if (err == noErr)
2505 {
2506 SInt16 unused;
2507
2508 rects[i] = empty_rect;
2509 err = GetBestControlRect (buttons[i], &rects[i], &unused);
2510 }
2511 if (err == noErr)
2512 {
2513 OffsetRect (&rects[i], -rects[i].left, -rects[i].top);
2514 if (rects[i].right < DIALOG_BUTTON_MIN_WIDTH)
2515 rects[i].right = DIALOG_BUTTON_MIN_WIDTH;
2516 else if (rects[i].right > DIALOG_MAX_INNER_WIDTH)
2517 rects[i].right = DIALOG_MAX_INNER_WIDTH;
2518
2519 err = SetControlCommandID (buttons[i],
2520 'Bt\0\0' + (int) wv->call_data);
2521 }
2522 if (err != noErr)
2523 break;
2524 wv = wv->next;
2525 }
2526 }
2527
2528 /* Layout buttons. rects[i] is set relative to the bottom-right
2529 corner of the inner box. */
2530 if (err == noErr)
2531 {
2532 short bottom, right, max_height, left_align_shift;
2533
2534 inner_width = DIALOG_MIN_INNER_WIDTH;
2535 bottom = right = max_height = 0;
2536 for (i = 0; i < nb_buttons; i++)
2537 {
2538 if (right - rects[i].right < - inner_width)
2539 {
2540 if (i != first_group_count
2541 && right - rects[i].right >= - DIALOG_MAX_INNER_WIDTH)
2542 inner_width = - (right - rects[i].right);
2543 else
2544 {
2545 bottom -= max_height + DIALOG_BUTTON_BUTTON_VERTICAL_SPACE;
2546 right = max_height = 0;
2547 }
2548 }
2549 if (max_height < rects[i].bottom)
2550 max_height = rects[i].bottom;
2551 OffsetRect (&rects[i], right - rects[i].right,
2552 bottom - rects[i].bottom);
2553 right = rects[i].left - DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
2554 if (i == first_group_count - 1)
2555 right -= DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE;
2556 }
2557 buttons_height = - (bottom - max_height);
2558
2559 left_align_shift = - (inner_width + rects[nb_buttons - 1].left);
2560 for (i = nb_buttons - 1; i >= first_group_count; i--)
2561 {
2562 if (bottom != rects[i].bottom)
2563 {
2564 left_align_shift = - (inner_width + rects[i].left);
2565 bottom = rects[i].bottom;
2566 }
2567 OffsetRect (&rects[i], left_align_shift, 0);
2568 }
2569 }
2570
2571 /* Create a static text control and measure its bounds. */
2572 if (err == noErr)
2573 {
2574 CFStringRef message_string;
2575 Rect bounds;
2576
2577 message_string = cfstring_create_with_utf8_cstring (message);
2578 if (message_string == NULL)
2579 err = memFullErr;
2580 else
2581 {
2582 ControlFontStyleRec text_style;
2583
2584 text_style.flags = 0;
2585 SetRect (&bounds, 0, 0, inner_width, 0);
2586 err = CreateStaticTextControl (window, &bounds, message_string,
2587 &text_style, &text);
2588 CFRelease (message_string);
2589 }
2590 if (err == noErr)
2591 {
2592 SInt16 unused;
2593
2594 bounds = empty_rect;
2595 err = GetBestControlRect (text, &bounds, &unused);
2596 }
2597 if (err == noErr)
2598 {
2599 text_height = bounds.bottom - bounds.top;
2600 if (text_height < DIALOG_TEXT_MIN_HEIGHT)
2601 text_height = DIALOG_TEXT_MIN_HEIGHT;
2602 }
2603 }
2604
2605 /* Place buttons. */
2606 if (err == noErr)
2607 {
2608 inner_height = (text_height + DIALOG_TEXT_BUTTONS_VERTICAL_SPACE
2609 + buttons_height);
2610
2611 for (i = 0; i < nb_buttons; i++)
2612 {
2613 OffsetRect (&rects[i], DIALOG_LEFT_MARGIN + inner_width,
2614 DIALOG_TOP_MARGIN + inner_height);
2615 SetControlBounds (buttons[i], &rects[i]);
2616 }
2617 }
2618
2619 /* Place text. */
2620 if (err == noErr)
2621 {
2622 Rect bounds;
2623
2624 SetRect (&bounds, DIALOG_LEFT_MARGIN, DIALOG_TOP_MARGIN,
2625 DIALOG_LEFT_MARGIN + inner_width,
2626 DIALOG_TOP_MARGIN + text_height);
2627 SetControlBounds (text, &bounds);
2628 }
2629
2630 /* Create the application icon at the upper-left corner. */
2631 if (err == noErr)
2632 {
2633 ControlButtonContentInfo content;
2634 ControlRef icon;
2635 static const ProcessSerialNumber psn = {0, kCurrentProcess};
2636#ifdef MAC_OSX
2637 FSRef app_location;
2638#else
2639 ProcessInfoRec pinfo;
2640 FSSpec app_spec;
2641#endif
2642 SInt16 unused;
2643
2644 content.contentType = kControlContentIconRef;
2645#ifdef MAC_OSX
2646 err = GetProcessBundleLocation (&psn, &app_location);
2647 if (err == noErr)
2648 err = GetIconRefFromFileInfo (&app_location, 0, NULL, 0, NULL,
2649 kIconServicesNormalUsageFlag,
2650 &content.u.iconRef, &unused);
2651#else
2652 bzero (&pinfo, sizeof (ProcessInfoRec));
2653 pinfo.processInfoLength = sizeof (ProcessInfoRec);
2654 pinfo.processAppSpec = &app_spec;
2655 err = GetProcessInformation (&psn, &pinfo);
2656 if (err == noErr)
2657 err = GetIconRefFromFile (&app_spec, &content.u.iconRef, &unused);
2658#endif
2659 if (err == noErr)
2660 {
2661 Rect bounds;
2662
2663 SetRect (&bounds, DIALOG_ICON_LEFT_MARGIN, DIALOG_ICON_TOP_MARGIN,
2664 DIALOG_ICON_LEFT_MARGIN + DIALOG_ICON_WIDTH,
2665 DIALOG_ICON_TOP_MARGIN + DIALOG_ICON_HEIGHT);
2666 err = CreateIconControl (window, &bounds, &content, true, &icon);
2667 ReleaseIconRef (content.u.iconRef);
2668 }
2669 }
2670
2671 /* Show the dialog window and run event loop. */
2672 if (err == noErr)
2673 if (default_button)
2674 err = SetWindowDefaultButton (window, default_button);
2675 if (err == noErr)
2676 err = install_dialog_event_handler (window);
2677 if (err == noErr)
2678 {
2679 SizeWindow (window,
2680 DIALOG_LEFT_MARGIN + inner_width + DIALOG_RIGHT_MARGIN,
2681 DIALOG_TOP_MARGIN + inner_height + DIALOG_BOTTOM_MARGIN,
2682 true);
2683 err = RepositionWindow (window, FRAME_MAC_WINDOW (f),
2684 kWindowAlertPositionOnParentWindow);
2685 }
2686 if (err == noErr)
2687 {
2688 SetWRefCon (window, 0);
2689 ShowWindow (window);
2690 BringToFront (window);
2691 err = RunAppModalLoopForWindow (window);
2692 }
2693 if (err == noErr)
2694 {
2695 UInt32 command_id = GetWRefCon (window);
2696
2697 if ((command_id & ~0xffff) == 'Bt\0\0')
2698 result = command_id - 'Bt\0\0';
2699 }
2700
2701 if (window)
2702 DisposeWindow (window);
2703
2704 return result;
2705}
2706#else /* not TARGET_API_MAC_CARBON */
2137static int 2707static int
2138mac_dialog (widget_value *wv) 2708mac_dialog (widget_value *wv)
2139{ 2709{
@@ -2238,6 +2808,7 @@ mac_dialog (widget_value *wv)
2238 2808
2239 return i; 2809 return i;
2240} 2810}
2811#endif /* not TARGET_API_MAC_CARBON */
2241 2812
2242static char * button_names [] = { 2813static char * button_names [] = {
2243 "button1", "button2", "button3", "button4", "button5", 2814 "button1", "button2", "button3", "button4", "button5",
@@ -2370,10 +2941,10 @@ mac_dialog_show (f, keymaps, title, header, error_name)
2370 } 2941 }
2371 2942
2372 /* Actually create the dialog. */ 2943 /* Actually create the dialog. */
2373#ifdef HAVE_DIALOGS 2944#if TARGET_API_MAC_CARBON
2374 menu_item_selection = mac_dialog (first_wv); 2945 menu_item_selection = create_and_show_dialog (f, first_wv);
2375#else 2946#else
2376 menu_item_selection = 0; 2947 menu_item_selection = mac_dialog (first_wv);
2377#endif 2948#endif
2378 2949
2379 /* Free the widget_value objects we used to specify the contents. */ 2950 /* Free the widget_value objects we used to specify the contents. */
@@ -2485,6 +3056,10 @@ add_menu_item (menu, pos, wv)
2485 EnableMenuItem (menu, pos); 3056 EnableMenuItem (menu, pos);
2486 else 3057 else
2487 DisableMenuItem (menu, pos); 3058 DisableMenuItem (menu, pos);
3059
3060 if (STRINGP (wv->help))
3061 SetMenuItemProperty (menu, pos, MAC_EMACS_CREATOR_CODE, 'help',
3062 sizeof (Lisp_Object), &wv->help);
2488#else /* ! TARGET_API_MAC_CARBON */ 3063#else /* ! TARGET_API_MAC_CARBON */
2489 item_name[sizeof (item_name) - 1] = '\0'; 3064 item_name[sizeof (item_name) - 1] = '\0';
2490 strncpy (item_name, wv->name, sizeof (item_name) - 1); 3065 strncpy (item_name, wv->name, sizeof (item_name) - 1);