precompiled header Carbon.h. */
#undef max
#undef min
+#undef init_process
#include <Carbon/Carbon.h>
#undef free
#define free unexec_free
#define min(a, b) ((a) < (b) ? (a) : (b))
#undef max
#define max(a, b) ((a) > (b) ? (a) : (b))
+#undef init_process
+#define init_process emacs_init_process
+/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
+ obtain events from the event queue. If set to 0, WaitNextEvent is
+ used instead. */
+#define USE_CARBON_EVENTS 1
#else /* not MAC_OSX */
#include <Quickdraw.h>
#include <ToolUtils.h>
#define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
+/* Set of macros that handle mapping of Mac modifier keys to emacs. */
+#define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
+ (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
+#define macShiftKey (shiftKey)
+#define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
+ (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
+ : controlKey)
+#define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
+
\f
/* Fringe bitmaps. */
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);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
SetPort (GetWindowPort (w));
- mac_set_colors (gc);
+
+ ForeColor (blackColor);
+ BackColor (whiteColor);
LockPortBits (GetWindowPort (w));
pmh = GetPortPixMap (GetWindowPort (w));
CopyBits ((BitMap *) *pmh, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
UnlockPortBits (GetWindowPort (w));
+
+ mac_set_colors (gc);
#else /* not TARGET_API_MAC_CARBON */
Rect src_r, dest_r;
the image. I believe it's looking better if we do
nothing here for mouse-face. */
if (s->hl == DRAW_CURSOR)
- mac_draw_rectangle (s->display, s->window, s->gc, x, y,
- s->img->width - 1, s->img->height - 1);
+ {
+ int r = s->img->relief;
+ if (r < 0) r = -r;
+ mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r,
+ s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+ }
}
}
else
the image. I believe it's looking better if we do
nothing here for mouse-face. */
if (s->hl == DRAW_CURSOR)
- mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y,
- s->img->width - 1, s->img->height - 1);
+ {
+ int r = s->img->relief;
+ if (r < 0) r = -r;
+ mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x - r, y - r,
+ s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+ }
}
}
else
}
-/* 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);
{
Point mouseLoc;
- result->kind = mouse_click;
+ result->kind = MOUSE_CLICK_EVENT;
result->code = 0; /* only one mouse button */
result->timestamp = event->when;
result->modifiers = event->what == mouseDown ? down_modifier : up_modifier;
if (glyph < end
&& STRINGP (glyph->object)
- && XSTRING (glyph->object)->intervals
+ && STRING_INTERVALS (glyph->object)
&& glyph->charpos >= 0
- && glyph->charpos < XSTRING (glyph->object)->size)
+ && glyph->charpos < SCHARS (glyph->object))
{
/* If we're on a string with `help-echo' text property,
arrange for the help to be displayed. This is done by
if (NILP (b))
b = make_number (0);
if (NILP (e))
- e = make_number (XSTRING (object)->size - 1);
+ e = make_number (SCHARS (object) - 1);
fast_find_string_pos (w, XINT (b), object,
&dpyinfo->mouse_face_beg_col,
&dpyinfo->mouse_face_beg_row,
/* Try text properties. */
if (STRINGP (object)
&& charpos >= 0
- && charpos < XSTRING (object)->size)
+ && charpos < SCHARS (object))
{
help = Fget_text_property (make_number (charpos),
Qhelp_echo, object);
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)
}
/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
- is set to something other than no_event, it is enqueued.
+ is set to something other than NO_EVENT, it is enqueued.
This may be called from a signal handler, so we have to ignore GC
mark bits. */
if (! GC_WINDOWP (bar->window))
abort ();
- bufp->kind = scroll_bar_click;
+ bufp->kind = SCROLL_BAR_CLICK_EVENT;
bufp->frame_or_window = bar->window;
bufp->arg = Qnil;
}
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;
-
- 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);
+ /* 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 (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;
if (NILP (icon))
hicon = LoadIcon (hinst, EMACS_CLASS);
else if (STRINGP (icon))
- hicon = LoadImage (NULL, (LPCTSTR) XSTRING (icon)->data, IMAGE_ICON, 0, 0,
+ hicon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
LR_DEFAULTSIZE | LR_LOADFROMFILE);
else if (SYMBOLP (icon))
{
/* Now make the frame display the given font. */
if (FRAME_MAC_WINDOW (f) != 0)
{
+ XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->normal_gc,
+ f->output_data.mac->font);
+ XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->reverse_gc,
+ f->output_data.mac->font);
+ XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->cursor_gc,
+ f->output_data.mac->font);
+
frame_update_line_height (f);
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
x_set_window_size (f, 0, f->width, f->height);
to do. */
return fontset_name (fontset);
- result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
+ result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
if (!STRINGP (result))
/* Can't load ASCII font. */
x_iconify_frame (f)
struct frame *f;
{
-#if 0 /* MAC_TODO: really no iconify on Mac */
- int result;
- Lisp_Object type;
-
/* Don't keep the highlight on an invisible frame. */
- if (FRAME_X_DISPLAY_INFO (f)->x_highlight_frame == f)
- FRAME_X_DISPLAY_INFO (f)->x_highlight_frame = 0;
+ if (FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame == f)
+ FRAME_MAC_DISPLAY_INFO (f)->x_highlight_frame = 0;
+#if 0
+ /* Review: Since window is still visible in dock, still allow updates? */
if (f->async_iconified)
return;
+#endif
BLOCK_INPUT;
- FRAME_SAMPLE_VISIBILITY (f);
-
- type = x_icon_type (f);
- if (!NILP (type))
- x_bitmap_icon (f, type);
-
-#ifdef USE_X_TOOLKIT
-
- if (! FRAME_VISIBLE_P (f))
- {
- if (! EQ (Vx_no_window_manager, Qt))
- x_wm_set_window_state (f, IconicState);
- /* This was XtPopup, but that did nothing for an iconified frame. */
- XtMapWidget (f->output_data.x->widget);
- /* The server won't give us any event to indicate
- that an invisible frame was changed to an icon,
- so we have to record it here. */
- f->iconified = 1;
- f->visible = 1;
- f->async_iconified = 1;
- f->async_visible = 0;
- UNBLOCK_INPUT;
- return;
- }
-
- result = XIconifyWindow (FRAME_X_DISPLAY (f),
- XtWindow (f->output_data.x->widget),
- DefaultScreen (FRAME_X_DISPLAY (f)));
- UNBLOCK_INPUT;
-
- if (!result)
- error ("Can't notify window manager of iconification");
-
- f->async_iconified = 1;
- f->async_visible = 0;
-
-
- BLOCK_INPUT;
- XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
-#else /* not USE_X_TOOLKIT */
-
- /* Make sure the X server knows where the window should be positioned,
- in case the user deiconifies with the window manager. */
- if (! FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f))
- x_set_offset (f, f->output_data.x->left_pos, f->output_data.x->top_pos, 0);
-
- /* Since we don't know which revision of X we're running, we'll use both
- the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
-
- /* X11R4: send a ClientMessage to the window manager using the
- WM_CHANGE_STATE type. */
- {
- XEvent message;
-
- message.xclient.window = FRAME_X_WINDOW (f);
- message.xclient.type = ClientMessage;
- message.xclient.message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_wm_change_state;
- message.xclient.format = 32;
- message.xclient.data.l[0] = IconicState;
-
- if (! XSendEvent (FRAME_X_DISPLAY (f),
- DefaultRootWindow (FRAME_X_DISPLAY (f)),
- False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &message))
- {
- UNBLOCK_INPUT_RESIGNAL;
- error ("Can't notify window manager of iconification");
- }
- }
-
- /* X11R3: set the initial_state field of the window manager hints to
- IconicState. */
- x_wm_set_window_state (f, IconicState);
-
- if (!FRAME_VISIBLE_P (f))
- {
- /* If the frame was withdrawn, before, we must map it. */
- XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
- }
-
- f->async_iconified = 1;
- f->async_visible = 0;
-
- XFlush (FRAME_X_DISPLAY (f));
+ CollapseWindow (FRAME_MAC_WINDOW (f), true);
+
UNBLOCK_INPUT;
-#endif /* not USE_X_TOOLKIT */
-#endif /* MAC_TODO */
}
\f
}
-/* Sets up the table font_name_table to contain the list of all
- monospace fonts in the system the first time the table is used so
- that the Resource Manager need not be accessed every time this
- information is needed. */
+static void
+add_font_name_table_entry (char *font_name)
+{
+ if (font_name_table_size == 0)
+ {
+ font_name_table_size = 16;
+ font_name_table = (char **)
+ xmalloc (font_name_table_size * sizeof (char *));
+ }
+ else if (font_name_count + 1 >= font_name_table_size)
+ {
+ font_name_table_size += 16;
+ font_name_table = (char **)
+ xrealloc (font_name_table,
+ font_name_table_size * sizeof (char *));
+ }
+
+ font_name_table[font_name_count++] = font_name;
+}
+
+/* Sets up the table font_name_table to contain the list of all fonts
+ in the system the first time the table is used so that the Resource
+ Manager need not be accessed every time this information is
+ needed. */
static void
init_font_name_table ()
while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
== noErr)
- {
- if (font_name_table_size == 0)
- {
- font_name_table_size = 16;
- font_name_table = (char **)
- xmalloc (font_name_table_size * sizeof (char *));
- }
- else if (font_name_count + 1 >= font_name_table_size)
- {
- font_name_table_size += 16;
- font_name_table = (char **)
- xrealloc (font_name_table,
- font_name_table_size * sizeof (char *));
- }
- font_name_table[font_name_count++]
- = mac_to_x_fontname (name, size, style, sc);
- }
+ if (size == 0)
+ {
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ style, sc));
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ italic, sc));
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ bold, sc));
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ italic | bold,
+ sc));
+ }
+ else
+ {
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ style, sc));
+ if (smJapanese == sc)
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ style,
+ -smJapanese));
+ }
}
/* Dispose of the iterators. */
= mac_to_x_fontname (name,
assc_entry->fontSize,
assc_entry->fontStyle,
- smRoman);
+ -smJapanese);
}
}
}
/* Return a list of at most MAXNAMES font specs matching the one in
- PATTERN. Note that each '*' in the PATTERN matches exactly one
- field of the font spec, unlike X in which an '*' in a font spec can
- match a number of fields. The result is in the Mac implementation
- all fonts must be specified by a font spec with all 13 fields
- (although many of these can be "*'s"). */
+ PATTERN. Cache matching fonts for patterns in
+ dpyinfo->name_list_element to avoid looking them up again by
+ calling mac_font_pattern_match (slow). */
Lisp_Object
x_list_fonts (struct frame *f,
int maxnames)
{
char *ptnstr;
- Lisp_Object newlist = Qnil;
+ Lisp_Object newlist = Qnil, tem, key;
int n_fonts = 0;
int i;
struct gcpro gcpro1, gcpro2;
+ struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
if (font_name_table == NULL) /* Initialize when first used. */
init_font_name_table ();
- ptnstr = XSTRING (pattern)->data;
+ if (dpyinfo)
+ {
+ tem = XCDR (dpyinfo->name_list_element);
+ key = Fcons (pattern, make_number (maxnames));
+
+ newlist = Fassoc (key, tem);
+ if (!NILP (newlist))
+ {
+ newlist = Fcdr_safe (newlist);
+ goto label_cached;
+ }
+ }
+
+ ptnstr = SDATA (pattern);
GCPRO2 (pattern, newlist);
UNGCPRO;
+ if (dpyinfo)
+ {
+ XSETCDR (dpyinfo->name_list_element,
+ Fcons (Fcons (key, newlist),
+ XCDR (dpyinfo->name_list_element)));
+ }
+ label_cached:
+
return newlist;
}
if (sscanf (name,
"-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
cs) == 1
- && 0 == strcmp (cs, "mac-roman"))
+ && 0 == strcmp (cs, "jisx0201.1976-0"))
font->mac_scriptcode = smRoman;
}
for (tail = font_names; CONSP (tail); tail = XCDR (tail))
if (dpyinfo->font_table[i].name
&& (!strcmp (dpyinfo->font_table[i].name,
- XSTRING (XCAR (tail))->data)
+ SDATA (XCAR (tail)))
|| !strcmp (dpyinfo->font_table[i].full_name,
- XSTRING (XCAR (tail))->data)))
+ SDATA (XCAR (tail)))))
return (dpyinfo->font_table + i);
}
a bug of not finding a font even if the font surely exists and
is loadable by XLoadQueryFont. */
if (size > 0 && !NILP (font_names))
- fontname = (char *) XSTRING (XCAR (font_names))->data;
+ fontname = (char *) SDATA (XCAR (font_names));
font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname);
if (!font)
char *name1, *name2;
{
int seen_colon = 0;
- unsigned char *system_name = XSTRING (Vsystem_name)->data;
+ unsigned char *system_name = SDATA (Vsystem_name);
int system_name_length = strlen (system_name);
int length_until_period = 0;
Boolean terminate_flag = false;
-/* true if using command key as meta key */
+/* True if using command key as meta key. */
Lisp_Object Vmac_command_key_is_meta;
+/* True if the ctrl and meta keys should be reversed. */
+Lisp_Object Vmac_reverse_ctrl_meta;
+
+#if USE_CARBON_EVENTS
+/* 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)
to this text encoding */
int mac_keyboard_text_encoding;
Point saved_menu_event_location;
/* Apple Events */
-static void init_required_apple_events(void);
+static void init_required_apple_events (void);
static pascal OSErr
-do_ae_open_application(const AppleEvent *, AppleEvent *, long);
+do_ae_open_application (const AppleEvent *, AppleEvent *, long);
static pascal OSErr
-do_ae_print_documents(const AppleEvent *, AppleEvent *, long);
-static pascal OSErr do_ae_open_documents(AppleEvent *, AppleEvent *, long);
-static pascal OSErr do_ae_quit_application(AppleEvent *, AppleEvent *, long);
+do_ae_print_documents (const AppleEvent *, AppleEvent *, long);
+static pascal OSErr do_ae_open_documents (AppleEvent *, AppleEvent *, long);
+static pascal OSErr do_ae_quit_application (AppleEvent *, AppleEvent *, long);
+
+/* Drag and Drop */
+static OSErr init_mac_drag_n_drop ();
+static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference);
+
+#if USE_CARBON_EVENTS
+/* Preliminary Support for the OSX Services Menu */
+static OSStatus mac_handle_service_event (EventHandlerCallRef,EventRef,void*);
+static void init_service_handler ();
+#endif
extern void init_emacs_passwd_dir ();
extern int emacs_main (int, char **, char **);
extern void initialize_applescript();
extern void terminate_applescript();
+static unsigned int
+#if USE_CARBON_EVENTS
+mac_to_emacs_modifiers (UInt32 mods)
+#else
+mac_to_emacs_modifiers (EventModifiers mods)
+#endif
+{
+ unsigned int result = 0;
+ if (mods & macShiftKey)
+ result |= shift_modifier;
+ if (mods & macCtrlKey)
+ result |= ctrl_modifier;
+ if (mods & macMetaKey)
+ result |= meta_modifier;
+ if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey))
+ result |= alt_modifier;
+ return result;
+}
+
+#if USE_CARBON_EVENTS
+/* Obtains the event modifiers from the event ref and then calls
+ mac_to_emacs_modifiers. */
+static int
+mac_event_to_emacs_modifiers (EventRef eventRef)
+{
+ UInt32 mods = 0;
+ GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof (UInt32), NULL, &mods);
+ return mac_to_emacs_modifiers (mods);
+}
+
+/* Given an event ref, return the code to use for the mouse button
+ code in the emacs input_event. */
+static int
+mac_get_mouse_btn (EventRef ref)
+{
+ EventMouseButton result = kEventMouseButtonPrimary;
+ GetEventParameter (ref, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof (EventMouseButton), NULL, &result);
+ switch (result)
+ {
+ case kEventMouseButtonPrimary:
+ return 0;
+ case kEventMouseButtonSecondary:
+ 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) ? 2 : 1;
+ default:
+ return 0;
+ }
+}
+
+/* Normally, ConvertEventRefToEventRecord will correctly handle all
+ events. However the click of the mouse wheel is not converted to a
+ mouseDown or mouseUp event. This calls ConvertEventRef, but then
+ checks to see if it is a mouse up or down carbon event that has not
+ been converted, and if so, converts it by hand (to be picked up in
+ the XTread_socket loop). */
+static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec)
+{
+ Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec);
+ /* Do special case for mouse wheel button. */
+ if (!result && GetEventClass (eventRef) == kEventClassMouse)
+ {
+ UInt32 kind = GetEventKind (eventRef);
+ if (kind == kEventMouseDown && !(eventRec->what == mouseDown))
+ {
+ eventRec->what = mouseDown;
+ result=1;
+ }
+ if (kind == kEventMouseUp && !(eventRec->what == mouseUp))
+ {
+ eventRec->what = mouseUp;
+ result=1;
+ }
+ if (result)
+ {
+ /* Need where and when. */
+ UInt32 mods;
+ GetEventParameter (eventRef, kEventParamMouseLocation,
+ typeQDPoint, NULL, sizeof (Point),
+ NULL, &eventRec->where);
+ /* Use two step process because new event modifiers are
+ 32-bit and old are 16-bit. Currently, only loss is
+ NumLock & Fn. */
+ GetEventParameter (eventRef, kEventParamKeyModifiers,
+ typeUInt32, NULL, sizeof (UInt32),
+ NULL, &mods);
+ eventRec->modifiers = mods;
+
+ eventRec->when = EventTimeToTicks (GetEventTime (eventRef));
+ }
+ }
+ return result;
+}
+
+#endif
static void
do_get_menus (void)
BeginUpdate (win);
handling_window_update = 1;
+ XClearWindow (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+
expose_frame (f, 0, 0, 0, 0);
handling_window_update = 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);
+ }
}
SetPort (save_port);
}
+/* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
+static OSErr
+init_mac_drag_n_drop ()
+{
+ OSErr result = InstallReceiveHandler (mac_do_receive_drag, 0L, NULL);
+ return result;
+}
/* Intialize AppleEvent dispatcher table for the required events. */
void
abort ();
}
+#if USE_CARBON_EVENTS
+
+void
+init_service_handler ()
+{
+ EventTypeSpec specs[] = {{kEventClassService, kEventServiceGetTypes},
+ {kEventClassService, kEventServiceCopy},
+ {kEventClassService, kEventServicePaste}};
+ InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event),
+ 3, specs, NULL, NULL);
+}
+
+/*
+ MAC_TODO: Check to see if this is called by AEProcessDesc...
+ */
+OSStatus
+mac_handle_service_event (EventHandlerCallRef callRef,
+ EventRef event, void *data)
+{
+ OSStatus err = noErr;
+ switch (GetEventKind (event))
+ {
+ case kEventServiceGetTypes:
+ {
+ CFMutableArrayRef copyTypes, pasteTypes;
+ CFStringRef type;
+ Boolean selection = true;
+ /*
+ GetEventParameter(event, kEventParamServicePasteTypes,
+ typeCFMutableArrayRef, NULL,
+ sizeof (CFMutableArrayRef), NULL, &pasteTypes);
+ */
+ GetEventParameter(event, kEventParamServiceCopyTypes,
+ typeCFMutableArrayRef, NULL,
+ sizeof (CFMutableArrayRef), NULL, ©Types);
+ type = CreateTypeStringWithOSType (kScrapFlavorTypeText);
+ if (type) {
+ CFArrayAppendValue (copyTypes, type);
+ //CFArrayAppendValue (pasteTypes, type);
+ CFRelease (type);
+ }
+ }
+ case kEventServiceCopy:
+ {
+ ScrapRef currentScrap, specificScrap;
+ char * buf = "";
+ Size byteCount = 0;
+
+ GetCurrentScrap (¤tScrap);
+
+ err = GetScrapFlavorSize (currentScrap, kScrapFlavorTypeText, &byteCount);
+ if (err == noErr)
+ {
+ void *buffer = xmalloc (byteCount);
+ if (buffer != NULL)
+ {
+ GetEventParameter (event, kEventParamScrapRef, typeScrapRef, NULL,
+ sizeof (ScrapRef), NULL, &specificScrap);
+
+ err = GetScrapFlavorData (currentScrap, kScrapFlavorTypeText,
+ &byteCount, buffer);
+ if (err == noErr)
+ PutScrapFlavor (specificScrap, kScrapFlavorTypeText,
+ kScrapFlavorMaskNone, byteCount, buffer);
+ xfree (buffer);
+ }
+ }
+ err = noErr;
+ }
+ case kEventServicePaste:
+ {
+ /*
+ // Get the current location
+ Size byteCount;
+ ScrapRef specificScrap;
+ GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
+ sizeof(ScrapRef), NULL, &specificScrap);
+ err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
+ if (err == noErr) {
+ void * buffer = xmalloc(byteCount);
+ if (buffer != NULL ) {
+ err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
+ &byteCount, buffer);
+ if (err == noErr) {
+ // Actually place in the buffer
+ BLOCK_INPUT;
+ // Get the current "selection" string here
+ UNBLOCK_INPUT;
+ }
+ }
+ xfree(buffer);
+ }
+ */
+ }
+ }
+ return err;
+}
+#endif
/* Open Application Apple Event */
static pascal OSErr
int i;
/* AE file list is one based so just use that for indexing here. */
- for (i = 1; (err == noErr) && (i <= num_files_to_open); i++) {
- FSSpec fs;
- Str255 path_name, unix_path_name;
+ for (i = 1; (err == noErr) && (i <= num_files_to_open); i++)
+ {
+ FSSpec fs;
+ Str255 path_name, unix_path_name;
+#ifdef MAC_OSX
+ FSRef fref;
+#endif
- err = AEGetNthPtr(&the_desc, i, typeFSS, &keyword, &actual_type,
- (Ptr) &fs, sizeof (fs), &actual_size);
- if (err != noErr) break;
+ err = AEGetNthPtr(&the_desc, i, typeFSS, &keyword, &actual_type,
+ (Ptr) &fs, sizeof (fs), &actual_size);
+ if (err != noErr) break;
- if (path_from_vol_dir_name (path_name, 255, fs.vRefNum, fs.parID,
- fs.name) &&
- mac_to_posix_pathname (path_name, unix_path_name, 255))
- drag_and_drop_file_list = Fcons (build_string (unix_path_name),
- drag_and_drop_file_list);
- }
+#ifdef MAC_OSX
+ err = FSpMakeFSRef (&fs, &fref);
+ if (err != noErr) break;
+
+ if (FSRefMakePath (&fref, unix_path_name, 255) == noErr)
+#else
+ if (path_from_vol_dir_name (path_name, 255, fs.vRefNum, fs.parID,
+ fs.name) &&
+ mac_to_posix_pathname (path_name, unix_path_name, 255))
+#endif
+ drag_and_drop_file_list = Fcons (build_string (unix_path_name),
+ drag_and_drop_file_list);
+ }
}
}
}
+static pascal OSErr
+mac_do_receive_drag (WindowPtr window, void *handlerRefCon,
+ DragReference theDrag)
+{
+ short items;
+ short index;
+ FlavorFlags theFlags;
+ Point mouse;
+ OSErr result;
+ ItemReference theItem;
+ HFSFlavor data;
+ FSRef fref;
+ Size size = sizeof (HFSFlavor);
+
+ drag_and_drop_file_list = Qnil;
+ GetDragMouse (theDrag, &mouse, 0L);
+ CountDragItems (theDrag, &items);
+ for (index = 1; index <= items; index++)
+ {
+ /* Only handle file references. */
+ GetDragItemReferenceNumber (theDrag, index, &theItem);
+ result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
+ if (result == noErr)
+ {
+#ifdef MAC_OSX
+ FSRef frref;
+#else
+ Str255 path_name;
+#endif
+ Str255 unix_path_name;
+ GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L);
+#ifdef MAC_OSX
+ /* Use Carbon routines, otherwise it converts the file name
+ to /Macintosh HD/..., which is not correct. */
+ FSpMakeFSRef (&data.fileSpec, &fref);
+ if (! FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name)));
+#else
+ if (path_from_vol_dir_name (path_name, 255, data.fileSpec.vRefNum,
+ data.fileSpec.parID, data.fileSpec.name) &&
+ mac_to_posix_pathname (path_name, unix_path_name, 255))
+#endif
+ drag_and_drop_file_list = Fcons (build_string (unix_path_name),
+ drag_and_drop_file_list);
+ }
+ else
+ return;
+ }
+ /* If there are items in the list, construct an event and post it to
+ the queue like an interrupt using kbd_buffer_store_event. */
+ if (!NILP (drag_and_drop_file_list))
+ {
+ struct input_event event;
+ Lisp_Object frame;
+ struct frame *f = ((mac_output *) GetWRefCon(window))->mFP;
+ SetPort (GetWindowPort (window));
+ GlobalToLocal (&mouse);
+
+ event.kind = DRAG_N_DROP_EVENT;
+ event.code = 0;
+ event.modifiers = 0;
+ event.timestamp = TickCount () * (1000 / 60);
+ XSETINT (event.x, mouse.h);
+ XSETINT (event.y, mouse.v);
+ XSETFRAME (frame, f);
+ event.frame_or_window = Fcons (frame, drag_and_drop_file_list);
+ event.arg = Qnil;
+ /* Post to the interrupt queue */
+ kbd_buffer_store_event (&event);
+ /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
+ {
+ ProcessSerialNumber psn;
+ GetCurrentProcess (&psn);
+ SetFrontProcess (&psn);
+ }
+ }
+}
+
+
/* Print Document Apple Event */
static pascal OSErr
do_ae_print_documents (const AppleEvent *pAE, AppleEvent *reply, long refcon)
/* 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* */,
int
XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
{
- int count = 0;
+ int count = 0;
+#if USE_CARBON_EVENTS
+ OSStatus rneResult;
+ EventRef eventRef;
+ EventMouseButton mouseBtn;
+#endif
EventRecord er;
int the_modifiers;
EventMask event_mask;
if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
event_mask -= highLevelEventMask;
- while (WaitNextEvent (event_mask, &er, 0L, NULL) && numchars > 0)
+#if USE_CARBON_EVENTS
+ rneResult = ReceiveNextEvent (0, NULL,
+ expected
+ ? TicksToEventTime (app_sleep_time)
+ : 0,
+ true, &eventRef);
+ if (!rneResult)
+ {
+ /* Handle new events */
+ if (!mac_convert_event_ref (eventRef, &er))
+ switch (GetEventClass (eventRef))
+ {
+ case kEventClassMouse:
+ if (GetEventKind (eventRef) == kEventMouseWheelMoved)
+ {
+ SInt32 delta;
+ Point point;
+ WindowPtr window_ptr = FrontNonFloatingWindow ();
+ struct mac_output *mwp = (mac_output *) GetWRefCon (window_ptr);
+ GetEventParameter(eventRef, kEventParamMouseWheelDelta,
+ typeSInt32, NULL, sizeof (SInt32),
+ NULL, &delta);
+ GetEventParameter(eventRef, kEventParamMouseLocation,
+ typeQDPoint, NULL, sizeof (Point),
+ NULL, &point);
+ bufp->kind = MOUSE_WHEEL_EVENT;
+ bufp->code = delta;
+ bufp->modifiers = mac_event_to_emacs_modifiers(eventRef);
+ SetPort (GetWindowPort (window_ptr));
+ GlobalToLocal (&point);
+ XSETINT (bufp->x, point.h);
+ XSETINT (bufp->y, point.v);
+ XSETFRAME (bufp->frame_or_window, mwp->mFP);
+ bufp->timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
+ count++;
+ }
+ else
+ SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+
+ break;
+ default:
+ /* Send the event to the appropriate receiver. */
+ SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+ }
+ else
+#else
+ if (WaitNextEvent (event_mask, &er, (expected ? app_sleep_time : 0L), NULL))
+#endif /* USE_CARBON_EVENTS */
switch (er.what)
{
case mouseDown:
WindowPtr window_ptr = FrontWindow ();
SInt16 part_code;
+#if USE_CARBON_EVENTS
+ /* 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
&& er.what == mouseUp)
{
GlobalToLocal (&mouse_loc);
+#if USE_CARBON_EVENTS
+ bufp->code = mac_get_mouse_btn (eventRef);
+#else
bufp->code = 0; /* only one mouse button */
- bufp->kind = scroll_bar_click;
+#endif
+ bufp->kind = SCROLL_BAR_CLICK_EVENT;
bufp->frame_or_window = tracked_scroll_bar->window;
bufp->part = scroll_bar_handle;
- bufp->modifiers = up_modifier;
+#if USE_CARBON_EVENTS
+ bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+ bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+#endif
+ bufp->modifiers |= up_modifier;
bufp->timestamp = er.when * (1000 / 60);
/* ticks to milliseconds */
mouse_tracking_in_progress = mouse_tracking_none;
tracked_scroll_bar = NULL;
count++;
- bufp++;
- numchars--;
break;
}
struct frame *f = ((mac_output *)
GetWRefCon (FrontWindow ()))->mFP;
saved_menu_event_location = er.where;
- bufp->kind = menu_bar_activate_event;
+ bufp->kind = MENU_BAR_ACTIVATE_EVENT;
XSETFRAME (bufp->frame_or_window, f);
count++;
- bufp++;
- numchars--;
}
break;
#else
control_part_code = FindControl (mouse_loc, window_ptr, &ch);
#endif
+
+#if USE_CARBON_EVENTS
+ bufp->code = mac_get_mouse_btn (eventRef);
+#else
bufp->code = 0; /* only one mouse button */
+#endif
XSETINT (bufp->x, mouse_loc.h);
XSETINT (bufp->y, mouse_loc.v);
bufp->timestamp = er.when * (1000 / 60);
}
else
{
- bufp->kind = mouse_click;
+ bufp->kind = MOUSE_CLICK_EVENT;
XSETFRAME (bufp->frame_or_window, mwp->mFP);
if (er.what == mouseDown)
mouse_tracking_in_progress
mouse_tracking_in_progress = mouse_tracking_none;
}
+#if USE_CARBON_EVENTS
+ bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+ bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+#endif
+
switch (er.what)
{
case mouseDown:
- bufp->modifiers = down_modifier;
+ bufp->modifiers |= down_modifier;
break;
case mouseUp:
- bufp->modifiers = up_modifier;
+ bufp->modifiers |= up_modifier;
break;
}
count++;
- bufp++;
- numchars--;
}
break;
case inGoAway:
if (TrackGoAway (window_ptr, er.where))
{
- bufp->kind = delete_window_event;
+ bufp->kind = DELETE_WINDOW_EVENT;
XSETFRAME (bufp->frame_or_window,
((mac_output *) GetWRefCon (window_ptr))->mFP);
count++;
- bufp++;
- numchars--;
}
break;
case updateEvt:
case osEvt:
case activateEvt:
+#if USE_CARBON_EVENTS
+ 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->kind = ascii_keystroke;
+ bufp->kind = ASCII_KEYSTROKE_EVENT;
}
else if (keycode_to_xkeysym (keycode, &xkeysym))
{
bufp->code = 0xff00 | xkeysym;
- bufp->kind = non_ascii_keystroke;
- }
+ 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
- & (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
+ if (er.modifiers & macMetaKey)
{
/* This code comes from Keyboard Resource, Appendix
C of IM - Text. This is necessary since shift is
}
else
bufp->code = er.message & charCodeMask;
- bufp->kind = ascii_keystroke;
+ bufp->kind = ASCII_KEYSTROKE_EVENT;
}
}
Mac keyboard to be used to enter non-ASCII iso-latin-1
characters directly. */
if (mac_keyboard_text_encoding != kTextEncodingMacRoman
- && bufp->kind == ascii_keystroke && bufp->code >= 128)
+ && bufp->kind == ASCII_KEYSTROKE_EVENT && bufp->code >= 128)
{
static TECObjectRef converter = NULL;
OSStatus the_err = noErr;
}
}
- the_modifiers = 0;
- if (er.modifiers & shiftKey)
- the_modifiers |= shift_modifier;
- if (er.modifiers & controlKey)
- the_modifiers |= ctrl_modifier;
- /* use option or command key as meta depending on value of
- mac-command-key-is-meta */
- if (er.modifiers
- & (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
- the_modifiers |= meta_modifier;
- bufp->modifiers = the_modifiers;
-
+#if USE_CARBON_EVENTS
+ bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+ bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+#endif
+
{
- mac_output *mwp = (mac_output *) GetWRefCon (FrontWindow ());
+ mac_output *mwp
+ = (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
XSETFRAME (bufp->frame_or_window, mwp->mFP);
}
bufp->timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
count++;
- bufp++;
- numchars--;
break;
case kHighLevelEvent:
AEProcessAppleEvent(&er);
- /* Build a drag_n_drop type event as is done in
+ /* Build a DRAG_N_DROP_EVENT type event as is done in
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;
-
- bufp->kind = drag_n_drop;
+ 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);
/* ticks to milliseconds */
- bufp->modifiers = 0;
+#if USE_CARBON_EVENTS
+ bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+ bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+#endif
XSETINT (bufp->x, 0);
XSETINT (bufp->y, 0);
#endif /* not TARGET_API_MAC_CARBON */
count++;
- bufp++;
- numchars--;
}
-
default:
break;
}
+#if USE_CARBON_EVENTS
+ ReleaseEvent (eventRef);
+ }
+#endif
/* If the focus was just given to an autoraising frame,
raise it now. */
if (!(mwp->mWP = GetNewCWindow (WINDOW_RESOURCE, NULL, (WindowPtr) -1)))
abort ();
-
SetWRefCon (mwp->mWP, (long) mwp);
/* so that update events can find this mac_output struct */
mwp->mFP = fp; /* point back to emacs frame */
}
-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);
- FRAME_BACKGROUND_PIXEL (f) = 0xffffff;
- FRAME_FOREGROUND_PIXEL (f) = 0;
f->output_data.mac->cursor_pixel = 0;
f->output_data.mac->border_pixel = 0x00ff00;
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;
char *name1, *name2;
{
int seen_colon = 0;
- unsigned char *system_name = XSTRING (Vsystem_name)->data;
+ unsigned char *system_name = SDATA (Vsystem_name);
int system_name_length = strlen (system_name);
int length_until_period = 0;
#if 0
dpyinfo->mac_id_name
- = (char *) xmalloc (XSTRING (Vinvocation_name)->size
- + XSTRING (Vsystem_name)->size
+ = (char *) xmalloc (SCHARS (Vinvocation_name)
+ + SCHARS (Vsystem_name)
+ 2);
sprintf (dpyinfo->mac_id_name, "%s@%s",
- XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
+ SDATA (Vinvocation_name), SDATA (Vsystem_name));
#else
dpyinfo->mac_id_name = (char *) xmalloc (strlen ("Mac Display") + 1);
strcpy (dpyinfo->mac_id_name, "Mac Display");
return dpyinfo;
}
\f
+#ifdef MAC_OSX
+void
+MakeMeTheFrontProcess ()
+{
+ ProcessSerialNumber psn;
+ OSErr err;
+
+ err = GetCurrentProcess (&psn);
+ if (err == noErr)
+ (void) SetFrontProcess (&psn);
+}
+#endif /* MAC_OSX */
+
/* Set up use of X before we make the first connection. */
static struct redisplay_interface x_redisplay_interface =
#endif
mac_initialize_display_info ();
+
+#if TARGET_API_MAC_CARBON
+ init_required_apple_events ();
+
+ init_mac_drag_n_drop ();
+
+#if USE_CARBON_EVENTS
+ init_service_handler ();
+#endif
+
+ DisableMenuCommand (NULL, kHICommandQuit);
+
+ if (!inhibit_window_system)
+ MakeMeTheFrontProcess ();
+#endif
}
Otherwise the option key is used. */);
Vmac_command_key_is_meta = Qt;
+ DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta,
+ doc: /* Non-nil means that the control and meta keys are reversed. This is
+ useful for non-standard keyboard layouts. */);
+ Vmac_reverse_ctrl_meta = Qnil;
+
+#if USE_CARBON_EVENTS
+ DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2,
+ doc: /* Non-nil means that the wheel button will be treated as mouse-2 and
+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 = Qnil;
+
+ 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,
doc: /* One of the Text Encoding Base constant values defined in the
Basic Text Constants section of Inside Macintosh - Text Encoding