Mercurial > emacs
comparison src/macmenu.c @ 81560:3ce0ebdd2017
(mac_dialog_modal_filter, Fx_popup_dialog) [MAC_OSX]:
Put special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p
in #if 0 as it is not compatible with y-or-n-p-with-timeout.
(timer_check) [TARGET_API_MAC_CARBON]: Add extern.
[TARGET_API_MAC_CARBON] (mac_handle_dialog_event): Use QuitEventLoop
instead of QuitAppModalLoopForWindow. Consolidate QuitEventLoop calls.
(pop_down_dialog) [TARGET_API_MAC_CARBON]: New function.
[TARGET_API_MAC_CARBON] (create_and_show_dialog): Use it for unwind.
Run timers during dialog popup.
(Fmenu_or_popup_active_p) [TARGET_API_MAC_CARBON]: Use popup_activated.
| author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
|---|---|
| date | Fri, 22 Jun 2007 09:05:35 +0000 |
| parents | ffe8cf8ef14e |
| children | b98604865ea0 0ece58f6e0aa 988f1edc9674 |
comparison
equal
deleted
inserted
replaced
| 81559:0e17f76d05e4 | 81560:3ce0ebdd2017 |
|---|---|
| 880 | 880 |
| 881 #ifdef HAVE_MENUS | 881 #ifdef HAVE_MENUS |
| 882 | 882 |
| 883 /* Regard ESC and C-g as Cancel even without the Cancel button. */ | 883 /* Regard ESC and C-g as Cancel even without the Cancel button. */ |
| 884 | 884 |
| 885 #ifdef MAC_OSX | 885 #if 0 /* defined (MAC_OSX) */ |
| 886 static Boolean | 886 static Boolean |
| 887 mac_dialog_modal_filter (dialog, event, item_hit) | 887 mac_dialog_modal_filter (dialog, event, item_hit) |
| 888 DialogRef dialog; | 888 DialogRef dialog; |
| 889 EventRecord *event; | 889 EventRecord *event; |
| 890 DialogItemIndex *item_hit; | 890 DialogItemIndex *item_hit; |
| 989 else | 989 else |
| 990 /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME, | 990 /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME, |
| 991 but I don't want to make one now. */ | 991 but I don't want to make one now. */ |
| 992 CHECK_WINDOW (window); | 992 CHECK_WINDOW (window); |
| 993 | 993 |
| 994 #ifdef MAC_OSX | 994 #if 0 /* defined (MAC_OSX) */ |
| 995 /* Special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p. */ | 995 /* Special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p. */ |
| 996 if (EQ (position, Qt) | 996 if (EQ (position, Qt) |
| 997 && STRINGP (Fcar (contents)) | 997 && STRINGP (Fcar (contents)) |
| 998 && ((!NILP (Fequal (XCDR (contents), | 998 && ((!NILP (Fequal (XCDR (contents), |
| 999 Fcons (Fcons (build_string ("OK"), Qt), Qnil))) | 999 Fcons (Fcons (build_string ("OK"), Qt), Qnil))) |
| 2328 #define DIALOG_BUTTON_COMMAND_ID_VALUE(id) \ | 2328 #define DIALOG_BUTTON_COMMAND_ID_VALUE(id) \ |
| 2329 ((id) - DIALOG_BUTTON_COMMAND_ID_OFFSET) | 2329 ((id) - DIALOG_BUTTON_COMMAND_ID_OFFSET) |
| 2330 #define DIALOG_BUTTON_MAKE_COMMAND_ID(value) \ | 2330 #define DIALOG_BUTTON_MAKE_COMMAND_ID(value) \ |
| 2331 ((value) + DIALOG_BUTTON_COMMAND_ID_OFFSET) | 2331 ((value) + DIALOG_BUTTON_COMMAND_ID_OFFSET) |
| 2332 | 2332 |
| 2333 extern EMACS_TIME timer_check P_ ((int)); | |
| 2334 | |
| 2333 static pascal OSStatus | 2335 static pascal OSStatus |
| 2334 mac_handle_dialog_event (next_handler, event, data) | 2336 mac_handle_dialog_event (next_handler, event, data) |
| 2335 EventHandlerCallRef next_handler; | 2337 EventHandlerCallRef next_handler; |
| 2336 EventRef event; | 2338 EventRef event; |
| 2337 void *data; | 2339 void *data; |
| 2338 { | 2340 { |
| 2339 OSStatus err; | 2341 OSStatus err, result = eventNotHandledErr; |
| 2340 WindowRef window = (WindowRef) data; | 2342 WindowRef window = (WindowRef) data; |
| 2343 int quit_event_loop_p = 0; | |
| 2341 | 2344 |
| 2342 switch (GetEventClass (event)) | 2345 switch (GetEventClass (event)) |
| 2343 { | 2346 { |
| 2344 case kEventClassCommand: | 2347 case kEventClassCommand: |
| 2345 { | 2348 { |
| 2350 NULL, &command); | 2353 NULL, &command); |
| 2351 if (err == noErr) | 2354 if (err == noErr) |
| 2352 if (DIALOG_BUTTON_COMMAND_ID_P (command.commandID)) | 2355 if (DIALOG_BUTTON_COMMAND_ID_P (command.commandID)) |
| 2353 { | 2356 { |
| 2354 SetWRefCon (window, command.commandID); | 2357 SetWRefCon (window, command.commandID); |
| 2355 err = QuitAppModalLoopForWindow (window); | 2358 quit_event_loop_p = 1; |
| 2356 | 2359 break; |
| 2357 return err == noErr ? noErr : eventNotHandledErr; | 2360 } |
| 2358 } | 2361 |
| 2359 | 2362 result = CallNextEventHandler (next_handler, event); |
| 2360 return CallNextEventHandler (next_handler, event); | |
| 2361 } | 2363 } |
| 2362 break; | 2364 break; |
| 2363 | 2365 |
| 2364 case kEventClassKeyboard: | 2366 case kEventClassKeyboard: |
| 2365 { | 2367 { |
| 2366 OSStatus result; | 2368 OSStatus result; |
| 2367 char char_code; | 2369 char char_code; |
| 2368 | 2370 |
| 2369 result = CallNextEventHandler (next_handler, event); | 2371 result = CallNextEventHandler (next_handler, event); |
| 2370 if (result == noErr) | 2372 if (result != eventNotHandledErr) |
| 2371 return noErr; | 2373 break; |
| 2372 | 2374 |
| 2373 err = GetEventParameter (event, kEventParamKeyMacCharCodes, | 2375 err = GetEventParameter (event, kEventParamKeyMacCharCodes, |
| 2374 typeChar, NULL, sizeof (char), | 2376 typeChar, NULL, sizeof (char), |
| 2375 NULL, &char_code); | 2377 NULL, &char_code); |
| 2376 if (err == noErr) | 2378 if (err == noErr) |
| 2377 switch (char_code) | 2379 switch (char_code) |
| 2378 { | 2380 { |
| 2379 case kEscapeCharCode: | 2381 case kEscapeCharCode: |
| 2380 err = QuitAppModalLoopForWindow (window); | 2382 quit_event_loop_p = 1; |
| 2381 break; | 2383 break; |
| 2382 | 2384 |
| 2383 default: | 2385 default: |
| 2384 { | 2386 { |
| 2385 UInt32 modifiers, key_code; | 2387 UInt32 modifiers, key_code; |
| 2390 if (err == noErr) | 2392 if (err == noErr) |
| 2391 err = GetEventParameter (event, kEventParamKeyCode, | 2393 err = GetEventParameter (event, kEventParamKeyCode, |
| 2392 typeUInt32, NULL, sizeof (UInt32), | 2394 typeUInt32, NULL, sizeof (UInt32), |
| 2393 NULL, &key_code); | 2395 NULL, &key_code); |
| 2394 if (err == noErr) | 2396 if (err == noErr) |
| 2395 { | 2397 if (mac_quit_char_key_p (modifiers, key_code)) |
| 2396 if (mac_quit_char_key_p (modifiers, key_code)) | 2398 quit_event_loop_p = 1; |
| 2397 err = QuitAppModalLoopForWindow (window); | |
| 2398 else | |
| 2399 err = eventNotHandledErr; | |
| 2400 } | |
| 2401 } | 2399 } |
| 2402 break; | 2400 break; |
| 2403 } | 2401 } |
| 2404 | |
| 2405 if (err == noErr) | |
| 2406 result = noErr; | |
| 2407 | |
| 2408 return result; | |
| 2409 } | 2402 } |
| 2410 break; | 2403 break; |
| 2411 | 2404 |
| 2412 default: | 2405 default: |
| 2413 abort (); | 2406 abort (); |
| 2414 } | 2407 } |
| 2408 | |
| 2409 if (quit_event_loop_p) | |
| 2410 { | |
| 2411 err = QuitEventLoop (GetCurrentEventLoop ()); | |
| 2412 if (err == noErr) | |
| 2413 result = noErr; | |
| 2414 } | |
| 2415 | |
| 2416 return result; | |
| 2415 } | 2417 } |
| 2416 | 2418 |
| 2417 static OSStatus | 2419 static OSStatus |
| 2418 install_dialog_event_handler (window) | 2420 install_dialog_event_handler (window) |
| 2419 WindowRef window; | 2421 WindowRef window; |
| 2444 #define DIALOG_ICON_WIDTH (64) | 2446 #define DIALOG_ICON_WIDTH (64) |
| 2445 #define DIALOG_ICON_HEIGHT (64) | 2447 #define DIALOG_ICON_HEIGHT (64) |
| 2446 #define DIALOG_ICON_LEFT_MARGIN (24) | 2448 #define DIALOG_ICON_LEFT_MARGIN (24) |
| 2447 #define DIALOG_ICON_TOP_MARGIN (15) | 2449 #define DIALOG_ICON_TOP_MARGIN (15) |
| 2448 | 2450 |
| 2451 static Lisp_Object | |
| 2452 pop_down_dialog (arg) | |
| 2453 Lisp_Object arg; | |
| 2454 { | |
| 2455 struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | |
| 2456 WindowRef window = p->pointer; | |
| 2457 | |
| 2458 BLOCK_INPUT; | |
| 2459 | |
| 2460 if (popup_activated_flag) | |
| 2461 EndAppModalStateForWindow (window); | |
| 2462 DisposeWindow (window); | |
| 2463 popup_activated_flag = 0; | |
| 2464 | |
| 2465 UNBLOCK_INPUT; | |
| 2466 | |
| 2467 return Qnil; | |
| 2468 } | |
| 2469 | |
| 2449 static int | 2470 static int |
| 2450 create_and_show_dialog (f, first_wv) | 2471 create_and_show_dialog (f, first_wv) |
| 2451 FRAME_PTR f; | 2472 FRAME_PTR f; |
| 2452 widget_value *first_wv; | 2473 widget_value *first_wv; |
| 2453 { | 2474 { |
| 2457 widget_value *wv; | 2478 widget_value *wv; |
| 2458 short buttons_height, text_height, inner_width, inner_height; | 2479 short buttons_height, text_height, inner_width, inner_height; |
| 2459 Rect empty_rect, *rects; | 2480 Rect empty_rect, *rects; |
| 2460 WindowRef window = NULL; | 2481 WindowRef window = NULL; |
| 2461 ControlRef *buttons, default_button = NULL, text; | 2482 ControlRef *buttons, default_button = NULL, text; |
| 2483 int specpdl_count = SPECPDL_INDEX (); | |
| 2462 | 2484 |
| 2463 dialog_name = first_wv->name; | 2485 dialog_name = first_wv->name; |
| 2464 nb_buttons = dialog_name[1] - '0'; | 2486 nb_buttons = dialog_name[1] - '0'; |
| 2465 first_group_count = nb_buttons - (dialog_name[4] - '0'); | 2487 first_group_count = nb_buttons - (dialog_name[4] - '0'); |
| 2466 | 2488 |
| 2473 /* Create dialog window. */ | 2495 /* Create dialog window. */ |
| 2474 err = CreateNewWindow (kMovableModalWindowClass, | 2496 err = CreateNewWindow (kMovableModalWindowClass, |
| 2475 kWindowStandardHandlerAttribute, | 2497 kWindowStandardHandlerAttribute, |
| 2476 &empty_rect, &window); | 2498 &empty_rect, &window); |
| 2477 if (err == noErr) | 2499 if (err == noErr) |
| 2478 err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground, | 2500 { |
| 2479 true); | 2501 record_unwind_protect (pop_down_dialog, make_save_value (window, 0)); |
| 2502 err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground, | |
| 2503 true); | |
| 2504 } | |
| 2480 if (err == noErr) | 2505 if (err == noErr) |
| 2481 err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q' | 2506 err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q' |
| 2482 ? CFSTR ("Question") | 2507 ? CFSTR ("Question") |
| 2483 : CFSTR ("Information"))); | 2508 : CFSTR ("Information"))); |
| 2484 | 2509 |
| 2699 if (err == noErr) | 2724 if (err == noErr) |
| 2700 { | 2725 { |
| 2701 SetWRefCon (window, 0); | 2726 SetWRefCon (window, 0); |
| 2702 ShowWindow (window); | 2727 ShowWindow (window); |
| 2703 BringToFront (window); | 2728 BringToFront (window); |
| 2704 err = RunAppModalLoopForWindow (window); | 2729 popup_activated_flag = 1; |
| 2730 err = BeginAppModalStateForWindow (window); | |
| 2731 } | |
| 2732 if (err == noErr) | |
| 2733 { | |
| 2734 EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget (); | |
| 2735 | |
| 2736 while (1) | |
| 2737 { | |
| 2738 EMACS_TIME next_time = timer_check (1); | |
| 2739 long secs = EMACS_SECS (next_time); | |
| 2740 long usecs = EMACS_USECS (next_time); | |
| 2741 EventTimeout timeout; | |
| 2742 EventRef event; | |
| 2743 | |
| 2744 if (secs < 0 || (secs == 0 && usecs == 0)) | |
| 2745 { | |
| 2746 /* Sometimes timer_check returns -1 (no timers) even if | |
| 2747 there are timers. So do a timeout anyway. */ | |
| 2748 secs = 1; | |
| 2749 usecs = 0; | |
| 2750 } | |
| 2751 | |
| 2752 timeout = (secs * kEventDurationSecond | |
| 2753 + usecs * kEventDurationMicrosecond); | |
| 2754 err = ReceiveNextEvent (0, NULL, timeout, kEventRemoveFromQueue, | |
| 2755 &event); | |
| 2756 if (err == noErr) | |
| 2757 { | |
| 2758 SendEventToEventTarget (event, toolbox_dispatcher); | |
| 2759 ReleaseEvent (event); | |
| 2760 } | |
| 2761 else if (err != eventLoopTimedOutErr) | |
| 2762 { | |
| 2763 if (err == eventLoopQuitErr) | |
| 2764 err = noErr; | |
| 2765 break; | |
| 2766 } | |
| 2767 } | |
| 2705 } | 2768 } |
| 2706 if (err == noErr) | 2769 if (err == noErr) |
| 2707 { | 2770 { |
| 2708 UInt32 command_id = GetWRefCon (window); | 2771 UInt32 command_id = GetWRefCon (window); |
| 2709 | 2772 |
| 2710 if (DIALOG_BUTTON_COMMAND_ID_P (command_id)) | 2773 if (DIALOG_BUTTON_COMMAND_ID_P (command_id)) |
| 2711 result = DIALOG_BUTTON_COMMAND_ID_VALUE (command_id); | 2774 result = DIALOG_BUTTON_COMMAND_ID_VALUE (command_id); |
| 2712 } | 2775 } |
| 2713 | 2776 |
| 2714 if (window) | 2777 unbind_to (specpdl_count, Qnil); |
| 2715 DisposeWindow (window); | |
| 2716 | 2778 |
| 2717 return result; | 2779 return result; |
| 2718 } | 2780 } |
| 2719 #else /* not TARGET_API_MAC_CARBON */ | 2781 #else /* not TARGET_API_MAC_CARBON */ |
| 2720 static int | 2782 static int |
| 3280 | 3342 |
| 3281 DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, | 3343 DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0, |
| 3282 doc: /* Return t if a menu or popup dialog is active. */) | 3344 doc: /* Return t if a menu or popup dialog is active. */) |
| 3283 () | 3345 () |
| 3284 { | 3346 { |
| 3347 #if TARGET_API_MAC_CARBON | |
| 3348 return (popup_activated ()) ? Qt : Qnil; | |
| 3349 #else | |
| 3285 /* Always return Qnil since menu selection functions do not return | 3350 /* Always return Qnil since menu selection functions do not return |
| 3286 until a selection has been made or cancelled. */ | 3351 until a selection has been made or cancelled. */ |
| 3287 return Qnil; | 3352 return Qnil; |
| 3353 #endif | |
| 3288 } | 3354 } |
| 3289 | 3355 |
| 3290 void | 3356 void |
| 3291 syms_of_macmenu () | 3357 syms_of_macmenu () |
| 3292 { | 3358 { |
