X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b2e6b10fe2d40020a75ab0025af98a4abf339cd2..0e2501ed344f5c8e251bcdca981f5d81dd78f663:/src/macterm.c diff --git a/src/macterm.c b/src/macterm.c index 654afcf6b1..842e1844f5 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -1,6 +1,6 @@ /* 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. @@ -228,14 +228,14 @@ void x_raise_frame P_ ((struct frame *)); 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 *)); @@ -263,6 +263,8 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *, 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) @@ -2360,6 +2362,9 @@ mac_define_fringe_bitmap (which, bits, h, wd) for (i = 0; i < h; i++) bits[i] = ~bits[i]; + + BLOCK_INPUT; + provider = CGDataProviderCreateWithData (NULL, bits, sizeof (unsigned short) * h, NULL); if (provider) @@ -2369,6 +2374,8 @@ mac_define_fringe_bitmap (which, bits, h, wd) provider, NULL, 0); CGDataProviderRelease (provider); } + + UNBLOCK_INPUT; } static void @@ -2379,7 +2386,11 @@ mac_destroy_fringe_bitmap (which) return; if (fringe_bmp[which]) - CGImageRelease (fringe_bmp[which]); + { + BLOCK_INPUT; + CGImageRelease (fringe_bmp[which]); + UNBLOCK_INPUT; + } fringe_bmp[which] = 0; } #endif @@ -2391,7 +2402,7 @@ mac_destroy_fringe_bitmap (which) rarely happens). */ static void -XTset_terminal_modes () +XTset_terminal_modes (struct terminal *t) { } @@ -2399,7 +2410,7 @@ XTset_terminal_modes () the windows go away, and suspending requires no action. */ static void -XTreset_terminal_modes () +XTreset_terminal_modes (struct terminal *t) { } @@ -2959,7 +2970,7 @@ x_draw_glyph_string_foreground (s) 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; @@ -3038,7 +3049,7 @@ x_draw_composite_glyph_string_foreground (s) 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; @@ -3058,10 +3069,17 @@ x_draw_composite_glyph_string_foreground (s) 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); } } @@ -3526,7 +3544,7 @@ x_draw_glyph_string_box (s) ? 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 @@ -3572,7 +3590,7 @@ x_draw_image_foreground (s) 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. */ @@ -3645,7 +3663,7 @@ x_draw_image_relief (s) 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. */ @@ -3662,7 +3680,7 @@ x_draw_image_relief (s) } else { - thick = abs (s->img->relief); + thick = eabs (s->img->relief); raised_p = s->img->relief > 0; } @@ -3723,7 +3741,7 @@ x_draw_image_glyph_string (s) 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; @@ -3773,7 +3791,6 @@ x_draw_stretch_glyph_string (s) 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) @@ -4042,15 +4059,8 @@ x_delete_glyphs (n) 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))); @@ -4568,7 +4578,7 @@ note_mouse_movement (frame, pos) 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); } @@ -5061,6 +5071,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height) #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; @@ -5277,14 +5288,24 @@ XTset_vertical_scroll_bar (w, portion, whole, position) 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. */ @@ -5326,6 +5347,8 @@ XTset_vertical_scroll_bar (w, portion, whole, position) 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)) { @@ -5683,8 +5706,15 @@ void 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; } @@ -8289,7 +8319,7 @@ init_font_name_table () 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))); } } @@ -8364,7 +8394,7 @@ init_font_name_table () { 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))); @@ -8774,7 +8804,7 @@ mac_load_query_font (f, fontname) 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; @@ -12167,7 +12197,13 @@ XTread_socket (sd, expected, hold_quit) 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; @@ -12545,6 +12581,7 @@ mac_term_init (display_name, xrm_option, resource_name) char *resource_name; { struct mac_display_info *dpyinfo; + struct terminal *terminal; BLOCK_INPUT; @@ -12560,6 +12597,13 @@ mac_term_init (display_name, xrm_option, resource_name) 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) @@ -12580,7 +12624,7 @@ mac_term_init (display_name, xrm_option, resource_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; @@ -12601,6 +12645,14 @@ mac_term_init (display_name, xrm_option, resource_name) 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; @@ -12761,44 +12813,90 @@ static struct redisplay_interface x_redisplay_interface = 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; @@ -12830,11 +12928,10 @@ mac_initialize () #if USE_CG_DRAWING init_cg_color (); - - mac_init_fringe (); #endif UNBLOCK_INPUT; + }