+2007-06-22 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
+
+ * macgui.h (USE_CG_DRAWING): Don't require USE_ATSUI.
+ (USE_MAC_TOOLBAR): Require USE_CG_DRAWING.
+
+ * macmenu.c (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.
+
2007-06-21 Jason Rumney <jasonr@gnu.org>
* image.c (convert_mono_to_color_image): Swap fore and background.
/* Regard ESC and C-g as Cancel even without the Cancel button. */
-#ifdef MAC_OSX
+#if 0 /* defined (MAC_OSX) */
static Boolean
mac_dialog_modal_filter (dialog, event, item_hit)
DialogRef dialog;
but I don't want to make one now. */
CHECK_WINDOW (window);
-#ifdef MAC_OSX
+#if 0 /* defined (MAC_OSX) */
/* Special treatment for Fmessage_box, Fyes_or_no_p, and Fy_or_n_p. */
if (EQ (position, Qt)
&& STRINGP (Fcar (contents))
#define DIALOG_BUTTON_MAKE_COMMAND_ID(value) \
((value) + DIALOG_BUTTON_COMMAND_ID_OFFSET)
+extern EMACS_TIME timer_check P_ ((int));
+
static pascal OSStatus
mac_handle_dialog_event (next_handler, event, data)
EventHandlerCallRef next_handler;
EventRef event;
void *data;
{
- OSStatus err;
+ OSStatus err, result = eventNotHandledErr;
WindowRef window = (WindowRef) data;
+ int quit_event_loop_p = 0;
switch (GetEventClass (event))
{
if (DIALOG_BUTTON_COMMAND_ID_P (command.commandID))
{
SetWRefCon (window, command.commandID);
- err = QuitAppModalLoopForWindow (window);
-
- return err == noErr ? noErr : eventNotHandledErr;
+ quit_event_loop_p = 1;
+ break;
}
- return CallNextEventHandler (next_handler, event);
+ result = CallNextEventHandler (next_handler, event);
}
break;
char char_code;
result = CallNextEventHandler (next_handler, event);
- if (result == noErr)
- return noErr;
+ if (result != eventNotHandledErr)
+ break;
err = GetEventParameter (event, kEventParamKeyMacCharCodes,
typeChar, NULL, sizeof (char),
switch (char_code)
{
case kEscapeCharCode:
- err = QuitAppModalLoopForWindow (window);
+ quit_event_loop_p = 1;
break;
default:
typeUInt32, NULL, sizeof (UInt32),
NULL, &key_code);
if (err == noErr)
- {
- if (mac_quit_char_key_p (modifiers, key_code))
- err = QuitAppModalLoopForWindow (window);
- else
- err = eventNotHandledErr;
- }
+ if (mac_quit_char_key_p (modifiers, key_code))
+ quit_event_loop_p = 1;
}
break;
}
-
- if (err == noErr)
- result = noErr;
-
- return result;
}
break;
default:
abort ();
}
+
+ if (quit_event_loop_p)
+ {
+ err = QuitEventLoop (GetCurrentEventLoop ());
+ if (err == noErr)
+ result = noErr;
+ }
+
+ return result;
}
static OSStatus
#define DIALOG_ICON_LEFT_MARGIN (24)
#define DIALOG_ICON_TOP_MARGIN (15)
+static Lisp_Object
+pop_down_dialog (arg)
+ Lisp_Object arg;
+{
+ struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+ WindowRef window = p->pointer;
+
+ BLOCK_INPUT;
+
+ if (popup_activated_flag)
+ EndAppModalStateForWindow (window);
+ DisposeWindow (window);
+ popup_activated_flag = 0;
+
+ UNBLOCK_INPUT;
+
+ return Qnil;
+}
+
static int
create_and_show_dialog (f, first_wv)
FRAME_PTR f;
Rect empty_rect, *rects;
WindowRef window = NULL;
ControlRef *buttons, default_button = NULL, text;
+ int specpdl_count = SPECPDL_INDEX ();
dialog_name = first_wv->name;
nb_buttons = dialog_name[1] - '0';
kWindowStandardHandlerAttribute,
&empty_rect, &window);
if (err == noErr)
- err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
- true);
+ {
+ record_unwind_protect (pop_down_dialog, make_save_value (window, 0));
+ err = SetThemeWindowBackground (window, kThemeBrushMovableModalBackground,
+ true);
+ }
if (err == noErr)
err = SetWindowTitleWithCFString (window, (dialog_name[0] == 'Q'
? CFSTR ("Question")
SetWRefCon (window, 0);
ShowWindow (window);
BringToFront (window);
- err = RunAppModalLoopForWindow (window);
+ popup_activated_flag = 1;
+ err = BeginAppModalStateForWindow (window);
+ }
+ if (err == noErr)
+ {
+ EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget ();
+
+ while (1)
+ {
+ EMACS_TIME next_time = timer_check (1);
+ long secs = EMACS_SECS (next_time);
+ long usecs = EMACS_USECS (next_time);
+ EventTimeout timeout;
+ EventRef event;
+
+ if (secs < 0 || (secs == 0 && usecs == 0))
+ {
+ /* Sometimes timer_check returns -1 (no timers) even if
+ there are timers. So do a timeout anyway. */
+ secs = 1;
+ usecs = 0;
+ }
+
+ timeout = (secs * kEventDurationSecond
+ + usecs * kEventDurationMicrosecond);
+ err = ReceiveNextEvent (0, NULL, timeout, kEventRemoveFromQueue,
+ &event);
+ if (err == noErr)
+ {
+ SendEventToEventTarget (event, toolbox_dispatcher);
+ ReleaseEvent (event);
+ }
+ else if (err != eventLoopTimedOutErr)
+ {
+ if (err == eventLoopQuitErr)
+ err = noErr;
+ break;
+ }
+ }
}
if (err == noErr)
{
result = DIALOG_BUTTON_COMMAND_ID_VALUE (command_id);
}
- if (window)
- DisposeWindow (window);
+ unbind_to (specpdl_count, Qnil);
return result;
}
doc: /* Return t if a menu or popup dialog is active. */)
()
{
+#if TARGET_API_MAC_CARBON
+ return (popup_activated ()) ? Qt : Qnil;
+#else
/* Always return Qnil since menu selection functions do not return
until a selection has been made or cancelled. */
return Qnil;
+#endif
}
\f
void