/* Implementation of GUI terminal on the Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <alloca.h>
#endif
-#ifdef MAC_OSX
+#if TARGET_API_MAC_CARBON
/* 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 */
+#else /* not TARGET_API_MAC_CARBON */
#include <Quickdraw.h>
#include <ToolUtils.h>
#include <Sound.h>
#if __profile__
#include <profiler.h>
#endif
-#endif /* not MAC_OSX */
+#endif /* not TARGET_API_MAC_CARBON */
#include "systty.h"
#include "systime.h"
#include <errno.h>
#include <setjmp.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include "keyboard.h"
#include "frame.h"
: controlKey)
#define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
+#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
\f
/* Non-nil means Emacs uses toolkit scroll bars. */
Lisp_Object Vx_toolkit_scroll_bars;
+/* If Non-nil, the text will be rendered using Core Graphics text rendering which may anti-alias the text. */
+Lisp_Object Vmac_use_core_graphics;
+
+
/* Non-zero means that a HELP_EVENT has been generated since Emacs
start. */
static int any_help_event_p;
-/* Non-zero means autoselect window with the mouse cursor. */
-
-int x_autoselect_window_p;
+/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
+static Lisp_Object last_window;
/* Non-zero means make use of UNDERLINE_POSITION font properties. */
struct x_display_info *x_display_list;
/* This is a list of cons cells, each of the form (NAME
- . FONT-LIST-CACHE), one for each element of x_display_list and in
- the same order. NAME is the name of the frame. FONT-LIST-CACHE
- records previous values returned by x-list-fonts. */
+ FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
+ x_display_list and in the same order. NAME is the name of the
+ frame. FONT-LIST-CACHE records previous values returned by
+ x-list-fonts. RESOURCE-DATABASE preserves the X Resource Database
+ equivalent, which is implemented with a Lisp object, for the
+ display. */
Lisp_Object x_display_name_list;
extern int inhibit_window_system;
-#if __MRC__
+#if __MRC__ && !TARGET_API_MAC_CARBON
QDGlobals qd; /* QuickDraw global information structure. */
#endif
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
static void XTframe_up_to_date P_ ((struct frame *));
-static void XTreassert_line_highlight P_ ((int, int));
-static void x_change_line_highlight P_ ((int, int, int, int));
static void XTset_terminal_modes P_ ((void));
static void XTreset_terminal_modes P_ ((void));
static void x_clear_frame P_ ((void));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
+static void mac_focus_changed P_ ((int, struct mac_display_info *,
+ struct frame *, struct input_event *));
+static void x_detect_focus_change P_ ((struct mac_display_info *,
+ EventRecord *, struct input_event *));
static void XTframe_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
static void x_update_window_begin P_ ((struct window *));
static void x_after_update_window_line P_ ((struct glyph_row *));
-void activate_scroll_bars (FRAME_PTR);
-void deactivate_scroll_bars (FRAME_PTR);
-
static int is_emacs_window (WindowPtr);
int x_bitmap_icon (struct frame *, Lisp_Object);
commands. Assume that the graphic port has already been set. */
static void
-mac_set_colors (GC gc)
+mac_set_colors (gc, bg_save)
+ GC gc;
+ RGBColor *bg_save;
{
+ if (bg_save)
+ GetBackColor (bg_save);
mac_set_forecolor (gc->foreground);
mac_set_backcolor (gc->background);
}
GC gc;
int x1, y1, x2, y2;
{
+ RGBColor old_bg;
+
SetPortWindowPort (w);
- mac_set_colors (gc);
+ mac_set_colors (gc, &old_bg);
MoveTo (x1, y1);
LineTo (x2, y2);
+
+ RGBBackColor (&old_bg);
}
void
GetGWorld (&old_port, &old_gdh);
SetGWorld (p, NULL);
- mac_set_colors (gc);
+ mac_set_colors (gc, NULL);
LockPixels (GetGWorldPixMap (p));
MoveTo (x1, y1);
struct mac_output *mwp = (mac_output *) GetWRefCon (w);
Rect r;
XGCValues xgc;
+ RGBColor old_bg;
xgc.foreground = mwp->x_compatible.foreground_pixel;
xgc.background = mwp->x_compatible.background_pixel;
SetPortWindowPort (w);
- mac_set_colors (&xgc);
+ mac_set_colors (&xgc, &old_bg);
SetRect (&r, x, y, x + width, y + height);
EraseRect (&r);
+
+ RGBBackColor (&old_bg);
}
/* Mac version of XClearWindow. */
SetPortWindowPort (w);
- mac_set_colors (&xgc);
+ mac_set_colors (&xgc, NULL);
#if TARGET_API_MAC_CARBON
{
{
BitMap bitmap;
Rect r;
+ RGBColor old_bg;
bitmap.rowBytes = sizeof(unsigned short);
bitmap.baseAddr = (char *)bits;
SetPortWindowPort (w);
- mac_set_colors (gc);
+ mac_set_colors (gc, &old_bg);
SetRect (&r, x, y, x + width, y + height);
#if TARGET_API_MAC_CARBON
CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
overlay_p ? srcOr : srcCopy, 0);
#endif /* not TARGET_API_MAC_CARBON */
+
+ RGBBackColor (&old_bg);
}
unsigned int width, height;
{
Rect r;
+ RGBColor old_bg;
SetPortWindowPort (w);
- mac_set_colors (gc);
+ mac_set_colors (gc, &old_bg);
SetRect (&r, x, y, x + width, y + height);
PaintRect (&r); /* using foreground color of gc */
+
+ RGBBackColor (&old_bg);
}
GetGWorld (&old_port, &old_gdh);
SetGWorld (p, NULL);
- mac_set_colors (gc);
+ mac_set_colors (gc, NULL);
SetRect (&r, x, y, x + width, y + height);
LockPixels (GetGWorldPixMap (p));
unsigned int width, height;
{
Rect r;
+ RGBColor old_bg;
SetPortWindowPort (w);
- mac_set_colors (gc);
+ mac_set_colors (gc, &old_bg);
SetRect (&r, x, y, x + width + 1, y + height + 1);
FrameRect (&r); /* using foreground color of gc */
+
+ RGBBackColor (&old_bg);
}
GetGWorld (&old_port, &old_gdh);
SetGWorld (p, NULL);
- mac_set_colors (gc);
+ mac_set_colors (gc, NULL);
SetRect (&r, x, y, x + width + 1, y + height + 1);
LockPixels (GetGWorldPixMap (p));
char *buf;
int nchars, mode, bytes_per_char;
{
+ RGBColor old_bg;
+
SetPortWindowPort (w);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ UInt32 textFlags, savedFlags;
+ if (!NILP(Vmac_use_core_graphics)) {
+ textFlags = kQDUseCGTextRendering;
+ savedFlags = SwapQDTextFlags(textFlags);
+ }
+#endif
- mac_set_colors (gc);
+ mac_set_colors (gc, &old_bg);
TextFont (gc->font->mac_fontnum);
TextSize (gc->font->mac_fontsize);
MoveTo (x, y);
DrawText (buf, 0, nchars * bytes_per_char);
+
+ RGBBackColor (&old_bg);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+ if (!NILP(Vmac_use_core_graphics))
+ SwapQDTextFlags(savedFlags);
+#endif
}
SetPort (w);
#if 0
- mac_set_colors (gc);
+ mac_set_colors (gc, NULL);
#endif
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
BackColor (whiteColor);
CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
- mac_set_colors (gc);
+ mac_set_colors (gc, NULL);
#endif
#endif /* not TARGET_API_MAC_CARBON */
}
}
-/* Mac replacement for XSetFont. */
+/* Mac replacement for XSetBackground. */
-static void
-XSetFont (display, gc, font)
+void
+XSetBackground (display, gc, color)
Display *display;
GC gc;
- XFontStruct *font;
+ unsigned long color;
{
- gc->font = font;
+ gc->background = color;
+}
+
+
+/* Mac replacement for XSetWindowBackground. */
+
+void
+XSetWindowBackground (display, w, color)
+ Display *display;
+ WindowPtr w;
+ unsigned long color;
+{
+#if !TARGET_API_MAC_CARBON
+ AuxWinHandle aw_handle;
+ CTabHandle ctab_handle;
+ ColorSpecPtr ct_table;
+ short ct_size;
+#endif
+ RGBColor bg_color;
+
+ bg_color.red = RED16_FROM_ULONG (color);
+ bg_color.green = GREEN16_FROM_ULONG (color);
+ bg_color.blue = BLUE16_FROM_ULONG (color);
+
+#if TARGET_API_MAC_CARBON
+ SetWindowContentColor (w, &bg_color);
+#else
+ if (GetAuxWin (w, &aw_handle))
+ {
+ ctab_handle = (*aw_handle)->awCTable;
+ HandToHand ((Handle *) &ctab_handle);
+ ct_table = (*ctab_handle)->ctTable;
+ ct_size = (*ctab_handle)->ctSize;
+ while (ct_size > -1)
+ {
+ if (ct_table->value == 0)
+ {
+ ct_table->rgb = bg_color;
+ CTabChanged (ctab_handle);
+ SetWinColor (w, (WCTabHandle) ctab_handle);
+ }
+ ct_size--;
+ }
+ }
+#endif
}
+/* Mac replacement for XSetFont. */
+
static void
-XTextExtents16 (XFontStruct *font, XChar2b *text, int nchars,
- int *direction,int *font_ascent,
- int *font_descent, XCharStruct *cs)
+XSetFont (display, gc, font)
+ Display *display;
+ GC gc;
+ XFontStruct *font;
{
- /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
+ gc->font = font;
}
FRAME_MAC_DISPLAY_INFO (f)->mouse_face_defer = 0;
BLOCK_INPUT;
- /* Reset the background color of Mac OS Window to that of the frame after
- update so that it is used by Mac Toolbox to clear the update region before
- an update event is generated. */
- SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
- mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f));
-
#if TARGET_API_MAC_CARBON
EnableScreenUpdates ();
#endif
mac_compute_glyph_string_overhangs (s)
struct glyph_string *s;
{
-#if 0
- /* MAC_TODO: XTextExtents16 does nothing yet... */
+ Rect r;
+ MacFontStruct *font = s->font;
- if (s->cmp == NULL
- && s->first_glyph->type == CHAR_GLYPH)
+ TextFont (font->mac_fontnum);
+ TextSize (font->mac_fontsize);
+ TextFace (font->mac_fontface);
+
+ if (s->two_byte_p)
+ QDTextBounds (s->nchars * 2, (char *)s->char2b, &r);
+ else
{
- XCharStruct cs;
- int direction, font_ascent, font_descent;
- XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
- &font_ascent, &font_descent, &cs);
- s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
- s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
+ int i;
+ char *buf = xmalloc (s->nchars);
+
+ if (buf == NULL)
+ SetRect (&r, 0, 0, 0, 0);
+ else
+ {
+ for (i = 0; i < s->nchars; ++i)
+ buf[i] = s->char2b[i].byte2;
+ QDTextBounds (s->nchars, buf, &r);
+ xfree (buf);
+ }
}
-#endif
+
+ s->right_overhang = r.right > s->width ? r.right - s->width : 0;
+ s->left_overhang = r.left < 0 ? -r.left : 0;
}
struct glyph *last_glyph;
Rect clip_rect;
- last_x = window_box_right (s->w, s->area);
- if (s->row->full_width_p
- && !s->w->pseudo_window_p)
- {
- last_x += WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s->w);
- if (s->area != RIGHT_MARGIN_AREA
- || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
- last_x += WINDOW_RIGHT_FRINGE_WIDTH (s->w);
- }
+ last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+ ? WINDOW_RIGHT_EDGE_X (s->w)
+ : window_box_right (s->w, s->area));
/* The glyph that may have a right box line. */
last_glyph = (s->cmp || s->img
{
int relief_drawn_p = 0;
- /* If S draws into the background of its successor, draw the
- background of the successor first so that S can draw into it.
- This makes S->next use XDrawString instead of XDrawImageString. */
- if (s->next && s->right_overhang && !s->for_overlaps_p)
+ /* If S draws into the background of its successor that does not
+ draw a cursor, draw the background of the successor first so that
+ S can draw into it. This makes S->next use XDrawString instead
+ of XDrawImageString. */
+ if (s->next && s->right_overhang && !s->for_overlaps_p
+ && s->next->hl != DRAW_CURSOR)
{
xassert (s->next->img == NULL);
x_set_glyph_string_gc (s->next);
frame_highlight (f)
struct frame *f;
{
+ OSErr err;
+ ControlRef root_control;
+
+ BLOCK_INPUT;
+ err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
+ if (err == noErr)
+ ActivateControl (root_control);
+ UNBLOCK_INPUT;
x_update_cursor (f, 1);
}
frame_unhighlight (f)
struct frame *f;
{
+ OSErr err;
+ ControlRef root_control;
+
+ BLOCK_INPUT;
+ err = GetRootControl (FRAME_MAC_WINDOW (f), &root_control);
+ if (err == noErr)
+ DeactivateControl (root_control);
+ UNBLOCK_INPUT;
x_update_cursor (f, 1);
}
x_frame_rehighlight (dpyinfo);
}
+/* Handle FocusIn and FocusOut state changes for FRAME.
+ If FRAME has focus and there exists more than one frame, puts
+ a FOCUS_IN_EVENT into *BUFP. */
+
+static void
+mac_focus_changed (type, dpyinfo, frame, bufp)
+ int type;
+ struct mac_display_info *dpyinfo;
+ struct frame *frame;
+ struct input_event *bufp;
+{
+ if (type == activeFlag)
+ {
+ if (dpyinfo->x_focus_event_frame != frame)
+ {
+ x_new_focus_frame (dpyinfo, frame);
+ dpyinfo->x_focus_event_frame = frame;
+
+ /* Don't stop displaying the initial startup message
+ for a switch-frame event we don't need. */
+ if (GC_NILP (Vterminal_frame)
+ && GC_CONSP (Vframe_list)
+ && !GC_NILP (XCDR (Vframe_list)))
+ {
+ bufp->kind = FOCUS_IN_EVENT;
+ XSETFRAME (bufp->frame_or_window, frame);
+ }
+ }
+ }
+ else
+ {
+ if (dpyinfo->x_focus_event_frame == frame)
+ {
+ dpyinfo->x_focus_event_frame = 0;
+ x_new_focus_frame (dpyinfo, 0);
+ }
+ }
+}
+
+/* The focus may have changed. Figure out if it is a real focus change,
+ by checking both FocusIn/Out and Enter/LeaveNotify events.
+
+ Returns FOCUS_IN_EVENT event in *BUFP. */
+
+static void
+x_detect_focus_change (dpyinfo, event, bufp)
+ struct mac_display_info *dpyinfo;
+ EventRecord *event;
+ struct input_event *bufp;
+{
+ struct frame *frame;
+
+ frame = mac_window_to_frame ((WindowPtr) event->message);
+ if (! frame)
+ return;
+
+ /* On Mac, this is only called from focus events, so no switch needed. */
+ mac_focus_changed ((event->modifiers & activeFlag),
+ dpyinfo, frame, bufp);
+}
+
+
/* Handle an event saying the mouse has moved out of an Emacs frame. */
void
}
-static WindowPtr
-front_emacs_window ()
+static struct frame *
+mac_focus_frame (dpyinfo)
+ struct mac_display_info *dpyinfo;
{
-#if TARGET_API_MAC_CARBON
- WindowPtr wp = GetFrontWindowOfClass (kDocumentWindowClass, true);
-
- while (wp && !is_emacs_window (wp))
- wp = GetNextWindowOfClass (wp, kDocumentWindowClass, true);
-#else
- WindowPtr wp = FrontWindow ();
-
- while (wp && (wp == tip_window || !is_emacs_window (wp)))
- wp = GetNextWindow (wp);
-#endif
-
- return wp;
+ if (dpyinfo->x_focus_frame)
+ return dpyinfo->x_focus_frame;
+ else
+ /* Mac version may get events, such as a menu bar click, even when
+ all the frames are invisible. In this case, we regard the
+ event came to the selected frame. */
+ return SELECTED_FRAME ();
}
-#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
/* Return the current position of the mouse.
*fp should be a frame which indicates which display to ask about.
{
Point mouse_pos;
int ignore1, ignore2;
- WindowPtr wp = front_emacs_window ();
- struct frame *f;
+ struct frame *f = mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp));
+ WindowPtr wp = FRAME_MAC_WINDOW (f);
Lisp_Object frame, tail;
- if (is_emacs_window(wp))
- f = mac_window_to_frame (wp);
-
BLOCK_INPUT;
if (! NILP (last_mouse_scroll_bar) && insist == 0)
}
-void
-activate_scroll_bars (frame)
- FRAME_PTR frame;
-{
- Lisp_Object bar;
- ControlHandle ch;
-
- bar = FRAME_SCROLL_BARS (frame);
- while (! NILP (bar))
- {
- ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar));
-#if 1 /* TARGET_API_MAC_CARBON */
- ActivateControl (ch);
-#else
- SetControlMaximum (ch,
- VERTICAL_SCROLL_BAR_TOP_RANGE (frame,
- XINT (XSCROLL_BAR (bar)
- ->height)) - 1);
-#endif
- bar = XSCROLL_BAR (bar)->next;
- }
-}
-
-
-void
-deactivate_scroll_bars (frame)
- FRAME_PTR frame;
-{
- Lisp_Object bar;
- ControlHandle ch;
-
- bar = FRAME_SCROLL_BARS (frame);
- while (! NILP (bar))
- {
- ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar));
-#if 1 /* TARGET_API_MAC_CARBON */
- DeactivateControl (ch);
-#else
- SetControlMaximum (ch, -1);
-#endif
- bar = XSCROLL_BAR (bar)->next;
- }
-}
-
/* 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.
unsigned long *time;
{
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
- WindowPtr wp = front_emacs_window ();
+ ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar);
+#if TARGET_API_MAC_CARBON
+ WindowPtr wp = GetControlOwner (ch);
+#else
+ WindowPtr wp = (*ch)->contrlOwner;
+#endif
Point mouse_pos;
struct frame *f = mac_window_to_frame (wp);
int win_y, top_range;
if (cursor_glyph == NULL)
return;
- /* Compute the width of the rectangle to draw. If on a stretch
- glyph, and `x-stretch-block-cursor' is nil, don't draw a
- rectangle as wide as the glyph, but use a canonical character
- width instead. */
- wd = cursor_glyph->pixel_width - 1;
- if (cursor_glyph->type == STRETCH_GLYPH
- && !x_stretch_cursor_p)
- wd = min (FRAME_COLUMN_WIDTH (f), wd);
- w->phys_cursor_width = wd;
-
- /* Compute frame-relative coordinates from window-relative
- coordinates. */
+ /* Compute frame-relative coordinates for phys cursor. */
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
-
- /* Compute the proper height and ascent of the rectangle, based
- on the actual glyph. Using the full height of the row looks
- bad when there are tall images on that row. */
- h = max (min (FRAME_LINE_HEIGHT (f), row->height),
- cursor_glyph->ascent + cursor_glyph->descent);
- if (h < row->height)
- y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
- h--;
+ y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ wd = w->phys_cursor_width;
/* The foreground of cursor_gc is typically the same as the normal
background color, which can cause the cursor box to be invisible. */
struct frame *f;
Cursor cursor;
{
-#if TARGET_API_MAC_CARBON
SetThemeCursor (cursor);
-#else
- SetCursor (*cursor);
-#endif
}
return Qnil;
/* Since x_new_font doesn't update any fontset information, do it now. */
- FRAME_FONTSET(f) = fontset;
+ FRAME_FONTSET (f) = fontset;
return build_string (fontsetname);
}
x_wm_set_size_hint (f, (long) 0, 0);
SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0);
+#if TARGET_API_MAC_CARBON
+ if (f->output_data.mac->hourglass_control)
+ MoveControl (f->output_data.mac->hourglass_control,
+ pixelwidth - HOURGLASS_WIDTH, 0);
+#endif
/* Now, strictly speaking, we can't be sure that this is accurate,
but the window manager will get around to dealing with the size
else
RepositionWindow (FRAME_MAC_WINDOW (f),
FRAME_MAC_WINDOW (sf),
-#ifdef MAC_OS_X_VERSION_10_2
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
kWindowCascadeStartAtParentWindowScreen
#else
kWindowCascadeOnParentWindowScreen
BLOCK_INPUT;
+ /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
+ that the current position of the window is user-specified, rather than
+ program-specified, so that when the window is mapped again, it will be
+ placed at the same location, without forcing the user to position it
+ by hand again (they have already done that once for this window.) */
+ x_wm_set_size_hint (f, (long) 0, 1);
+
HideWindow (FRAME_MAC_WINDOW (f));
/* We can't distinguish this from iconification
BLOCK_INPUT;
+ if (wp != tip_window)
+ remove_window_handler (wp);
+
DisposeWindow (wp);
if (wp == tip_window)
/* Neither WaitNextEvent nor ReceiveNextEvent receives `window
static char *
-mac_to_x_fontname (name, size, style, scriptcode, encoding_base)
+mac_to_x_fontname (name, size, style, scriptcode)
char *name;
int size;
Style style;
if (dpyinfo)
{
- tem = XCDR (dpyinfo->name_list_element);
+ tem = XCAR (XCDR (dpyinfo->name_list_element));
key = Fcons (pattern, make_number (maxnames));
newlist = Fassoc (key, tem);
if (dpyinfo)
{
- XSETCDR (dpyinfo->name_list_element,
+ XSETCAR (XCDR (dpyinfo->name_list_element),
Fcons (Fcons (key, newlist),
- XCDR (dpyinfo->name_list_element)));
+ XCAR (XCDR (dpyinfo->name_list_element))));
}
label_cached:
returns 15 for 12-point Monaco! */
char_width = CharWidth ('m');
- font->max_bounds.rbearing = char_width;
- font->max_bounds.lbearing = 0;
- font->max_bounds.width = char_width;
- font->max_bounds.ascent = the_fontinfo.ascent;
- font->max_bounds.descent = the_fontinfo.descent;
+ if (is_two_byte_font)
+ {
+ font->per_char = NULL;
- font->min_bounds = font->max_bounds;
+ if (fontface & italic)
+ font->max_bounds.rbearing = char_width + 1;
+ else
+ font->max_bounds.rbearing = char_width;
+ font->max_bounds.lbearing = 0;
+ font->max_bounds.width = char_width;
+ font->max_bounds.ascent = the_fontinfo.ascent;
+ font->max_bounds.descent = the_fontinfo.descent;
- if (is_two_byte_font || CharWidth ('m') == CharWidth ('i'))
- font->per_char = NULL;
+ font->min_bounds = font->max_bounds;
+ }
else
{
font->per_char = (XCharStruct *)
xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1));
{
- int c, min_width, max_width;
+ int c, min_width, max_width;
+ Rect char_bounds, min_bounds, max_bounds;
+ char ch;
min_width = max_width = char_width;
+ SetRect (&min_bounds, -32767, -32767, 32767, 32767);
+ SetRect (&max_bounds, 0, 0, 0, 0);
for (c = 0x20; c <= 0xff; c++)
{
- font->per_char[c - 0x20] = font->max_bounds;
- char_width = CharWidth (c);
- font->per_char[c - 0x20].width = char_width;
- font->per_char[c - 0x20].rbearing = char_width;
- min_width = min (min_width, char_width);
- max_width = max (max_width, char_width);
- }
- font->min_bounds.width = min_width;
- font->max_bounds.width = max_width;
+ ch = c;
+ char_width = CharWidth (ch);
+ QDTextBounds (1, &ch, &char_bounds);
+ STORE_XCHARSTRUCT (font->per_char[c - 0x20],
+ char_width, char_bounds);
+ /* Some Japanese fonts (in SJIS encoding) return 0 as the
+ character width of 0x7f. */
+ if (char_width > 0)
+ {
+ min_width = min (min_width, char_width);
+ max_width = max (max_width, char_width);
+ }
+ if (!EmptyRect (&char_bounds))
+ {
+ SetRect (&min_bounds,
+ max (min_bounds.left, char_bounds.left),
+ max (min_bounds.top, char_bounds.top),
+ min (min_bounds.right, char_bounds.right),
+ min (min_bounds.bottom, char_bounds.bottom));
+ UnionRect (&max_bounds, &char_bounds, &max_bounds);
+ }
+ }
+ STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds);
+ STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds);
+ if (min_width == max_width
+ && max_bounds.left >= 0 && max_bounds.right <= max_width)
+ {
+ /* Fixed width and no overhangs. */
+ xfree (font->per_char);
+ font->per_char = NULL;
+ }
}
}
\f
/* The Mac Event loop code */
-#ifndef MAC_OSX
+#if !TARGET_API_MAC_CARBON
#include <Events.h>
#include <Quickdraw.h>
#include <Balloons.h>
#include <Dialogs.h>
#include <Script.h>
#include <Types.h>
-#include <TextEncodingConverter.h>
#include <Resources.h>
#if __MWERKS__
#include <unix.h>
#endif
-#endif /* ! MAC_OSX */
+#endif /* ! TARGET_API_MAC_CARBON */
#define M_APPLE 128
#define I_ABOUT 1
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;
-int current_mac_keyboard_text_encoding = kTextEncodingMacRoman;
-
/* Set in term/mac-win.el to indicate that event loop can now generate
drag and drop events. */
Lisp_Object Qmac_ready_for_drag_n_drop;
Point saved_menu_event_location;
-#if !TARGET_API_MAC_CARBON
-/* Place holder for the default arrow cursor. */
-CursPtr arrow_cursor;
-#endif
-
/* Apple Events */
static void init_required_apple_events (void);
static pascal OSErr
/* Drag and Drop */
static pascal OSErr mac_do_track_drag (DragTrackingMessage, WindowPtr, void*, DragReference);
static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference);
+static DragTrackingHandlerUPP mac_do_track_dragUPP = NULL;
+static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL;
#endif
#if USE_CARBON_EVENTS
+#ifdef MAC_OSX
/* Preliminary Support for the OSX Services Menu */
static OSStatus mac_handle_service_event (EventHandlerCallRef,EventRef,void*);
static void init_service_handler ();
+#endif
/* Window Event Handler */
static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
EventRef, void *);
InitCursor ();
#if !TARGET_API_MAC_CARBON
- arrow_cursor = &qd.arrow;
-
/* set up some extra stack space for use by emacs */
SetApplLimit ((Ptr) ((long) GetApplLimit () - EXTRA_STACK_ALLOC));
RgnHandle region = NewRgn ();
GetPortVisibleRegion (GetWindowPort (win), region);
- UpdateControls (win, region);
GetRegionBounds (region, &r);
+ expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+ UpdateControls (win, region);
DisposeRgn (region);
}
#else
- UpdateControls (win, win->visRgn);
r = (*win->visRgn)->rgnBBox;
-#endif
expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+ UpdateControls (win, win->visRgn);
+#endif
handling_window_update = 0;
}
{
/* Window-activate events will do the job. */
#if 0
- WindowPtr wp;
- struct frame *f;
-
- wp = front_emacs_window ();
- if (wp)
- {
- f = mac_window_to_frame (wp);
-
- if (f)
- {
- x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), f);
- activate_scroll_bars (f);
- }
- }
-
app_is_suspended = false;
app_sleep_time = WNE_SLEEP_AT_RESUME;
#endif
{
/* Window-deactivate events will do the job. */
#if 0
- WindowPtr wp;
- struct frame *f;
-
- wp = front_emacs_window ();
- if (wp)
- {
- f = mac_window_to_frame (wp);
-
- if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
- {
- x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), 0);
- deactivate_scroll_bars (f);
- }
- }
-
app_is_suspended = true;
app_sleep_time = WNE_SLEEP_AT_SUSPEND;
#endif
}
-static void
-do_mouse_moved (mouse_pos, f)
- Point mouse_pos;
- FRAME_PTR *f;
-{
- WindowPtr wp = front_emacs_window ();
- struct x_display_info *dpyinfo;
-
- if (wp)
- {
- *f = mac_window_to_frame (wp);
- dpyinfo = FRAME_MAC_DISPLAY_INFO (*f);
-
- if (dpyinfo->mouse_face_hidden)
- {
- dpyinfo->mouse_face_hidden = 0;
- clear_mouse_face (dpyinfo);
- }
-
- SetPortWindowPort (wp);
-
- GlobalToLocal (&mouse_pos);
-
- if (dpyinfo->grabbed && tracked_scroll_bar)
- x_scroll_bar_note_movement (tracked_scroll_bar,
- mouse_pos.v
- - XINT (tracked_scroll_bar->top),
- TickCount() * (1000 / 60));
- else
- note_mouse_movement (*f, &mouse_pos);
- }
-}
-
-
static void
do_apple_menu (SInt16 menu_item)
{
default:
{
- struct frame *f = mac_window_to_frame (front_emacs_window ());
+ struct frame *f = mac_focus_frame (&one_mac_display_info);
MenuHandle menu = GetMenuHandle (menu_id);
if (menu)
{
Point top_left;
int w_title_height, columns, rows, width, height;
struct frame *f = mac_window_to_frame (w);
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
#if TARGET_API_MAC_CARBON
{
Point standard_size;
standard_size.h = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS);
- standard_size.v = FRAME_MAC_DISPLAY_INFO (f)->height;
+ standard_size.v = dpyinfo->height;
if (IsWindowInStandardState (w, &standard_size, &zoom_rect))
zoom_in_or_out = inZoomIn;
= zoom_rect;
}
- ZoomWindow (w, zoom_in_or_out, w == front_emacs_window ());
+ ZoomWindow (w, zoom_in_or_out, f == mac_focus_frame (dpyinfo));
SetPort (save_port);
#endif /* not TARGET_API_MAC_CARBON */
}
#if USE_CARBON_EVENTS
-
+#ifdef MAC_OSX
void
init_service_handler ()
{
}
return err;
}
-
+#endif
static pascal OSStatus
mac_handle_window_event (next_handler, event, data)
EventRef event;
void *data;
{
- extern Lisp_Object Qcontrol;
-
WindowPtr wp;
OSStatus result;
UInt32 attributes;
switch (GetEventKind (event))
{
+ case kEventWindowUpdate:
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ return result;
+
+ do_window_update (wp);
+ break;
+
case kEventWindowBoundsChanging:
result = CallNextEventHandler (next_handler, event);
if (result != eventNotHandledErr)
{
OSErr err = noErr;
#if USE_CARBON_EVENTS
- EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowBoundsChanging}};
+ EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowUpdate},
+ {kEventClassWindow, kEventWindowBoundsChanging}};
static EventHandlerUPP handle_window_event_UPP = NULL;
if (handle_window_event_UPP == NULL)
NULL, NULL);
#endif
#if TARGET_API_MAC_CARBON
+ if (mac_do_track_dragUPP == NULL)
+ mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag);
+ if (mac_do_receive_dragUPP == NULL)
+ mac_do_receive_dragUPP = NewDragReceiveHandlerUPP (mac_do_receive_drag);
+
if (err == noErr)
- err = InstallTrackingHandler (mac_do_track_drag, window, NULL);
+ err = InstallTrackingHandler (mac_do_track_dragUPP, window, NULL);
if (err == noErr)
- err = InstallReceiveHandler (mac_do_receive_drag, window, NULL);
+ err = InstallReceiveHandler (mac_do_receive_dragUPP, window, NULL);
#endif
return err;
}
+void
+remove_window_handler (window)
+ WindowPtr window;
+{
+#if TARGET_API_MAC_CARBON
+ if (mac_do_track_dragUPP)
+ RemoveTrackingHandler (mac_do_track_dragUPP, window);
+ if (mac_do_receive_dragUPP)
+ RemoveReceiveHandler (mac_do_receive_dragUPP, window);
+#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++)
+ for (i = 1; i <= num_files_to_open; i++)
{
- FSSpec fs;
- Str255 path_name, unix_path_name;
+ char unix_path_name[MAXPATHLEN];
#ifdef MAC_OSX
FSRef fref;
-#endif
+
+ err = AEGetNthPtr (&the_desc, i, typeFSRef, &keyword,
+ &actual_type, &fref, sizeof (FSRef),
+ &actual_size);
+ if (err != noErr || actual_type != typeFSRef)
+ continue;
+
+ if (FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name))
+ == noErr)
+#else
+ FSSpec fs;
err = AEGetNthPtr(&the_desc, i, typeFSS, &keyword, &actual_type,
(Ptr) &fs, sizeof (fs), &actual_size);
- if (err != noErr) break;
-
-#ifdef MAC_OSX
- err = FSpMakeFSRef (&fs, &fref);
- if (err != noErr) break;
+ if (err != noErr) continue;
- 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))
+ if (fsspec_to_posix_pathname (&fs, unix_path_name,
+ sizeof (unix_path_name) - 1) == noErr)
#endif
/* x-dnd functions expect undecoded filenames. */
drag_and_drop_file_list =
FlavorFlags theFlags;
OSErr result;
+ if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
+ return dragNotAcceptedErr;
+
switch (message)
{
case kDragTrackingEnterHandler:
CountDragItems (theDrag, &items);
- can_accept = 1;
+ can_accept = 0;
for (index = 1; index <= items; index++)
{
GetDragItemReferenceNumber (theDrag, index, &theItem);
result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags);
- if (result != noErr)
+ if (result == noErr)
{
- can_accept = 0;
+ can_accept = 1;
break;
}
}
{
RgnHandle hilite_rgn = NewRgn ();
Rect r;
+ struct frame *f = mac_window_to_frame (window);
GetWindowPortBounds (window, &r);
OffsetRect (&r, -r.left, -r.top);
case kDragTrackingLeaveWindow:
if (can_accept)
{
+ struct frame *f = mac_window_to_frame (window);
+
HideDragHilite (theDrag);
SetThemeCursor (kThemeArrowCursor);
}
OSErr result;
ItemReference theItem;
HFSFlavor data;
- FSRef fref;
Size size = sizeof (HFSFlavor);
+ if (GetFrontWindowOfClass (kMovableModalWindowClass, false))
+ return dragNotAcceptedErr;
+
drag_and_drop_file_list = Qnil;
GetDragMouse (theDrag, &mouse, 0L);
CountDragItems (theDrag, &items);
if (result == noErr)
{
#ifdef MAC_OSX
- FSRef frref;
-#else
- Str255 path_name;
+ FSRef fref;
#endif
- Str255 unix_path_name;
+ char unix_path_name[MAXPATHLEN];
+
GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L);
#ifdef MAC_OSX
/* Use Carbon routines, otherwise it converts the file name
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))
+ if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name,
+ sizeof (unix_path_name) - 1) == noErr)
#endif
/* x-dnd functions expect undecoded filenames. */
drag_and_drop_file_list =
strlen (unix_path_name)),
drag_and_drop_file_list);
}
- else
- continue;
}
/* If there are items in the list, construct an event and post it to
the queue like an interrupt using kbd_buffer_store_event. */
hints and prompts in the minibuffer after the user stops typing for
a wait, etc. */
-#if !TARGET_API_MAC_CARBON
+#ifdef MAC_OS8
#undef main
int
main (void)
#endif
/* Table for translating Mac keycode to X keysym values. Contributed
- by Sudhir Shenoy. */
+ by Sudhir Shenoy.
+ Mapping for special keys is now identical to that in Apple X11
+ except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
+ on the right of the Cmd key on laptops, and fn + `enter' (->
+ <linefeed>). */
static unsigned char keycode_to_xkeysym_table[] = {
/*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
- /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
+ /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
/*0x38*/ 0, 0, 0, 0,
/*0x3C*/ 0, 0, 0, 0,
/*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
- /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
+ /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x0b /*clear*/,
/*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
/*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
/*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
/*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
/*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
- /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
+ /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
- /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
- /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
- /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
+ /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
+ /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
+ /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
/*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
};
{
SInt32 delta;
Point point;
- WindowPtr window_ptr = front_emacs_window ();
+ struct frame *f = mac_focus_frame (dpyinfo);
+ WindowPtr window_ptr;
- if (!IsValidWindowPtr (window_ptr))
+ if (!f)
{
+ /* Beep if wheel move occurs when all the frames
+ are invisible. */
SysBeep(1);
break;
}
inev.modifiers = (mac_event_to_emacs_modifiers (eventRef)
| ((delta < 0) ? down_modifier
: up_modifier));
+ window_ptr = FRAME_MAC_WINDOW (f);
SetPortWindowPort (window_ptr);
GlobalToLocal (&point);
XSETINT (inev.x, point.h);
switch (part_code)
{
case inMenuBar:
- f = mac_window_to_frame (front_emacs_window ());
+ f = mac_focus_frame (dpyinfo);
saved_menu_event_location = er.where;
inev.kind = MENU_BAR_ACTIVATE_EVENT;
XSETFRAME (inev.frame_or_window, f);
break;
case inContent:
- if (window_ptr != front_emacs_window ())
+ if (window_ptr != FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo)))
SelectWindow (window_ptr);
else
{
/* ticks to milliseconds */
if (dpyinfo->grabbed && tracked_scroll_bar
-#if TARGET_API_MAC_CARBON
- || ch != 0
-#else
- || control_part_code != 0
-#endif
- )
+ /* control_part_code becomes kControlNoPart if
+ a progress indicator is clicked. */
+ || ch != 0 && control_part_code != kControlNoPart)
{
struct scroll_bar *bar;
if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
!= eventNotHandledErr)
break;
-#endif
+#else
do_window_update ((WindowPtr) er.message);
+#endif
break;
case osEvt:
help_echo_string = help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1;
- do_mouse_moved (er.where, &f);
+ if (dpyinfo->grabbed && last_mouse_frame
+ && FRAME_LIVE_P (last_mouse_frame))
+ f = last_mouse_frame;
+ else
+ f = dpyinfo->x_focus_frame;
+
+ if (dpyinfo->mouse_face_hidden)
+ {
+ dpyinfo->mouse_face_hidden = 0;
+ clear_mouse_face (dpyinfo);
+ }
+
+ if (f)
+ {
+ WindowPtr wp = FRAME_MAC_WINDOW (f);
+ Point mouse_pos = er.where;
+
+ SetPortWindowPort (wp);
+
+ GlobalToLocal (&mouse_pos);
+
+ if (dpyinfo->grabbed && tracked_scroll_bar)
+ x_scroll_bar_note_movement (tracked_scroll_bar,
+ mouse_pos.v
+ - XINT (tracked_scroll_bar->top),
+ TickCount() * (1000 / 60));
+ else
+ {
+ /* Generate SELECT_WINDOW_EVENTs when needed. */
+ if (mouse_autoselect_window)
+ {
+ Lisp_Object window;
+
+ window = window_from_coordinates (f,
+ mouse_pos.h,
+ mouse_pos.v,
+ 0, 0, 0, 0);
+
+ /* Window will be selected only when it is
+ not selected now and last mouse movement
+ event was not in it. Minibuffer window
+ will be selected iff it is active. */
+ if (WINDOWP (window)
+ && !EQ (window, last_window)
+ && !EQ (window, selected_window))
+ {
+ inev.kind = SELECT_WINDOW_EVENT;
+ inev.frame_or_window = window;
+ }
+
+ last_window=window;
+ }
+ note_mouse_movement (f, &mouse_pos);
+ }
+ }
/* If the contents of the global variable
help_echo_string has changed, generate a
if (!is_emacs_window (window_ptr))
break;
- f = mac_window_to_frame (window_ptr);
-
if ((er.modifiers & activeFlag) != 0)
{
/* A window has been activated */
Point mouse_loc = er.where;
- x_new_focus_frame (dpyinfo, f);
- activate_scroll_bars (f);
+ x_detect_focus_change (dpyinfo, &er, &inev);
SetPortWindowPort (window_ptr);
GlobalToLocal (&mouse_loc);
/* A window has been deactivated */
dpyinfo->grabbed = 0;
- if (f == dpyinfo->x_focus_frame)
- {
- x_new_focus_frame (dpyinfo, 0);
- deactivate_scroll_bars (f);
- }
-
+ x_detect_focus_change (dpyinfo, &er, &inev);
+ f = mac_window_to_frame (window_ptr);
if (f == dpyinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
int keycode = (er.message & keyCodeMask) >> 8;
int xkeysym;
-#if USE_CARBON_EVENTS
+#if USE_CARBON_EVENTS && defined (MAC_OSX)
/* 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
break;
#endif
-#if TARGET_API_MAC_CARBON
- if (!IsValidWindowPtr (front_emacs_window ()))
+ if (dpyinfo->x_focus_frame == NULL)
{
+ /* Beep if keyboard input occurs when all the frames
+ are invisible. */
SysBeep (1);
break;
}
-#endif
+
+ {
+ static SInt16 last_key_script = -1;
+ SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
+
+ if (last_key_script != current_key_script)
+ {
+ struct input_event event;
+
+ EVENT_INIT (event);
+ event.kind = LANGUAGE_CHANGE_EVENT;
+ event.arg = Qnil;
+ event.code = current_key_script;
+ kbd_buffer_store_event (&event);
+ count++;
+ }
+ last_key_script = current_key_script;
+ }
ObscureCursor ();
unsigned long some_state = 0;
inev.code = KeyTranslate (kchr_ptr, new_keycode,
&some_state) & 0xff;
- } else if (!NILP(Vmac_option_modifier) && (er.modifiers & optionKey))
- {
- /* When using the option key as an emacs modifier, convert
- the pressed key code back to one without the Mac option
- modifier applied. */
- int new_modifiers = er.modifiers & ~optionKey;
- int new_keycode = keycode | new_modifiers;
- Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- unsigned long some_state = 0;
- inev.code = KeyTranslate (kchr_ptr, new_keycode,
- &some_state) & 0xff;
- }
+ }
+ else if (!NILP (Vmac_option_modifier)
+ && (er.modifiers & optionKey))
+ {
+ /* When using the option key as an emacs modifier,
+ convert the pressed key code back to one
+ without the Mac option modifier applied. */
+ int new_modifiers = er.modifiers & ~optionKey;
+ int new_keycode = keycode | new_modifiers;
+ Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+ unsigned long some_state = 0;
+ inev.code = KeyTranslate (kchr_ptr, new_keycode,
+ &some_state) & 0xff;
+ }
else
inev.code = er.message & charCodeMask;
inev.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
- && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
- {
- 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
- = 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,
- kTextEncodingMacRoman,
- mac_keyboard_text_encoding);
- current_mac_keyboard_text_encoding
- = mac_keyboard_text_encoding;
- }
-
- if (the_err == noErr)
- {
- unsigned char ch = inev.code;
- ByteCount actual_input_length, actual_output_length;
- unsigned char outbuf[32];
-
- convert_status = TECConvertText (converter, &ch, 1,
- &actual_input_length,
- outbuf, 1,
- &actual_output_length);
- if (convert_status == noErr
- && actual_input_length == 1
- && actual_output_length == 1)
- inev.code = *outbuf;
-
- /* Reset internal states of the converter object.
- If it fails, create another one. */
- convert_status = TECFlushText (converter, outbuf,
- sizeof (outbuf),
- &actual_output_length);
- if (convert_status != noErr)
- {
- TECDisposeConverter (converter);
- TECCreateConverter (&converter,
- kTextEncodingMacRoman,
- mac_keyboard_text_encoding);
- }
- }
- }
-
#if USE_CARBON_EVENTS
inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
- XSETFRAME (inev.frame_or_window,
- mac_window_to_frame (front_emacs_window ()));
+ XSETFRAME (inev.frame_or_window, mac_focus_frame (dpyinfo));
inev.timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
break;
constuct_drag_n_drop in w32term.c. */
if (!NILP (drag_and_drop_file_list))
{
- struct frame *f = NULL;
+ struct frame *f = mac_focus_frame (dpyinfo);
WindowPtr wp;
Lisp_Object frame;
- wp = front_emacs_window ();
-
- if (!wp)
- {
- struct frame *f = XFRAME (XCAR (Vframe_list));
- CollapseWindow (FRAME_MAC_WINDOW (f), false);
- wp = front_emacs_window ();
- }
-
- if (wp)
- f = mac_window_to_frame (wp);
-
inev.kind = DRAG_N_DROP_EVENT;
inev.code = 0;
inev.timestamp = er.when * (1000 / 60);
XSETFRAME (frame, f);
inev.frame_or_window = Fcons (frame, drag_and_drop_file_list);
+#if 0
/* Regardless of whether Emacs was suspended or in the
foreground, ask it to redraw its entire screen.
Otherwise parts of the screen can be left in an
inconsistent state. */
+ wp = FRAME_MAC_WINDOW (f);
if (wp)
#if TARGET_API_MAC_CARBON
{
#else /* not TARGET_API_MAC_CARBON */
InvalRect (&(wp->portRect));
#endif /* not TARGET_API_MAC_CARBON */
+#endif
}
default:
break;
f->output_data.mac->mouse_pixel = 0xff00ff;
f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
- f->output_data.mac->text_cursor = GetCursor (iBeamCursor);
- f->output_data.mac->nontext_cursor = &arrow_cursor;
- f->output_data.mac->modeline_cursor = &arrow_cursor;
- f->output_data.mac->hand_cursor = &arrow_cursor;
- f->output_data.mac->hourglass_cursor = GetCursor (watchCursor);
- f->output_data.mac->horizontal_drag_cursor = &arrow_cursor;
+ f->output_data.mac->text_cursor = kThemeIBeamCursor;
+ f->output_data.mac->nontext_cursor = kThemeArrowCursor;
+ f->output_data.mac->modeline_cursor = kThemeArrowCursor;
+ f->output_data.mac->hand_cursor = kThemePointingHandCursor;
+ f->output_data.mac->hourglass_cursor = kThemeWatchCursor;
+ f->output_data.mac->horizontal_drag_cursor = kThemeResizeLeftRightCursor;
FRAME_FONTSET (f) = -1;
f->output_data.mac->explicit_parent = 0;
dpyinfo->mouse_face_hidden = 0;
}
-/* Create an xrdb-style database of resources to supercede registry settings.
- The database is just a concatenation of C strings, finished by an additional
- \0. The string are submitted to some basic normalization, so
- [ *]option[ *]:[ *]value...
-
- becomes
-
- option:value...
-
- but any whitespace following value is not removed. */
-
-static char *
+static XrmDatabase
mac_make_rdb (xrm_option)
char *xrm_option;
{
- char *buffer = xmalloc (strlen (xrm_option) + 2);
- char *current = buffer;
- char ch;
- int in_option = 1;
- int before_value = 0;
-
- do {
- ch = *xrm_option++;
-
- if (ch == '\n')
- {
- *current++ = '\0';
- in_option = 1;
- before_value = 0;
- }
- else if (ch != ' ')
- {
- *current++ = ch;
- if (in_option && (ch == ':'))
- {
- in_option = 0;
- before_value = 1;
- }
- else if (before_value)
- {
- before_value = 0;
- }
- }
- else if (!(in_option || before_value))
- {
- *current++ = ch;
- }
- } while (ch);
+ XrmDatabase database;
- *current = '\0';
+ database = xrm_get_preference_database (NULL);
+ if (xrm_option)
+ xrm_merge_string_database (database, xrm_option);
- return buffer;
+ return database;
}
struct mac_display_info *
dpyinfo = &one_mac_display_info;
- dpyinfo->xrdb = xrm_option ? mac_make_rdb (xrm_option) : NULL;
+ dpyinfo->xrdb = mac_make_rdb (xrm_option);
/* Put this display on the chain. */
dpyinfo->next = x_display_list;
x_display_list = dpyinfo;
/* Put it on x_display_name_list. */
- x_display_name_list = Fcons (Fcons (display_name, Qnil),
+ x_display_name_list = Fcons (Fcons (display_name,
+ Fcons (Qnil, dpyinfo->xrdb)),
x_display_name_list);
dpyinfo->name_list_element = XCAR (x_display_name_list);
e.arg = Qnil;
e.modifiers = NULL;
e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60);
- XSETFRAME (e.frame_or_window, mac_window_to_frame (front_emacs_window ()));
+ XSETFRAME (e.frame_or_window, mac_focus_frame (&one_mac_display_info));
/* Remove event from queue to prevent looping. */
RemoveEventFromQueue (GetMainEventQueue (), event);
ReleaseEvent (event);
0, /* destroy_fringe_bitmap */
mac_per_char_metric,
mac_encode_char,
- NULL, /* mac_compute_glyph_string_overhangs */
+ mac_compute_glyph_string_overhangs,
x_draw_glyph_string,
mac_define_frame_cursor,
mac_clear_frame_area,
redeem_scroll_bar_hook = XTredeem_scroll_bar;
judge_scroll_bars_hook = XTjudge_scroll_bars;
- scroll_region_ok = 1; /* we'll scroll partial frames */
- char_ins_del_ok = 1;
- line_ins_del_ok = 1; /* we'll just blt 'em */
- fast_clear_end_of_line = 1; /* X does this well */
- memory_below_frame = 0; /* we don't remember what scrolls
- off the bottom */
+ TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */
+ TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1;
+ TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */
+ TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */
+ TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what
+ scrolls off the
+ bottom */
baud_rate = 19200;
x_noop_count = 0;
#if TARGET_API_MAC_CARBON
init_required_apple_events ();
-#if USE_CARBON_EVENTS
+#if USE_CARBON_EVENTS && defined (MAC_OSX)
init_service_handler ();
init_quit_char_handler ();
DisableMenuCommand (NULL, kHICommandQuit);
+#ifdef MAC_OSX
if (!inhibit_window_system)
MakeMeTheFrontProcess ();
+#endif
#endif
UNBLOCK_INPUT;
}
Qeuc_kr = intern ("euc-kr");
staticpro (&Qeuc_kr);
- DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p,
- doc: /* *Non-nil means autoselect window with mouse pointer. */);
- x_autoselect_window_p = 0;
-
DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
doc: /* If not nil, Emacs uses toolkit scroll bars. */);
Vx_toolkit_scroll_bars = 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. */);
+useful for non-standard keyboard layouts. */);
Vmac_reverse_ctrl_meta = Qnil;
DEFVAR_LISP ("mac-emulate-three-button-mouse",
&Vmac_emulate_three_button_mouse,
doc: /* t means that when the option-key is held down while pressing the
- mouse button, the click will register as mouse-2 and while the
- command-key is held down, the click will register as mouse-3.
- 'reverse means that the the option-key will register for mouse-3
- and the command-key will register for mouse-2. nil means that
- not emulation should be done and the modifiers should be placed
- on the mouse-1 event. */);
+mouse button, the click will register as mouse-2 and while the
+command-key is held down, the click will register as mouse-3.
+'reverse means that the the option-key will register for mouse-3
+and the command-key will register for mouse-2. nil means that
+no emulation should be done and the modifiers should be placed
+on the mouse-1 event. */);
Vmac_emulate_three_button_mouse = Qnil;
#if USE_CARBON_EVENTS
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
-Conversion Manager. Its value determines the encoding characters
-typed at the Mac keyboard (presumed to be in the MacRoman encoding)
-will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
-its default value, no conversion takes place. If it is set to
-kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
-characters typed on Mac keyboard are first converted into the
-ISO Latin-1 or ISO Latin-2 encoding, respectively before being
-passed to Emacs. Together with Emacs's set-keyboard-coding-system
-command, this enables the Mac keyboard to be used to enter non-ASCII
-characters directly. */);
- mac_keyboard_text_encoding = kTextEncodingMacRoman;
+ DEFVAR_LISP ("mac-allow-anti-aliasing", &Vmac_use_core_graphics,
+ doc: /* If non-nil, allow anti-aliasing.
+The text will be rendered using Core Graphics text rendering which
+may anti-alias the text. */);
+ Vmac_use_core_graphics = Qnil;
}
/* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b