X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f00691a3e4e5b7997ee7efe6e745d1158a439b21..72742a999a8b0ea7a67dd2c3c17f89579a2bb102:/src/macterm.c diff --git a/src/macterm.c b/src/macterm.c index d98f24bc4f..a0997c4e06 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -58,6 +58,10 @@ Boston, MA 02111-1307, USA. */ #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 #include @@ -106,6 +110,15 @@ Boston, MA 02111-1307, USA. */ #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) + /* Fringe bitmaps. */ @@ -353,6 +366,7 @@ extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *)); extern Lisp_Object x_icon_type P_ ((struct frame *)); +extern int inhibit_window_system; #if __MRC__ QDGlobals qd; /* QuickDraw global information structure. */ @@ -405,7 +419,6 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int)); 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)); @@ -430,6 +443,8 @@ static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); 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)); @@ -461,6 +476,8 @@ static void x_produce_stretch_glyph P_ ((struct it *)); 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); @@ -970,12 +987,16 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y) 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; @@ -6221,8 +6242,41 @@ x_phys_cursor_in_rect_p (w, r) } -/* 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. */ @@ -6262,7 +6316,8 @@ expose_window (w, fr) 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)); @@ -6282,7 +6337,8 @@ expose_window (w, fr) 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) @@ -6295,10 +6351,17 @@ expose_window (w, fr) || (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; } @@ -6315,9 +6378,13 @@ expose_window (w, fr) 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); @@ -7001,9 +7068,9 @@ note_mode_line_highlight (w, x, mode_line_p) 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 @@ -7263,7 +7330,8 @@ note_mouse_highlight (f, x, y) 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); @@ -7305,7 +7373,8 @@ note_mouse_highlight (f, x, y) 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); @@ -7324,7 +7393,7 @@ note_mouse_highlight (f, x, y) 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, @@ -7384,7 +7453,8 @@ note_mouse_highlight (f, x, y) 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); @@ -7422,7 +7492,7 @@ note_mouse_highlight (f, x, y) /* 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); @@ -8233,9 +8303,12 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) 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) @@ -9026,7 +9099,7 @@ x_draw_bar_cursor (w, row, width) } 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); @@ -9228,11 +9301,10 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) 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 @@ -9262,65 +9334,9 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) 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, @@ -9330,7 +9346,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) || 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); @@ -9361,6 +9377,8 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) 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; @@ -9465,7 +9483,7 @@ x_bitmap_icon (f, icon) 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)) { @@ -9602,7 +9620,7 @@ x_new_fontset (f, fontsetname) 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. */ @@ -10088,108 +10106,21 @@ void 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 */ } @@ -10743,8 +10674,14 @@ init_font_name_table () sc)); } else - add_font_name_table_entry (mac_to_x_fontname (name, size, style, - sc)); + { + 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. */ @@ -10829,7 +10766,7 @@ init_font_name_table () = mac_to_x_fontname (name, assc_entry->fontSize, assc_entry->fontStyle, - smRoman); + -smJapanese); } } } @@ -10850,11 +10787,9 @@ init_font_name_table () /* 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, @@ -10863,15 +10798,29 @@ 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); @@ -10892,6 +10841,14 @@ x_list_fonts (struct frame *f, UNGCPRO; + if (dpyinfo) + { + XSETCDR (dpyinfo->name_list_element, + Fcons (Fcons (key, newlist), + XCDR (dpyinfo->name_list_element))); + } + label_cached: + return newlist; } @@ -11101,7 +11058,7 @@ XLoadQueryFont (Display *dpy, char *fontname) if (sscanf (name, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", cs) == 1 - && 0 == strcmp (cs, "mac-roman")) + && 0 == strcmp (cs, "jisx0201.1976-0")) font->mac_scriptcode = smRoman; } @@ -11213,9 +11170,9 @@ x_load_font (f, fontname, size) 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); } @@ -11233,7 +11190,7 @@ x_load_font (f, fontname, size) 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) @@ -11427,7 +11384,7 @@ same_x_server (name1, name2) 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; @@ -11530,9 +11487,26 @@ static long app_sleep_time = WNE_SLEEP_AT_RESUME; 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; @@ -11547,13 +11521,23 @@ Lisp_Object drag_and_drop_file_list; 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 **); @@ -11562,6 +11546,104 @@ extern void check_alarm (); 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) @@ -11649,6 +11731,8 @@ do_window_update (WindowPtr win) 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; @@ -11764,17 +11848,22 @@ static void 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); + } } @@ -11987,6 +12076,13 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) 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 @@ -12060,6 +12156,104 @@ init_required_apple_events () 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 @@ -12117,20 +12311,31 @@ do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon) 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); + } } } @@ -12144,6 +12349,84 @@ descriptor_error_exit: } +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) @@ -12255,7 +12538,7 @@ static unsigned char keycode_to_xkeysym_table[] = { /* 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* */, @@ -12291,7 +12574,12 @@ keycode_to_xkeysym (int keyCode, int *xKeySym) 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; @@ -12337,7 +12625,54 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) if (NILP (Fboundp (Qmac_ready_for_drag_n_drop))) event_mask -= highLevelEventMask; +#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: @@ -12346,6 +12681,17 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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) { @@ -12361,11 +12707,20 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) GlobalToLocal (&mouse_loc); +#if USE_CARBON_EVENTS + bufp->code = mac_get_mouse_btn (eventRef); +#else bufp->code = 0; /* only one mouse button */ +#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 */ @@ -12418,7 +12773,12 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) #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); @@ -12458,13 +12818,19 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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; } @@ -12516,6 +12882,9 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) case updateEvt: case osEvt: case activateEvt: +#if USE_CARBON_EVENTS + if (eventNotHandledErr == SendEventToEventTarget (eventRef, GetEventDispatcherTarget ())) +#endif do_events (&er); break; @@ -12525,6 +12894,31 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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) */ @@ -12536,11 +12930,21 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) { 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 - & (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 @@ -12611,20 +13015,15 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) } } - 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); } @@ -12642,21 +13041,31 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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); /* 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); @@ -12682,10 +13091,13 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) count++; } - default: break; } +#if USE_CARBON_EVENTS + ReleaseEvent (eventRef); + } +#endif /* If the focus was just given to an autoraising frame, raise it now. */ @@ -12797,7 +13209,6 @@ NewMacWindow (FRAME_PTR fp) 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 */ @@ -12816,22 +13227,21 @@ NewMacWindow (FRAME_PTR fp) } -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; @@ -12851,7 +13261,8 @@ void make_mac_frame (struct frame *f) f->new_height = 0; } -void make_mac_terminal_frame (struct frame *f) +void +make_mac_terminal_frame (struct frame *f) { Lisp_Object frame; @@ -12920,7 +13331,7 @@ same_x_server (name1, name2) 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; @@ -12978,11 +13389,11 @@ mac_initialize_display_info () #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"); @@ -13033,6 +13444,19 @@ mac_term_init (display_name, xrm_option, resource_name) return dpyinfo; } +#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 = @@ -13131,6 +13555,21 @@ mac_initialize () #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 } @@ -13199,6 +13638,29 @@ to 4.1, set this to nil. */); 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