diff options
author | Steven Tamm <steventamm@mac.com> | 2004-12-27 17:27:30 +0000 |
---|---|---|
committer | Steven Tamm <steventamm@mac.com> | 2004-12-27 17:27:30 +0000 |
commit | b15325b22a301f3f1d150ab15dff23521cc79711 (patch) | |
tree | 82a57d1a677ac34da4e6a4d0ab6767a4e2a10778 /src/macterm.c | |
parent | 22933cbff47c023e8a37677112e847c9242d8a54 (diff) | |
download | emacs-b15325b22a301f3f1d150ab15dff23521cc79711.tar.gz |
* dispextern.h: Change HAVE_CARBON to MAC_OS.
(struct glyph_string): Likewise.
* emacs.c (main) [MAC_OS8]: Call mac_term_init instead of
mac_initialize.
* fileio.c (Fnext_read_file_uses_dialog_p, Fread_file_name):
Change TARGET_API_MAC_CARBON to HAVE_CARBON.
* fns.c (vector): Change MAC_OSX to MAC_OS.
* frame.c (x_set_frame_parameters, x_report_frame_params)
(x_set_fullscreen): Remove #ifndef HAVE_CARBON.
(x_set_border_width, Vdefault_frame_scroll_bars): Change
HAVE_CARBON to MAC_OS.
* image.c [MAC_OS]: Include sys/stat.h.
[MAC_OS && !MAC_OSX]: Include sys/param.h, ImageCompression.h, and
QuickTimeComponents.h.
* mac.c [!MAC_OSX] (mac_wait_next_event): Add extern.
[!MAC_OSX] (select): Use mac_wait_next_event.
[!MAC_OSX] (run_mac_command): Change EXEC_SUFFIXES to
Vexec_suffixes.
[!MAC_OSX] (select, run_mac_command): Change `#ifdef
TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'.
(mac_clear_font_name_table): Add extern.
(Fmac_clear_font_name_table): New defun.
(syms_of_mac): Defsubr it.
[MAC_OSX] (SELECT_POLLING_PERIOD_USEC): New define.
[MAC_OSX] (select_and_poll_event): New function.
[MAC_OSX] (sys_select): Use it.
[MAC_OSX && SELECT_USE_CFSOCKET] (socket_callback): New function.
[MAC_OSX && SELECT_USE_CFSOCKET]
(SELECT_TIMEOUT_THRESHOLD_RUNLOOP, EVENT_CLASS_SOCK): New defines.
[MAC_OSX] (sys_select) [SELECT_USE_CFSOCKET]: Use CFSocket and
RunLoop for simultaneously monitoring two kinds of inputs, window
events and process outputs, without periodically polling.
* macfns.c (mac_initialized): Remove extern.
(stricmp): Put in #if 0. All callers changed to use xstricmp in
xfaces.c.
(strnicmp): Decrement `n' at the end of each loop, not the
beginning.
(check_mac): Use the term "Mac native windows" instead of "Mac
OS".
(check_x_display_info, x_display_info_for_name): Sync with xfns.c.
(mac_get_rdb_resource): New function (from w32reg.c).
(x_get_string_resource): Use it.
(install_window_handler): Add extern.
(mac_window): New function.
(Fx_create_frame): Use it instead of make_mac_frame. Set
parameter for Qfullscreen. Call x_wm_set_size_hint.
(Fx_open_connection, Fx_close_connection): New defuns.
(syms_of_macfns): Defsubr them.
(x_create_tip_frame) [TARGET_API_MAC_CARBON]: Add
kWindowNoUpdatesAttribute to the window attribute.
(x_create_tip_frame) [!TARGET_API_MAC_CARBON]: Use NewCWindow.
(x_create_tip_frame): Don't call ShowWindow.
(Fx_show_tip): Call ShowWindow.
(Fx_file_dialog): Change `#ifdef TARGET_API_MAC_CARBON' to `#if
TARGET_API_MAC_CARBON'.
(mac_frame_parm_handlers): Set handlers for Qfullscreen.
(syms_of_macfns) [MAC_OSX]: Initialize mac_in_use to 0.
* macgui.h [!MAC_OSX]: Don't include Controls.h. Include
Windows.h.
(Window): Typedef to WindowPtr and move outside `#if
TARGET_API_MAC_CARBON'.
(XSizeHints): New struct.
* macterm.c (x_update_begin, x_update_end)
[TARGET_API_MAC_CARBON]: Disable screen updates during update of a
frame.
(x_draw_glyph_string_background, x_draw_glyph_string_foreground)
[MAC_OS8]: Use XDrawImageString/XDrawImageString16.
(construct_mouse_click): Put in #if 0.
(x_check_fullscreen, x_check_fullscreen_move): Remove decls.
(x_scroll_bar_create, x_scroll_bar_handle_click): Change `#ifdef
TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'.
(activate_scroll_bars, deactivate_scroll_bars)
[!TARGET_API_MAC_CARBON]: Use ActivateControl/DeactivateControl.
(x_make_frame_visible) [TARGET_API_MAC_CARBON]: Reposition window
if the position is neither user-specified nor program-specified.
(x_free_frame_resources): Free size_hints.
(x_wm_set_size_hint): Allocate size_hints if needed. Set
size_hints.
(mac_clear_font_name_table): New function.
(mac_do_list_fonts): Initialize font_name_table if needed.
(x_list_fonts): Don't initialize font_name_table. Add BLOCK_INPUT
around mac_do_list_fonts.
(mac_unload_font): New function.
(x_load_font): Add BLOCK_INPUT around XLoadQueryFont.
(init_mac_drag_n_drop, mac_do_receive_drag): Enclose declarations
and definitions with #if TARGET_API_MAC_CARBON.
[USE_CARBON_EVENTS] (mac_handle_window_event): Add decl.
(install_window_handler): Add decl.
(do_window_update): Add BeginUpdate/EndUpdate for the tooltip
window. Use UpdateControls. Get the rectangle that should be
updated and restrict the target of expose_frame to it.
(do_grow_window): Set minimum height/width according to
size_hints.
(do_grow_window) [TARGET_API_MAC_CARBON]: Use ResizeWindow.
(do_zoom_window): Don't use x_set_window_size.
[USE_CARBON_EVENTS] (mac_handle_window_event): New function.
(install_window_handler): New function.
[!USE_CARBON_EVENTS] (mouse_region): New variable.
[!USE_CARBON_EVENTS] (mac_wait_next_event): New function.
(XTread_socket) [USE_CARBON_EVENTS]: Move call to
GetEventDispatcherTarget inside BLOCK_INPUT.
(XTread_socket) [!USE_CARBON_EVENTS]: Use mac_wait_next_event.
Update mouse_region when mouse is moved.
(make_mac_frame): Remove.
(make_mac_terminal_frame): Put in #ifdef MAC_OS8. Initialize
mouse pointer shapes. Change values of f->left_pos and
f->top_pos. Don't use make_mac_frame. Use NewCWindow. Don't
call ShowWindow.
(mac_initialize_display_info) [MAC_OSX]: Create mac_id_name from
Vinvocation_name and Vsystem_name.
(mac_make_rdb): New function (from w32term.c).
(mac_term_init): Use it. Add BLOCK_INPUT. Error if display has
already been opened. Don't pass argument to
mac_initialize_display_info. Don't set dpyinfo->height/width.
Add entries to x_display_list and x_display_name_list.
(x_delete_display): New function.
(mac_initialize): Don't call mac_initialize_display_info.
(syms_of_macterm) [!MAC_OSX]: Don't call Fprovide.
* macterm.h (check_mac): Add extern.
(struct mac_output): New member size_hints.
(FRAME_SIZE_HINTS): New macro.
(mac_unload_font): Add extern.
* xdisp.c (expose_window, expose_frame): Remove kludges for Mac.
* xfaces.c (clear_font_table) [MAC_OS]: call mac_unload_font.
Diffstat (limited to 'src/macterm.c')
-rw-r--r-- | src/macterm.c | 748 |
1 files changed, 496 insertions, 252 deletions
diff --git a/src/macterm.c b/src/macterm.c index 9dae0b54d70..3f1fb1642f1 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -1178,7 +1178,17 @@ static void x_update_begin (f) struct frame *f; { - /* Nothing to do. */ +#if TARGET_API_MAC_CARBON + /* During update of a frame, availability of input events is + periodically checked with ReceiveNextEvent if + redisplay-dont-pause is nil. That normally flushes window buffer + changes for every check, and thus screen update looks waving even + if no input is available. So we disable screen updates during + update of a frame. */ + BLOCK_INPUT; + DisableScreenUpdates (); + UNBLOCK_INPUT; +#endif } @@ -1263,7 +1273,7 @@ mac_draw_vertical_window_border (w, x, y0, y1) make sure that the mouse-highlight is properly redrawn. W may be a menu bar pseudo-window in case we don't have X toolkit - support. Such windows don't have a cursor, so don't display it + support. Such windows don't have a cursor, so don't display it here. */ static void @@ -1327,6 +1337,9 @@ x_update_end (f) mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f)); +#if TARGET_API_MAC_CARBON + EnableScreenUpdates (); +#endif XFlush (FRAME_MAC_DISPLAY (f)); UNBLOCK_INPUT; } @@ -1983,7 +1996,7 @@ x_draw_glyph_string_background (s, force_p) } else #endif -#if 0 /* defined(MAC_OS8)*/ +#ifdef MAC_OS8 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width || s->font_not_found_p || s->extends_to_end_of_line_p @@ -2041,7 +2054,7 @@ x_draw_glyph_string_foreground (s) for (i = 0; i < s->nchars; ++i) char1b[i] = s->char2b[i].byte2; -#if 0 /* defined(MAC_OS8) */ +#ifdef MAC_OS8 /* Draw text with XDrawString if background has already been filled. Otherwise, use XDrawImageString. (Note that XDrawImageString is usually faster than XDrawString.) Always @@ -2059,7 +2072,7 @@ x_draw_glyph_string_foreground (s) XDrawString (s->display, s->window, s->gc, x, s->ybase - boff, char1b, s->nchars); } -#if 0 /* defined(MAC_OS8)*/ +#ifdef MAC_OS8 else { if (s->two_byte_p) @@ -3652,6 +3665,7 @@ x_get_keysym_name (keysym) +#if 0 /* Mouse clicks and mouse movement. Rah. */ /* Prepare a mouse-event in *RESULT for placement in the input queue. @@ -3685,6 +3699,7 @@ construct_mouse_click (result, event, f) result->arg = Qnil; return Qnil; } +#endif /* Function to report a mouse movement to the mainstream Emacs code. @@ -3754,8 +3769,6 @@ int disable_mouse_highlight; static struct scroll_bar *x_window_to_scroll_bar (); static void x_scroll_bar_report_motion (); -static void x_check_fullscreen P_ ((struct frame *)); -static void x_check_fullscreen_move P_ ((struct frame *)); static int glyph_rect P_ ((struct frame *f, int, int, Rect *)); @@ -4017,7 +4030,7 @@ x_scroll_bar_create (w, top, left, width, height, disp_top, disp_height) r.right = left + width; r.bottom = disp_top + disp_height; -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", 1, 0, 0, 0, kControlScrollBarProc, 0L); #else @@ -4395,7 +4408,7 @@ activate_scroll_bars (frame) while (! NILP (bar)) { ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar)); -#ifdef TARGET_API_MAC_CARBON +#if 1 /* TARGET_API_MAC_CARBON */ ActivateControl (ch); #else SetControlMaximum (ch, @@ -4419,10 +4432,10 @@ deactivate_scroll_bars (frame) while (! NILP (bar)) { ch = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar)); -#ifdef TARGET_API_MAC_CARBON +#if 1 /* TARGET_API_MAC_CARBON */ DeactivateControl (ch); #else - SetControlMaximum (ch, XINT (-1)); + SetControlMaximum (ch, -1); #endif bar = XSCROLL_BAR (bar)->next; } @@ -4466,7 +4479,7 @@ x_scroll_bar_handle_click (bar, part_code, er, bufp) case kControlPageDownPart: bufp->part = scroll_bar_below_handle; break; -#ifdef TARGET_API_MAC_CARBON +#if TARGET_API_MAC_CARBON default: #else case kControlIndicatorPart: @@ -4974,13 +4987,16 @@ x_new_font (f, fontname) XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->cursor_gc, FRAME_FONT (f)); + /* Don't change the size of a tip frame; there's no point in + doing it because it's done in Fx_show_tip, and it leads to + problems because the tip frame has no widget. */ if (NILP (tip_frame) || XFRAME (tip_frame) != f) x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); } return build_string (fontp->full_name); } - + /* Give frame F the fontset named FONTSETNAME as its default font, and return the full name of that fontset. FONTSETNAME may be a wildcard pattern; in that case, we choose some fontset that fits the pattern. @@ -5369,6 +5385,25 @@ x_make_frame_visible (f) f->output_data.mac->asked_for_visible = 1; +#if TARGET_API_MAC_CARBON + if (!(FRAME_SIZE_HINTS (f)->flags & (USPosition | PPosition))) + { + struct frame *sf = SELECTED_FRAME (); + if (!FRAME_MAC_P (sf)) + RepositionWindow (FRAME_MAC_WINDOW (f), NULL, + kWindowCenterOnMainScreen); + else + RepositionWindow (FRAME_MAC_WINDOW (f), + FRAME_MAC_WINDOW (sf), +#ifdef MAC_OS_X_VERSION_10_2 + kWindowCascadeStartAtParentWindowScreen +#else + kWindowCascadeOnParentWindowScreen +#endif + ); + x_real_positions (f, &f->left_pos, &f->top_pos); + } +#endif ShowWindow (FRAME_MAC_WINDOW (f)); } @@ -5496,6 +5531,9 @@ x_free_frame_resources (f) x_free_gcs (f); + if (FRAME_SIZE_HINTS (f)) + xfree (FRAME_SIZE_HINTS (f)); + xfree (f->output_data.mac); f->output_data.mac = NULL; @@ -5548,143 +5586,39 @@ x_wm_set_size_hint (f, flags, user_position) long flags; int user_position; { -#if 0 /* MAC_TODO: connect this to the Appearance Manager */ - XSizeHints size_hints; - -#ifdef USE_X_TOOLKIT - Arg al[2]; - int ac = 0; - Dimension widget_width, widget_height; - Window window = XtWindow (f->output_data.x->widget); -#else /* not USE_X_TOOLKIT */ - Window window = FRAME_X_WINDOW (f); -#endif /* not USE_X_TOOLKIT */ - - /* Setting PMaxSize caused various problems. */ - size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; - - size_hints.x = f->left_pos; - size_hints.y = f->top_pos; - -#ifdef USE_X_TOOLKIT - XtSetArg (al[ac], XtNwidth, &widget_width); ac++; - XtSetArg (al[ac], XtNheight, &widget_height); ac++; - XtGetValues (f->output_data.x->widget, al, ac); - size_hints.height = widget_height; - size_hints.width = widget_width; -#else /* not USE_X_TOOLKIT */ - size_hints.height = FRAME_PIXEL_HEIGHT (f); - size_hints.width = FRAME_PIXEL_WIDTH (f); -#endif /* not USE_X_TOOLKIT */ - - size_hints.width_inc = FRAME_COLUMN_WIDTH (f); - size_hints.height_inc = FRAME_LINE_HEIGHT (f); - size_hints.max_width - = FRAME_X_DISPLAY_INFO (f)->width - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); - size_hints.max_height - = FRAME_X_DISPLAY_INFO (f)->height - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); - - /* Calculate the base and minimum sizes. - - (When we use the X toolkit, we don't do it here. - Instead we copy the values that the widgets are using, below.) */ -#ifndef USE_X_TOOLKIT - { - int base_width, base_height; - int min_rows = 0, min_cols = 0; - - base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); - base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); + int base_width, base_height, width_inc, height_inc; + int min_rows = 0, min_cols = 0; + XSizeHints *size_hints; - check_frame_size (f, &min_rows, &min_cols); + base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); + base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); + width_inc = FRAME_COLUMN_WIDTH (f); + height_inc = FRAME_LINE_HEIGHT (f); - /* The window manager uses the base width hints to calculate the - current number of rows and columns in the frame while - resizing; min_width and min_height aren't useful for this - purpose, since they might not give the dimensions for a - zero-row, zero-column frame. + check_frame_size (f, &min_rows, &min_cols); - We use the base_width and base_height members if we have - them; otherwise, we set the min_width and min_height members - to the size for a zero x zero frame. */ - -#ifdef HAVE_X11R4 - size_hints.flags |= PBaseSize; - size_hints.base_width = base_width; - size_hints.base_height = base_height; - size_hints.min_width = base_width + min_cols * size_hints.width_inc; - size_hints.min_height = base_height + min_rows * size_hints.height_inc; -#else - size_hints.min_width = base_width; - size_hints.min_height = base_height; -#endif - } - - /* If we don't need the old flags, we don't need the old hint at all. */ - if (flags) + size_hints = FRAME_SIZE_HINTS (f); + if (size_hints == NULL) { - size_hints.flags |= flags; - goto no_read; + size_hints = FRAME_SIZE_HINTS (f) = xmalloc (sizeof (XSizeHints)); + bzero (size_hints, sizeof (XSizeHints)); } -#endif /* not USE_X_TOOLKIT */ - - { - XSizeHints hints; /* Sometimes I hate X Windows... */ - long supplied_return; - int value; - -#ifdef HAVE_X11R4 - value = XGetWMNormalHints (FRAME_X_DISPLAY (f), window, &hints, - &supplied_return); -#else - value = XGetNormalHints (FRAME_X_DISPLAY (f), window, &hints); -#endif - -#ifdef USE_X_TOOLKIT - size_hints.base_height = hints.base_height; - size_hints.base_width = hints.base_width; - size_hints.min_height = hints.min_height; - size_hints.min_width = hints.min_width; -#endif - - if (flags) - size_hints.flags |= flags; - else - { - if (value == 0) - hints.flags = 0; - if (hints.flags & PSize) - size_hints.flags |= PSize; - if (hints.flags & PPosition) - size_hints.flags |= PPosition; - if (hints.flags & USPosition) - size_hints.flags |= USPosition; - if (hints.flags & USSize) - size_hints.flags |= USSize; - } - } - -#ifndef USE_X_TOOLKIT - no_read: -#endif -#ifdef PWinGravity - size_hints.win_gravity = f->win_gravity; - size_hints.flags |= PWinGravity; + size_hints->flags |= PResizeInc | PMinSize | PBaseSize ; + size_hints->width_inc = width_inc; + size_hints->height_inc = height_inc; + size_hints->min_width = base_width + min_cols * width_inc; + size_hints->min_height = base_height + min_rows * height_inc; + size_hints->base_width = base_width; + size_hints->base_height = base_height; - if (user_position) + if (flags) + size_hints->flags = flags; + else if (user_position) { - size_hints.flags &= ~ PPosition; - size_hints.flags |= USPosition; + size_hints->flags &= ~ PPosition; + size_hints->flags |= USPosition; } -#endif /* PWinGravity */ - -#ifdef HAVE_X11R4 - XSetWMNormalHints (FRAME_X_DISPLAY (f), window, &size_hints); -#else - XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints); -#endif -#endif /* MAC_TODO */ } #if 0 /* MAC_TODO: hide application instead of iconify? */ @@ -6120,7 +6054,7 @@ init_font_name_table () break; sc = GetTextEncodingBase (encoding); decode_mac_font_name (name, sizeof (name), sc); - + /* Point the instance iterator at the current font family. */ if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr) break; @@ -6259,6 +6193,19 @@ init_font_name_table () } +void +mac_clear_font_name_table () +{ + int i; + + for (i = 0; i < font_name_count; i++) + xfree (font_name_table[i]); + xfree (font_name_table); + font_name_table = NULL; + font_name_table_size = font_name_count = 0; +} + + enum xlfd_scalable_field_index { XLFD_SCL_PIXEL_SIZE, @@ -6311,6 +6258,9 @@ mac_do_list_fonts (pattern, maxnames) char *longest_start, *cur_start, *nonspecial; int longest_len, cur_len, exact; + if (font_name_table == NULL) /* Initialize when first used. */ + init_font_name_table (); + for (i = 0; i < XLFD_SCL_LAST; i++) scl_val[i] = -1; @@ -6471,9 +6421,6 @@ x_list_fonts (struct frame *f, Lisp_Object newlist = Qnil, tem, key; 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 (); - if (dpyinfo) { tem = XCDR (dpyinfo->name_list_element); @@ -6487,7 +6434,9 @@ x_list_fonts (struct frame *f, } } + BLOCK_INPUT; newlist = mac_do_list_fonts (SDATA (pattern), maxnames); + UNBLOCK_INPUT; /* MAC_TODO: add code for matching outline fonts here */ @@ -6791,6 +6740,18 @@ XLoadQueryFont (Display *dpy, char *fontname) } +void +mac_unload_font (dpyinfo, font) + struct mac_display_info *dpyinfo; + XFontStruct *font; +{ + xfree (font->fontname); + if (font->per_char) + xfree (font->per_char); + xfree (font); +} + + /* Load font named FONTNAME of the size SIZE for frame F, and return a pointer to the structure font_info while allocating it dynamically. If SIZE is 0, load any size of font. @@ -6841,7 +6802,9 @@ x_load_font (f, fontname, size) if (size > 0 && !NILP (font_names)) fontname = (char *) SDATA (XCAR (font_names)); + BLOCK_INPUT; font = (MacFontStruct *) XLoadQueryFont (FRAME_MAC_DISPLAY (f), fontname); + UNBLOCK_INPUT; if (!font) return NULL; @@ -7121,15 +7084,21 @@ 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); +#if TARGET_API_MAC_CARBON /* Drag and Drop */ static OSErr init_mac_drag_n_drop (); static pascal OSErr mac_do_receive_drag (WindowPtr, void*, DragReference); +#endif #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 (); +/* Window Event Handler */ +static pascal OSStatus mac_handle_window_event (EventHandlerCallRef, + EventRef, void *); #endif +void install_window_handler (WindowPtr); extern void init_emacs_passwd_dir (); extern int emacs_main (int, char **, char **); @@ -7336,12 +7305,11 @@ do_window_update (WindowPtr win) { struct frame *f = mac_window_to_frame (win); - if (win == tip_window) - /* The tooltip has been drawn already. Avoid the - SET_FRAME_GARBAGED below. */ - return; + BeginUpdate (win); - if (f) + /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED + below. */ + if (win != tip_window) { if (f->async_visible == 0) { @@ -7358,17 +7326,30 @@ do_window_update (WindowPtr win) } else { - BeginUpdate (win); + Rect r; + handling_window_update = 1; - XClearWindow (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); +#if TARGET_API_MAC_CARBON + { + RgnHandle region = NewRgn (); - expose_frame (f, 0, 0, 0, 0); + GetPortVisibleRegion (GetWindowPort (win), region); + UpdateControls (win, region); + GetRegionBounds (region, &r); + 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); handling_window_update = 0; - EndUpdate (win); } } + + EndUpdate (win); } static int @@ -7530,20 +7511,43 @@ do_menu_choice (SInt32 menu_choice) static void do_grow_window (WindowPtr w, EventRecord *e) { - long grow_size; Rect limit_rect; - int rows, columns; + int rows, columns, width, height; struct frame *f = mac_window_to_frame (w); + XSizeHints *size_hints = FRAME_SIZE_HINTS (f); + int min_width = MIN_DOC_SIZE, min_height = MIN_DOC_SIZE; +#if TARGET_API_MAC_CARBON + Rect new_rect; +#else + long grow_size; +#endif - SetRect(&limit_rect, MIN_DOC_SIZE, MIN_DOC_SIZE, MAX_DOC_SIZE, MAX_DOC_SIZE); + if (size_hints->flags & PMinSize) + { + min_width = size_hints->min_width; + min_height = size_hints->min_height; + } + SetRect (&limit_rect, min_width, min_height, MAX_DOC_SIZE, MAX_DOC_SIZE); +#if TARGET_API_MAC_CARBON + if (!ResizeWindow (w, e->where, &limit_rect, &new_rect)) + return; + height = new_rect.bottom - new_rect.top; + width = new_rect.right - new_rect.left; +#else grow_size = GrowWindow (w, e->where, &limit_rect); - /* see if it really changed size */ - if (grow_size != 0) + if (grow_size == 0) + return; + height = HiWord (grow_size); + width = LoWord (grow_size); +#endif + + if (width != FRAME_PIXEL_WIDTH (f) + || height != FRAME_PIXEL_HEIGHT (f)) { - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, HiWord (grow_size)); - columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, LoWord (grow_size)); + rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); + columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); x_set_window_size (f, 0, columns, rows); } @@ -7561,7 +7565,7 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) GrafPtr save_port; Rect zoom_rect, port_rect; Point top_left; - int w_title_height, columns, rows; + int w_title_height, columns, rows, width, height; struct frame *f = mac_window_to_frame (w); #if TARGET_API_MAC_CARBON @@ -7636,12 +7640,26 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) #else port_rect = w->portRect; #endif - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, port_rect.bottom - port_rect.top); - columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, port_rect.right - port_rect.left); - x_set_window_size (f, 0, columns, rows); + height = port_rect.bottom - port_rect.top; + width = port_rect.right - port_rect.left; + + if (width != FRAME_PIXEL_WIDTH (f) + || height != FRAME_PIXEL_HEIGHT (f)) + { + rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height); + columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width); + + change_frame_size (f, rows, columns, 0, 1, 0); + SET_FRAME_GARBAGED (f); + cancel_mouse_face (f); + + FRAME_PIXEL_WIDTH (f) = width; + FRAME_PIXEL_HEIGHT (f) = height; + } x_real_positions (f, &f->left_pos, &f->top_pos); } +#if TARGET_API_MAC_CARBON /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */ static OSErr init_mac_drag_n_drop () @@ -7649,6 +7667,7 @@ init_mac_drag_n_drop () OSErr result = InstallReceiveHandler (mac_do_receive_drag, 0L, NULL); return result; } +#endif /* Intialize AppleEvent dispatcher table for the required events. */ void @@ -7819,7 +7838,93 @@ mac_handle_service_event (EventHandlerCallRef callRef, } return err; } + + +static pascal OSStatus +mac_handle_window_event (next_handler, event, data) + EventHandlerCallRef next_handler; + EventRef event; + void *data; +{ + extern Lisp_Object Qcontrol; + + WindowPtr wp; + OSStatus result; + UInt32 attributes; + XSizeHints *size_hints; + + GetEventParameter (event, kEventParamDirectObject, typeWindowRef, + NULL, sizeof (WindowPtr), NULL, &wp); + + switch (GetEventKind (event)) + { + case kEventWindowBoundsChanging: + result = CallNextEventHandler (next_handler, event); + if (result != eventNotHandledErr) + return result; + + GetEventParameter (event, kEventParamAttributes, typeUInt32, + NULL, sizeof (UInt32), NULL, &attributes); + size_hints = FRAME_SIZE_HINTS (mac_window_to_frame (wp)); + if ((attributes & kWindowBoundsChangeUserResize) + && ((size_hints->flags & (PResizeInc | PBaseSize | PMinSize)) + == (PResizeInc | PBaseSize | PMinSize))) + { + Rect bounds; + int width, height; + + GetEventParameter (event, kEventParamCurrentBounds, + typeQDRectangle, + NULL, sizeof (Rect), NULL, &bounds); + width = bounds.right - bounds.left; + height = bounds.bottom - bounds.top; + + if (width < size_hints->min_width) + width = size_hints->min_width; + else + width = size_hints->base_width + + (int) ((width - size_hints->base_width) + / (float) size_hints->width_inc + .5) + * size_hints->width_inc; + + if (height < size_hints->min_height) + height = size_hints->min_height; + else + height = size_hints->base_height + + (int) ((height - size_hints->base_height) + / (float) size_hints->height_inc + .5) + * size_hints->height_inc; + + bounds.right = bounds.left + width; + bounds.bottom = bounds.top + height; + SetEventParameter (event, kEventParamCurrentBounds, + typeQDRectangle, sizeof (Rect), &bounds); + return noErr; + } + break; + } + + return eventNotHandledErr; +} +#endif /* USE_CARBON_EVENTS */ + + +void +install_window_handler (window) + WindowPtr window; +{ +#if USE_CARBON_EVENTS + EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowBoundsChanging}}; + static EventHandlerUPP handle_window_event_UPP = NULL; + + if (handle_window_event_UPP == NULL) + handle_window_event_UPP = NewEventHandlerUPP (mac_handle_window_event); + + InstallWindowEventHandler (window, handle_window_event_UPP, + GetEventTypeCount (specs), specs, NULL, NULL); #endif +} + /* Open Application Apple Event */ static pascal OSErr @@ -7915,6 +8020,7 @@ descriptor_error_exit: } +#if TARGET_API_MAC_CARBON static pascal OSErr mac_do_receive_drag (WindowPtr window, void *handlerRefCon, DragReference theDrag) @@ -7991,6 +8097,7 @@ mac_do_receive_drag (WindowPtr window, void *handlerRefCon, } } } +#endif /* Print Document Apple Event */ @@ -8140,6 +8247,45 @@ keycode_to_xkeysym (int keyCode, int *xKeySym) return *xKeySym != 0; } +#if !USE_CARBON_EVENTS +static RgnHandle mouse_region = NULL; + +Boolean +mac_wait_next_event (er, sleep_time, dequeue) + EventRecord *er; + UInt32 sleep_time; + Boolean dequeue; +{ + static EventRecord er_buf = {nullEvent}; + UInt32 target_tick, current_tick; + EventMask event_mask; + + if (mouse_region == NULL) + mouse_region = NewRgn (); + + event_mask = everyEvent; + if (NILP (Fboundp (Qmac_ready_for_drag_n_drop))) + event_mask -= highLevelEventMask; + + current_tick = TickCount (); + target_tick = current_tick + sleep_time; + + if (er_buf.what == nullEvent) + while (!WaitNextEvent (event_mask, &er_buf, + target_tick - current_tick, mouse_region)) + { + current_tick = TickCount (); + if (target_tick <= current_tick) + return false; + } + + *er = er_buf; + if (dequeue) + er_buf.what = nullEvent; + return true; +} +#endif /* not USE_CARBON_EVENTS */ + /* Emacs calls this whenever it wants to read an input event from the user. */ int @@ -8151,9 +8297,7 @@ XTread_socket (sd, expected, hold_quit) int count = 0; #if USE_CARBON_EVENTS EventRef eventRef; - EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget (); -#else - EventMask event_mask; + EventTargetRef toolbox_dispatcher; #endif EventRecord er; struct mac_display_info *dpyinfo = &one_mac_display_info; @@ -8184,16 +8328,14 @@ XTread_socket (sd, expected, hold_quit) if (terminate_flag) Fkill_emacs (make_number (1)); -#if !USE_CARBON_EVENTS - event_mask = everyEvent; - if (NILP (Fboundp (Qmac_ready_for_drag_n_drop))) - event_mask -= highLevelEventMask; +#if USE_CARBON_EVENTS + toolbox_dispatcher = GetEventDispatcherTarget (); - while (WaitNextEvent (event_mask, &er, 0L, NULL)) -#else /* USE_CARBON_EVENTS */ while (!ReceiveNextEvent (0, NULL, kEventDurationNoWait, kEventRemoveFromQueue, &eventRef)) -#endif /* USE_CARBON_EVENTS */ +#else /* !USE_CARBON_EVENTS */ + while (mac_wait_next_event (&er, 0, true)) +#endif /* !USE_CARBON_EVENTS */ { int do_help = 0; struct frame *f; @@ -8260,6 +8402,7 @@ XTread_socket (sd, expected, hold_quit) SendEventToEventTarget (eventRef, toolbox_dispatcher); break; + default: /* Send the event to the appropriate receiver. */ SendEventToEventTarget (eventRef, toolbox_dispatcher); @@ -8497,6 +8640,10 @@ XTread_socket (sd, expected, hold_quit) break; case mouseMovedMessage: +#if !USE_CARBON_EVENTS + SetRectRgn (mouse_region, er.where.h, er.where.v, + er.where.h + 1, er.where.v + 1); +#endif previous_help_echo_string = help_echo_string; help_echo_string = help_echo_object = help_echo_window = Qnil; help_echo_pos = -1; @@ -8697,21 +8844,21 @@ XTread_socket (sd, expected, hold_quit) 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, + + 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) + &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. */ + If it fails, create another one. */ convert_status = TECFlushText (converter, outbuf, sizeof (outbuf), - &actual_output_length); + &actual_output_length); if (convert_status != noErr) { TECDisposeConverter (converter); @@ -8719,7 +8866,7 @@ XTread_socket (sd, expected, hold_quit) kTextEncodingMacRoman, mac_keyboard_text_encoding); } - } + } } #if USE_CARBON_EVENTS @@ -8864,59 +9011,12 @@ __convert_from_newlines (unsigned char * p, size_t * n) } #endif - -/* Initialize the struct pointed to by MW to represent a new COLS x - ROWS Macintosh window, using font with name FONTNAME and size - FONTSIZE. */ -void -make_mac_frame (FRAME_PTR fp) -{ - mac_output *mwp; -#if TARGET_API_MAC_CARBON - static int making_terminal_window = 0; -#else - static int making_terminal_window = 1; -#endif - - mwp = fp->output_data.mac; - - BLOCK_INPUT; - if (making_terminal_window) - { - if (!(mwp->mWP = GetNewCWindow (TERM_WINDOW_RESOURCE, NULL, - (WindowPtr) -1))) - abort (); - making_terminal_window = 0; - } - else - { -#if TARGET_API_MAC_CARBON - Rect r; - - SetRect (&r, 0, 0, 1, 1); - if (CreateNewWindow (kDocumentWindowClass, - kWindowStandardDocumentAttributes - /* | kWindowToolbarButtonAttribute */, - &r, &mwp->mWP) != noErr) -#else - if (!(mwp->mWP = GetNewCWindow (WINDOW_RESOURCE, NULL, (WindowPtr) -1))) -#endif - abort (); - } - - SetWRefCon (mwp->mWP, (long) mwp); - /* so that update events can find this mac_output struct */ - mwp->mFP = fp; /* point back to emacs frame */ - - SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false); - UNBLOCK_INPUT; -} - - +#ifdef MAC_OS8 void make_mac_terminal_frame (struct frame *f) { Lisp_Object frame; + Rect r; XSETFRAME (frame, f); @@ -8940,10 +9040,17 @@ make_mac_terminal_frame (struct frame *f) 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; + FRAME_FONTSET (f) = -1; f->output_data.mac->explicit_parent = 0; - f->left_pos = 4; - f->top_pos = 4; + f->left_pos = 8; + f->top_pos = 32; f->border_width = 0; f->internal_border_width = 0; @@ -8954,7 +9061,20 @@ make_mac_terminal_frame (struct frame *f) f->new_text_cols = 0; f->new_text_lines = 0; - make_mac_frame (f); + SetRect (&r, f->left_pos, f->top_pos, + f->left_pos + FRAME_PIXEL_WIDTH (f), + f->top_pos + FRAME_PIXEL_HEIGHT (f)); + + BLOCK_INPUT; + + if (!(FRAME_MAC_WINDOW (f) = + NewCWindow (NULL, &r, "\p", true, dBoxProc, + (WindowPtr) -1, 1, (long) f->output_data.mac))) + abort (); + /* so that update events can find this mac_output struct */ + f->output_data.mac->mFP = f; /* point back to emacs frame */ + + UNBLOCK_INPUT; x_make_gc (f); @@ -8970,9 +9090,8 @@ make_mac_terminal_frame (struct frame *f) Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, build_string ("white")), Qnil)); - - ShowWindow (f->output_data.mac->mWP); } +#endif /*********************************************************************** @@ -8989,12 +9108,7 @@ mac_initialize_display_info () bzero (dpyinfo, sizeof (*dpyinfo)); - /* Put it on x_display_name_list. */ - x_display_name_list = Fcons (Fcons (build_string ("Mac"), Qnil), - x_display_name_list); - dpyinfo->name_list_element = XCAR (x_display_name_list); - -#if 0 +#ifdef MAC_OSX dpyinfo->mac_id_name = (char *) xmalloc (SCHARS (Vinvocation_name) + SCHARS (Vsystem_name) @@ -9049,6 +9163,61 @@ mac_initialize_display_info () 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 * +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); + + *current = '\0'; + + return buffer; +} + struct mac_display_info * mac_term_init (display_name, xrm_option, resource_name) Lisp_Object display_name; @@ -9056,7 +9225,8 @@ mac_term_init (display_name, xrm_option, resource_name) char *resource_name; { struct mac_display_info *dpyinfo; - GDHandle main_device_handle; + + BLOCK_INPUT; if (!mac_initialized) { @@ -9064,17 +9234,90 @@ mac_term_init (display_name, xrm_option, resource_name) mac_initialized = 1; } - mac_initialize_display_info (display_name); + if (x_display_list) + error ("Sorry, this version can only handle one display"); + + mac_initialize_display_info (); dpyinfo = &one_mac_display_info; - main_device_handle = LMGetMainDevice(); + dpyinfo->xrdb = xrm_option ? mac_make_rdb (xrm_option) : NULL; - dpyinfo->height = (**main_device_handle).gdRect.bottom; - dpyinfo->width = (**main_device_handle).gdRect.right; + /* 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); + dpyinfo->name_list_element = XCAR (x_display_name_list); + + UNBLOCK_INPUT; return dpyinfo; } +/* Get rid of display DPYINFO, assuming all frames are already gone. */ + +void +x_delete_display (dpyinfo) + struct mac_display_info *dpyinfo; +{ + int i; + + /* Discard this display from x_display_name_list and x_display_list. + We can't use Fdelq because that can quit. */ + if (! NILP (x_display_name_list) + && EQ (XCAR (x_display_name_list), dpyinfo->name_list_element)) + x_display_name_list = XCDR (x_display_name_list); + else + { + Lisp_Object tail; + + tail = x_display_name_list; + while (CONSP (tail) && CONSP (XCDR (tail))) + { + if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element)) + { + XSETCDR (tail, XCDR (XCDR (tail))); + break; + } + tail = XCDR (tail); + } + } + + if (x_display_list == dpyinfo) + x_display_list = dpyinfo->next; + else + { + struct x_display_info *tail; + + for (tail = x_display_list; tail; tail = tail->next) + if (tail->next == dpyinfo) + tail->next = tail->next->next; + } + + /* Free the font names in the font table. */ + for (i = 0; i < dpyinfo->n_fonts; i++) + if (dpyinfo->font_table[i].name) + { + if (dpyinfo->font_table[i].name != dpyinfo->font_table[i].full_name) + xfree (dpyinfo->font_table[i].full_name); + xfree (dpyinfo->font_table[i].name); + } + + if (dpyinfo->font_table->font_encoder) + xfree (dpyinfo->font_table->font_encoder); + + xfree (dpyinfo->font_table); + xfree (dpyinfo->mac_id_name); + + if (x_display_list == 0) + { + mac_clear_font_name_table (); + bzero (dpyinfo, sizeof (*dpyinfo)); + } +} + #ifdef MAC_OSX void @@ -9333,7 +9576,6 @@ mac_initialize () #endif BLOCK_INPUT; - mac_initialize_display_info (); #if TARGET_API_MAC_CARBON init_required_apple_events (); @@ -9371,7 +9613,9 @@ syms_of_macterm () Qsuper = intern ("super"); Fput (Qsuper, Qmodifier_value, make_number (super_modifier)); +#ifdef MAC_OSX Fprovide (intern ("mac-carbon"), Qnil); +#endif staticpro (&Qreverse); Qreverse = intern ("reverse"); |