/* Implementation of GUI terminal on the Mac OS.
Copyright (C) 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU Emacs.
void x_set_window_size P_ ((struct frame *, int, int, int));
void x_wm_set_window_state P_ ((struct frame *, int));
void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-void mac_initialize P_ ((void));
+static 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 *));
static void x_update_end P_ ((struct frame *));
static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void XTset_terminal_modes P_ ((struct terminal *));
+static void XTreset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
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 int is_emacs_window P_ ((WindowRef));
static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int));
static void XSetFont P_ ((Display *, GC, XFontStruct *));
+static struct terminal *mac_create_terminal P_ ((struct mac_display_info *dpyinfo));
+
#define GC_FORE_COLOR(gc) (&(gc)->fore_color)
#define GC_BACK_COLOR(gc) (&(gc)->back_color)
for (i = 0; i < h; i++)
bits[i] = ~bits[i];
+
+ BLOCK_INPUT;
+
provider = CGDataProviderCreateWithData (NULL, bits,
sizeof (unsigned short) * h, NULL);
if (provider)
provider, NULL, 0);
CGDataProviderRelease (provider);
}
+
+ UNBLOCK_INPUT;
}
static void
return;
if (fringe_bmp[which])
- CGImageRelease (fringe_bmp[which]);
+ {
+ BLOCK_INPUT;
+ CGImageRelease (fringe_bmp[which]);
+ UNBLOCK_INPUT;
+ }
fringe_bmp[which] = 0;
}
#endif
rarely happens). */
static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct terminal *t)
{
}
the windows go away, and suspending requires no action. */
static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct terminal *t)
{
}
of S to the right of that box line. */
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p)
- x = s->x + abs (s->face->box_line_width);
+ x = s->x + eabs (s->face->box_line_width);
else
x = s->x;
of S to the right of that box line. */
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p)
- x = s->x + abs (s->face->box_line_width);
+ x = s->x + eabs (s->face->box_line_width);
else
x = s->x;
else
{
for (i = 0; i < s->nchars; i++, ++s->gidx)
- mac_draw_image_string_16 (s->f, s->gc,
- x + s->cmp->offsets[s->gidx * 2],
- s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
- s->char2b + i, 1, 0, s->face->overstrike);
+ if (mac_per_char_metric (GC_FONT (s->gc), s->char2b + i, 0) == NULL)
+ /* This is a nonexistent or zero-width glyph such as a
+ combining diacritic. Draw a rectangle. */
+ mac_draw_rectangle (s->f, s->gc,
+ x + s->cmp->offsets[s->gidx * 2], s->y,
+ FONT_WIDTH (GC_FONT (s->gc)) - 1, s->height - 1);
+ else
+ mac_draw_image_string_16 (s->f, s->gc,
+ x + s->cmp->offsets[s->gidx * 2],
+ s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
+ s->char2b + i, 1, 0, s->face->overstrike);
}
}
? s->first_glyph
: s->first_glyph + s->nchars - 1);
- width = abs (s->face->box_line_width);
+ width = eabs (s->face->box_line_width);
raised_p = s->face->box == FACE_RAISED_BOX;
left_x = s->x;
right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p
&& s->slice.x == 0)
- x += abs (s->face->box_line_width);
+ x += eabs (s->face->box_line_width);
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p
&& s->slice.x == 0)
- x += abs (s->face->box_line_width);
+ x += eabs (s->face->box_line_width);
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
}
else
{
- thick = abs (s->img->relief);
+ thick = eabs (s->img->relief);
raised_p = s->img->relief > 0;
}
struct glyph_string *s;
{
int x, y;
- int box_line_hwidth = abs (s->face->box_line_width);
+ int box_line_hwidth = eabs (s->face->box_line_width);
int box_line_vwidth = max (s->face->box_line_width, 0);
int height;
struct glyph_string *s;
{
xassert (s->first_glyph->type == STRETCH_GLYPH);
- s->stippled_p = s->face->stipple != 0;
if (s->hl == DRAW_CURSOR
&& !x_stretch_cursor_p)
frame. Otherwise clear the selected frame. */
static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
/* Clearing the frame will erase any cursor, so mark them all as no
longer visible. */
mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
clear_mouse_face (dpyinfo);
dpyinfo->mouse_face_mouse_frame = 0;
if (!dpyinfo->grabbed)
- rif->define_frame_cursor (frame,
+ FRAME_RIF (frame)->define_frame_cursor (frame,
frame->output_data.mac->nontext_cursor);
}
#ifdef MAC_OSX
bar->fringe_extended_p = Qnil;
#endif
+ bar->redraw_needed_p = Qnil;
#ifdef USE_TOOLKIT_SCROLL_BARS
bar->track_top = Qnil;
bar->track_height = Qnil;
BLOCK_INPUT;
/* If already correctly positioned, do nothing. */
- if (!(XINT (bar->left) == sb_left
- && XINT (bar->top) == top
- && XINT (bar->width) == sb_width
- && XINT (bar->height) == height
+ if (XINT (bar->left) == sb_left
+ && XINT (bar->top) == top
+ && XINT (bar->width) == sb_width
+ && XINT (bar->height) == height
#ifdef MAC_OSX
- && !NILP (bar->fringe_extended_p) == fringe_extended_p
+ && !NILP (bar->fringe_extended_p) == fringe_extended_p
#endif
- ))
+ )
+ {
+ if (!NILP (bar->redraw_needed_p))
+ {
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
+ Draw1Control (SCROLL_BAR_CONTROL_REF (bar));
+ }
+ }
+ else
{
/* Since toolkit scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
#endif
+ bar->redraw_needed_p = Qnil;
+
#ifdef USE_TOOLKIT_SCROLL_BARS
if (NILP (bar->track_top))
{
x_scroll_bar_clear (f)
FRAME_PTR f;
{
- XTcondemn_scroll_bars (f);
- XTjudge_scroll_bars (f);
+ Lisp_Object bar;
+
+ /* We can have scroll bars even if this is 0,
+ if we just turned off scroll bar mode.
+ But in that case we should not clear them. */
+ if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
+ for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
+ bar = XSCROLL_BAR (bar)->next)
+ XSCROLL_BAR (bar)->redraw_needed_p = Qt;
}
\f
Lisp_Object rest = XCDR (XCDR (text_encoding_info));
if (size > 0 || style == normal)
- for (; !NILP (rest); rest = XCDR (rest))
+ for (; CONSP (rest); rest = XCDR (rest))
add_mac_font_name (name, size, style, SDATA (XCAR (rest)));
}
}
{
Lisp_Object rest = XCDR (XCDR (text_encoding_info));
- for (; !NILP (rest); rest = XCDR (rest))
+ for (; CONSP (rest); rest = XCDR (rest))
add_mac_font_name (name, assc_entry->fontSize,
assc_entry->fontStyle,
SDATA (XCAR (rest)));
font_id = atsu_find_font_from_family_name (family);
if (font_id == kATSUInvalidFontID)
- return;
+ return NULL;
size_fixed = Long2Fix (size);
bold_p = (fontface & bold) != 0;
italic_p = (fontface & italic) != 0;
will be selected only when it is active. */
if (WINDOWP (window)
&& !EQ (window, last_window)
- && !EQ (window, selected_window))
+ && !EQ (window, selected_window)
+ /* For click-to-focus window managers
+ create event iff we don't leave the
+ selected frame. */
+ && (focus_follows_mouse
+ || (EQ (XWINDOW (window)->frame,
+ XWINDOW (selected_window)->frame))))
{
inev.kind = SELECT_WINDOW_EVENT;
inev.frame_or_window = window;
char *resource_name;
{
struct mac_display_info *dpyinfo;
+ struct terminal *terminal;
BLOCK_INPUT;
dpyinfo = &one_mac_display_info;
bzero (dpyinfo, sizeof (*dpyinfo));
+ terminal = mac_create_terminal (dpyinfo);
+
+ /* Set the name of the terminal. */
+ terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+ strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+ terminal->name[SBYTES (display_name)] = 0;
+
#ifdef MAC_OSX
dpyinfo->mac_id_name
= (char *) xmalloc (SCHARS (Vinvocation_name)
dpyinfo->grabbed = 0;
dpyinfo->root_window = NULL;
- dpyinfo->image_cache = make_image_cache ();
+ dpyinfo->terminal->image_cache = make_image_cache ();
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
x_display_name_list);
dpyinfo->name_list_element = XCAR (x_display_name_list);
+ /* FIXME: Untested.
+ Add the default keyboard. */
+ add_keyboard_wait_descriptor (0);
+
+#if USE_CG_DRAWING
+ mac_init_fringe (terminal->rif);
+#endif
+
UNBLOCK_INPUT;
return dpyinfo;
mac_shift_glyphs_for_insert
};
-void
+static struct terminal *
+mac_create_terminal (struct mac_display_info *dpyinfo)
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal ();
+
+ terminal->type = output_mac;
+ terminal->display_info.mac = dpyinfo;
+ dpyinfo->terminal = terminal;
+
+ terminal->clear_frame_hook = x_clear_frame;
+ terminal->ins_del_lines_hook = x_ins_del_lines;
+ terminal->delete_glyphs_hook = x_delete_glyphs;
+ terminal->ring_bell_hook = XTring_bell;
+ terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
+ terminal->set_terminal_modes_hook = XTset_terminal_modes;
+ terminal->update_begin_hook = x_update_begin;
+ terminal->update_end_hook = x_update_end;
+ terminal->set_terminal_window_hook = XTset_terminal_window;
+ terminal->read_socket_hook = XTread_socket;
+ terminal->frame_up_to_date_hook = XTframe_up_to_date;
+ terminal->mouse_position_hook = XTmouse_position;
+ terminal->frame_rehighlight_hook = XTframe_rehighlight;
+ terminal->frame_raise_lower_hook = XTframe_raise_lower;
+ /* terminal->fullscreen_hook = XTfullscreen_hook; */
+ terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+ terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+ terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+ terminal->delete_frame_hook = x_destroy_window;
+ /* terminal->delete_terminal_hook = x_delete_terminal; */
+
+ terminal->rif = &x_redisplay_interface;
+#if 0
+ 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 */
+#else
+ terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
+ terminal->char_ins_del_ok = 1;
+ terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
+ terminal->fast_clear_end_of_line = 1; /* X does this well. */
+ terminal->memory_below_frame = 0; /* We don't remember what scrolls
+ off the bottom. */
+
+#endif
+
+ /* FIXME: This keyboard setup is 100% untested, just copied from
+ w32_create_terminal in order to set window-system now that it's
+ a keyboard object. */
+ /* We don't yet support separate terminals on Mac, so don't try to share
+ keyboards between virtual terminals that are on the same physical
+ terminal like X does. */
+ terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ init_kboard (terminal->kboard);
+ terminal->kboard->Vwindow_system = intern ("mac");
+ terminal->kboard->next_kboard = all_kboards;
+ all_kboards = terminal->kboard;
+ /* Don't let the initial kboard remain current longer than necessary.
+ That would cause problems if a file loaded on startup tries to
+ prompt in the mini-buffer. */
+ if (current_kboard == initial_kboard)
+ current_kboard = terminal->kboard;
+ terminal->kboard->reference_count++;
+
+ return terminal;
+}
+
+static void
mac_initialize ()
{
- rif = &x_redisplay_interface;
-
- clear_frame_hook = x_clear_frame;
- ins_del_lines_hook = x_ins_del_lines;
- delete_glyphs_hook = x_delete_glyphs;
- ring_bell_hook = XTring_bell;
- reset_terminal_modes_hook = XTreset_terminal_modes;
- set_terminal_modes_hook = XTset_terminal_modes;
- update_begin_hook = x_update_begin;
- update_end_hook = x_update_end;
- set_terminal_window_hook = XTset_terminal_window;
- read_socket_hook = XTread_socket;
- frame_up_to_date_hook = XTframe_up_to_date;
- mouse_position_hook = XTmouse_position;
- frame_rehighlight_hook = XTframe_rehighlight;
- frame_raise_lower_hook = XTframe_raise_lower;
-
- set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
- condemn_scroll_bars_hook = XTcondemn_scroll_bars;
- 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 */
+
baud_rate = 19200;
last_tool_bar_item = -1;
any_help_event_p = 0;
/* Try to use interrupt input; if we can't, then start polling. */
- Fset_input_mode (Qt, Qnil, Qt, Qnil);
+ Fset_input_interrupt_mode (Qt);
BLOCK_INPUT;
#if USE_CG_DRAWING
init_cg_color ();
-
- mac_init_fringe ();
#endif
UNBLOCK_INPUT;
+
}