summaryrefslogtreecommitdiff
path: root/src/macterm.c
diff options
context:
space:
mode:
authorSteven Tamm <steventamm@mac.com>2004-12-27 17:27:30 +0000
committerSteven Tamm <steventamm@mac.com>2004-12-27 17:27:30 +0000
commitb15325b22a301f3f1d150ab15dff23521cc79711 (patch)
tree82a57d1a677ac34da4e6a4d0ab6767a4e2a10778 /src/macterm.c
parent22933cbff47c023e8a37677112e847c9242d8a54 (diff)
downloademacs-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.c748
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");