extern Lisp_Object x_icon_type P_ ((struct frame *));
+extern int inhibit_window_system;
#if __MRC__
QDGlobals qd; /* QuickDraw global information structure. */
void mac_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
-enum text_cursor_kinds x_specified_cursor_type P_ ((Lisp_Object, int *));
static void x_draw_phys_cursor_glyph P_ ((struct window *,
struct glyph_row *,
enum draw_glyphs_face));
static int x_intersect_rectangles P_ ((Rect *, Rect *, Rect *));
static void expose_frame P_ ((struct frame *, int, int, int, int));
static int expose_window_tree P_ ((struct window *, Rect *));
+static void expose_overlaps P_ ((struct window *, struct glyph_row *,
+ struct glyph_row *));
static int expose_window P_ ((struct window *, Rect *));
static void expose_area P_ ((struct window *, struct glyph_row *,
Rect *, enum glyph_row_area));
static void activate_scroll_bars (FRAME_PTR);
static void deactivate_scroll_bars (FRAME_PTR);
+static int is_emacs_window (WindowPtr);
+
extern int image_ascent (struct image *, struct face *);
void x_set_offset (struct frame *, int, int, int);
int x_bitmap_icon (struct frame *, Lisp_Object);
}
-/* Redraw the part of window W intersection rectagle FR. Pixel
- coordinates in FR are frame relative. Call this function with
+/* Redraw those parts of glyphs rows during expose event handling that
+ overlap other rows. Redrawing of an exposed line writes over parts
+ of lines overlapping that exposed line; this function fixes that.
+
+ W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
+ row in W's current matrix that is exposed and overlaps other rows.
+ LAST_OVERLAPPING_ROW is the last such row. */
+
+static void
+expose_overlaps (w, first_overlapping_row, last_overlapping_row)
+ struct window *w;
+ struct glyph_row *first_overlapping_row;
+ struct glyph_row *last_overlapping_row;
+{
+ struct glyph_row *row;
+
+ for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
+ if (row->overlapping_p)
+ {
+ xassert (row->enabled_p && !row->mode_line_p);
+
+ if (row->used[LEFT_MARGIN_AREA])
+ x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
+
+ if (row->used[TEXT_AREA])
+ x_fix_overlapping_area (w, row, TEXT_AREA);
+
+ if (row->used[RIGHT_MARGIN_AREA])
+ x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
+ }
+}
+
+
+/* Redraw the part of window W intersection rectangle FR. Pixel
+ coordinates in FR are frame-relative. Call this function with
input blocked. Value is non-zero if the exposure overwrites
mouse-face. */
int yb = window_text_bottom_y (w);
struct glyph_row *row;
int cursor_cleared_p;
-
+ struct glyph_row *first_overlapping_row, *last_overlapping_row;
+
TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
r.left, r.top, r.right, r.bottom));
else
cursor_cleared_p = 0;
- /* Find the first row intersecting the rectangle R. */
+ /* Update lines intersecting rectangle R. */
+ first_overlapping_row = last_overlapping_row = NULL;
for (row = w->current_matrix->rows;
row->enabled_p;
++row)
|| (r.top >= y0 && r.top < y1)
|| (r.bottom > y0 && r.bottom < y1))
{
+ if (row->overlapping_p)
+ {
+ if (first_overlapping_row == NULL)
+ first_overlapping_row = row;
+ last_overlapping_row = row;
+ }
+
if (expose_line (w, row, &r))
mouse_face_overwritten_p = 1;
}
-
+
if (y1 >= yb)
break;
}
if (!w->pseudo_window_p)
{
+ /* Fix the display of overlapping rows. */
+ if (first_overlapping_row)
+ expose_overlaps (w, first_overlapping_row, last_overlapping_row);
+
/* Draw border between windows. */
x_draw_vertical_border (w);
-
+
/* Turn the cursor on again. */
if (cursor_cleared_p)
x_update_window_cursor (w, 1);
dpyinfo->mouse_face_face_id
= face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1, 1);
+ &ignore, pos + 1,
+ !dpyinfo->mouse_face_hidden);
/* Display it as active. */
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
if (BUFFERP (object))
dpyinfo->mouse_face_face_id
= face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1, 1);
+ &ignore, pos + 1,
+ !dpyinfo->mouse_face_hidden);
/* Display it as active. */
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
dpyinfo->mouse_face_window = window;
dpyinfo->mouse_face_face_id
= face_at_buffer_position (w, pos, 0, 0,
- &ignore, pos + 1, 1);
+ &ignore, pos + 1,
+ !dpyinfo->mouse_face_hidden);
/* Display it as active. */
show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
Point mouse_pos;
int ignore1, ignore2;
WindowPtr wp = FrontWindow ();
- struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;
+ struct frame *f;
Lisp_Object frame, tail;
+ if (is_emacs_window(wp))
+ f = ((mac_output *) GetWRefCon (wp))->mFP;
+
BLOCK_INPUT;
if (! NILP (last_mouse_scroll_bar) && insist == 0)
}
if (width < 0)
- width = f->output_data.mac->cursor_width;
+ width = FRAME_CURSOR_WIDTH (f);
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
x_clip_to_row (w, row, gc, 0);
struct frame *f = XFRAME (w->frame);
int new_cursor_type;
int new_cursor_width;
+ int active_cursor;
struct glyph_matrix *current_glyphs;
struct glyph_row *glyph_row;
struct glyph *glyph;
- int cursor_non_selected;
- int active_cursor = 1;
/* This is pointless on invisible frames, and dangerous on garbaged
windows and frames; in the latter case, the frame or window may
xassert (interrupt_input_blocked);
- /* Set new_cursor_type to the cursor we want to be displayed. In a
- mini-buffer window, we want the cursor only to appear if we are
- reading input from this window. For the selected window, we want
- the cursor type given by the frame parameter. If explicitly
- marked off, draw no cursor. In all other cases, we want a hollow
- box cursor. */
- cursor_non_selected
- = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
- w->buffer));
- new_cursor_width = -1;
- if (cursor_in_echo_area
- && FRAME_HAS_MINIBUF_P (f)
- && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
- {
- if (w == XWINDOW (echo_area_window))
- new_cursor_type = FRAME_DESIRED_CURSOR (f);
- else
- {
- if (cursor_non_selected)
- new_cursor_type = HOLLOW_BOX_CURSOR;
- else
- new_cursor_type = NO_CURSOR;
- active_cursor = 0;
- }
- }
- else
- {
- if (f != FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame
- || w != XWINDOW (f->selected_window))
- {
- active_cursor = 0;
+ /* Set new_cursor_type to the cursor we want to be displayed. */
+ new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
- if (MINI_WINDOW_P (w)
- || !cursor_non_selected
- || NILP (XBUFFER (w->buffer)->cursor_type))
- new_cursor_type = NO_CURSOR;
- else
- new_cursor_type = HOLLOW_BOX_CURSOR;
- }
- else
- {
- struct buffer *b = XBUFFER (w->buffer);
-
- if (EQ (b->cursor_type, Qt))
- new_cursor_type = FRAME_DESIRED_CURSOR (f);
- else
- new_cursor_type = x_specified_cursor_type (b->cursor_type,
- &new_cursor_width);
- if (w->cursor_off_p)
- {
- if (new_cursor_type == FILLED_BOX_CURSOR)
- new_cursor_type = HOLLOW_BOX_CURSOR;
- else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
- new_cursor_width = 1;
- else
- new_cursor_type = NO_CURSOR;
- }
- }
- }
/* If cursor is currently being shown and we don't want it to be or
it is in the wrong place, or the cursor type is not what we want,
|| w->phys_cursor.x != x
|| w->phys_cursor.y != y
|| new_cursor_type != w->phys_cursor_type
- || (new_cursor_type == BAR_CURSOR
+ || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
&& new_cursor_width != w->phys_cursor_width)))
x_erase_phys_cursor (w);
x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
break;
+ case HBAR_CURSOR:
+ /* TODO. For now, just draw bar cursor. */
case BAR_CURSOR:
x_draw_bar_cursor (w, glyph_row, new_cursor_width);
break;
/* True if the mouse wheel button (i.e. button 4) should map to
mouse-2, instead of mouse-3. */
Lisp_Object Vmac_wheel_button_is_mouse_2;
+
+/* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
+ for processing before Emacs sees it. */
+Lisp_Object Vmac_pass_command_to_system;
+
+/* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
+ for processing before Emacs sees it. */
+Lisp_Object Vmac_pass_control_to_system;
#endif
/* convert input from Mac keyboard (assumed to be in Mac Roman coding)
case kEventMouseButtonPrimary:
return 0;
case kEventMouseButtonSecondary:
- return NILP (Vmac_wheel_button_is_mouse_2) ? 2 : 1;
+ return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2;
case kEventMouseButtonTertiary:
case 4: /* 4 is the number for the mouse wheel button */
- return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2;
+ return NILP (Vmac_wheel_button_is_mouse_2) ? 2 : 1;
default:
return 0;
}
do_mouse_moved (Point mouse_pos)
{
WindowPtr wp = FrontWindow ();
- struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;
+ struct frame *f;
+ if (is_emacs_window (wp))
+ {
+ f = ((mac_output *) GetWRefCon (wp))->mFP;
+
#if TARGET_API_MAC_CARBON
SetPort (GetWindowPort (wp));
#else
SetPort (wp);
#endif
- GlobalToLocal (&mouse_pos);
-
- note_mouse_movement (f, &mouse_pos);
+ GlobalToLocal (&mouse_pos);
+
+ note_mouse_movement (f, &mouse_pos);
+ }
}
#if USE_CARBON_EVENTS
-void init_service_handler()
+void
+init_service_handler ()
{
EventTypeSpec specs[] = {{kEventClassService, kEventServiceGetTypes},
{kEventClassService, kEventServiceCopy},
/*
MAC_TODO: Check to see if this is called by AEProcessDesc...
*/
-OSStatus mac_handle_service_event (EventHandlerCallRef callRef,
- EventRef event, void *data)
+OSStatus
+mac_handle_service_event (EventHandlerCallRef callRef,
+ EventRef event, void *data)
{
OSStatus err = noErr;
switch (GetEventKind (event))
}
-static pascal OSErr mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
- DragReference theDrag)
+static pascal OSErr
+mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
+ DragReference theDrag)
{
short items;
short index;
/* 0x00 - 0x3f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, '\x0d', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0x40 */
0, '\xae' /* kp. */, 0, '\xaa' /* kp* */,
expected
? TicksToEventTime (app_sleep_time)
: 0,
- true, &eventRef);
+ kEventRemoveFromQueue, &eventRef);
if (!rneResult)
{
/* Handle new events */
{
SInt32 delta;
Point point;
- WindowPtr window_ptr = FrontWindow ();
+ WindowPtr window_ptr = FrontNonFloatingWindow ();
struct mac_output *mwp = (mac_output *) GetWRefCon (window_ptr);
GetEventParameter(eventRef, kEventParamMouseWheelDelta,
typeSInt32, NULL, sizeof (SInt32),
bufp->timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
count++;
}
- else
+ else
SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
break;
SInt16 part_code;
#if USE_CARBON_EVENTS
- /* This is needed to correctly */
- SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+ /* This is needed to send mouse events like aqua window buttons
+ to the correct handler. */
+ if (eventNotHandledErr != SendEventToEventTarget (eventRef, GetEventDispatcherTarget ())) {
+ break;
+ }
+
+ if (!is_emacs_window(window_ptr))
+ break;
#endif
if (mouse_tracking_in_progress == mouse_tracking_scroll_bar
case osEvt:
case activateEvt:
#if USE_CARBON_EVENTS
- SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+ if (eventNotHandledErr == SendEventToEventTarget (eventRef, GetEventDispatcherTarget ()))
#endif
do_events (&er);
break;
int keycode = (er.message & keyCodeMask) >> 8;
int xkeysym;
+#if USE_CARBON_EVENTS
+ /* When using Carbon Events, we need to pass raw keyboard events
+ to the TSM ourselves. If TSM handles it, it will pass back
+ noErr, otherwise it will pass back "eventNotHandledErr" and
+ we can process it normally. */
+ if ((!NILP (Vmac_pass_command_to_system)
+ || !(er.modifiers & cmdKey))
+ && (!NILP (Vmac_pass_control_to_system)
+ || !(er.modifiers & controlKey)))
+ {
+ OSStatus err;
+ err = SendEventToEventTarget (eventRef,
+ GetEventDispatcherTarget ());
+ if (err != eventNotHandledErr)
+ break;
+ }
+#endif
+
if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
{
SysBeep (1);
UNBLOCK_INPUT;
return 0;
}
-
+
ObscureCursor ();
-
+
if (keycode == 0x33) /* delete key (charCode translated to 0x8) */
{
bufp->code = 0x7f;
bufp->code = 0xff00 | xkeysym;
bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
}
- else if (!NILP (Vmac_reverse_ctrl_meta) && (er.modifiers & controlKey))
- {
- /* This is a special case to deal with converting from
- a control character to non-control character */
- int new_modifiers = er.modifiers & ~controlKey;
- int new_keycode = keycode | new_modifiers;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- unsigned long some_state = 0;
- bufp->code = KeyTranslate (kchr_ptr, new_keycode, &some_state) & 0xff;
- bufp->kind = ASCII_KEYSTROKE_EVENT;
- }
else
{
- if (er.modifiers & macMetaKey)
- {
- /* This code comes from Keyboard Resource, Appendix
+ if (er.modifiers & (controlKey |
+ (NILP (Vmac_command_key_is_meta) ? optionKey
+ : cmdKey)))
+ {
+ /* This code comes from Keyboard Resource, Appendix
C of IM - Text. This is necessary since shift is
ignored in KCHR table translation when option or
- command is pressed. */
- int new_modifiers = er.modifiers & 0xf600;
- /* mask off option and command */
- int new_keycode = keycode | new_modifiers;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- unsigned long some_state = 0;
- bufp->code = KeyTranslate (kchr_ptr, new_keycode,
+ command is pressed. It also does not translate
+ correctly control-shift chars like C-% so mask off
+ shift here also */
+ int new_modifiers = er.modifiers & 0xe600;
+ /* mask off option and command */
+ int new_keycode = keycode | new_modifiers;
+ Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+ unsigned long some_state = 0;
+ bufp->code = KeyTranslate (kchr_ptr, new_keycode,
&some_state) & 0xff;
- }
-#if USE_CARBON_EVENTS
- else if (er.modifiers & cmdKey &&
- (NILP (Vmac_command_key_is_meta)))
- {
- /* If this is a command key (and we are not overriding it),
- send back to the operating system */
- SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
- break;
}
-#endif
else
- bufp->code = er.message & charCodeMask;
+ bufp->code = er.message & charCodeMask;
bufp->kind = ASCII_KEYSTROKE_EVENT;
}
}
-
- /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
- convert non-ASCII characters typed at the Mac keyboard
- (presumed to be in the Mac Roman encoding) to iso-latin-1
- encoding before they are passed to Emacs. This enables the
- Mac keyboard to be used to enter non-ASCII iso-latin-1
- characters directly. */
- if (mac_keyboard_text_encoding != kTextEncodingMacRoman
+
+ /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
+ convert non-ASCII characters typed at the Mac keyboard
+ (presumed to be in the Mac Roman encoding) to iso-latin-1
+ encoding before they are passed to Emacs. This enables the
+ Mac keyboard to be used to enter non-ASCII iso-latin-1
+ characters directly. */
+ if (mac_keyboard_text_encoding != kTextEncodingMacRoman
&& bufp->kind == ASCII_KEYSTROKE_EVENT && bufp->code >= 128)
{
- static TECObjectRef converter = NULL;
- OSStatus the_err = noErr;
- OSStatus convert_status = noErr;
-
- if (converter == NULL)
- {
- the_err = TECCreateConverter (&converter,
+ static TECObjectRef converter = NULL;
+ OSStatus the_err = noErr;
+ OSStatus convert_status = noErr;
+
+ if (converter == NULL)
+ {
+ the_err = TECCreateConverter (&converter,
kTextEncodingMacRoman,
mac_keyboard_text_encoding);
- current_mac_keyboard_text_encoding
+ current_mac_keyboard_text_encoding
= mac_keyboard_text_encoding;
- }
- else if (mac_keyboard_text_encoding
+ }
+ else if (mac_keyboard_text_encoding
!= current_mac_keyboard_text_encoding)
- {
- /* Free the converter for the current encoding before
- creating a new one. */
- TECDisposeConverter (converter);
- the_err = TECCreateConverter (&converter,
+ {
+ /* Free the converter for the current encoding before
+ creating a new one. */
+ TECDisposeConverter (converter);
+ the_err = TECCreateConverter (&converter,
kTextEncodingMacRoman,
mac_keyboard_text_encoding);
- current_mac_keyboard_text_encoding
+ current_mac_keyboard_text_encoding
= mac_keyboard_text_encoding;
- }
-
- if (the_err == noErr)
- {
- unsigned char ch = bufp->code;
- ByteCount actual_input_length, actual_output_length;
- unsigned char outch;
-
- convert_status = TECConvertText (converter, &ch, 1,
+ }
+
+ if (the_err == noErr)
+ {
+ unsigned char ch = bufp->code;
+ ByteCount actual_input_length, actual_output_length;
+ unsigned char outch;
+
+ convert_status = TECConvertText (converter, &ch, 1,
&actual_input_length,
- &outch, 1,
+ &outch, 1,
&actual_output_length);
- if (convert_status == noErr
+ if (convert_status == noErr
&& actual_input_length == 1
&& actual_output_length == 1)
- bufp->code = outch;
- }
+ bufp->code = outch;
+ }
}
-
+
#if USE_CARBON_EVENTS
bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
= (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
XSETFRAME (bufp->frame_or_window, mwp->mFP);
}
-
+
bufp->timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
count++;
constuct_drag_n_drop in w32term.c. */
if (!NILP (drag_and_drop_file_list))
{
- struct frame *f;
+ struct frame *f = NULL;
WindowPtr wp;
Lisp_Object frame;
- wp = FrontWindow ();
- if (!wp)
- f = NULL;
- else
- f = ((mac_output *) GetWRefCon (wp))->mFP;
-
+ wp = FrontNonFloatingWindow ();
+
+ if (!wp)
+ {
+ struct frame *f = XFRAME (XCAR (Vframe_list));
+ CollapseWindow (FRAME_MAC_WINDOW (f), false);
+ wp = FrontNonFloatingWindow ();
+ }
+
+ if (wp && is_emacs_window(wp))
+ f = ((mac_output *) GetWRefCon (wp))->mFP;
+
bufp->kind = DRAG_N_DROP_EVENT;
bufp->code = 0;
bufp->timestamp = er.when * (1000 / 60);
}
-void make_mac_frame (struct frame *f)
+void
+make_mac_frame (struct frame *f)
{
FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
-
+
+ FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
+
NewMacWindow(f);
f->output_data.mac->cursor_pixel = 0;
f->output_data.mac->mouse_pixel = 0xff00ff;
f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
- f->output_data.mac->desired_cursor = FILLED_BOX_CURSOR;
-
f->output_data.mac->fontset = -1;
f->output_data.mac->scroll_bar_foreground_pixel = -1;
f->output_data.mac->scroll_bar_background_pixel = -1;
f->new_height = 0;
}
-void make_mac_terminal_frame (struct frame *f)
+void
+make_mac_terminal_frame (struct frame *f)
{
Lisp_Object frame;
return dpyinfo;
}
\f
+#ifdef MAC_OSX
+void
+mac_check_bundle()
+{
+ extern int inhibit_window_system;
+ extern int noninteractive;
+ CFBundleRef appsBundle;
+ pid_t child;
+
+ /* No need to test if already -nw*/
+ if (inhibit_window_system || noninteractive)
+ return;
+
+ appsBundle = CFBundleGetMainBundle();
+ if (appsBundle != NULL)
+ {
+ CFStringRef cfBI = CFSTR("CFBundleIdentifier");
+ CFTypeRef res = CFBundleGetValueForInfoDictionaryKey(appsBundle, cfBI);
+ /* We found the bundle identifier, now we know we are valid. */
+ if (res != NULL)
+ {
+ CFRelease(res);
+ return;
+ }
+ }
+ /* MAC_TODO: Have this start the bundled executable */
+
+ /* For now, prevent the fatal error by bringing it up in the terminal */
+ inhibit_window_system = 1;
+}
+
+void
+MakeMeTheFrontProcess ()
+{
+ ProcessSerialNumber psn;
+ OSErr err;
+
+ err = GetCurrentProcess (&psn);
+ if (err == noErr)
+ (void) SetFrontProcess (&psn);
+}
+
+/***** Code to handle C-g testing *****/
+
+/* Contains the Mac modifier formed from quit_char */
+static mac_quit_char_modifiers = 0;
+static mac_quit_char_keycode;
+extern int quit_char;
+
+static void
+mac_determine_quit_char_modifiers()
+{
+ /* Todo: Determine modifiers from quit_char. */
+ UInt32 qc_modifiers = ctrl_modifier;
+
+ /* Map modifiers */
+ mac_quit_char_modifiers = 0;
+ if (qc_modifiers & ctrl_modifier) mac_quit_char_modifiers |= macCtrlKey;
+ if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= macShiftKey;
+ if (qc_modifiers & meta_modifier) mac_quit_char_modifiers |= macMetaKey;
+ if (qc_modifiers & alt_modifier) mac_quit_char_modifiers |= macAltKey;
+}
+
+static void
+init_quit_char_handler ()
+{
+ /* TODO: Let this support keys other the 'g' */
+ mac_quit_char_keycode = 5;
+ /* Look at <architecture/adb_kb_map.h> for details */
+ /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
+
+ mac_determine_quit_char_modifiers();
+}
+
+static Boolean
+quit_char_comp (EventRef inEvent, void *inCompData)
+{
+ if (GetEventClass(inEvent) != kEventClassKeyboard)
+ return false;
+ if (GetEventKind(inEvent) != kEventRawKeyDown)
+ return false;
+ {
+ UInt32 keyCode;
+ UInt32 keyModifiers;
+ GetEventParameter(inEvent, kEventParamKeyCode,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode);
+ if (keyCode != mac_quit_char_keycode)
+ return false;
+ GetEventParameter(inEvent, kEventParamKeyModifiers,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &keyModifiers);
+ if (keyModifiers != mac_quit_char_modifiers)
+ return false;
+ }
+ return true;
+}
+
+void
+mac_check_for_quit_char()
+{
+ EventRef event;
+ /* If windows are not initialized, return immediately (keep it bouncin')*/
+ if (!mac_quit_char_modifiers)
+ return;
+
+ /* Redetermine modifiers because they are based on lisp variables */
+ mac_determine_quit_char_modifiers();
+
+ /* Fill the queue with events */
+ ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event);
+ event = FindSpecificEventInQueue (GetMainEventQueue(), quit_char_comp, NULL);
+ if (event)
+ {
+ struct input_event e;
+ struct mac_output *mwp = (mac_output*) GetWRefCon (FrontNonFloatingWindow ());
+ /* Use an input_event to emulate what the interrupt handler does. */
+ e.kind = ASCII_KEYSTROKE_EVENT;
+ e.code = quit_char;
+ e.arg = NULL;
+ e.modifiers = NULL;
+ e.timestamp = EventTimeToTicks(GetEventTime(event))*(1000/60);
+ XSETFRAME(e.frame_or_window, mwp->mFP);
+ /* Remove event from queue to prevent looping. */
+ RemoveEventFromQueue(GetMainEventQueue(), event);
+ ReleaseEvent(event);
+ kbd_buffer_store_event(&e);
+ }
+}
+
+#endif /* MAC_OSX */
+
/* Set up use of X before we make the first connection. */
static struct redisplay_interface x_redisplay_interface =
#if USE_CARBON_EVENTS
init_service_handler ();
+
+ init_quit_char_handler ();
#endif
DisableMenuCommand (NULL, kHICommandQuit);
+
+ if (!inhibit_window_system)
+ MakeMeTheFrontProcess ();
#endif
}
x_error_message_string = Qnil;
#endif
+ Fprovide (intern ("mac-carbon"), Qnil);
+
staticpro (&x_display_name_list);
x_display_name_list = Qnil;
the right click will be mouse-3.
Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
Vmac_wheel_button_is_mouse_2 = Qt;
+
+ DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system,
+ doc: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
+Toolbox for processing before Emacs sees it. */);
+ Vmac_pass_command_to_system = Qt;
+
+ DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system,
+ doc: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
+Toolbox for processing before Emacs sees it. */);
+ Vmac_pass_control_to_system = Qt;
#endif
DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding,