changeset 55851:f1d6a507dcfd

Support Tooltips with the Carbon emacs port. Some code cleanup using helper macros.
author Steven Tamm <steventamm@mac.com>
date Sun, 30 May 2004 00:18:41 +0000
parents 63ca25eb73a1
children 92338f8e9f27
files src/ChangeLog src/macfns.c src/macgui.h src/macmenu.c src/macterm.c src/xdisp.c
diffstat 6 files changed, 1070 insertions(+), 892 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sun May 30 00:09:37 2004 +0000
+++ b/src/ChangeLog	Sun May 30 00:18:41 2004 +0000
@@ -1,3 +1,78 @@
+2004-05-29  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* macfns.c: Don't include ccl.h.
+	[MAC_OSX]: Don't include QuickTime/QuickTime.h.
+	[!MAC_OSX]: Don't include alloca.h, Windows.h, Gestalt.h, or
+	TextUtils.h.
+	(Fx_create_frame): Sync with xfns.c.  Initialize cursor
+	descriptors.
+	(Fx_display_mm_height, Fx_display_mm_width): Calculate length from
+	display height/width.
+	(compute_tip_xy, Vx_max_tooltip_size): Declare.
+	(unwind_create_tip_frame, compute_tip_xy): New functions.
+	(x_create_tip_frame, Fx_show_tip, Fx_hide_tip): Sync with xfns.c.
+	(syms_of_macfns): Initialize Qcancel_timer, Vx_max_tooltip_size,
+	and last_show_tip_args.
+	
+	* macgui.h [!MAC_OSX]: Include Gestalt.h.
+	(Cursor, No_Cursor): New defines.
+	[!TARGET_API_MAC_CARBON] (SetPortWindowPort): New compatibility
+	macro.
+	[!TARGET_API_MAC_CARBON] (arrow_cursor): Declare.
+
+	* macmenu.c (mac_menu_show, mac_dialog): Use SetPortWindowPort.
+
+	* macterm.c: Don't include Gestalt.h.
+	(enum mouse_tracking_type, mouse_tracking_in_progress): Remove.
+	(XDrawLine, XClearArea, XClearWindow, mac_draw_bitmap)
+	(mac_set_clip_rectangle, mac_reset_clipping, XCreatePixmap)
+	(XFillRectangle, mac_draw_rectangle, mac_draw_string_common)
+	(mac_copy_area, mac_copy_area_with_mask, x_update_end)
+	(construct_mouse_click, XTmouse_position)
+	(x_scroll_bar_report_motion, x_calc_absolute_position)
+	(do_mouse_moved, do_zoom_window, mac_do_receive_drag)
+	(XTread_socket, make_mac_frame): Use SetPortWindowPort.
+	(note_mouse_movement): Clear the mouse face and reset the pointer
+	shape when the pointer goes outside the frame without grabbing.
+	(mac_front_window): New function.
+	(mac_window_to_frame): New macro.
+	(XTmouse_position, x_scroll_bar_report_motion, do_window_update)
+	(do_window_activate, do_window_deactivate, do_app_resume)
+	(do_app_suspend, do_mouse_moved, do_menu_choice, do_grow_window)
+	(do_zoom_window, mac_do_receive_drag, XTread_socket)
+	(mac_check_for_quit_char): Use mac_front_window and/or
+	mac_window_to_frame.
+	(x_scroll_bar_handle_click): Set `(PORTION . WHOLE)' part in a
+	scroll-bar click event.
+	(mac_define_frame_cursor): Change the pointer shape.
+	(x_free_frame_resources): Reset tip_window to NULL when it is
+	disposed.
+	[!TARGET_API_MAC_CARBON] (arrow_cursor): New variable.
+	[!TARGET_API_MAC_CARBON] (do_init_managers): Initialize
+	arrow_cursor.
+	(do_window_update): Don't do anything if the updated window is the
+	tooltip window.
+	(do_mouse_moved): Handle mouse movement events here (previously in
+	XTread_socket).  Clear the mouse face if
+	dpyinfo->mouse_face_hidden is set.
+	(do_os_event, do_events): Remove (now in XTread_socket).
+	(XTread_socket): Immediately return if interrupt_input_blocked.
+	Loop until all the events in the queue are processed.  Rearrange
+	codes for mouse grabbing.  Add tooltip support.  Include the
+	contents of do_os_event and do_events.  Remove mouse movement
+	handling (now in do_mouse_moved).  Add the case where
+	Vmouse_highlight has an integer value.
+	(NewMacWindow): Remove.
+	(make_mac_frame): Do what NewMacWindow previously did.  Don't do
+	excess initializations.
+	(make_mac_terminal_frame): Previous initializations in
+	make_mac_frame are moved here.
+	(mac_initialize_display_info): Initialize
+	dpyinfo->mouse_face_overlay and dpyinfo->mouse_face_hidden.
+
+	* xdisp.c [MAC_OS] (No_Cursor): Remove variable.
+	(define_frame_cursor1): Don't treat HAVE_CARBON as a special case.
+
 2004-05-29  Richard M. Stallman  <rms@gnu.org>
 
 	* lisp.h (truncate_undo_list): Update decl.
--- a/src/macfns.c	Sun May 30 00:09:37 2004 +0000
+++ b/src/macfns.c	Sun May 30 00:18:41 2004 +0000
@@ -42,7 +42,6 @@
 #include "epaths.h"
 #include "termhooks.h"
 #include "coding.h"
-#include "ccl.h"
 #include "systime.h"
 
 /* #include "bitmaps/gray.xbm" */
@@ -59,17 +58,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#ifndef MAC_OSX
-#include <alloca.h>
-#endif
-
-#ifdef MAC_OSX
-#include <QuickTime/QuickTime.h>
-#else /* not MAC_OSX */
-#include <Windows.h>
-#include <Gestalt.h>
-#include <TextUtils.h>
-#endif /* not MAC_OSX */
 
 /*extern void free_frame_menubar ();
 extern double atof ();
@@ -2580,8 +2568,6 @@
   f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output));
   bzero (f->output_data.mac, sizeof (struct mac_output));
   FRAME_FONTSET (f) = -1;
-  f->output_data.mac->scroll_bar_foreground_pixel = -1;
-  f->output_data.mac->scroll_bar_background_pixel = -1;
   record_unwind_protect (unwind_create_frame, frame);
 
   f->icon_name
@@ -2717,25 +2703,32 @@
 
   f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
 
-  /* MAC_TODO: specify 1 below when toolbars are implemented.  */
-  window_prompting = x_figure_window_size (f, parms, 0);
+#if TARGET_API_MAC_CARBON
+  f->output_data.mac->text_cursor = kThemeIBeamCursor;
+  f->output_data.mac->nontext_cursor = kThemeArrowCursor;
+  f->output_data.mac->modeline_cursor = kThemeArrowCursor;
+  f->output_data.mac->hand_cursor = kThemePointingHandCursor;
+  f->output_data.mac->hourglass_cursor = kThemeWatchCursor;
+  f->output_data.mac->horizontal_drag_cursor = kThemeResizeLeftRightCursor;
+#else
+  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;
+#endif
+
+  /* Compute the size of the window.  */
+  window_prompting = x_figure_window_size (f, parms, 1);
 
   tem = mac_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
 
-  /* Create the window. Add the tool-bar height to the initial frame
-     height so that the user gets a text display area of the size he
-     specified with -g or via the registry. Later changes of the
-     tool-bar height don't change the frame size. This is done so that
-     users can create tall Emacs frames without having to guess how
-     tall the tool-bar will get. */
-  FRAME_LINES (f) += FRAME_TOOL_BAR_LINES (f);
-
   /* mac_window (f, window_prompting, minibuffer_only); */
   make_mac_frame (f);
 
   x_icon (f, parms);
-
   x_make_gc (f);
 
   /* Now consider the frame official.  */
@@ -2754,7 +2747,8 @@
   x_default_parameter (f, parms, Qcursor_type, Qbox,
 		       "cursorType", "CursorType", RES_TYPE_SYMBOL);
   x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
-		       "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
+		       "scrollBarWidth", "ScrollBarWidth",
+		       RES_TYPE_NUMBER);
 
   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
      Change will not be effected unless different from the current
@@ -2762,13 +2756,10 @@
   width = FRAME_COLS (f);
   height = FRAME_LINES (f);
 
+  SET_FRAME_COLS (f, 0);
   FRAME_LINES (f) = 0;
-  SET_FRAME_COLS (f, 0);
   change_frame_size (f, height, width, 1, 0, 0);
 
-  /* Set up faces after all frame parameters are known.  */
-  call1 (Qface_set_after_frame_default, frame);
-
 #if 0 /* MAC_TODO: when we have window manager hints */
   /* Tell the server what size and position, etc, we want, and how
      badly we want them.  This should be done after we have the menu
@@ -3025,11 +3016,8 @@
   /* MAC_TODO: this is an approximation, and only of the main display */
 
   struct mac_display_info *dpyinfo = check_x_display_info (display);
-  short h, v;
-
-  ScreenRes (&h, &v);
-
-  return make_number ((int) (v / 72.0 * 25.4));
+
+  return make_number ((int) (dpyinfo->height * 25.4 / dpyinfo->resy));
 }
 
 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
@@ -3043,11 +3031,8 @@
   /* MAC_TODO: this is an approximation, and only of the main display */
 
   struct mac_display_info *dpyinfo = check_x_display_info (display);
-  short h, v;
-
-  ScreenRes (&h, &v);
-
-  return make_number ((int) (h / 72.0 * 25.4));
+
+  return make_number ((int) (dpyinfo->width * 25.4 / dpyinfo->resx));
 }
 
 DEFUN ("x-display-backing-store", Fx_display_backing_store,
@@ -3595,9 +3580,11 @@
  ***********************************************************************/
 
 static Lisp_Object x_create_tip_frame P_ ((struct mac_display_info *,
-					   Lisp_Object));
-
-/* The frame of a currently visible tooltip, or null.  */
+					   Lisp_Object, Lisp_Object));
+static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
+				Lisp_Object, int, int, int *, int *));
+
+/* The frame of a currently visible tooltip.  */
 
 Lisp_Object tip_frame;
 
@@ -3612,15 +3599,42 @@
 
 Lisp_Object last_show_tip_args;
 
-/* Create a frame for a tooltip on the display described by DPYINFO.
-   PARMS is a list of frame parameters.  Value is the frame.  */
+/* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
+
+Lisp_Object Vx_max_tooltip_size;
+
 
 static Lisp_Object
-x_create_tip_frame (dpyinfo, parms)
+unwind_create_tip_frame (frame)
+     Lisp_Object frame;
+{
+  Lisp_Object deleted;
+
+  deleted = unwind_create_frame (frame);
+  if (EQ (deleted, Qt))
+    {
+      tip_window = NULL;
+      tip_frame = Qnil;
+    }
+
+  return deleted;
+}
+
+
+/* Create a frame for a tooltip on the display described by DPYINFO.
+   PARMS is a list of frame parameters.  TEXT is the string to
+   display in the tip frame.  Value is the frame.
+
+   Note that functions called here, esp. x_default_parameter can
+   signal errors, for instance when a specified color name is
+   undefined.  We have to make sure that we're in a consistent state
+   when this happens.  */
+
+static Lisp_Object
+x_create_tip_frame (dpyinfo, parms, text)
      struct mac_display_info *dpyinfo;
-     Lisp_Object parms;
+     Lisp_Object parms, text;
 {
-#if 0 /* MAC_TODO : Mac version */
   struct frame *f;
   Lisp_Object frame, tem;
   Lisp_Object name;
@@ -3629,8 +3643,11 @@
   int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2, gcpro3;
   struct kboard *kb;
-
-  check_x ();
+  int face_change_count_before = face_change_count;
+  Lisp_Object buffer;
+  struct buffer *old_buffer;
+
+  check_mac ();
 
   /* Use this general default value to start with until we know if
      this frame has a specified name.  */
@@ -3643,7 +3660,7 @@
 #endif
 
   /* Get the name of the frame to use for resource lookup.  */
-  name = w32_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
+  name = mac_get_arg (parms, Qname, "name", "Name", RES_TYPE_STRING);
   if (!STRINGP (name)
       && !EQ (name, Qunbound)
       && !NILP (name))
@@ -3652,31 +3669,50 @@
 
   frame = Qnil;
   GCPRO3 (parms, name, frame);
-  tip_frame = f = make_frame (1);
+  f = make_frame (1);
   XSETFRAME (frame, f);
+
+  buffer = Fget_buffer_create (build_string (" *tip*"));
+  Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
+  old_buffer = current_buffer;
+  set_buffer_internal_1 (XBUFFER (buffer));
+  current_buffer->truncate_lines = Qnil;
+  specbind (Qinhibit_read_only, Qt);
+  specbind (Qinhibit_modification_hooks, Qt);
+  Ferase_buffer ();
+  Finsert (1, &text);
+  set_buffer_internal_1 (old_buffer);
+
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
-
-  f->output_method = output_w32;
-  f->output_data.w32 =
-    (struct w32_output *) xmalloc (sizeof (struct w32_output));
-  bzero (f->output_data.w32, sizeof (struct w32_output));
-#if 0
-  f->output_data.w32->icon_bitmap = -1;
-#endif
-  FRAME_FONTSET (f) = -1;
+  record_unwind_protect (unwind_create_tip_frame, frame);
+
+  /* By setting the output method, we're essentially saying that
+     the frame is live, as per FRAME_LIVE_P.  If we get a signal
+     from this point on, x_destroy_window might screw up reference
+     counts etc.  */
+  f->output_method = output_mac;
+  f->output_data.mac =
+    (struct mac_output *) xmalloc (sizeof (struct mac_output));
+  bzero (f->output_data.mac, sizeof (struct mac_output));
+
+  FRAME_FONTSET (f)  = -1;
   f->icon_name = Qnil;
 
+#if 0 /* GLYPH_DEBUG TODO: image support.  */
+  image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
+  dpyinfo_refcount = dpyinfo->reference_count;
+#endif /* GLYPH_DEBUG */
 #ifdef MULTI_KBOARD
   FRAME_KBOARD (f) = kb;
 #endif
-  f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
-  f->output_data.w32->explicit_parent = 0;
+  f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
+  f->output_data.mac->explicit_parent = 0;
 
   /* Set the name; the functions to which we pass f expect the name to
      be set.  */
   if (EQ (name, Qunbound) || NILP (name))
     {
-      f->name = build_string (dpyinfo->x_id_name);
+      f->name = build_string (dpyinfo->mac_id_name);
       f->explicit_name = 0;
     }
   else
@@ -3687,12 +3723,12 @@
       specbind (Qx_resource_name, name);
     }
 
-  /* Extract the window parameters from the supplied values
-     that are needed to determine window geometry.  */
+  /* Extract the window parameters from the supplied values that are
+     needed to determine window geometry.  */
   {
     Lisp_Object font;
 
-    font = w32_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
+    font = mac_get_arg (parms, Qfont, "font", "Font", RES_TYPE_STRING);
 
     BLOCK_INPUT;
     /* First, try whatever font the caller has specified.  */
@@ -3706,22 +3742,16 @@
       }
 
     /* Try out a font which we hope has bold and italic variations.  */
-    if (!STRINGP (font))
-      font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1");
-    if (!STRINGP (font))
-      font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
     if (! STRINGP (font))
-      font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
-    if (! STRINGP (font))
-      /* This was formerly the first thing tried, but it finds too many fonts
-	 and takes too long.  */
-      font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
+      font = x_new_font (f, "-ETL-fixed-medium-r-*--*-160-*-*-*-*-iso8859-1");
     /* If those didn't work, look for something which will at least work.  */
     if (! STRINGP (font))
-      font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
+      font = x_new_font (f, "-*-monaco-*-12-*-mac-roman");
+    if (! STRINGP (font))
+      font = x_new_font (f, "-*-courier-*-10-*-mac-roman");
     UNBLOCK_INPUT;
     if (! STRINGP (font))
-      font = build_string ("fixed");
+      error ("Cannot find any usable font");
 
     x_default_parameter (f, parms, Qfont, font,
 			 "font", "Font", RES_TYPE_STRING);
@@ -3737,7 +3767,7 @@
     {
       Lisp_Object value;
 
-      value = w32_get_arg (parms, Qinternal_border_width,
+      value = mac_get_arg (parms, Qinternal_border_width,
 			 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
       if (! EQ (value, Qunbound))
 	parms = Fcons (Fcons (Qinternal_border_width, value),
@@ -3768,34 +3798,26 @@
      happen.  */
   init_frame_faces (f);
 
-  f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
+  f->output_data.mac->parent_desc = FRAME_MAC_DISPLAY_INFO (f)->root_window;
 
   window_prompting = x_figure_window_size (f, parms, 0);
 
   {
-    XSetWindowAttributes attrs;
-    unsigned long mask;
-
     BLOCK_INPUT;
-    mask = CWBackPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask;
-    /* Window managers looks at the override-redirect flag to
-       determine whether or net to give windows a decoration (Xlib
-       3.2.8).  */
-    attrs.override_redirect = True;
-    attrs.save_under = True;
-    attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
-    /* Arrange for getting MapNotify and UnmapNotify events.  */
-    attrs.event_mask = StructureNotifyMask;
-    tip_window
-      = FRAME_W32_WINDOW (f)
-      = XCreateWindow (FRAME_W32_DISPLAY (f),
-		       FRAME_W32_DISPLAY_INFO (f)->root_window,
-		       /* x, y, width, height */
-		       0, 0, 1, 1,
-		       /* Border.  */
-		       1,
-		       CopyFromParent, InputOutput, CopyFromParent,
-		       mask, &attrs);
+    Rect r;
+
+    SetRect (&r, 0, 0, 1, 1);
+    if (CreateNewWindow (kHelpWindowClass,
+			 kWindowNoActivatesAttribute
+			 | kWindowIgnoreClicksAttribute,
+			 &r, &tip_window) == noErr)
+      {
+	FRAME_MAC_WINDOW (f) = tip_window;
+	SetWRefCon (tip_window, (long) f->output_data.mac);
+	/* so that update events can find this mac_output struct */
+	f->output_data.mac->mFP = f;
+	ShowWindow (tip_window);
+      }
     UNBLOCK_INPUT;
   }
 
@@ -3813,8 +3835,8 @@
      FRAME_LINES (f).  */
   width = FRAME_COLS (f);
   height = FRAME_LINES (f);
+  SET_FRAME_COLS (f, 0);
   FRAME_LINES (f) = 0;
-  SET_FRAME_COLS (f, 0);
   change_frame_size (f, height, width, 1, 0, 0);
 
   /* Add `tooltip' frame parameter's default value. */
@@ -3822,6 +3844,26 @@
     Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
 					    Qnil));
 
+  /* Set up faces after all frame parameters are known.  This call
+     also merges in face attributes specified for new frames.
+
+     Frame parameters may be changed if .Xdefaults contains
+     specifications for the default font.  For example, if there is an
+     `Emacs.default.attributeBackground: pink', the `background-color'
+     attribute of the frame get's set, which let's the internal border
+     of the tooltip frame appear in pink.  Prevent this.  */
+  {
+    Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
+
+    /* Set tip_frame here, so that */
+    tip_frame = frame;
+    call1 (Qface_set_after_frame_default, frame);
+
+    if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
+      Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg),
+					      Qnil));
+  }
+
   f->no_split = 1;
 
   UNGCPRO;
@@ -3833,17 +3875,80 @@
 
   /* Now that the frame is official, it counts as a reference to
      its display.  */
-  FRAME_W32_DISPLAY_INFO (f)->reference_count++;
-
+  FRAME_MAC_DISPLAY_INFO (f)->reference_count++;
+
+  /* Setting attributes of faces of the tooltip frame from resources
+     and similar will increment face_change_count, which leads to the
+     clearing of all current matrices.  Since this isn't necessary
+     here, avoid it by resetting face_change_count to the value it
+     had before we created the tip frame.  */
+  face_change_count = face_change_count_before;
+
+  /* Discard the unwind_protect.  */
   return unbind_to (count, frame);
-#endif /* MAC_TODO */
-  return Qnil;
+}
+
+
+/* Compute where to display tip frame F.  PARMS is the list of frame
+   parameters for F.  DX and DY are specified offsets from the current
+   location of the mouse.  WIDTH and HEIGHT are the width and height
+   of the tooltip.  Return coordinates relative to the root window of
+   the display in *ROOT_X, and *ROOT_Y.  */
+
+static void
+compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
+     struct frame *f;
+     Lisp_Object parms, dx, dy;
+     int width, height;
+     int *root_x, *root_y;
+{
+  Lisp_Object left, top;
+
+  /* User-specified position?  */
+  left = Fcdr (Fassq (Qleft, parms));
+  top  = Fcdr (Fassq (Qtop, parms));
+
+  /* Move the tooltip window where the mouse pointer is.  Resize and
+     show it.  */
+  if (!INTEGERP (left) || !INTEGERP (top))
+    {
+      Point mouse_pos;
+
+      BLOCK_INPUT;
+      GetMouse (&mouse_pos);
+      LocalToGlobal (&mouse_pos);
+      *root_x = mouse_pos.h;
+      *root_y = mouse_pos.v;
+      UNBLOCK_INPUT;
+    }
+
+  if (INTEGERP (top))
+    *root_y = XINT (top);
+  else if (*root_y + XINT (dy) - height < 0)
+    *root_y -= XINT (dy);
+  else
+    {
+      *root_y -= height;
+      *root_y += XINT (dy);
+    }
+
+  if (INTEGERP (left))
+    *root_x = XINT (left);
+  else if (*root_x + XINT (dx) + width <= FRAME_MAC_DISPLAY_INFO (f)->width)
+    /* It fits to the right of the pointer.  */
+    *root_x += XINT (dx);
+  else if (width + XINT (dx) <= *root_x)
+    /* It fits to the left of the pointer.  */
+    *root_x -= width + XINT (dx);
+  else
+    /* Put it left-justified on the screen -- it ought to fit that way.  */
+    *root_x = 0;
 }
 
 
 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
-       doc : /* Show STRING in a "tooltip" window on frame FRAME.
-A tooltip window is a small window displaying a string.
+       doc: /* Show STRING in a "tooltip" window on frame FRAME.
+A tooltip window is a small X window displaying a string.
 
 FRAME nil or omitted means use the selected frame.
 
@@ -3859,19 +3964,19 @@
 DX isn't specified).  Likewise for the y-position; if a `top' frame
 parameter is specified, it determines the y-position of the tooltip
 window, otherwise it is displayed at the mouse position, with offset
-DY added (default is 10).  */)
-  (string, frame, parms, timeout, dx, dy)
+DY added (default is -10).
+
+A tooltip's maximum size is specified by `x-max-tooltip-size'.
+Text larger than the specified size is clipped.  */)
+     (string, frame, parms, timeout, dx, dy)
      Lisp_Object string, frame, parms, timeout, dx, dy;
 {
   struct frame *f;
   struct window *w;
-  Window root, child;
-  Lisp_Object buffer, top, left;
+  int root_x, root_y;
   struct buffer *old_buffer;
   struct text_pos pos;
   int i, width, height;
-  int root_x, root_y, win_x, win_y;
-  unsigned pmask;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
   int count = SPECPDL_INDEX ();
@@ -3920,13 +4025,11 @@
 	      call1 (Qcancel_timer, timer);
 	    }
 
-#if 0 /* MAC_TODO : Mac specifics */
 	  BLOCK_INPUT;
-	  compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
-	  XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-		       root_x, root_y - FRAME_PIXEL_HEIGHT (f));
+	  compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
+			  FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
+	  MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
 	  UNBLOCK_INPUT;
-#endif /* MAC_TODO */
 	  goto start_timer;
 	}
     }
@@ -3953,26 +4056,36 @@
 
   /* Create a frame for the tooltip, and record it in the global
      variable tip_frame.  */
-  frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms);
+  frame = x_create_tip_frame (FRAME_MAC_DISPLAY_INFO (f), parms, string);
   f = XFRAME (frame);
 
-  /* Set up the frame's root window.  Currently we use a size of 80
-     columns x 40 lines.  If someone wants to show a larger tip, he
-     will loose.  I don't think this is a realistic case.  */
+  /* Set up the frame's root window.  */
   w = XWINDOW (FRAME_ROOT_WINDOW (f));
   w->left_col = w->top_line = make_number (0);
-  w->total_cols = make_number (80);
-  w->total_lines = make_number (40);
+
+  if (CONSP (Vx_max_tooltip_size)
+      && INTEGERP (XCAR (Vx_max_tooltip_size))
+      && XINT (XCAR (Vx_max_tooltip_size)) > 0
+      && INTEGERP (XCDR (Vx_max_tooltip_size))
+      && XINT (XCDR (Vx_max_tooltip_size)) > 0)
+    {
+      w->total_cols = XCAR (Vx_max_tooltip_size);
+      w->total_lines = XCDR (Vx_max_tooltip_size);
+    }
+  else
+    {
+      w->total_cols = make_number (80);
+      w->total_lines = make_number (40);
+    }
+
+  FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
   adjust_glyphs (f);
   w->pseudo_window_p = 1;
 
   /* Display the tooltip text in a temporary buffer.  */
-  buffer = Fget_buffer_create (build_string (" *tip*"));
-  Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
   old_buffer = current_buffer;
-  set_buffer_internal_1 (XBUFFER (buffer));
-  Ferase_buffer ();
-  Finsert (1, &string);
+  set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
+  current_buffer->truncate_lines = Qnil;
   clear_glyph_matrix (w->desired_matrix);
   clear_glyph_matrix (w->current_matrix);
   SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
@@ -3993,7 +4106,7 @@
       /* Let the row go over the full width of the frame.  */
       row->full_width_p = 1;
 
-      /* There's a glyph at the end of rows that is use to place
+      /* There's a glyph at the end of rows that is used to place
 	 the cursor there.  Don't include the width of this glyph.  */
       if (row->used[TEXT_AREA])
 	{
@@ -4014,17 +4127,13 @@
 
   /* Move the tooltip window where the mouse pointer is.  Resize and
      show it.  */
-#if 0 /* TODO : Mac specifics */
-  compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
+  compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
 
   BLOCK_INPUT;
-  XQueryPointer (FRAME_W32_DISPLAY (f), FRAME_W32_DISPLAY_INFO (f)->root_window,
-		 &root, &child, &root_x, &root_y, &win_x, &win_y, &pmask);
-  XMoveResizeWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
-		     root_x + 5, root_y - height - 5, width, height);
-  XMapRaised (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
+  MoveWindow (FRAME_MAC_WINDOW (f), root_x, root_y, false);
+  SizeWindow (FRAME_MAC_WINDOW (f), width, height, true);
+  BringToFront (FRAME_MAC_WINDOW (f));
   UNBLOCK_INPUT;
-#endif /* MAC_TODO */
 
   /* Draw into the window.  */
   w->must_be_updated_p = 1;
@@ -4046,8 +4155,8 @@
 
 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
        doc: /* Hide the current tooltip window, if there is any.
-Value is t is tooltip was open, nil otherwise.  */)
-  ()
+Value is t if tooltip was open, nil otherwise.  */)
+     ()
 {
   int count;
   Lisp_Object deleted, frame, timer;
@@ -4249,7 +4358,8 @@
   staticpro (&Qsuppress_icon);
   Qundefined_color = intern ("undefined-color");
   staticpro (&Qundefined_color);
-  /* This is the end of symbol initialization.  */
+  Qcancel_timer = intern ("cancel-timer");
+  staticpro (&Qcancel_timer);
 
   Qhyper = intern ("hyper");
   staticpro (&Qhyper);
@@ -4265,6 +4375,7 @@
   staticpro (&Qcontrol);
   Qshift = intern ("shift");
   staticpro (&Qshift);
+  /* This is the end of symbol initialization.  */
 
   /* Text property `display' should be nonsticky by default.  */
   Vtext_property_default_nonsticky
@@ -4314,6 +4425,11 @@
 	       doc: /* A string indicating the foreground color of the cursor box.  */);
   Vx_cursor_fore_pixel = Qnil;
 
+  DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
+    doc: /* Maximum size for tooltips.  Value is a pair (COLUMNS . ROWS).
+Text larger than this is clipped.  */);
+  Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
+
   DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
 	       doc: /* Non-nil if no window manager is in use.
 Emacs doesn't try to figure this out; this is always nil
@@ -4386,6 +4502,9 @@
   tip_frame = Qnil;
   staticpro (&tip_frame);
 
+  last_show_tip_args = Qnil;
+  staticpro (&last_show_tip_args);
+
 #if 0 /* MAC_TODO */
   defsubr (&Sx_file_dialog);
 #endif
--- a/src/macgui.h	Sun May 30 00:09:37 2004 +0000
+++ b/src/macgui.h	Sun May 30 00:18:41 2004 +0000
@@ -57,16 +57,27 @@
 #undef init_process
 #define init_process emacs_init_process
 #undef INFINITY
-typedef struct OpaqueWindowPtr* Window;
 #else
 #include <QuickDraw.h>		/* for WindowPtr */
 #include <QDOffscreen.h>	/* for GWorldPtr */
 #include <Controls.h>		/* for ControlHandle in xdisp.c */
-typedef WindowPtr Window;
+#include <Gestalt.h>
 #endif
 
 typedef GWorldPtr Pixmap;
 
+#if TARGET_API_MAC_CARBON
+typedef struct OpaqueWindowPtr *Window;
+#define Cursor ThemeCursor
+#define No_Cursor (-1)
+#else
+typedef WindowPtr Window;
+#define SetPortWindowPort(w) SetPort(w)
+#define Cursor CursHandle
+#define No_Cursor (0)
+extern CursPtr arrow_cursor;
+#endif
+
 #define FACE_DEFAULT (~0)
 
 
--- a/src/macmenu.c	Sun May 30 00:09:37 2004 +0000
+++ b/src/macmenu.c	Sun May 30 00:18:41 2004 +0000
@@ -1784,11 +1784,7 @@
   pos.h = x;
   pos.v = y;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (FRAME_MAC_WINDOW (f)));
-#else
-  SetPort (FRAME_MAC_WINDOW (f));
-#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   LocalToGlobal (&pos);
 
@@ -1942,11 +1938,7 @@
 
   window_ptr = GetNewCWindow (DIALOG_WINDOW_RESOURCE, NULL, (WindowPtr) -1);
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (window_ptr));
-#else
-  SetPort (window_ptr);
-#endif
+  SetPortWindowPort (window_ptr);
 
   TextFont (0);
   /* Left and right margins in the dialog are 13 pixels each.*/
@@ -1964,11 +1956,7 @@
   SizeWindow (window_ptr, dialog_width, 78, 0);
   ShowWindow (window_ptr);
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (window_ptr));
-#else
-  SetPort (window_ptr);
-#endif
+  SetPortWindowPort (window_ptr);
 
   TextFont (0);
 
--- a/src/macterm.c	Sun May 30 00:09:37 2004 +0000
+++ b/src/macterm.c	Sun May 30 00:18:41 2004 +0000
@@ -53,7 +53,6 @@
 #if defined (__MRC__) || (__MSL__ >= 0x6000)
 #include <ControlDefinitions.h>
 #endif
-#include <Gestalt.h>
 
 #if __profile__
 #include <profiler.h>
@@ -196,14 +195,6 @@
 
 static Time last_mouse_movement_time;
 
-enum mouse_tracking_type {
-  mouse_tracking_none,
-  mouse_tracking_mouse_movement,
-  mouse_tracking_scroll_bar
-};
-
-enum mouse_tracking_type mouse_tracking_in_progress = mouse_tracking_none;
-
 struct scroll_bar *tracked_scroll_bar = NULL;
 
 /* Incremented by XTread_socket whenever it really tries to read
@@ -364,11 +355,7 @@
      GC gc;
      int x1, y1, x2, y2;
 {
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
 
@@ -416,11 +403,7 @@
   xgc.foreground = mwp->x_compatible.foreground_pixel;
   xgc.background = mwp->x_compatible.background_pixel;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (&xgc);
   SetRect (&r, x, y, x + width, y + height);
@@ -441,11 +424,7 @@
   xgc.foreground = mwp->x_compatible.foreground_pixel;
   xgc.background = mwp->x_compatible.background_pixel;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (&xgc);
 
@@ -480,11 +459,7 @@
   bitmap.baseAddr = (char *)bits;
   SetRect (&(bitmap.bounds), 0, 0, width, height);
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
   SetRect (&r, x, y, x + width, y + height);
@@ -509,11 +484,7 @@
      WindowPtr w;
      Rect *r;
 {
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   ClipRect (r);
 }
@@ -528,11 +499,7 @@
 {
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   SetRect (&r, -32767, -32767, 32767, 32767);
   ClipRect (&r);
@@ -601,11 +568,7 @@
   Rect r;
   QDErr err;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   SetRect (&r, 0, 0, width, height);
   err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0);
@@ -666,11 +629,7 @@
 {
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
   SetRect (&r, x, y, x + width, y + height);
@@ -716,11 +675,7 @@
 {
   Rect r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
   SetRect (&r, x, y, x + width + 1, y + height + 1);
@@ -766,11 +721,7 @@
      char *buf;
      int nchars, mode, bytes_per_char;
 {
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   mac_set_colors (gc);
 
@@ -861,11 +812,7 @@
 {
   Rect src_r, dest_r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (dest));
-#else
-  SetPort (dest);
-#endif
+  SetPortWindowPort (dest);
 
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
   SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -901,11 +848,7 @@
 {
   Rect src_r, dest_r;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (dest));
-#else
-  SetPort (dest);
-#endif
+  SetPortWindowPort (dest);
 
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
   SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -965,7 +908,7 @@
   SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
   SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
 
-  SetPort (GetWindowPort (w));
+  SetPortWindowPort (w);
 
   ForeColor (blackColor);
   BackColor (whiteColor);
@@ -1290,7 +1233,7 @@
 	{
 	  int i;
 
-          for (i = 0; i < w->desired_matrix->nrows; ++i)
+	  for (i = 0; i < w->desired_matrix->nrows; ++i)
 	    if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
 	      break;
 
@@ -1385,11 +1328,7 @@
   /* Reset the background color of Mac OS Window to that of the frame after
      update so that it is used by Mac Toolbox to clear the update region before
      an update event is generated.  */
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (FRAME_MAC_WINDOW (f)));
-#else
-  SetPort (FRAME_MAC_WINDOW (f));
-#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f));
 
@@ -3745,11 +3684,7 @@
 
   mouseLoc = event->where;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (FRAME_MAC_WINDOW (f)));
-#else
-  SetPort (FRAME_MAC_WINDOW (f));
-#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   GlobalToLocal (&mouseLoc);
   XSETINT (result->x, mouseLoc.h);
@@ -3778,6 +3713,7 @@
      FRAME_PTR frame;
      Point *pos;
 {
+  struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (frame);
 #if TARGET_API_MAC_CARBON
   Rect r;
 #endif
@@ -3792,9 +3728,17 @@
   if (!PtInRect (*pos, &FRAME_MAC_WINDOW (frame)->portRect))
 #endif
     {
-      frame->mouse_moved = 1;
-      last_mouse_scroll_bar = Qnil;
-      note_mouse_highlight (frame, -1, -1);
+      if (frame == dpyinfo->mouse_face_mouse_frame)
+	/* This case corresponds to LeaveNotify in X11.  */
+	{
+	  /* If we move outside the frame, then we're certainly no
+	     longer on any text in the frame.  */
+	  clear_mouse_face (dpyinfo);
+	  dpyinfo->mouse_face_mouse_frame = 0;
+	  if (!dpyinfo->grabbed)
+	    rif->define_frame_cursor (frame,
+				      frame->output_data.mac->nontext_cursor);
+	}
     }
   /* Has the mouse moved off the glyph it was on at the last sighting?  */
   else if (pos->h < last_mouse_glyph.left
@@ -3942,6 +3886,23 @@
 }
 
 
+static WindowPtr
+mac_front_window ()
+{
+#if TARGET_API_MAC_CARBON
+  return GetFrontWindowOfClass (kDocumentWindowClass, true);
+#else
+  WindowPtr front_window = FrontWindow ();
+
+  if (tip_window && front_window == tip_window)
+    return GetNextWindow (front_window);
+  else
+    return front_window;
+#endif
+}
+
+#define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
+
 /* Return the current position of the mouse.
    *fp should be a frame which indicates which display to ask about.
 
@@ -3973,12 +3934,12 @@
 {
   Point mouse_pos;
   int ignore1, ignore2;
-  WindowPtr wp = FrontWindow ();
+  WindowPtr wp = mac_front_window ();
   struct frame *f;
   Lisp_Object frame, tail;
 
   if (is_emacs_window(wp))
-    f = ((mac_output *) GetWRefCon (wp))->mFP;
+    f = mac_window_to_frame (wp);
 
   BLOCK_INPUT;
 
@@ -3992,11 +3953,7 @@
 
       last_mouse_scroll_bar = Qnil;
 
-#if TARGET_API_MAC_CARBON
-      SetPort (GetWindowPort (wp));
-#else
-      SetPort (wp);
-#endif
+      SetPortWindowPort (wp);
 
       GetMouse (&mouse_pos);
 
@@ -4491,6 +4448,8 @@
      EventRecord *er;
      struct input_event *bufp;
 {
+  int win_y, top_range;
+
   if (! GC_WINDOWP (bar->window))
     abort ();
 
@@ -4525,6 +4484,24 @@
       bufp->part = scroll_bar_handle;
       break;
     }
+
+  win_y = XINT (bufp->y) - XINT (bar->top);
+  top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar->height));
+
+  win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
+
+  win_y -= 24;
+
+  if (! NILP (bar->dragging))
+    win_y -= XINT (bar->dragging);
+
+  if (win_y < 0)
+    win_y = 0;
+  if (win_y > top_range)
+    win_y = top_range;
+
+  XSETINT (bufp->x, win_y);
+  XSETINT (bufp->y, top_range);
 }
 
 
@@ -4574,16 +4551,12 @@
      unsigned long *time;
 {
   struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
-  WindowPtr wp = FrontWindow ();
+  WindowPtr wp = mac_front_window ();
   Point mouse_pos;
-  struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;
+  struct frame *f = mac_window_to_frame (wp);
   int win_y, top_range;
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (wp));
-#else
-  SetPort (wp);
-#endif
+  SetPortWindowPort (wp);
 
   GetMouse (&mouse_pos);
 
@@ -4810,7 +4783,11 @@
      struct frame *f;
      Cursor cursor;
 {
-  /* MAC TODO */
+#if TARGET_API_MAC_CARBON
+  SetThemeCursor (cursor);
+#else
+  SetCursor (*cursor);
+#endif
 }
 
 
@@ -5078,11 +5055,7 @@
       GrafPtr savePort;
       GetPort (&savePort);
 
-#if TARGET_API_MAC_CARBON
-      SetPort (GetWindowPort (FRAME_MAC_WINDOW (f)));
-#else
-      SetPort (FRAME_MAC_WINDOW (f));
-#endif
+      SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
 #if TARGET_API_MAC_CARBON
       {
@@ -5457,10 +5430,15 @@
      struct frame *f;
 {
   struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+  WindowPtr wp = FRAME_MAC_WINDOW (f);
 
   BLOCK_INPUT;
 
-  DisposeWindow (FRAME_MAC_WINDOW (f));
+  DisposeWindow (wp);
+  if (wp == tip_window)
+    /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
+       closed' event.  So we reset tip_window here.  */
+    tip_window = NULL;
 
   free_frame_menubar (f);
 
@@ -6984,6 +6962,11 @@
 
 Point saved_menu_event_location;
 
+#if !TARGET_API_MAC_CARBON
+/* Place holder for the default arrow cursor.  */
+CursPtr arrow_cursor;
+#endif
+
 /* Apple Events */
 static void init_required_apple_events (void);
 static pascal OSErr
@@ -7170,6 +7153,8 @@
   InitCursor ();
 
 #if !TARGET_API_MAC_CARBON
+  arrow_cursor = &qd.arrow;
+
   /* set up some extra stack space for use by emacs */
   SetApplLimit ((Ptr) ((long) GetApplLimit () - EXTRA_STACK_ALLOC));
 
@@ -7198,8 +7183,12 @@
 static void
 do_window_update (WindowPtr win)
 {
-  struct mac_output *mwp = (mac_output *) GetWRefCon (win);
-  struct frame *f = mwp->mFP;
+  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;
 
   if (f)
     {
@@ -7250,13 +7239,11 @@
 static void
 do_window_activate (WindowPtr win)
 {
-  mac_output *mwp;
   struct frame *f;
 
   if (is_emacs_window (win))
     {
-      mwp = (mac_output *) GetWRefCon (win);
-      f = mwp->mFP;
+      f = mac_window_to_frame (win);
 
       if (f)
 	{
@@ -7269,13 +7256,11 @@
 static void
 do_window_deactivate (WindowPtr win)
 {
-  mac_output *mwp;
   struct frame *f;
 
   if (is_emacs_window (win))
     {
-      mwp = (mac_output *) GetWRefCon (win);
-      f = mwp->mFP;
+      f = mac_window_to_frame (win);
 
       if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
 	{
@@ -7289,14 +7274,12 @@
 do_app_resume ()
 {
   WindowPtr wp;
-  mac_output *mwp;
   struct frame *f;
 
-  wp = FrontWindow();
+  wp = mac_front_window ();
   if (is_emacs_window (wp))
     {
-      mwp = (mac_output *) GetWRefCon (wp);
-      f = mwp->mFP;
+      f = mac_window_to_frame (wp);
 
       if (f)
 	{
@@ -7313,14 +7296,12 @@
 do_app_suspend ()
 {
   WindowPtr wp;
-  mac_output *mwp;
   struct frame *f;
 
-  wp = FrontWindow();
+  wp = mac_front_window ();
   if (is_emacs_window (wp))
     {
-      mwp = (mac_output *) GetWRefCon (wp);
-      f = mwp->mFP;
+      f = mac_window_to_frame (wp);
 
       if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
 	{
@@ -7335,67 +7316,38 @@
 
 
 static void
-do_mouse_moved (Point mouse_pos)
-{
-  WindowPtr wp = FrontWindow ();
-  struct frame *f;
+do_mouse_moved (mouse_pos, f)
+     Point mouse_pos;
+     FRAME_PTR *f;
+{
+  WindowPtr wp = mac_front_window ();
+  struct x_display_info *dpyinfo;
 
   if (is_emacs_window (wp))
     {
-      f = ((mac_output *) GetWRefCon (wp))->mFP;
-
-#if TARGET_API_MAC_CARBON
-      SetPort (GetWindowPort (wp));
-#else
-      SetPort (wp);
-#endif
+      *f = mac_window_to_frame (wp);
+      dpyinfo = FRAME_MAC_DISPLAY_INFO (*f);
+
+      if (dpyinfo->mouse_face_hidden)
+	{
+	  dpyinfo->mouse_face_hidden = 0;
+	  clear_mouse_face (dpyinfo);
+	}
+
+      SetPortWindowPort (wp);
 
       GlobalToLocal (&mouse_pos);
 
-      note_mouse_movement (f, &mouse_pos);
-    }
-}
-
-
-static void
-do_os_event (EventRecord *erp)
-{
-  switch((erp->message >> 24) & 0x000000FF)
-    {
-    case suspendResumeMessage:
-      if((erp->message & resumeFlag) == 1)
-	do_app_resume ();
+      if (dpyinfo->grabbed && tracked_scroll_bar)
+	x_scroll_bar_note_movement (tracked_scroll_bar,
+				    mouse_pos.v
+				    - XINT (tracked_scroll_bar->top),
+				    TickCount() * (1000 / 60));
       else
-	do_app_suspend ();
-      break;
-
-    case mouseMovedMessage:
-      do_mouse_moved (erp->where);
-      break;
-    }
-}
-
-static void
-do_events (EventRecord *erp)
-{
-  switch (erp->what)
-    {
-    case updateEvt:
-      do_window_update ((WindowPtr) erp->message);
-      break;
-
-    case osEvt:
-      do_os_event (erp);
-      break;
-
-    case activateEvt:
-      if ((erp->modifiers & activeFlag) != 0)
-	do_window_activate ((WindowPtr) erp->message);
-      else
-	do_window_deactivate ((WindowPtr) erp->message);
-      break;
-    }
-}
+	note_mouse_movement (*f, &mouse_pos);
+    }
+}
+
 
 static void
 do_apple_menu (SInt16 menu_item)
@@ -7433,8 +7385,7 @@
 
     default:
       {
-        WindowPtr wp = FrontWindow ();
-        struct frame *f = ((mac_output *) GetWRefCon (wp))->mFP;
+        struct frame *f = mac_window_to_frame (mac_front_window ());
         MenuHandle menu = GetMenuHandle (menu_id);
         if (menu)
           {
@@ -7459,8 +7410,7 @@
   long grow_size;
   Rect limit_rect;
   int rows, columns;
-  mac_output *mwp = (mac_output *) GetWRefCon (w);
-  struct frame *f = mwp->mFP;
+  struct frame *f = mac_window_to_frame (w);
 
   SetRect(&limit_rect, MIN_DOC_SIZE, MIN_DOC_SIZE, MAX_DOC_SIZE, MAX_DOC_SIZE);
 
@@ -7489,16 +7439,11 @@
   Rect zoom_rect, port_rect;
   Point top_left;
   int w_title_height, columns, rows, width, height, dummy, x, y;
-  mac_output *mwp = (mac_output *) GetWRefCon (w);
-  struct frame *f = mwp->mFP;
+  struct frame *f = mac_window_to_frame (w);
 
   GetPort (&save_port);
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (w));
-#else
-  SetPort (w);
-#endif
+  SetPortWindowPort (w);
 
   /* Clear window to avoid flicker.  */
 #if TARGET_API_MAC_CARBON
@@ -7551,7 +7496,7 @@
     }
 #endif /* not TARGET_API_MAC_CARBON */
 
-  ZoomWindow (w, zoom_in_or_out, w == FrontWindow ());
+  ZoomWindow (w, zoom_in_or_out, w == mac_front_window ());
 
   /* retrieve window size and update application values */
 #if TARGET_API_MAC_CARBON
@@ -7561,7 +7506,7 @@
 #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 (mwp->mFP, 0, columns, rows);
+  x_set_window_size (f, 0, columns, rows);
 
   SetPort (save_port);
 }
@@ -7892,8 +7837,8 @@
     {
       struct input_event event;
       Lisp_Object frame;
-      struct frame *f = ((mac_output *) GetWRefCon(window))->mFP;
-      SetPort (GetWindowPort (window));
+      struct frame *f = mac_window_to_frame (window);
+      SetPortWindowPort (window);
       GlobalToLocal (&mouse);
 
       event.kind = DRAG_N_DROP_EVENT;
@@ -8067,26 +8012,26 @@
 /* Emacs calls this whenever it wants to read an input event from the
    user. */
 int
-XTread_socket (int sd, int expected, struct input_event *hold_quit)
+XTread_socket (sd, expected, hold_quit)
+     int sd, expected;
+     struct input_event *hold_quit;
 {
   struct input_event inev;
   int count = 0;
 #if USE_CARBON_EVENTS
-  OSStatus rneResult;
   EventRef eventRef;
-  EventMouseButton mouseBtn;
+  EventTargetRef toolbox_dispatcher = GetEventDispatcherTarget ();
+#else
+  EventMask event_mask;
 #endif
   EventRecord er;
-  int the_modifiers;
-  EventMask event_mask;
-
-#if 0
+  struct mac_display_info *dpyinfo = &one_mac_display_info;
+
   if (interrupt_input_blocked)
     {
       interrupt_input_pending = 1;
       return -1;
     }
-#endif
 
   interrupt_input_pending = 0;
   BLOCK_INPUT;
@@ -8108,26 +8053,33 @@
   if (terminate_flag)
     Fkill_emacs (make_number (1));
 
-  /* It is necessary to set this (additional) argument slot of an
-     event to nil because keyboard.c protects incompletely processed
-     event from being garbage collected by placing them in the
-     kbd_buffer_gcpro vector.  */
-  EVENT_INIT (inev);
-  inev.kind = NO_EVENT;
-  inev.arg = Qnil;
-
+#if !USE_CARBON_EVENTS
   event_mask = everyEvent;
   if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
     event_mask -= highLevelEventMask;
 
+  while (WaitNextEvent (event_mask, &er,
+			(expected ? app_sleep_time : 0L), NULL))
+#else
+  while (!ReceiveNextEvent (0, NULL,
+			    (expected ? TicksToEventTime (app_sleep_time) : 0),
+			    kEventRemoveFromQueue, &eventRef))
+#endif /* !USE_CARBON_EVENTS */
+    {
+      int do_help = 0;
+      struct frame *f;
+
+      expected = 0;
+
+      /* It is necessary to set this (additional) argument slot of an
+	 event to nil because keyboard.c protects incompletely
+	 processed event from being garbage collected by placing them
+	 in the kbd_buffer_gcpro vector.  */
+      EVENT_INIT (inev);
+      inev.kind = NO_EVENT;
+      inev.arg = Qnil;
+
 #if USE_CARBON_EVENTS
-  rneResult = ReceiveNextEvent (0, NULL,
-				expected
-				? TicksToEventTime (app_sleep_time)
-				: 0,
-				kEventRemoveFromQueue, &eventRef);
-  if (!rneResult)
-    {
       /* Handle new events */
       if (!mac_convert_event_ref (eventRef, &er))
 	switch (GetEventClass (eventRef))
@@ -8137,13 +8089,12 @@
 	      {
 		SInt32 delta;
 		Point point;
-		WindowPtr window_ptr = FrontNonFloatingWindow ();
-		struct mac_output *mwp = (mac_output *) GetWRefCon (window_ptr);
+		WindowPtr window_ptr = mac_front_window ();
+
 		if (!IsValidWindowPtr (window_ptr))
 		  {
 		    SysBeep(1);
-		    UNBLOCK_INPUT;
-		    return 0;
+		    break;
 		  }
 
 		GetEventParameter(eventRef, kEventParamMouseWheelDelta,
@@ -8154,458 +8105,556 @@
 				  NULL, &point);
 		inev.kind = WHEEL_EVENT;
 		inev.code = 0;
-		inev.modifiers = (mac_event_to_emacs_modifiers(eventRef)
+		inev.modifiers = (mac_event_to_emacs_modifiers (eventRef)
 				  | ((delta < 0) ? down_modifier
 				     : up_modifier));
-		SetPort (GetWindowPort (window_ptr));
+		SetPortWindowPort (window_ptr);
 		GlobalToLocal (&point);
 		XSETINT (inev.x, point.h);
 		XSETINT (inev.y, point.v);
-		XSETFRAME (inev.frame_or_window, mwp->mFP);
+		XSETFRAME (inev.frame_or_window,
+			   mac_window_to_frame (window_ptr));
 		inev.timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
 	      }
 	    else
-	      SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+	      SendEventToEventTarget (eventRef, toolbox_dispatcher);
 
 	    break;
 	  default:
 	    /* Send the event to the appropriate receiver.  */
-	    SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
+	    SendEventToEventTarget (eventRef, toolbox_dispatcher);
 	  }
       else
+#endif /* USE_CARBON_EVENTS */
+      switch (er.what)
+	{
+	case mouseDown:
+	case mouseUp:
+	  {
+	    WindowPtr window_ptr;
+	    SInt16 part_code;
+	    int tool_bar_p = 0;
+
+	    if (dpyinfo->grabbed && last_mouse_frame
+		&& FRAME_LIVE_P (last_mouse_frame))
+	      {
+		window_ptr = FRAME_MAC_WINDOW (last_mouse_frame);
+		part_code = inContent;
+	      }
+	    else
+	      {
+		window_ptr = FrontWindow ();
+		if (tip_window && window_ptr == tip_window)
+		  {
+		    HideWindow (tip_window);
+		    window_ptr = FrontWindow ();
+		  }
+
+#if USE_CARBON_EVENTS
+		/* This is needed to send mouse events like aqua
+		   window buttons to the correct handler.  */
+		if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+		    != eventNotHandledErr)
+		  break;
+
+		if (!is_emacs_window (window_ptr))
+		  break;
+#endif
+		part_code = FindWindow (er.where, &window_ptr);
+	      }
+
+	    switch (part_code)
+	      {
+	      case inMenuBar:
+		if (er.what == mouseDown)
+		  {
+		    f = mac_window_to_frame (mac_front_window ());
+		    saved_menu_event_location = er.where;
+		    inev.kind = MENU_BAR_ACTIVATE_EVENT;
+		    XSETFRAME (inev.frame_or_window, f);
+		  }
+		break;
+
+	      case inContent:
+		if (window_ptr != mac_front_window ())
+		  SelectWindow (window_ptr);
+		else
+		  {
+		    SInt16 control_part_code;
+		    ControlHandle ch;
+		    Point mouse_loc = er.where;
+
+		    f = mac_window_to_frame (window_ptr);
+		    /* convert to local coordinates of new window */
+		    SetPortWindowPort (window_ptr);
+
+		    GlobalToLocal (&mouse_loc);
+#if TARGET_API_MAC_CARBON
+		    ch = FindControlUnderMouse (mouse_loc, window_ptr,
+						&control_part_code);
 #else
-  if (WaitNextEvent (event_mask, &er, (expected ? app_sleep_time : 0L), NULL))
-#endif /* USE_CARBON_EVENTS */
-    switch (er.what)
-      {
-      case mouseDown:
-      case mouseUp:
-	{
-	  WindowPtr window_ptr = FrontWindow ();
-	  SInt16 part_code;
+		    control_part_code = FindControl (mouse_loc, window_ptr,
+						     &ch);
+#endif
 
 #if USE_CARBON_EVENTS
-	  /* This is needed to send mouse events like aqua window buttons
-	     to the correct handler.  */
-	  if (eventNotHandledErr != SendEventToEventTarget (eventRef, GetEventDispatcherTarget ())) {
+		    inev.code = mac_get_mouse_btn (eventRef);
+		    inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+		    inev.code = mac_get_emulated_btn (er.modifiers);
+		    inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
+#endif
+		    XSETINT (inev.x, mouse_loc.h);
+		    XSETINT (inev.y, mouse_loc.v);
+		    inev.timestamp = er.when * (1000 / 60);
+		    /* ticks to milliseconds */
+
+		    if (dpyinfo->grabbed && tracked_scroll_bar
+#if TARGET_API_MAC_CARBON
+			|| ch != 0
+#else
+			|| control_part_code != 0
+#endif
+			)
+		      {
+			struct scroll_bar *bar;
+
+			if (dpyinfo->grabbed && tracked_scroll_bar)
+			  {
+			    bar = tracked_scroll_bar;
+			    control_part_code = kControlIndicatorPart;
+			  }
+			else
+			  bar = (struct scroll_bar *) GetControlReference (ch);
+			x_scroll_bar_handle_click (bar, control_part_code,
+						   &er, &inev);
+			if (er.what == mouseDown
+			    && control_part_code == kControlIndicatorPart)
+			  tracked_scroll_bar = bar;
+			else
+			  tracked_scroll_bar = NULL;
+		      }
+		    else
+		      {
+			Lisp_Object window;
+			int x = mouse_loc.h;
+			int y = mouse_loc.v;
+
+			window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
+			if (EQ (window, f->tool_bar_window))
+			  {
+			    if (er.what == mouseDown)
+			      handle_tool_bar_click (f, x, y, 1, 0);
+			    else
+			      handle_tool_bar_click (f, x, y, 0,
+						     inev.modifiers);
+			    tool_bar_p = 1;
+			  }
+			else
+			  {
+			    XSETFRAME (inev.frame_or_window, f);
+			    inev.kind = MOUSE_CLICK_EVENT;
+			  }
+		      }
+
+		    if (er.what == mouseDown)
+		      {
+			dpyinfo->grabbed |= (1 << inev.code);
+			last_mouse_frame = f;
+			/* Ignore any mouse motion that happened
+			   before this event; any subsequent
+			   mouse-movement Emacs events should reflect
+			   only motion after the ButtonPress.  */
+			if (f != 0)
+			  f->mouse_moved = 0;
+
+			if (!tool_bar_p)
+			  last_tool_bar_item = -1;
+		      }
+		    else
+		      {
+			if (dpyinfo->grabbed & (1 << inev.code) == 0)
+			  /* If a button is released though it was not
+			     previously pressed, that would be because
+			     of multi-button emulation.  */
+			  dpyinfo->grabbed = 0;
+			else
+			  dpyinfo->grabbed &= ~(1 << inev.code);
+		      }
+
+		    switch (er.what)
+		      {
+		      case mouseDown:
+			inev.modifiers |= down_modifier;
+			break;
+		      case mouseUp:
+			inev.modifiers |= up_modifier;
+			break;
+		      }
+		  }
+		break;
+
+	      case inDrag:
+#if TARGET_API_MAC_CARBON
+		if (er.what == mouseDown)
+		  {
+		    BitMap bm;
+
+		    GetQDGlobalsScreenBits (&bm);
+		    DragWindow (window_ptr, er.where, &bm.bounds);
+		  }
+#else /* not TARGET_API_MAC_CARBON */
+		DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
+#endif /* not TARGET_API_MAC_CARBON */
+		break;
+
+	      case inGoAway:
+		if (TrackGoAway (window_ptr, er.where))
+		  {
+		    inev.kind = DELETE_WINDOW_EVENT;
+		    XSETFRAME (inev.frame_or_window,
+			       mac_window_to_frame (window_ptr));
+		  }
+		break;
+
+		/* window resize handling added --ben */
+	      case inGrow:
+		if (er.what == mouseDown)
+		  {
+		    do_grow_window(window_ptr, &er);
+		    break;
+		  }
+
+		/* window zoom handling added --ben */
+	      case inZoomIn:
+	      case inZoomOut:
+		if (TrackBox (window_ptr, er.where, part_code))
+		  do_zoom_window (window_ptr, part_code);
+		break;
+
+	      default:
+		break;
+	      }
+	  }
+	  break;
+
+	case updateEvt:
+#if USE_CARBON_EVENTS
+	  if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+	      != eventNotHandledErr)
 	    break;
-	  }
-
-	  if (!is_emacs_window(window_ptr))
+#endif
+	  do_window_update ((WindowPtr) er.message);
+	  break;
+
+	case osEvt:
+#if USE_CARBON_EVENTS
+	  if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+	      != eventNotHandledErr)
 	    break;
 #endif
-
-          if (mouse_tracking_in_progress == mouse_tracking_scroll_bar
-	      && er.what == mouseUp)
-            {
-	      struct mac_output *mwp = (mac_output *) GetWRefCon (window_ptr);
-	      Point mouse_loc = er.where;
-
-	      /* Convert to local coordinates of new window.  */
-#if TARGET_API_MAC_CARBON
-              SetPort (GetWindowPort (window_ptr));
-#else
-              SetPort (window_ptr);
+	  switch ((er.message >> 24) & 0x000000FF)
+	    {
+	    case suspendResumeMessage:
+	      if ((er.message & resumeFlag) == 1)
+		do_app_resume ();
+	      else
+		do_app_suspend ();
+	      break;
+
+	    case mouseMovedMessage:
+	      previous_help_echo_string = help_echo_string;
+	      help_echo_string = help_echo_object = help_echo_window = Qnil;
+	      help_echo_pos = -1;
+
+	      do_mouse_moved (er.where, &f);
+
+	      /* If the contents of the global variable
+		 help_echo_string has changed, generate a
+		 HELP_EVENT.  */
+	      if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
+		do_help = 1;
+	      break;
+	    }
+	  break;
+
+	case activateEvt:
+	  {
+	    WindowPtr window_ptr = (WindowPtr) er.message;
+
+#if USE_CARBON_EVENTS
+	    if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+		!= eventNotHandledErr)
+	      break;
 #endif
-
-	      GlobalToLocal (&mouse_loc);
+	    if (window_ptr == tip_window)
+	      {
+		HideWindow (tip_window);
+		break;
+	      }
+
+	    if ((er.modifiers & activeFlag) != 0)
+	      {
+		Point mouse_loc = er.where;
+
+		do_window_activate (window_ptr);
+
+		SetPortWindowPort (window_ptr);
+		GlobalToLocal (&mouse_loc);
+		/* activateEvt counts as mouse movement,
+		   so update things that depend on mouse position.  */
+		note_mouse_movement (mac_window_to_frame (window_ptr),
+				     &mouse_loc);
+	      }
+	    else
+	      {
+		do_window_deactivate (window_ptr);
+
+		f = mac_window_to_frame (window_ptr);
+		if (f == dpyinfo->mouse_face_mouse_frame)
+		  {
+		    /* If we move outside the frame, then we're
+		       certainly no longer on any text in the
+		       frame.  */
+		    clear_mouse_face (dpyinfo);
+		    dpyinfo->mouse_face_mouse_frame = 0;
+		  }
+
+		/* Generate a nil HELP_EVENT to cancel a help-echo.
+		   Do it only if there's something to cancel.
+		   Otherwise, the startup message is cleared when the
+		   mouse leaves the frame.  */
+		if (any_help_event_p)
+		  do_help = -1;
+	      }
+	  }
+	  break;
+
+	case keyDown:
+	case autoKey:
+	  {
+	    int keycode = (er.message & keyCodeMask) >> 8;
+	    int xkeysym;
 
 #if USE_CARBON_EVENTS
-	      inev.code = mac_get_mouse_btn (eventRef);
-#else
-	      inev.code = mac_get_emulate_btn (er.modifiers);
+	    /* When using Carbon Events, we need to pass raw keyboard
+	       events to the TSM ourselves.  If TSM handles it, it
+	       will pass back noErr, otherwise it will pass back
+	       "eventNotHandledErr" and we can process it
+	       normally.  */
+	    if ((!NILP (Vmac_pass_command_to_system)
+		 || !(er.modifiers & cmdKey))
+		&& (!NILP (Vmac_pass_control_to_system)
+		    || !(er.modifiers & controlKey)))
+	      if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
+		  != eventNotHandledErr)
+		break;
+#endif
+
+#if TARGET_API_MAC_CARBON
+	    if (!IsValidWindowPtr (mac_front_window ()))
+	      {
+		SysBeep (1);
+		break;
+	      }
 #endif
-              inev.kind = SCROLL_BAR_CLICK_EVENT;
-              inev.frame_or_window = tracked_scroll_bar->window;
-              inev.part = scroll_bar_handle;
+
+	    ObscureCursor ();
+
+	    if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+	      {
+		clear_mouse_face (dpyinfo);
+		dpyinfo->mouse_face_hidden = 1;
+	      }
+
+	    if (keycode_to_xkeysym (keycode, &xkeysym))
+	      {
+		inev.code = 0xff00 | xkeysym;
+		inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+	      }
+	    else
+	      {
+		if (er.modifiers & (controlKey |
+				    (NILP (Vmac_command_key_is_meta) ? optionKey
+				     : cmdKey)))
+		  {
+		    /* This code comes from Keyboard Resource,
+		       Appendix C of IM - Text.  This is necessary
+		       since shift is ignored in KCHR table
+		       translation when option or command is pressed.
+		       It also does not translate correctly
+		       control-shift chars like C-% so mask off shift
+		       here also */
+		    int new_modifiers = er.modifiers & 0xe600;
+		    /* mask off option and command */
+		    int new_keycode = keycode | new_modifiers;
+		    Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+		    unsigned long some_state = 0;
+		    inev.code = KeyTranslate (kchr_ptr, new_keycode,
+					      &some_state) & 0xff;
+		  }
+		else
+		  inev.code = er.message & charCodeMask;
+		inev.kind = ASCII_KEYSTROKE_EVENT;
+	      }
+	  }
+
+	  /* If variable mac-convert-keyboard-input-to-latin-1 is
+	     non-nil, convert non-ASCII characters typed at the Mac
+	     keyboard (presumed to be in the Mac Roman encoding) to
+	     iso-latin-1 encoding before they are passed to Emacs.
+	     This enables the Mac keyboard to be used to enter
+	     non-ASCII iso-latin-1 characters directly.  */
+	  if (mac_keyboard_text_encoding != kTextEncodingMacRoman
+	      && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
+	    {
+	      static TECObjectRef converter = NULL;
+	      OSStatus the_err = noErr;
+	      OSStatus convert_status = noErr;
+
+	      if (converter ==  NULL)
+		{
+		  the_err = TECCreateConverter (&converter,
+						kTextEncodingMacRoman,
+						mac_keyboard_text_encoding);
+		  current_mac_keyboard_text_encoding
+		    = mac_keyboard_text_encoding;
+		}
+	      else if (mac_keyboard_text_encoding
+		       != current_mac_keyboard_text_encoding)
+		{
+		  /* Free the converter for the current encoding
+		     before creating a new one.  */
+		  TECDisposeConverter (converter);
+		  the_err = TECCreateConverter (&converter,
+						kTextEncodingMacRoman,
+						mac_keyboard_text_encoding);
+		  current_mac_keyboard_text_encoding
+		    = mac_keyboard_text_encoding;
+		}
+
+	      if (the_err == noErr)
+		{
+		  unsigned char ch = inev.code;
+		  ByteCount actual_input_length, actual_output_length;
+		  unsigned char outch;
+
+		  convert_status = TECConvertText (converter, &ch, 1,
+						   &actual_input_length,
+						   &outch, 1,
+						   &actual_output_length);
+		  if (convert_status == noErr
+		      && actual_input_length == 1
+		      && actual_output_length == 1)
+		    inev.code = outch;
+		}
+	    }
+
+#if USE_CARBON_EVENTS
+	  inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
+#else
+	  inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
+#endif
+	  XSETFRAME (inev.frame_or_window,
+		     mac_window_to_frame (mac_front_window ()));
+	  inev.timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
+	  break;
+
+	case kHighLevelEvent:
+	  drag_and_drop_file_list = Qnil;
+
+	  AEProcessAppleEvent(&er);
+
+	  /* Build a DRAG_N_DROP_EVENT type event as is done in
+	     constuct_drag_n_drop in w32term.c.  */
+	  if (!NILP (drag_and_drop_file_list))
+	    {
+	      struct frame *f = NULL;
+	      WindowPtr wp;
+	      Lisp_Object frame;
+
+	      wp = mac_front_window ();
+
+	      if (!wp)
+		{
+		  struct frame *f = XFRAME (XCAR (Vframe_list));
+		  CollapseWindow (FRAME_MAC_WINDOW (f), false);
+		  wp = mac_front_window ();
+		}
+
+	      if (wp && is_emacs_window (wp))
+		f = mac_window_to_frame (wp);
+
+	      inev.kind = DRAG_N_DROP_EVENT;
+	      inev.code = 0;
+	      inev.timestamp = er.when * (1000 / 60);
+	      /* ticks to milliseconds */
 #if USE_CARBON_EVENTS
 	      inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
 #else
 	      inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
 #endif
-              inev.modifiers |= up_modifier;
-	      inev.timestamp = er.when * (1000 / 60);
-	        /* ticks to milliseconds */
-
-              XSETINT (inev.x, XFASTINT (tracked_scroll_bar->left) + 2);
-              XSETINT (inev.y, mouse_loc.v - 24);
-              tracked_scroll_bar->dragging = Qnil;
-              mouse_tracking_in_progress = mouse_tracking_none;
-              tracked_scroll_bar = NULL;
-              break;
-            }
-
-	  part_code = FindWindow (er.where, &window_ptr);
-
-	  switch (part_code)
-	    {
-	    case inMenuBar:
-	      if (er.what == mouseDown)
-		{
-		  struct frame *f = ((mac_output *)
-				     GetWRefCon (FrontWindow ()))->mFP;
-		  saved_menu_event_location = er.where;
-		  inev.kind = MENU_BAR_ACTIVATE_EVENT;
-		  XSETFRAME (inev.frame_or_window, f);
-		}
-	      break;
-
-	    case inContent:
-	      if (window_ptr != FrontWindow ())
-		SelectWindow (window_ptr);
-	      else
-	        {
-		  SInt16 control_part_code;
-		  ControlHandle ch;
-		  struct mac_output *mwp = (mac_output *)
-		    GetWRefCon (window_ptr);
-		  Point mouse_loc = er.where;
-
-		  /* convert to local coordinates of new window */
-#if TARGET_API_MAC_CARBON
-                  SetPort (GetWindowPort (window_ptr));
-#else
-                  SetPort (window_ptr);
-#endif
-
-		  GlobalToLocal (&mouse_loc);
-#if TARGET_API_MAC_CARBON
-		  ch = FindControlUnderMouse (mouse_loc, window_ptr,
-					      &control_part_code);
-#else
-		  control_part_code = FindControl (mouse_loc, window_ptr, &ch);
-#endif
-
-#if USE_CARBON_EVENTS
-		  inev.code = mac_get_mouse_btn (eventRef);
-#else
-		  inev.code = mac_get_emulate_btn (er.modifiers);
-#endif
-		  XSETINT (inev.x, mouse_loc.h);
-		  XSETINT (inev.y, mouse_loc.v);
-		  inev.timestamp = er.when * (1000 / 60);
-		    /* ticks to milliseconds */
-
+
+	      XSETINT (inev.x, 0);
+	      XSETINT (inev.y, 0);
+
+	      XSETFRAME (frame, f);
+	      inev.frame_or_window = Fcons (frame, drag_and_drop_file_list);
+
+	      /* Regardless of whether Emacs was suspended or in the
+		 foreground, ask it to redraw its entire screen.
+		 Otherwise parts of the screen can be left in an
+		 inconsistent state.  */
+	      if (wp)
 #if TARGET_API_MAC_CARBON
-		  if (ch != 0)
-#else
-		  if (control_part_code != 0)
-#endif
-		    {
-		      struct scroll_bar *bar = (struct scroll_bar *)
-			GetControlReference (ch);
-		      x_scroll_bar_handle_click (bar, control_part_code, &er,
-						 &inev);
-		      if (er.what == mouseDown
-			  && control_part_code == kControlIndicatorPart)
-		        {
-		          mouse_tracking_in_progress
-			    = mouse_tracking_scroll_bar;
-		          tracked_scroll_bar = bar;
-		        }
-		      else
-		        {
-		          mouse_tracking_in_progress = mouse_tracking_none;
-		          tracked_scroll_bar = NULL;
-		        }
-		    }
-		  else
-	            {
-		      Lisp_Object window;
-		      int x = mouse_loc.h;
-		      int y = mouse_loc.v;
-
-		      XSETFRAME (inev.frame_or_window, mwp->mFP);
-		      if (er.what == mouseDown)
-			mouse_tracking_in_progress
-			  = mouse_tracking_mouse_movement;
-		      else
-			mouse_tracking_in_progress = mouse_tracking_none;
-		      window = window_from_coordinates (mwp->mFP, x, y, 0, 0, 0, 1);
-
-		      if (EQ (window, mwp->mFP->tool_bar_window))
-			{
-			  if (er.what == mouseDown)
-			    handle_tool_bar_click (mwp->mFP, x, y, 1, 0);
-			  else
-			    handle_tool_bar_click (mwp->mFP, x, y, 0,
-#if USE_CARBON_EVENTS
-						   mac_event_to_emacs_modifiers (eventRef)
-#else
-						   er.modifiers
-#endif
-						   );
-			  break;
-			}
-		      else
-			inev.kind = MOUSE_CLICK_EVENT;
-		    }
-
-#if USE_CARBON_EVENTS
-		  inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
-		  inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
-#endif
-
-	          switch (er.what)
-		    {
-		    case mouseDown:
-		      inev.modifiers |= down_modifier;
-		      break;
-		    case mouseUp:
-		      inev.modifiers |= up_modifier;
-		      break;
-		    }
-	        }
-	      break;
-
-	    case inDrag:
-#if TARGET_API_MAC_CARBON
-              if (er.what == mouseDown)
 		{
-		  BitMap bm;
-
-		  GetQDGlobalsScreenBits (&bm);
-		  DragWindow (window_ptr, er.where, &bm.bounds);
+		  Rect r;
+
+		  GetWindowPortBounds (wp, &r);
+		  InvalWindowRect (wp, &r);
 		}
 #else /* not TARGET_API_MAC_CARBON */
-	      DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
+                InvalRect (&(wp->portRect));
 #endif /* not TARGET_API_MAC_CARBON */
-	      break;
-
-	    case inGoAway:
-	      if (TrackGoAway (window_ptr, er.where))
-	        {
-	          inev.kind = DELETE_WINDOW_EVENT;
-	          XSETFRAME (inev.frame_or_window,
-			     ((mac_output *) GetWRefCon (window_ptr))->mFP);
-	        }
-	      break;
-
-	    /* window resize handling added --ben */
-	    case inGrow:
-              if (er.what == mouseDown)
-		{
-		  do_grow_window(window_ptr, &er);
-		  break;
-		}
-
-	    /* window zoom handling added --ben */
-	    case inZoomIn:
-	    case inZoomOut:
-	      if (TrackBox (window_ptr, er.where, part_code))
-	        do_zoom_window (window_ptr, part_code);
-	      break;
-
-	    default:
-	      break;
 	    }
+	default:
+	  break;
 	}
-	break;
-
-      case updateEvt:
-      case osEvt:
-      case activateEvt:
 #if USE_CARBON_EVENTS
-	if (eventNotHandledErr == SendEventToEventTarget (eventRef, GetEventDispatcherTarget ()))
+      ReleaseEvent (eventRef);
 #endif
-    	do_events (&er);
-	break;
-
-      case keyDown:
-      case autoKey:
+
+      if (inev.kind != NO_EVENT)
 	{
-	  int keycode = (er.message & keyCodeMask) >> 8;
-	  int xkeysym;
-
-#if USE_CARBON_EVENTS
-	  /* When using Carbon Events, we need to pass raw keyboard events
-	     to the TSM ourselves.  If TSM handles it, it will pass back
-	     noErr, otherwise it will pass back "eventNotHandledErr" and
-	     we can process it normally.   */
-	  if ((!NILP (Vmac_pass_command_to_system)
-	       || !(er.modifiers & cmdKey))
-	      && (!NILP (Vmac_pass_control_to_system)
-		  || !(er.modifiers & controlKey)))
+	  kbd_buffer_store_event_hold (&inev, hold_quit);
+	  count++;
+	}
+
+      if (do_help
+	  && !(hold_quit && hold_quit->kind != NO_EVENT))
+	{
+	  Lisp_Object frame;
+
+	  if (f)
+	    XSETFRAME (frame, f);
+	  else
+	    frame = Qnil;
+
+	  if (do_help > 0)
 	    {
-	      OSStatus err;
-	      err = SendEventToEventTarget (eventRef,
-					    GetEventDispatcherTarget ());
-	      if (err != eventNotHandledErr)
-		break;
-	    }
-#endif
-
-	  if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
-	    {
-	      SysBeep (1);
-	      UNBLOCK_INPUT;
-	      return 0;
-	    }
-
-	  ObscureCursor ();
-
-	  if (keycode_to_xkeysym (keycode, &xkeysym))
-	    {
-	      inev.code = 0xff00 | xkeysym;
-	      inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+	      any_help_event_p = 1;
+	      gen_help_event (help_echo_string, frame, help_echo_window,
+			      help_echo_object, help_echo_pos);
 	    }
 	  else
 	    {
-	      if (er.modifiers & (controlKey |
-				  (NILP (Vmac_command_key_is_meta) ? optionKey
-				   : cmdKey)))
-		{
-		  /* This code comes from Keyboard Resource, Appendix
-		     C of IM - Text.  This is necessary since shift is
-		     ignored in KCHR table translation when option or
-		     command is pressed.  It also does not translate
-		     correctly control-shift chars like C-% so mask off
-		     shift here also */
-		  int new_modifiers = er.modifiers & 0xe600;
-		  /* mask off option and command */
-		  int new_keycode = keycode | new_modifiers;
-		  Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
-		  unsigned long some_state = 0;
-		  inev.code = KeyTranslate (kchr_ptr, new_keycode,
-					    &some_state) & 0xff;
-		}
-	      else
-		inev.code = er.message & charCodeMask;
-	      inev.kind = ASCII_KEYSTROKE_EVENT;
+	      help_echo_string = Qnil;
+	      gen_help_event (Qnil, frame, Qnil, Qnil, 0);
 	    }
+	  count++;
 	}
 
-	/* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
-	   convert non-ASCII characters typed at the Mac keyboard
-	   (presumed to be in the Mac Roman encoding) to iso-latin-1
-	   encoding before they are passed to Emacs.  This enables the
-	   Mac keyboard to be used to enter non-ASCII iso-latin-1
-	   characters directly.  */
-	if (mac_keyboard_text_encoding != kTextEncodingMacRoman
-	    && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
-	  {
-	    static TECObjectRef converter = NULL;
-	    OSStatus the_err = noErr;
-	    OSStatus convert_status = noErr;
-
-	    if (converter ==  NULL)
-	      {
-		the_err = TECCreateConverter (&converter,
-					      kTextEncodingMacRoman,
-					      mac_keyboard_text_encoding);
-		current_mac_keyboard_text_encoding
-		  = mac_keyboard_text_encoding;
-	      }
-	    else if (mac_keyboard_text_encoding
-		     != current_mac_keyboard_text_encoding)
-	      {
-		/* Free the converter for the current encoding before
-		   creating a new one.  */
-		TECDisposeConverter (converter);
-		the_err = TECCreateConverter (&converter,
-					      kTextEncodingMacRoman,
-					      mac_keyboard_text_encoding);
-		current_mac_keyboard_text_encoding
-		  = mac_keyboard_text_encoding;
-	      }
-
-	    if (the_err == noErr)
-	      {
-		unsigned char ch = inev.code;
-		ByteCount actual_input_length, actual_output_length;
-		unsigned char outch;
-
-		convert_status = TECConvertText (converter, &ch, 1,
-						 &actual_input_length,
-						 &outch, 1,
-						 &actual_output_length);
-		if (convert_status == noErr
-		    && actual_input_length == 1
-		    && actual_output_length == 1)
-		  inev.code = outch;
-	      }
-	  }
-
-#if USE_CARBON_EVENTS
-	inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
-	inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
-#endif
-
-	{
-	  mac_output *mwp
-	    = (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
-	  XSETFRAME (inev.frame_or_window, mwp->mFP);
-	}
-
-	inev.timestamp = er.when * (1000 / 60);  /* ticks to milliseconds */
-	break;
-
-      case kHighLevelEvent:
-        drag_and_drop_file_list = Qnil;
-
-        AEProcessAppleEvent(&er);
-
-        /* Build a DRAG_N_DROP_EVENT type event as is done in
-           constuct_drag_n_drop in w32term.c.  */
-        if (!NILP (drag_and_drop_file_list))
-          {
-            struct frame *f = NULL;
-            WindowPtr wp;
-            Lisp_Object frame;
-
-            wp = FrontNonFloatingWindow ();
-
-	    if (!wp)
-	      {
-		struct frame *f = XFRAME (XCAR (Vframe_list));
-		CollapseWindow (FRAME_MAC_WINDOW (f), false);
-		wp = FrontNonFloatingWindow ();
-	      }
-
-            if (wp && is_emacs_window(wp))
-	        f = ((mac_output *) GetWRefCon (wp))->mFP;
-
-            inev.kind = DRAG_N_DROP_EVENT;
-            inev.code = 0;
-            inev.timestamp = er.when * (1000 / 60);
-	      /* ticks to milliseconds */
-#if USE_CARBON_EVENTS
-	    inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
-	    inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
-#endif
-
-            XSETINT (inev.x, 0);
-            XSETINT (inev.y, 0);
-
-            XSETFRAME (frame, f);
-            inev.frame_or_window = Fcons (frame, drag_and_drop_file_list);
-
-            /* Regardless of whether Emacs was suspended or in the
-               foreground, ask it to redraw its entire screen.
-               Otherwise parts of the screen can be left in an
-               inconsistent state.  */
-            if (wp)
-#if TARGET_API_MAC_CARBON
-	      {
-	        Rect r;
-
-	        GetWindowPortBounds (wp, &r);
-	        InvalWindowRect (wp, &r);
-	      }
-#else /* not TARGET_API_MAC_CARBON */
-              InvalRect (&(wp->portRect));
-#endif /* not TARGET_API_MAC_CARBON */
-          }
-      default:
-	break;
-      }
-#if USE_CARBON_EVENTS
-      ReleaseEvent (eventRef);
-    }
-#endif
+    }
 
   /* If the focus was just given to an autoraising frame,
      raise it now.  */
@@ -8620,58 +8669,6 @@
   check_alarm ();  /* simulate the handling of a SIGALRM */
 #endif
 
-  {
-    static Point old_mouse_pos = { -1, -1 };
-
-    if (app_is_suspended)
-      {
-        old_mouse_pos.h = -1;
-        old_mouse_pos.v = -1;
-      }
-    else
-      {
-        Point mouse_pos;
-        WindowPtr wp;
-        struct frame *f;
-        Lisp_Object bar;
-        struct scroll_bar *sb;
-
-        wp = FrontWindow ();
-	if (is_emacs_window (wp))
-	  {
-	    f = ((mac_output *) GetWRefCon (wp))->mFP;
-
-#if TARGET_API_MAC_CARBON
-	    SetPort (GetWindowPort (wp));
-#else
-	    SetPort (wp);
-#endif
-
-	    GetMouse (&mouse_pos);
-
-	    if (!EqualPt (mouse_pos, old_mouse_pos))
-	      {
-		if (mouse_tracking_in_progress == mouse_tracking_scroll_bar
-		    && tracked_scroll_bar)
-		  x_scroll_bar_note_movement (tracked_scroll_bar,
-					      mouse_pos.v
-					      - XINT (tracked_scroll_bar->top),
-					      TickCount() * (1000 / 60));
-		else
-		  note_mouse_movement (f, &mouse_pos);
-
-		old_mouse_pos = mouse_pos;
-	      }
-	  }
-      }
-  }
-
-  if (inev.kind != NO_EVENT)
-    {
-      kbd_buffer_store_event_hold (&inev, hold_quit);
-      count++;
-    }
-
   UNBLOCK_INPUT;
   return count;
 }
@@ -8700,7 +8697,7 @@
    ROWS Macintosh window, using font with name FONTNAME and size
    FONTSIZE.  */
 void
-NewMacWindow (FRAME_PTR fp)
+make_mac_frame (FRAME_PTR fp)
 {
   mac_output *mwp;
 #if TARGET_API_MAC_CARBON
@@ -8719,57 +8716,30 @@
       making_terminal_window = 0;
     }
   else
-    if (!(mwp->mWP = GetNewCWindow (WINDOW_RESOURCE, NULL, (WindowPtr) -1)))
-      abort ();
+    {
+#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 */
 
-#if TARGET_API_MAC_CARBON
-  SetPort (GetWindowPort (mwp->mWP));
-#else
-  SetPort (mwp->mWP);
-#endif
-
-  mwp->fontset = -1;
+  SetPortWindowPort (mwp->mWP);
 
   SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false);
-  ShowWindow (mwp->mWP);
-
-}
-
-
-void
-make_mac_frame (struct frame *f)
-{
-  FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
-
-  NewMacWindow(f);
-
-  f->output_data.mac->cursor_pixel = 0;
-  f->output_data.mac->border_pixel = 0x00ff00;
-  f->output_data.mac->mouse_pixel = 0xff00ff;
-  f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
-
-  FRAME_FONTSET (f) = -1;
-  f->output_data.mac->scroll_bar_foreground_pixel = -1;
-  f->output_data.mac->scroll_bar_background_pixel = -1;
-  f->output_data.mac->explicit_parent = 0;
-  f->left_pos = 4;
-  f->top_pos = 4;
-  f->border_width = 0;
-
-  f->internal_border_width = 0;
-
-  f->output_method = output_mac;
-
-  f->auto_raise = 1;
-  f->auto_lower = 1;
-
-  f->new_text_cols = 0;
-  f->new_text_lines = 0;
-}
+}
+
 
 void
 make_mac_terminal_frame (struct frame *f)
@@ -8782,9 +8752,6 @@
   f->output_data.mac = (struct mac_output *)
     xmalloc (sizeof (struct mac_output));
   bzero (f->output_data.mac, sizeof (struct mac_output));
-  FRAME_FONTSET (f) = -1;
-  f->output_data.mac->scroll_bar_foreground_pixel = -1;
-  f->output_data.mac->scroll_bar_background_pixel = -1;
 
   XSETFRAME (FRAME_KBOARD (f)->Vdefault_minibuffer_frame, f);
 
@@ -8794,6 +8761,27 @@
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
 
+  FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
+
+  f->output_data.mac->cursor_pixel = 0;
+  f->output_data.mac->border_pixel = 0x00ff00;
+  f->output_data.mac->mouse_pixel = 0xff00ff;
+  f->output_data.mac->cursor_foreground_pixel = 0x0000ff;
+
+  FRAME_FONTSET (f) = -1;
+  f->output_data.mac->explicit_parent = 0;
+  f->left_pos = 4;
+  f->top_pos = 4;
+  f->border_width = 0;
+
+  f->internal_border_width = 0;
+
+  f->auto_raise = 1;
+  f->auto_lower = 1;
+
+  f->new_text_cols = 0;
+  f->new_text_lines = 0;
+
   make_mac_frame (f);
 
   x_make_gc (f);
@@ -8810,6 +8798,8 @@
   Fmodify_frame_parameters (frame,
                             Fcons (Fcons (Qbackground_color,
                                           build_string ("white")), Qnil));
+
+  ShowWindow (f->output_data.mac->mWP);
 }
 
 
@@ -8864,6 +8854,8 @@
   dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
   dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
   dpyinfo->mouse_face_window = Qnil;
+  dpyinfo->mouse_face_overlay = Qnil;
+  dpyinfo->mouse_face_hidden = 0;
 }
 
 struct mac_display_info *
@@ -9020,8 +9012,7 @@
   if (event)
     {
       struct input_event e;
-      struct mac_output *mwp =
-	(mac_output *) GetWRefCon (FrontNonFloatingWindow ());
+
       /* Use an input_event to emulate what the interrupt handler does. */
       EVENT_INIT (e);
       e.kind = ASCII_KEYSTROKE_EVENT;
@@ -9029,7 +9020,7 @@
       e.arg = Qnil;
       e.modifiers = NULL;
       e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60);
-      XSETFRAME (e.frame_or_window, mwp->mFP);
+      XSETFRAME (e.frame_or_window, mac_window_to_frame (mac_front_window ()));
       /* Remove event from queue to prevent looping. */
       RemoveEventFromQueue (GetMainEventQueue (), event);
       ReleaseEvent (event);
--- a/src/xdisp.c	Sun May 30 00:09:37 2004 +0000
+++ b/src/xdisp.c	Sun May 30 00:18:41 2004 +0000
@@ -198,8 +198,6 @@
 #endif
 #ifdef MAC_OS
 #include "macterm.h"
-
-Cursor No_Cursor;
 #endif
 
 #ifndef FRAME_X_OUTPUT
@@ -20638,11 +20636,7 @@
 	cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
     }
 
-#ifndef HAVE_CARBON
   if (cursor != No_Cursor)
-#else
-  if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
-#endif
     rif->define_frame_cursor (f, cursor);
 }