changeset 81242:95935a0c1560

(mac_begin_cg_clip): New arg F. Call SetPortWindowPort. All callers changed so as not to call SetPortWindowPort. (mac_begin_cg_clip) [USE_CG_DRAWING]: Call mac_prepare_for_quickdraw. (mac_draw_image_string_atsui) [USE_ATSUI]: New function created from mac_draw_string_common. (mac_draw_image_string_qd): Likewise. (mac_draw_string_common): Use them. Add INLINE. (XTmouse_position, x_scroll_bar_report_motion) [TARGET_API_MAC_CARBON]: Use FRAME_OUTER_TO_INNER_DIFF_X, FRAME_OUTER_TO_INNER_DIFF_Y, and GetGlobalMouse. (x_set_mouse_pixel_position) [MAC_OSX]: Use FRAME_OUTER_TO_INNER_DIFF_X and FRAME_OUTER_TO_INNER_DIFF_Y. [TARGET_API_MAC_CARBON] (mac_handle_mouse_event): Likewise. [USE_MAC_TSM] (mac_handle_text_input_event): Likewise. (x_make_frame_visible) [TARGET_API_MAC_CARBON]: Move code for repositioning window to mac_handle_window_event. (x_make_frame_invisible) [TARGET_API_MAC_CARBON]: Move code for saving window location to mac_handle_window_event [USE_MAC_FONT_PANEL] (mac_show_hide_font_panel): Install handler here. (install_menu_target_item_handler): Remove argument in extern. [TARGET_API_MAC_CARBON] (mac_event_to_emacs_modifiers): Also accept command events. (do_keystroke): New function created from XTread_socket. (init_command_handler): Remove functions. [TARGET_API_MAC_CARBON] (mac_handle_window_event): Reposition window and save window location by kEventWindowShowing and kEventWindowHiding handlers here. Don't call next handler for window state change and focus events. (mac_handle_application_event, mac_handle_keyboard_event) [TARGET_API_MAC_CARBON]: New functions. (install_window_handler) [TARGET_API_MAC_CARBON]: Register handlers for kEventWindowShowing and kEventWindowHiding events. Move installation of mouse, font, text input and menu target item handlers to install_application_handler. (install_application_handler) [TARGET_API_MAC_CARBON]: New function. (mac_handle_cg_display_reconfig) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: New function. (init_dm_notification_handler) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Register it. (XTread_socket) [TARGET_API_MAC_CARBON]: Consolidate SendEventToEventTarget calls. Use FRAME_OUTER_TO_INNER_DIFF_X and FRAME_OUTER_TO_INNER_DIFF_Y. Move application activation handler to mac_handle_application_event. Move keyboard handler to mac_handle_keyboard_event. (XTread_socket) [!TARGET_API_MAC_CARBON]: Use do_keystroke. (mac_initialize) [TARGET_API_MAC_CARBON]: Don't call init_command_handler. Call install_application_handler.
author YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
date Thu, 07 Jun 2007 08:45:00 +0000
parents b453bc0cb471
children a45c50c85284
files src/macterm.c
diffstat 1 files changed, 1147 insertions(+), 932 deletions(-) [+]
line wrap: on
line diff
--- a/src/macterm.c	Thu Jun 07 08:44:47 2007 +0000
+++ b/src/macterm.c	Thu Jun 07 08:45:00 2007 +0000
@@ -411,7 +411,8 @@
 static RgnHandle saved_port_clip_region = NULL;
 
 static void
-mac_begin_clip (gc)
+mac_begin_clip (f, gc)
+     struct frame *f;
      GC gc;
 {
   static RgnHandle new_region = NULL;
@@ -421,6 +422,11 @@
   if (new_region == NULL)
     new_region = NewRgn ();
 
+#if USE_CG_DRAWING
+  mac_prepare_for_quickdraw (f);
+#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+
   if (gc->n_clip_rects)
     {
       GetClip (saved_port_clip_region);
@@ -440,15 +446,6 @@
 
 /* X display function emulation */
 
-void
-XFreePixmap (display, pixmap)
-     Display *display;		/* not used */
-     Pixmap pixmap;
-{
-  DisposeGWorld (pixmap);
-}
-
-
 /* Mac version of XDrawLine.  */
 
 static void
@@ -490,11 +487,8 @@
 	x2--;
     }
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
-
-  mac_begin_clip (gc);
   MoveTo (x1, y1);
   LineTo (x2, y2);
   mac_end_clip (gc);
@@ -550,25 +544,25 @@
      unsigned int width, height;
 {
 #if USE_CG_DRAWING
-  CGContextRef context;
-
-  context = mac_begin_cg_clip (f, gc);
-  CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
-  CGContextFillRect (context, CGRectMake (x, y, width, height));
-  mac_end_cg_clip (f);
+    {
+      CGContextRef context;
+
+      context = mac_begin_cg_clip (f, gc);
+      CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+      CGContextFillRect (context, CGRectMake (x, y, width, height));
+      mac_end_cg_clip (f);
+    }
 #else
-  Rect r;
-
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-  RGBBackColor (GC_BACK_COLOR (gc));
-  SetRect (&r, x, y, x + width, y + height);
-
-  mac_begin_clip (gc);
-  EraseRect (&r);
-  mac_end_clip (gc);
-
-  RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+    {
+      Rect r;
+
+      mac_begin_clip (f, gc);
+      RGBBackColor (GC_BACK_COLOR (gc));
+      SetRect (&r, x, y, x + width, y + height);
+      EraseRect (&r);
+      RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+      mac_end_clip (gc);
+    }
 #endif
 }
 
@@ -591,15 +585,17 @@
      struct frame *f;
 {
 #if USE_CG_DRAWING
-  CGContextRef context;
-  GC gc = FRAME_NORMAL_GC (f);
-
-  context = mac_begin_cg_clip (f, NULL);
-  CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
-  CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
-					  FRAME_PIXEL_HEIGHT (f)));
-  mac_end_cg_clip (f);
-#else
+  {
+    CGContextRef context;
+    GC gc = FRAME_NORMAL_GC (f);
+
+    context = mac_begin_cg_clip (f, NULL);
+    CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+    CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
+					    FRAME_PIXEL_HEIGHT (f)));
+    mac_end_cg_clip (f);
+  }
+#else  /* !USE_CG_DRAWING */
   SetPortWindowPort (FRAME_MAC_WINDOW (f));
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
@@ -673,13 +669,10 @@
   bitmap.baseAddr = (char *)bits;
   SetRect (&(bitmap.bounds), 0, 0, width, height);
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
   RGBBackColor (GC_BACK_COLOR (gc));
   SetRect (&r, x, y, x + width, y + height);
-
-  mac_begin_clip (gc);
 #if TARGET_API_MAC_CARBON
   {
     CGrafPtr port;
@@ -694,9 +687,8 @@
   CopyBits (&bitmap, &(FRAME_MAC_WINDOW (f)->portBits), &(bitmap.bounds), &r,
 	    overlay_p ? srcOr : srcCopy, 0);
 #endif /* not TARGET_API_MAC_CARBON */
+  RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
   mac_end_clip (gc);
-
-  RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
 }
 #endif	/* !USE_CG_DRAWING */
 
@@ -747,7 +739,7 @@
 
 Pixmap
 XCreatePixmap (display, w, width, height, depth)
-     Display *display;		/* not used */
+     Display *display;
      WindowRef w;
      unsigned int width, height;
      unsigned int depth;
@@ -776,7 +768,7 @@
 
 Pixmap
 XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
-     Display *display;		/* not used */
+     Display *display;
      WindowRef w;
      char *data;
      unsigned int width, height;
@@ -787,7 +779,7 @@
   BitMap bitmap;
   CGrafPtr old_port;
   GDHandle old_gdh;
-  static GC gc = NULL;		/* not reentrant */
+  static GC gc = NULL;
 
   if (gc == NULL)
     gc = XCreateGC (display, w, 0, NULL);
@@ -819,6 +811,15 @@
 }
 
 
+void
+XFreePixmap (display, pixmap)
+     Display *display;
+     Pixmap pixmap;
+{
+  DisposeGWorld (pixmap);
+}
+
+
 /* Mac replacement for XFillRectangle.  */
 
 static void
@@ -838,12 +839,9 @@
 #else
   Rect r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
   SetRect (&r, x, y, x + width, y + height);
-
-  mac_begin_clip (gc);
   PaintRect (&r); /* using foreground color of gc */
   mac_end_clip (gc);
 #endif
@@ -870,18 +868,34 @@
 #else
   Rect r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
+  mac_begin_clip (f, gc);
   RGBForeColor (GC_FORE_COLOR (gc));
   SetRect (&r, x, y, x + width + 1, y + height + 1);
-
-  mac_begin_clip (gc);
   FrameRect (&r); /* using foreground color of gc */
   mac_end_clip (gc);
 #endif
 }
 
 
+static void
+mac_invert_rectangle (f, x, y, width, height)
+     struct frame *f;
+     int x, y;
+     unsigned int width, height;
+{
+  Rect r;
+
+#if USE_CG_DRAWING
+  mac_prepare_for_quickdraw (f);
+#endif
+  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+
+  SetRect (&r, x, y, x + width, y + height);
+
+  InvertRect (&r);
+}
+
+
 #if USE_ATSUI
 static OSStatus
 atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout)
@@ -891,7 +905,7 @@
      ATSUTextLayout *text_layout;
 {
   OSStatus err;
-  static ATSUTextLayout saved_text_layout = NULL; /* not reentrant */
+  static ATSUTextLayout saved_text_layout = NULL;
 
   if (saved_text_layout == NULL)
     {
@@ -918,7 +932,6 @@
 	err = ATSUSetLayoutControls (saved_text_layout,
 				     sizeof (tags) / sizeof (tags[0]),
 				     tags, sizes, values);
-      /* XXX: Should we do this? */
       if (err == noErr)
 	err = ATSUSetTransientFontMatching (saved_text_layout, true);
     }
@@ -937,29 +950,208 @@
     *text_layout = saved_text_layout;
   return err;
 }
-#endif
-
-
-static void
-mac_invert_rectangle (f, x, y, width, height)
+
+
+static void
+mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+			     overstrike_p, bytes_per_char)
      struct frame *f;
+     GC gc;
      int x, y;
-     unsigned int width, height;
-{
-  Rect r;
+     char *buf;
+     int nchars, bg_width, overstrike_p, bytes_per_char;
+{
+  OSStatus err;
+  ATSUTextLayout text_layout;
+
+  xassert (bytes_per_char == 2);
+
+#ifndef WORDS_BIG_ENDIAN
+  {
+    int i;
+    UniChar *text = (UniChar *)buf;
+
+    for (i = 0; i < nchars; i++)
+      text[i] = EndianU16_BtoN (text[i]);
+  }
+#endif
+  err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
+					    nchars,
+					    GC_FONT (gc)->mac_style,
+					    &text_layout);
+  if (err != noErr)
+    return;
+#ifdef MAC_OSX
+  if (!mac_use_core_graphics)
+    {
+#endif
+      mac_begin_clip (f, gc);
+      RGBForeColor (GC_FORE_COLOR (gc));
+      if (bg_width)
+	{
+	  Rect r;
+
+	  SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+		   x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+	  RGBBackColor (GC_BACK_COLOR (gc));
+	  EraseRect (&r);
+	  RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+	}
+      MoveTo (x, y);
+      ATSUDrawText (text_layout,
+		    kATSUFromTextBeginning, kATSUToTextEnd,
+		    kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+      if (overstrike_p)
+	{
+	  MoveTo (x + 1, y);
+	  ATSUDrawText (text_layout,
+			kATSUFromTextBeginning, kATSUToTextEnd,
+			kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
+	}
+      mac_end_clip (gc);
+#ifdef MAC_OSX
+    }
+  else
+    {
+      static CGContextRef context;
+      float port_height = FRAME_PIXEL_HEIGHT (f);
+      static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
+      static const ByteCount sizes[] = {sizeof (CGContextRef)};
+      static const ATSUAttributeValuePtr values[] = {&context};
 
 #if USE_CG_DRAWING
-  mac_prepare_for_quickdraw (f);
-#endif
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
-  SetRect (&r, x, y, x + width, y + height);
-
-  InvertRect (&r);
-}
-
-
-static void
+      context = mac_begin_cg_clip (f, gc);
+#else
+      CGrafPtr port;
+
+      GetPort (&port);
+      QDBeginCGContext (port, &context);
+      if (gc->n_clip_rects || bg_width)
+	{
+	  CGContextTranslateCTM (context, 0, port_height);
+	  CGContextScaleCTM (context, 1, -1);
+	  if (gc->n_clip_rects)
+	    CGContextClipToRects (context, gc->clip_rects,
+				  gc->n_clip_rects);
+#endif
+	  if (bg_width)
+	    {
+	      CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
+	      CGContextFillRect	(context,
+				 CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
+					     bg_width,
+					     FONT_HEIGHT (GC_FONT (gc))));
+	    }
+	  CGContextScaleCTM (context, 1, -1);
+	  CGContextTranslateCTM (context, 0, -port_height);
+#if !USE_CG_DRAWING
+	}
+#endif
+      CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
+      err = ATSUSetLayoutControls (text_layout,
+				   sizeof (tags) / sizeof (tags[0]),
+				   tags, sizes, values);
+      if (err == noErr)
+	{
+	  ATSUDrawText (text_layout,
+			kATSUFromTextBeginning, kATSUToTextEnd,
+			Long2Fix (x), Long2Fix (port_height - y));
+	  if (overstrike_p)
+	    ATSUDrawText (text_layout,
+			  kATSUFromTextBeginning, kATSUToTextEnd,
+			  Long2Fix (x + 1), Long2Fix (port_height - y));
+	}
+#if USE_CG_DRAWING
+      mac_end_cg_clip (f);
+      context = NULL;
+#else
+      CGContextSynchronize (context);
+      QDEndCGContext (port, &context);
+#endif
+#if 0
+      /* This doesn't work on Mac OS X 10.1.  */
+      ATSUClearLayoutControls (text_layout,
+			       sizeof (tags) / sizeof (tags[0]), tags);
+#else
+      ATSUSetLayoutControls (text_layout,
+			     sizeof (tags) / sizeof (tags[0]),
+			     tags, sizes, values);
+#endif
+    }
+#endif	/* MAC_OSX */
+}
+#endif	/* USE_ATSUI */
+
+
+static void
+mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+			  overstrike_p, bytes_per_char)
+     struct frame *f;
+     GC gc;
+     int x, y;
+     char *buf;
+     int nchars, bg_width, overstrike_p, bytes_per_char;
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  UInt32 savedFlags;
+#endif
+
+  mac_begin_clip (f, gc);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  if (mac_use_core_graphics)
+    savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
+#endif
+  RGBForeColor (GC_FORE_COLOR (gc));
+#ifdef MAC_OS8
+  if (bg_width)
+    {
+      RGBBackColor (GC_BACK_COLOR (gc));
+      TextMode (srcCopy);
+    }
+  else
+    TextMode (srcOr);
+#else
+  /* We prefer not to use srcCopy text transfer mode on Mac OS X
+     because:
+     - Screen is double-buffered.  (In srcCopy mode, a text is drawn
+       into an offscreen graphics world first.  So performance gain
+       cannot be expected.)
+     - It lowers rendering quality.
+     - Some fonts leave garbage on cursor movement.  */
+  if (bg_width)
+    {
+      Rect r;
+
+      RGBBackColor (GC_BACK_COLOR (gc));
+      SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
+	       x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
+      EraseRect (&r);
+    }
+  TextMode (srcOr);
+#endif
+  TextFont (GC_FONT (gc)->mac_fontnum);
+  TextSize (GC_FONT (gc)->mac_fontsize);
+  TextFace (GC_FONT (gc)->mac_fontface);
+  MoveTo (x, y);
+  DrawText (buf, 0, nchars * bytes_per_char);
+  if (overstrike_p)
+    {
+      TextMode (srcOr);
+      MoveTo (x + 1, y);
+      DrawText (buf, 0, nchars * bytes_per_char);
+    }
+  if (bg_width)
+    RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+  mac_end_clip (gc);
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+  if (mac_use_core_graphics)
+    SwapQDTextFlags(savedFlags);
+#endif
+}
+
+
+static INLINE void
 mac_draw_string_common (f, gc, x, y, buf, nchars, bg_width,
 			overstrike_p, bytes_per_char)
      struct frame *f;
@@ -968,193 +1160,14 @@
      char *buf;
      int nchars, bg_width, overstrike_p, bytes_per_char;
 {
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-
 #if USE_ATSUI
   if (GC_FONT (gc)->mac_style)
-    {
-      OSStatus err;
-      ATSUTextLayout text_layout;
-
-      xassert (bytes_per_char == 2);
-
-#ifndef WORDS_BIG_ENDIAN
-      {
-	int i;
-	UniChar *text = (UniChar *)buf;
-
-	for (i = 0; i < nchars; i++)
-	  text[i] = EndianU16_BtoN (text[i]);
-      }
-#endif
-      err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf,
-						nchars,
-						GC_FONT (gc)->mac_style,
-						&text_layout);
-      if (err != noErr)
-	return;
-#ifdef MAC_OSX
-      if (!mac_use_core_graphics)
-	{
-#endif
-#if USE_CG_DRAWING
-	  mac_prepare_for_quickdraw (f);
-#endif
-	  mac_begin_clip (gc);
-	  RGBForeColor (GC_FORE_COLOR (gc));
-	  if (bg_width)
-	    {
-	      Rect r;
-
-	      SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
-		       x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
-	      RGBBackColor (GC_BACK_COLOR (gc));
-	      EraseRect (&r);
-	      RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-	    }
-	  MoveTo (x, y);
-	  ATSUDrawText (text_layout,
-			kATSUFromTextBeginning, kATSUToTextEnd,
-			kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
-	  if (overstrike_p)
-	    {
-	      MoveTo (x + 1, y);
-	      ATSUDrawText (text_layout,
-			    kATSUFromTextBeginning, kATSUToTextEnd,
-			    kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc);
-	    }
-	  mac_end_clip (gc);
-#ifdef MAC_OSX
-	}
-      else
-	{
-	  CGrafPtr port;
-	  static CGContextRef context;
-	  float port_height = FRAME_PIXEL_HEIGHT (f);
-	  static const ATSUAttributeTag tags[] = {kATSUCGContextTag};
-	  static const ByteCount sizes[] = {sizeof (CGContextRef)};
-	  static const ATSUAttributeValuePtr values[] = {&context};
-
-#if USE_CG_DRAWING
-	  context = mac_begin_cg_clip (f, gc);
-#else
-	  GetPort (&port);
-	  QDBeginCGContext (port, &context);
-	  if (gc->n_clip_rects || bg_width)
-	    {
-	      CGContextTranslateCTM (context, 0, port_height);
-	      CGContextScaleCTM (context, 1, -1);
-	      if (gc->n_clip_rects)
-		CGContextClipToRects (context, gc->clip_rects,
-				      gc->n_clip_rects);
-#endif
-	      if (bg_width)
-		{
-		  CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
-		  CGContextFillRect
-		    (context,
-		     CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
-				 bg_width, FONT_HEIGHT (GC_FONT (gc))));
-		}
-	      CGContextScaleCTM (context, 1, -1);
-	      CGContextTranslateCTM (context, 0, -port_height);
-#if !USE_CG_DRAWING
-	    }
-#endif
-	  CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
-	  err = ATSUSetLayoutControls (text_layout,
-				       sizeof (tags) / sizeof (tags[0]),
-				       tags, sizes, values);
-	  if (err == noErr)
-	    {
-	      ATSUDrawText (text_layout,
-			    kATSUFromTextBeginning, kATSUToTextEnd,
-			    Long2Fix (x), Long2Fix (port_height - y));
-	      if (overstrike_p)
-		ATSUDrawText (text_layout,
-			      kATSUFromTextBeginning, kATSUToTextEnd,
-			      Long2Fix (x + 1), Long2Fix (port_height - y));
-	    }
-#if USE_CG_DRAWING
-	  mac_end_cg_clip (f);
-	  context = NULL;
-#else
-	  CGContextSynchronize (context);
-	  QDEndCGContext (port, &context);
-#endif
-#if 0
-	  /* This doesn't work on Mac OS X 10.1.  */
-	  ATSUClearLayoutControls (text_layout,
-				   sizeof (tags) / sizeof (tags[0]), tags);
-#else
-	  ATSUSetLayoutControls (text_layout,
-				 sizeof (tags) / sizeof (tags[0]),
-				 tags, sizes, values);
-#endif
-	}
-#endif	/* MAC_OSX */
-    }
+    mac_draw_image_string_atsui (f, gc, x, y, buf, nchars, bg_width,
+				 overstrike_p, bytes_per_char);
   else
 #endif	/* USE_ATSUI */
-    {
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-      UInt32 savedFlags;
-
-      if (mac_use_core_graphics)
-	savedFlags = SwapQDTextFlags (kQDUseCGTextRendering);
-#endif
-#if USE_CG_DRAWING
-      mac_prepare_for_quickdraw (f);
-#endif
-      mac_begin_clip (gc);
-      RGBForeColor (GC_FORE_COLOR (gc));
-#ifdef MAC_OS8
-      if (bg_width)
-	{
-	  RGBBackColor (GC_BACK_COLOR (gc));
-	  TextMode (srcCopy);
-	}
-      else
-	TextMode (srcOr);
-#else
-      /* We prefer not to use srcCopy text transfer mode on Mac OS X
-	 because:
-	 - Screen is double-buffered.  (In srcCopy mode, a text is
-	   drawn into an offscreen graphics world first.  So
-	   performance gain cannot be expected.)
-	 - It lowers rendering quality.
-	 - Some fonts leave garbage on cursor movement.  */
-      if (bg_width)
-	{
-	  Rect r;
-
-	  RGBBackColor (GC_BACK_COLOR (gc));
-	  SetRect (&r, x, y - FONT_BASE (GC_FONT (gc)),
-		   x + bg_width, y + FONT_DESCENT (GC_FONT (gc)));
-	  EraseRect (&r);
-	}
-      TextMode (srcOr);
-#endif
-      TextFont (GC_FONT (gc)->mac_fontnum);
-      TextSize (GC_FONT (gc)->mac_fontsize);
-      TextFace (GC_FONT (gc)->mac_fontface);
-      MoveTo (x, y);
-      DrawText (buf, 0, nchars * bytes_per_char);
-      if (overstrike_p)
-	{
-	  TextMode (srcOr);
-	  MoveTo (x + 1, y);
-	  DrawText (buf, 0, nchars * bytes_per_char);
-	}
-      if (bg_width)
-	RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
-      mac_end_clip (gc);
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-      if (mac_use_core_graphics)
-	SwapQDTextFlags(savedFlags);
-#endif
-    }
+    mac_draw_image_string_qd (f, gc, x, y, buf, nchars, bg_width,
+			      overstrike_p, bytes_per_char);
 }
 
 
@@ -1371,7 +1384,6 @@
      XChar2b *buf;
      int nchars, bg_width, overstrike_p;
 {
-  CGrafPtr port;
   float port_height, gx, gy;
   int i;
   CGContextRef context;
@@ -1381,7 +1393,6 @@
   if (!mac_use_core_graphics || GC_FONT (gc)->cg_font == NULL)
     return 0;
 
-  port = GetWindowPort (FRAME_MAC_WINDOW (f));
   port_height = FRAME_PIXEL_HEIGHT (f);
   gx = x;
   gy = port_height - y;
@@ -1402,7 +1413,7 @@
 #if USE_CG_DRAWING
   context = mac_begin_cg_clip (f, gc);
 #else
-  QDBeginCGContext (port, &context);
+  QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
   if (gc->n_clip_rects || bg_width)
     {
       CGContextTranslateCTM (context, 0, port_height);
@@ -1442,7 +1453,7 @@
 	}
     }
 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
-  else
+  else			 /* CGContextShowGlyphsWithAdvances == NULL */
 #endif
 #endif	/* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030  */
 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
@@ -1460,7 +1471,7 @@
   mac_end_cg_clip (f);
 #else
   CGContextSynchronize (context);
-  QDEndCGContext (port, &context);
+  QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f)), &context);
 #endif
 
   return 1;
@@ -1482,7 +1493,7 @@
 {
   Rect src_r, dest_r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+  mac_begin_clip (f, gc);
 
   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);
@@ -1490,7 +1501,6 @@
   ForeColor (blackColor);
   BackColor (whiteColor);
 
-  mac_begin_clip (gc);
   LockPixels (GetGWorldPixMap (src));
 #if TARGET_API_MAC_CARBON
   {
@@ -1508,9 +1518,10 @@
 	    &src_r, &dest_r, srcCopy, 0);
 #endif /* not TARGET_API_MAC_CARBON */
   UnlockPixels (GetGWorldPixMap (src));
-  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+  mac_end_clip (gc);
 }
 
 
@@ -1526,7 +1537,7 @@
 {
   Rect src_r, dest_r;
 
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
+  mac_begin_clip (f, gc);
 
   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);
@@ -1534,7 +1545,6 @@
   ForeColor (blackColor);
   BackColor (whiteColor);
 
-  mac_begin_clip (gc);
   LockPixels (GetGWorldPixMap (src));
   LockPixels (GetGWorldPixMap (mask));
 #if TARGET_API_MAC_CARBON
@@ -1554,9 +1564,10 @@
 #endif /* not TARGET_API_MAC_CARBON */
   UnlockPixels (GetGWorldPixMap (mask));
   UnlockPixels (GetGWorldPixMap (src));
-  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+  mac_end_clip (gc);
 }
 #endif	/* !USE_CG_DRAWING */
 
@@ -1587,7 +1598,7 @@
   Rect src_r, dest_r;
   WindowRef w = FRAME_MAC_WINDOW (f);
 
-  SetPort (w);
+  mac_begin_clip (f, gc);
 
   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);
@@ -1596,11 +1607,11 @@
      color mapping in CopyBits.  Otherwise, it will be slow.  */
   ForeColor (blackColor);
   BackColor (whiteColor);
-  mac_begin_clip (gc);
   CopyBits (&(w->portBits), &(w->portBits), &src_r, &dest_r, srcCopy, 0);
-  mac_end_clip (gc);
 
   RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f)));
+
+  mac_end_clip (gc);
 #endif /* not TARGET_API_MAC_CARBON */
 }
 
@@ -4608,8 +4619,14 @@
 	     the frame are divided into.  */
 	  Point mouse_pos;
 
+#if TARGET_API_MAC_CARBON
+	  GetGlobalMouse (&mouse_pos);
+	  mouse_pos.h -= f1->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f1);
+	  mouse_pos.v -= f1->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f1);
+#else
 	  SetPortWindowPort (FRAME_MAC_WINDOW (f1));
 	  GetMouse (&mouse_pos);
+#endif
 	  remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v,
 				&last_mouse_glyph);
 	  last_mouse_glyph_frame = f1;
@@ -5511,9 +5528,14 @@
   struct frame *f = mac_window_to_frame (wp);
   int win_y, top_range;
 
+#if TARGET_API_MAC_CARBON
+  GetGlobalMouse (&mouse_pos);
+  mouse_pos.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+  mouse_pos.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
+#else
   SetPortWindowPort (wp);
-
   GetMouse (&mouse_pos);
+#endif
 
   win_y = mouse_pos.v - XINT (bar->top);
   top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
@@ -6264,17 +6286,11 @@
      int pix_x, pix_y;
 {
 #ifdef MAC_OSX
-  Point p;
-  CGPoint point;
+  pix_x += f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+  pix_y += f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
 
   BLOCK_INPUT;
-  SetPortWindowPort (FRAME_MAC_WINDOW (f));
-  p.h = pix_x;
-  p.v = pix_y;
-  LocalToGlobal (&p);
-  point.x = p.h;
-  point.y = p.v;
-  CGWarpMouseCursorPosition (point);
+  CGWarpMouseCursorPosition (CGPointMake (pix_x, pix_y));
   UNBLOCK_INPUT;
 #else
 #if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
@@ -6424,30 +6440,7 @@
 	 before the window gets really visible.  */
       if (! FRAME_ICONIFIED_P (f)
 	  && ! f->output_data.mac->asked_for_visible)
-	{
-#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),
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-				  kWindowCascadeStartAtParentWindowScreen
-#else
-				  kWindowCascadeOnParentWindowScreen
-#endif
-				  );
-	      if (!NILP (tip_frame) && f == XFRAME (tip_frame))
-		mac_handle_origin_change (f);
-	    }
-	  else
-#endif
-	    x_set_offset (f, f->left_pos, f->top_pos, 0);
-	}
+	x_set_offset (f, f->left_pos, f->top_pos, 0);
 
       f->output_data.mac->asked_for_visible = 1;
 
@@ -6521,12 +6514,14 @@
 
   BLOCK_INPUT;
 
+#if !TARGET_API_MAC_CARBON
   /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
      that the current position of the window is user-specified, rather than
      program-specified, so that when the window is mapped again, it will be
      placed at the same location, without forcing the user to position it
      by hand again (they have already done that once for this window.)  */
   x_wm_set_size_hint (f, (long) 0, 1);
+#endif
 
   HideWindow (FRAME_MAC_WINDOW (f));
 
@@ -8719,16 +8714,93 @@
    possible.  */
 static int font_panel_shown_p = 0;
 
+extern Lisp_Object Qfont;
+static Lisp_Object Qpanel_closed, Qselection;
+
+static OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID,
+							Lisp_Object,
+							Lisp_Object,
+							EventRef, UInt32,
+							const EventParamName *,
+							const EventParamType *));
+
 int
 mac_font_panel_visible_p ()
 {
   return font_panel_shown_p && FPIsFontPanelVisible ();
 }
 
+static pascal OSStatus
+mac_handle_font_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus result, err;
+  Lisp_Object id_key;
+  int num_params;
+  const EventParamName *names;
+  const EventParamType *types;
+  static const EventParamName names_sel[] = {kEventParamATSUFontID,
+					     kEventParamATSUFontSize,
+					     kEventParamFMFontFamily,
+					     kEventParamFMFontSize,
+					     kEventParamFontColor};
+  static const EventParamType types_sel[] = {typeATSUFontID,
+					     typeATSUSize,
+					     typeFMFontFamily,
+					     typeFMFontSize,
+					     typeFontColor};
+
+  result = CallNextEventHandler (next_handler, event);
+  if (result != eventNotHandledErr)
+    return result;
+
+  switch (GetEventKind (event))
+    {
+    case kEventFontPanelClosed:
+      id_key = Qpanel_closed;
+      num_params = 0;
+      names = NULL;
+      types = NULL;
+      break;
+
+    case kEventFontSelection:
+      id_key = Qselection;
+      num_params = sizeof (names_sel) / sizeof (names_sel[0]);
+      names = names_sel;
+      types = types_sel;
+      break;
+    }
+
+  err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
+					    event, num_params,
+					    names, types);
+  if (err == noErr)
+    result = noErr;
+
+  return result;
+}
+
 OSStatus
 mac_show_hide_font_panel ()
 {
-  font_panel_shown_p = 1;
+  if (!font_panel_shown_p)
+    {
+      OSStatus err;
+
+      static const EventTypeSpec specs[] =
+	{{kEventClassFont, kEventFontPanelClosed},
+	 {kEventClassFont, kEventFontSelection}};
+
+      err = InstallApplicationEventHandler (mac_handle_font_event,
+					    GetEventTypeCount (specs),
+					    specs, NULL, NULL);
+      if (err != noErr)
+	return err;
+
+      font_panel_shown_p = 1;
+    }
 
   return FPShowHideFontPanel ();
 }
@@ -8875,10 +8947,6 @@
 extern Lisp_Object Qwindow;
 static Lisp_Object Qtoolbar_switch_mode;
 #endif
-#if USE_MAC_FONT_PANEL
-extern Lisp_Object Qfont;
-static Lisp_Object Qpanel_closed, Qselection;
-#endif
 #if USE_MAC_TSM
 static TSMDocumentID tsm_document_id;
 static Lisp_Object Qtext_input;
@@ -8890,7 +8958,7 @@
 static ScriptLanguageRecord saved_ts_language;
 static Component saved_ts_component;
 #endif
-#endif
+#endif	/* TARGET_API_MAC_CARBON */
 extern int mac_ready_for_apple_events;
 extern Lisp_Object Qundefined;
 extern void init_apple_event_handler P_ ((void));
@@ -8903,20 +8971,15 @@
 extern OSErr install_drag_handler P_ ((WindowRef));
 extern void remove_drag_handler P_ ((WindowRef));
 
+#if TARGET_API_MAC_CARBON
 /* Showing help echo string during menu tracking  */
-extern OSStatus install_menu_target_item_handler P_ ((WindowRef));
-
-#if TARGET_API_MAC_CARBON
+extern OSStatus install_menu_target_item_handler P_ ((void));
+
 #ifdef MAC_OSX
-extern void init_service_handler ();
+extern OSStatus install_service_handler ();
 static Lisp_Object Qservice, Qpaste, Qperform;
 #endif
-
-/* Window Event Handler */
-static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
-						EventRef, void *);
-#endif
-OSStatus install_window_handler (WindowRef);
+#endif
 
 extern void init_emacs_passwd_dir ();
 extern int emacs_main (int, char **, char **);
@@ -9115,11 +9178,13 @@
 static int
 mac_event_to_emacs_modifiers (EventRef eventRef)
 {
-  UInt32 mods = 0;
+  UInt32 mods = 0, class;
+
   GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
 		    sizeof (UInt32), NULL, &mods);
+  class = GetEventClass (eventRef);
   if (!NILP (Vmac_emulate_three_button_mouse) &&
-      GetEventClass(eventRef) == kEventClassMouse)
+      (class == kEventClassMouse || class == kEventClassCommand))
     {
       mods &= ~(optionKey | cmdKey);
     }
@@ -9639,6 +9704,210 @@
 #endif
 }
 
+static void
+mac_set_unicode_keystroke_event (code, buf)
+     UniChar code;
+     struct input_event *buf;
+{
+  int charset_id, c1, c2;
+
+  if (code < 0x80)
+    {
+      buf->kind = ASCII_KEYSTROKE_EVENT;
+      buf->code = code;
+    }
+  else if (code < 0x100)
+    {
+      if (code < 0xA0)
+	charset_id = CHARSET_8_BIT_CONTROL;
+      else
+	charset_id = charset_latin_iso8859_1;
+      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+      buf->code = MAKE_CHAR (charset_id, code, 0);
+    }
+  else
+    {
+      if (code < 0x2500)
+	charset_id = charset_mule_unicode_0100_24ff,
+	  code -= 0x100;
+      else if (code < 0x33FF)
+	charset_id = charset_mule_unicode_2500_33ff,
+	  code -= 0x2500;
+      else if (code >= 0xE000)
+	charset_id = charset_mule_unicode_e000_ffff,
+	  code -= 0xE000;
+      c1 = (code / 96) + 32, c2 = (code % 96) + 32;
+      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+      buf->code = MAKE_CHAR (charset_id, c1, c2);
+    }
+}
+
+static void
+do_keystroke (action, char_code, key_code, modifiers, timestamp, buf)
+     EventKind action;
+     unsigned char char_code;
+     UInt32 key_code, modifiers;
+     unsigned long timestamp;
+     struct input_event *buf;
+{
+  static SInt16 last_key_script = -1;
+  SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
+  UInt32 mapped_modifiers = mac_mapped_modifiers (modifiers);
+
+#ifdef MAC_OSX
+  if (mapped_modifiers & kEventKeyModifierFnMask
+      && key_code <= 0x7f
+      && fn_keycode_to_keycode_table[key_code])
+    key_code = fn_keycode_to_keycode_table[key_code];
+#endif
+
+  if (key_code <= 0x7f && keycode_to_xkeysym_table[key_code])
+    {
+      buf->kind = NON_ASCII_KEYSTROKE_EVENT;
+      buf->code = 0xff00 | keycode_to_xkeysym_table[key_code];
+#ifdef MAC_OSX
+      if (modifiers & kEventKeyModifierFnMask
+	  && key_code <= 0x7f
+	  && fn_keycode_to_keycode_table[key_code] == key_code)
+	modifiers &= ~kEventKeyModifierFnMask;
+#endif
+    }
+  else if (mapped_modifiers)
+    {
+      /* translate the keycode back to determine the original key */
+#ifdef MAC_OSX
+      UCKeyboardLayout *uchr_ptr = NULL;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      OSStatus err;
+      KeyboardLayoutRef layout;
+
+      err = KLGetCurrentKeyboardLayout (&layout);
+      if (err == noErr)
+	err = KLGetKeyboardLayoutProperty (layout, kKLuchrData,
+					   (const void **) &uchr_ptr);
+#else
+      static SInt16 last_key_layout_id = 0;
+      static Handle uchr_handle = (Handle)-1;
+      SInt16 current_key_layout_id =
+	GetScriptVariable (current_key_script, smScriptKeys);
+
+      if (uchr_handle == (Handle)-1
+	  || last_key_layout_id != current_key_layout_id)
+	{
+	  uchr_handle = GetResource ('uchr', current_key_layout_id);
+	  last_key_layout_id = current_key_layout_id;
+	}
+      if (uchr_handle)
+	uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
+#endif
+
+      if (uchr_ptr)
+	{
+	  OSStatus status;
+	  UInt16 key_action = action - keyDown;
+	  UInt32 modifier_key_state = (modifiers & ~mapped_modifiers) >> 8;
+	  UInt32 keyboard_type = LMGetKbdType ();
+	  SInt32 dead_key_state = 0;
+	  UniChar code;
+	  UniCharCount actual_length;
+
+	  status = UCKeyTranslate (uchr_ptr, key_code, key_action,
+				   modifier_key_state, keyboard_type,
+				   kUCKeyTranslateNoDeadKeysMask,
+				   &dead_key_state,
+				   1, &actual_length, &code);
+	  if (status == noErr && actual_length == 1)
+	    mac_set_unicode_keystroke_event (code, buf);
+	}
+#endif	/* MAC_OSX */
+
+      if (buf->kind == NO_EVENT)
+	{
+	  /* 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.  */
+	  /* Mask off modifier keys that are mapped to some Emacs
+	     modifiers.  */
+	  int new_modifiers = modifiers & ~mapped_modifiers;
+	  /* set high byte of keycode to modifier high byte*/
+	  int new_key_code = key_code | new_modifiers;
+	  Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+	  unsigned long some_state = 0;
+	  UInt32 new_char_code;
+
+	  new_char_code = KeyTranslate (kchr_ptr, new_key_code, &some_state);
+	  if (new_char_code == 0)
+	    /* Seems like a dead key.  Append up-stroke.  */
+	    new_char_code = KeyTranslate (kchr_ptr, new_key_code | 0x80,
+					  &some_state);
+	  if (new_char_code)
+	    {
+	      buf->kind = ASCII_KEYSTROKE_EVENT;
+	      buf->code = new_char_code & 0xff;
+	    }
+	}
+    }
+
+  if (buf->kind == NO_EVENT)
+    {
+      buf->kind = ASCII_KEYSTROKE_EVENT;
+      buf->code = char_code;
+    }
+
+  buf->modifiers = mac_to_emacs_modifiers (modifiers);
+  buf->modifiers |= (extra_keyboard_modifiers
+		     & (meta_modifier | alt_modifier
+			| hyper_modifier | super_modifier));
+
+#if TARGET_API_MAC_CARBON
+  if (buf->kind == ASCII_KEYSTROKE_EVENT
+      && buf->code >= 0x80 && buf->modifiers)
+    {
+      OSStatus err;
+      TextEncoding encoding = kTextEncodingMacRoman;
+      TextToUnicodeInfo ttu_info;
+
+      UpgradeScriptInfoToTextEncoding (current_key_script,
+				       kTextLanguageDontCare,
+				       kTextRegionDontCare,
+				       NULL, &encoding);
+      err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
+      if (err == noErr)
+	{
+	  UniChar code;
+	  Str255 pstr;
+	  ByteCount unicode_len;
+
+	  pstr[0] = 1;
+	  pstr[1] = buf->code;
+	  err = ConvertFromPStringToUnicode (ttu_info, pstr,
+					     sizeof (UniChar),
+					     &unicode_len, &code);
+	  if (err == noErr && unicode_len == sizeof (UniChar))
+	    mac_set_unicode_keystroke_event (code, buf);
+	  DisposeTextToUnicodeInfo (&ttu_info);
+	}
+    }
+#endif
+
+  if (buf->kind == ASCII_KEYSTROKE_EVENT
+      && buf->code >= 0x80
+      && last_key_script != current_key_script)
+    {
+      struct input_event event;
+
+      EVENT_INIT (event);
+      event.kind = LANGUAGE_CHANGE_EVENT;
+      event.arg = Qnil;
+      event.code = current_key_script;
+      event.timestamp = timestamp;
+      kbd_buffer_store_event (&event);
+      last_key_script = current_key_script;
+    }
+}
+
 void
 mac_store_apple_event (class, id, desc)
      Lisp_Object class, id;
@@ -9718,51 +9987,48 @@
   kbd_buffer_store_event (&buf);
 }
 
-static pascal OSStatus
-mac_handle_command_event (next_handler, event, data)
-     EventHandlerCallRef next_handler;
+#ifdef MAC_OSX
+OSStatus
+mac_store_service_event (event)
      EventRef event;
-     void *data;
-{
-  OSStatus result, err;
-  HICommand command;
-  static const EventParamName names[] =
-    {kEventParamDirectObject, kEventParamKeyModifiers};
-  static const EventParamType types[] =
-    {typeHICommand, typeUInt32};
-  int num_params = sizeof (names) / sizeof (names[0]);
-
-  result = CallNextEventHandler (next_handler, event);
-  if (result != eventNotHandledErr)
-    return result;
-
-  err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
-			   NULL, sizeof (HICommand), NULL, &command);
-
-  if (err != noErr || command.commandID == 0)
-    return eventNotHandledErr;
-
-  /* A HI command event is mapped to an Apple event whose event class
-     symbol is `hi-command' and event ID is its command ID.  */
-  err = mac_store_event_ref_as_apple_event (0, command.commandID,
-					    Qhi_command, Qnil,
-					    event, num_params, names, types);
-  return err == noErr ? noErr : eventNotHandledErr;
-}
-
-static OSStatus
-init_command_handler ()
-{
-  static const EventTypeSpec specs[] =
-    {{kEventClassCommand, kEventCommandProcess}};
-  static EventHandlerUPP handle_command_eventUPP = NULL;
-
-  if (handle_command_eventUPP == NULL)
-    handle_command_eventUPP = NewEventHandlerUPP (mac_handle_command_event);
-  return InstallApplicationEventHandler (handle_command_eventUPP,
-					 GetEventTypeCount (specs), specs,
-					 NULL, NULL);
-}
+{
+  OSStatus err;
+  Lisp_Object id_key;
+  int num_params;
+  const EventParamName *names;
+  const EventParamType *types;
+  static const EventParamName names_pfm[] =
+    {kEventParamServiceMessageName, kEventParamServiceUserData};
+  static const EventParamType types_pfm[] =
+    {typeCFStringRef, typeCFStringRef};
+
+  switch (GetEventKind (event))
+    {
+    case kEventServicePaste:
+      id_key = Qpaste;
+      num_params = 0;
+      names = NULL;
+      types = NULL;
+      break;
+
+    case kEventServicePerform:
+      id_key = Qperform;
+      num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
+      names = names_pfm;
+      types = types_pfm;
+      break;
+
+    default:
+      abort ();
+    }
+
+  err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
+					    event, num_params,
+					    names, types);
+
+  return err;
+}
+#endif	/* MAC_OSX */
 
 static pascal OSStatus
 mac_handle_window_event (next_handler, event, data)
@@ -9771,7 +10037,7 @@
      void *data;
 {
   WindowRef wp;
-  OSStatus result, err;
+  OSStatus err, result = eventNotHandledErr;
   struct frame *f;
   UInt32 attributes;
   XSizeHints *size_hints;
@@ -9784,33 +10050,64 @@
   f = mac_window_to_frame (wp);
   switch (GetEventKind (event))
     {
+      /* -- window refresh events -- */
+
     case kEventWindowUpdate:
       result = CallNextEventHandler (next_handler, event);
       if (result != eventNotHandledErr)
-	return result;
+	break;
 
       do_window_update (wp);
-      return noErr;
-
-    case kEventWindowGetIdealSize:
-      result = CallNextEventHandler (next_handler, event);
-      if (result != eventNotHandledErr)
-	return result;
-
-      {
-	Point ideal_size = mac_get_ideal_size (f);
-
-	err = SetEventParameter (event, kEventParamDimensions,
-				 typeQDPoint, sizeof (Point), &ideal_size);
-	if (err == noErr)
-	  return noErr;
-      }
+      result = noErr;
+      break;
+
+      /* -- window state change events -- */
+
+    case kEventWindowShowing:
+      size_hints = FRAME_SIZE_HINTS (f);
+      if (!(size_hints->flags & (USPosition | PPosition)))
+	{
+	  struct frame *sf = SELECTED_FRAME ();
+
+	  if (!(FRAME_MAC_P (sf)))
+	    RepositionWindow (wp, NULL, kWindowCenterOnMainScreen);
+	  else
+	    {
+	      RepositionWindow (wp, FRAME_MAC_WINDOW (sf),
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+				kWindowCascadeStartAtParentWindowScreen
+#else
+				kWindowCascadeOnParentWindowScreen
+#endif
+				);
+	    }
+	  result = noErr;
+	}
+      break;
+
+    case kEventWindowHiding:
+      /* Before unmapping the window, update the WM_SIZE_HINTS
+	 property to claim that the current position of the window is
+	 user-specified, rather than program-specified, so that when
+	 the window is mapped again, it will be placed at the same
+	 location, without forcing the user to position it by hand
+	 again (they have already done that once for this window.)  */
+      x_wm_set_size_hint (f, (long) 0, 1);
+      result = noErr;
+      break;
+
+    case kEventWindowShown:
+    case kEventWindowHidden:
+    case kEventWindowCollapsed:
+    case kEventWindowExpanded:
+      mac_handle_visibility_change (f);
+      result = noErr;
       break;
 
     case kEventWindowBoundsChanging:
       result = CallNextEventHandler (next_handler, event);
       if (result != eventNotHandledErr)
-	return result;
+	break;
 
       err = GetEventParameter (event, kEventParamAttributes, typeUInt32,
 			       NULL, sizeof (UInt32), NULL, &attributes);
@@ -9854,7 +10151,7 @@
 	  bounds.bottom = bounds.top + height;
 	  SetEventParameter (event, kEventParamCurrentBounds,
 			     typeQDRectangle, sizeof (Rect), &bounds);
-	  return noErr;
+	  result = noErr;
 	}
       break;
 
@@ -9885,21 +10182,12 @@
       if (attributes & kWindowBoundsChangeOriginChanged)
 	mac_handle_origin_change (f);
 
-      return noErr;
-
-    case kEventWindowShown:
-    case kEventWindowHidden:
-    case kEventWindowExpanded:
-    case kEventWindowCollapsed:
-      result = CallNextEventHandler (next_handler, event);
-
-      mac_handle_visibility_change (f);
-      return noErr;
-
+      result = noErr;
       break;
 
+      /* -- window action events -- */
+
     case kEventWindowClose:
-      result = CallNextEventHandler (next_handler, event);
       {
 	struct input_event buf;
 
@@ -9909,11 +10197,26 @@
 	buf.arg = Qnil;
 	kbd_buffer_store_event (&buf);
       }
-      return noErr;
+      result = noErr;
+      break;
+
+    case kEventWindowGetIdealSize:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+	break;
+
+      {
+	Point ideal_size = mac_get_ideal_size (f);
+
+	err = SetEventParameter (event, kEventParamDimensions,
+				 typeQDPoint, sizeof (Point), &ideal_size);
+	if (err == noErr)
+	  result = noErr;
+      }
+      break;
 
 #ifdef MAC_OSX
     case kEventWindowToolbarSwitchMode:
-      result = CallNextEventHandler (next_handler, event);
       {
 	static const EventParamName names[] = {kEventParamDirectObject,
 					       kEventParamWindowMouseLocation,
@@ -9935,23 +10238,195 @@
 						  event, num_params,
 						  names, types);
       }
-      return err == noErr ? noErr : result;
+      if (err == noErr)
+	result = noErr;
+      break;
 #endif
 
 #if USE_MAC_TSM
+      /* -- window focus events -- */
+
     case kEventWindowFocusAcquired:
-      result = CallNextEventHandler (next_handler, event);
       err = mac_tsm_resume ();
-      return err == noErr ? noErr : result;
+      if (err == noErr)
+	result = noErr;
+      break;
 
     case kEventWindowFocusRelinquish:
-      result = CallNextEventHandler (next_handler, event);
+      err = mac_tsm_suspend ();
+      if (err == noErr)
+	result = noErr;
+      break;
+#endif
+
+    default:
+      abort ();
+    }
+
+  return result;
+}
+
+static pascal OSStatus
+mac_handle_application_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+
+  switch (GetEventKind (event))
+    {
+#if USE_MAC_TSM
+    case kEventAppActivated:
+      err = mac_tsm_resume ();
+      break;
+
+    case kEventAppDeactivated:
       err = mac_tsm_suspend ();
-      return err == noErr ? noErr : result;
-#endif
-    }
-
-  return eventNotHandledErr;
+      break;
+#endif
+
+    default:
+      abort ();
+    }
+
+  if (err == noErr)
+    result = noErr;
+
+  return result;
+}
+
+static pascal OSStatus
+mac_handle_keyboard_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+  UInt32 event_kind, key_code, modifiers, mapped_modifiers;
+  unsigned char char_code;
+
+  event_kind = GetEventKind (event);
+  switch (event_kind)
+    {
+    case kEventRawKeyDown:
+    case kEventRawKeyRepeat:
+    case kEventRawKeyUp:
+      if (read_socket_inev == NULL)
+	{
+	  result = CallNextEventHandler (next_handler, event);
+	  break;
+	}
+
+      err = GetEventParameter (event, kEventParamKeyModifiers,
+			       typeUInt32, NULL,
+			       sizeof (UInt32), NULL, &modifiers);
+      if (err != noErr)
+	break;
+
+      mapped_modifiers = mac_mapped_modifiers (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 (!(mapped_modifiers
+	    & ~(mac_pass_command_to_system ? cmdKey : 0)
+	    & ~(mac_pass_control_to_system ? controlKey : 0)))
+	{
+	  result = CallNextEventHandler (next_handler, event);
+	  if (result != eventNotHandledErr)
+	    break;
+	}
+
+#if USE_MAC_TSM
+      if (read_socket_inev->kind != NO_EVENT)
+	{
+	  result = noErr;
+	  break;
+	}
+#endif
+
+      if (event_kind == kEventRawKeyUp)
+	break;
+
+      err = GetEventParameter (event, kEventParamKeyMacCharCodes,
+			       typeChar, NULL,
+			       sizeof (char), NULL, &char_code);
+      if (err != noErr)
+	break;
+
+      err = GetEventParameter (event, kEventParamKeyCode,
+			       typeUInt32, NULL,
+			       sizeof (UInt32), NULL, &key_code);
+      if (err != noErr)
+	break;
+
+      do_keystroke ((GetEventKind (event) == kEventRawKeyDown
+		     ? keyDown : autoKey),
+		    char_code, key_code, modifiers,
+		    ((unsigned long)
+		     (GetEventTime (event) / kEventDurationMillisecond)),
+		    read_socket_inev);
+      result = noErr;
+      break;
+
+    default:
+      abort ();
+    }
+
+  return result;
+}
+
+static pascal OSStatus
+mac_handle_command_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result = eventNotHandledErr;
+  HICommand command;
+  static const EventParamName names[] =
+    {kEventParamDirectObject, kEventParamKeyModifiers};
+  static const EventParamType types[] =
+    {typeHICommand, typeUInt32};
+  int num_params = sizeof (names) / sizeof (names[0]);
+
+  err = GetEventParameter (event, kEventParamDirectObject, typeHICommand,
+			   NULL, sizeof (HICommand), NULL, &command);
+  if (err != noErr)
+    return eventNotHandledErr;
+
+  switch (GetEventKind (event))
+    {
+    case kEventCommandProcess:
+      result = CallNextEventHandler (next_handler, event);
+      if (result != eventNotHandledErr)
+	break;
+
+      err = GetEventParameter (event, kEventParamDirectObject,
+			       typeHICommand, NULL,
+			       sizeof (HICommand), NULL, &command);
+
+      if (err != noErr || command.commandID == 0)
+	break;
+
+      /* A HI command event is mapped to an Apple event whose event
+	 class symbol is `hi-command' and event ID is its command
+	 ID.  */
+      err = mac_store_event_ref_as_apple_event (0, command.commandID,
+						Qhi_command, Qnil,
+						event, num_params,
+						names, types);
+      if (err == noErr)
+	result = noErr;
+      break;
+
+    default:
+      abort ();
+    }
+
+  return result;
 }
 
 static pascal OSStatus
@@ -9960,7 +10435,7 @@
      EventRef event;
      void *data;
 {
-  OSStatus result, err;
+  OSStatus err, result = eventNotHandledErr;
 
   switch (GetEventKind (event))
     {
@@ -9974,15 +10449,14 @@
 
 	result = CallNextEventHandler (next_handler, event);
 	if (result != eventNotHandledErr || read_socket_inev == NULL)
-	  return result;
+	  break;
+
+	f = mac_focus_frame (&one_mac_display_info);
 
 	err = GetEventParameter (event, kEventParamWindowRef, typeWindowRef,
 				 NULL, sizeof (WindowRef), NULL, &wp);
-	if (err != noErr)
-	  break;
-
-	f = mac_window_to_frame (wp);
-	if (f != mac_focus_frame (&one_mac_display_info))
+	if (err != noErr
+	    || wp != FRAME_MAC_WINDOW (f))
 	  break;
 
 	err = GetEventParameter (event, kEventParamMouseWheelAxis,
@@ -9997,8 +10471,8 @@
 	if (err != noErr)
 	  break;
 
-	SetPortWindowPort (wp);
-	GlobalToLocal (&point);
+	point.h -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f);
+	point.v -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f);
 	if (point.h < 0 || point.v < 0
 	    || EQ (window_from_coordinates (f, point.h, point.v, 0, 0, 0, 1),
 		   f->tool_bar_window))
@@ -10019,68 +10493,16 @@
 	XSETINT (read_socket_inev->y, point.v);
 	XSETFRAME (read_socket_inev->frame_or_window, f);
 
-	return noErr;
+	result = noErr;
       }
       break;
 
     default:
-      break;
-    }
-
-  return eventNotHandledErr;
-}
-
-#if USE_MAC_FONT_PANEL
-static pascal OSStatus
-mac_handle_font_event (next_handler, event, data)
-     EventHandlerCallRef next_handler;
-     EventRef event;
-     void *data;
-{
-  OSStatus result, err;
-  Lisp_Object id_key;
-  int num_params;
-  const EventParamName *names;
-  const EventParamType *types;
-  static const EventParamName names_sel[] = {kEventParamATSUFontID,
-					     kEventParamATSUFontSize,
-					     kEventParamFMFontFamily,
-					     kEventParamFMFontSize,
-					     kEventParamFontColor};
-  static const EventParamType types_sel[] = {typeATSUFontID,
-					     typeATSUSize,
-					     typeFMFontFamily,
-					     typeFMFontSize,
-					     typeFontColor};
-
-  result = CallNextEventHandler (next_handler, event);
-  if (result != eventNotHandledErr)
-    return result;
-
-  switch (GetEventKind (event))
-    {
-    case kEventFontPanelClosed:
-      id_key = Qpanel_closed;
-      num_params = 0;
-      names = NULL;
-      types = NULL;
-      break;
-
-    case kEventFontSelection:
-      id_key = Qselection;
-      num_params = sizeof (names_sel) / sizeof (names_sel[0]);
-      names = names_sel;
-      types = types_sel;
-      break;
-    }
-
-  err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
-					    event, num_params,
-					    names, types);
-
-  return err == noErr ? noErr : eventNotHandledErr;
-}
-#endif
+      abort ();
+    }
+
+  return result;
+}
 
 #if USE_MAC_TSM
 static pascal OSStatus
@@ -10137,6 +10559,8 @@
      typeUnicodeText};
 
   result = CallNextEventHandler (next_handler, event);
+  if (result != eventNotHandledErr)
+    return result;
 
   switch (GetEventKind (event))
     {
@@ -10164,7 +10588,7 @@
 				   sizeof (UInt32), NULL, &modifiers);
 	if (err == noErr && mac_mapped_modifiers (modifiers))
 	  /* There're mapped modifier keys.  Process it in
-	     XTread_socket.  */
+	     do_keystroke.  */
 	  return eventNotHandledErr;
 	if (err == noErr)
 	  err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
@@ -10179,7 +10603,7 @@
 				     sizeof (UniChar), NULL, &code);
 	    if (err == noErr && code < 0x80)
 	      {
-		/* ASCII character.  Process it in XTread_socket.  */
+		/* ASCII character.  Process it in do_keystroke.  */
 		if (read_socket_inev && code >= 0x20 && code <= 0x7e)
 		  {
 		    UInt32 key_code;
@@ -10241,11 +10665,11 @@
 	  }
 
 	p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
-	       + WINDOW_LEFT_FRINGE_WIDTH (w));
+	       + WINDOW_LEFT_FRINGE_WIDTH (w)
+	       + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
 	p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
-	       + FONT_BASE (FRAME_FONT (f)));
-	SetPortWindowPort (FRAME_MAC_WINDOW (f));
-	LocalToGlobal (&p);
+	       + FONT_BASE (FRAME_FONT (f))
+	       + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
 	err = SetEventParameter (event, kEventParamTextInputReplyPoint,
 				 typeQDPoint, sizeof (typeQDPoint), &p);
       }
@@ -10259,53 +10683,12 @@
     err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
 					      event, num_params,
 					      names, types);
-
-  return err == noErr ? noErr : result;
-}
-#endif
-
-#ifdef MAC_OSX
-OSStatus
-mac_store_service_event (event)
-     EventRef event;
-{
-  OSStatus err;
-  Lisp_Object id_key;
-  int num_params;
-  const EventParamName *names;
-  const EventParamType *types;
-  static const EventParamName names_pfm[] =
-    {kEventParamServiceMessageName, kEventParamServiceUserData};
-  static const EventParamType types_pfm[] =
-    {typeCFStringRef, typeCFStringRef};
-
-  switch (GetEventKind (event))
-    {
-    case kEventServicePaste:
-      id_key = Qpaste;
-      num_params = 0;
-      names = NULL;
-      types = NULL;
-      break;
-
-    case kEventServicePerform:
-      id_key = Qperform;
-      num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
-      names = names_pfm;
-      types = types_pfm;
-      break;
-
-    default:
-      abort ();
-    }
-
-  err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
-					    event, num_params,
-					    names, types);
-
-  return err;
-}
-#endif	/* MAC_OSX */
+  if (err == noErr)
+    result = noErr;
+
+  return result;
+}
+#endif
 #endif	/* TARGET_API_MAC_CARBON */
 
 
@@ -10314,80 +10697,48 @@
      WindowRef window;
 {
   OSStatus err = noErr;
+
 #if TARGET_API_MAC_CARBON
-  static const EventTypeSpec specs_window[] =
-    {{kEventClassWindow, kEventWindowUpdate},
-     {kEventClassWindow, kEventWindowGetIdealSize},
-     {kEventClassWindow, kEventWindowBoundsChanging},
-     {kEventClassWindow, kEventWindowBoundsChanged},
-     {kEventClassWindow, kEventWindowShown},
-     {kEventClassWindow, kEventWindowHidden},
-     {kEventClassWindow, kEventWindowExpanded},
-     {kEventClassWindow, kEventWindowCollapsed},
-     {kEventClassWindow, kEventWindowClose},
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+	{
+	  /* -- window refresh events -- */
+	  {kEventClassWindow, kEventWindowUpdate},
+	  /* -- window state change events -- */
+	  {kEventClassWindow, kEventWindowShowing},
+	  {kEventClassWindow, kEventWindowHiding},
+	  {kEventClassWindow, kEventWindowShown},
+	  {kEventClassWindow, kEventWindowHidden},
+	  {kEventClassWindow, kEventWindowCollapsed},
+	  {kEventClassWindow, kEventWindowExpanded},
+	  {kEventClassWindow, kEventWindowBoundsChanging},
+	  {kEventClassWindow, kEventWindowBoundsChanged},
+	  /* -- window action events -- */
+	  {kEventClassWindow, kEventWindowClose},
+	  {kEventClassWindow, kEventWindowGetIdealSize},
 #ifdef MAC_OSX
-     {kEventClassWindow, kEventWindowToolbarSwitchMode},
-#endif
-#if USE_MAC_TSM
-     {kEventClassWindow, kEventWindowFocusAcquired},
-     {kEventClassWindow, kEventWindowFocusRelinquish},
-#endif
-  };
-  static const EventTypeSpec specs_mouse[] =
-    {{kEventClassMouse, kEventMouseWheelMoved}};
-  static EventHandlerUPP handle_window_eventUPP = NULL;
-  static EventHandlerUPP handle_mouse_eventUPP = NULL;
-#if USE_MAC_FONT_PANEL
-  static const EventTypeSpec specs_font[] =
-    {{kEventClassFont, kEventFontPanelClosed},
-     {kEventClassFont, kEventFontSelection}};
-  static EventHandlerUPP handle_font_eventUPP = NULL;
+	  {kEventClassWindow, kEventWindowToolbarSwitchMode},
 #endif
 #if USE_MAC_TSM
-  static const EventTypeSpec specs_text_input[] =
-    {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
-     {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
-     {kEventClassTextInput, kEventTextInputOffsetToPos}};
-  static EventHandlerUPP handle_text_input_eventUPP = NULL;
-#endif
-
-  if (handle_window_eventUPP == NULL)
-    handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
-  if (handle_mouse_eventUPP == NULL)
-    handle_mouse_eventUPP = NewEventHandlerUPP (mac_handle_mouse_event);
-#if USE_MAC_FONT_PANEL
-  if (handle_font_eventUPP == NULL)
-    handle_font_eventUPP = NewEventHandlerUPP (mac_handle_font_event);
-#endif
-#if USE_MAC_TSM
-  if (handle_text_input_eventUPP == NULL)
-    handle_text_input_eventUPP =
-      NewEventHandlerUPP (mac_handle_text_input_event);
-#endif
-  err = InstallWindowEventHandler (window, handle_window_eventUPP,
-				   GetEventTypeCount (specs_window),
-				   specs_window, NULL, NULL);
-  if (err == noErr)
-    err = InstallWindowEventHandler (window, handle_mouse_eventUPP,
-				     GetEventTypeCount (specs_mouse),
-				     specs_mouse, NULL, NULL);
-#if USE_MAC_FONT_PANEL
-  if (err == noErr)
-    err = InstallWindowEventHandler (window, handle_font_eventUPP,
-				     GetEventTypeCount (specs_font),
-				     specs_font, NULL, NULL);
-#endif
-#if USE_MAC_TSM
-  if (err == noErr)
-    err = InstallWindowEventHandler (window, handle_text_input_eventUPP,
-				     GetEventTypeCount (specs_text_input),
-				     specs_text_input, window, NULL);
-#endif
-#endif
+	  /* -- window focus events -- */
+	  {kEventClassWindow, kEventWindowFocusAcquired},
+	  {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
+	};
+      static EventHandlerUPP handle_window_eventUPP = NULL;
+
+      if (handle_window_eventUPP == NULL)
+	handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
+
+      err = InstallWindowEventHandler (window, handle_window_eventUPP,
+				       GetEventTypeCount (specs),
+				       specs, NULL, NULL);
+    }
+#endif
+
   if (err == noErr)
     err = install_drag_handler (window);
-  if (err == noErr)
-    err = install_menu_target_item_handler (window);
 
   return err;
 }
@@ -10399,6 +10750,88 @@
   remove_drag_handler (window);
 }
 
+#if TARGET_API_MAC_CARBON
+static OSStatus
+install_application_handler ()
+{
+  OSStatus err = noErr;
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] = {
+#if USE_MAC_TSM
+	{kEventClassApplication, kEventAppActivated},
+	{kEventClassApplication, kEventAppDeactivated},
+#endif
+      };
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+					    (mac_handle_application_event),
+					    GetEventTypeCount (specs),
+					    specs, NULL, NULL);
+    }
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+	{{kEventClassKeyboard, kEventRawKeyDown},
+	 {kEventClassKeyboard, kEventRawKeyRepeat},
+	 {kEventClassKeyboard, kEventRawKeyUp}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+					    (mac_handle_keyboard_event),
+					    GetEventTypeCount (specs),
+					    specs, NULL, NULL);
+    }
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+	{{kEventClassCommand, kEventCommandProcess}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+					    (mac_handle_command_event),
+					    GetEventTypeCount (specs),
+					    specs, NULL, NULL);
+    }
+
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+	{{kEventClassMouse, kEventMouseWheelMoved}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+					    (mac_handle_mouse_event),
+					    GetEventTypeCount (specs),
+					    specs, NULL, NULL);
+    }
+
+#if USE_MAC_TSM
+  if (err == noErr)
+    {
+      static const EventTypeSpec spec[] =
+	{{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
+	 {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
+	 {kEventClassTextInput, kEventTextInputOffsetToPos}};
+
+      err = InstallApplicationEventHandler (NewEventHandlerUPP
+					    (mac_handle_text_input_event),
+					    GetEventTypeCount (spec),
+					    spec, NULL, NULL);
+    }
+#endif
+
+  if (err == noErr)
+    err = install_menu_target_item_handler ();
+
+#ifdef MAC_OSX
+  if (err == noErr)
+    err = install_service_handler ();
+#endif
+
+  return err;
+}
+#endif
 
 static pascal void
 mac_handle_dm_notification (event)
@@ -10407,20 +10840,48 @@
   mac_screen_config_changed = 1;
 }
 
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static void
+mac_handle_cg_display_reconfig (display, flags, user_info)
+     CGDirectDisplayID display;
+     CGDisplayChangeSummaryFlags flags;
+     void *user_info;
+{
+  mac_screen_config_changed = 1;
+}
+#endif
+
 static OSErr
 init_dm_notification_handler ()
 {
-  OSErr err;
-  static DMNotificationUPP handle_dm_notificationUPP = NULL;
-  ProcessSerialNumber psn;
-
-  if (handle_dm_notificationUPP == NULL)
-    handle_dm_notificationUPP =
-      NewDMNotificationUPP (mac_handle_dm_notification);
-
-  err = GetCurrentProcess (&psn);
-  if (err == noErr)
-    err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
+  OSErr err = noErr;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  if (CGDisplayRegisterReconfigurationCallback != NULL)
+#endif
+    {
+      CGDisplayRegisterReconfigurationCallback (mac_handle_cg_display_reconfig,
+						NULL);
+    }
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+  else		/* CGDisplayRegisterReconfigurationCallback == NULL */
+#endif
+#endif	/* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+    {
+      static DMNotificationUPP handle_dm_notificationUPP = NULL;
+      ProcessSerialNumber psn;
+
+      if (handle_dm_notificationUPP == NULL)
+	handle_dm_notificationUPP =
+	  NewDMNotificationUPP (mac_handle_dm_notification);
+
+      err = GetCurrentProcess (&psn);
+      if (err == noErr)
+	err = DMRegisterNotifyProc (handle_dm_notificationUPP, &psn);
+    }
+#endif
 
   return err;
 }
@@ -10636,44 +11097,6 @@
 
   return err;
 }
-
-static void
-mac_set_unicode_keystroke_event (code, buf)
-     UniChar code;
-     struct input_event *buf;
-{
-  int charset_id, c1, c2;
-
-  if (code < 0x80)
-    {
-      buf->kind = ASCII_KEYSTROKE_EVENT;
-      buf->code = code;
-    }
-  else if (code < 0x100)
-    {
-      if (code < 0xA0)
-	charset_id = CHARSET_8_BIT_CONTROL;
-      else
-	charset_id = charset_latin_iso8859_1;
-      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
-      buf->code = MAKE_CHAR (charset_id, code, 0);
-    }
-  else
-    {
-      if (code < 0x2500)
-	charset_id = charset_mule_unicode_0100_24ff,
-	  code -= 0x100;
-      else if (code < 0x33FF)
-	charset_id = charset_mule_unicode_2500_33ff,
-	  code -= 0x2500;
-      else if (code >= 0xE000)
-	charset_id = charset_mule_unicode_e000_ffff,
-	  code -= 0xE000;
-      c1 = (code / 96) + 32, c2 = (code % 96) + 32;
-      buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
-      buf->code = MAKE_CHAR (charset_id, c1, c2);
-    }
-}
 #endif
 
 /* Emacs calls this whenever it wants to read an input event from the
@@ -10729,28 +11152,13 @@
 
 #if TARGET_API_MAC_CARBON
       timestamp = GetEventTime (eventRef) / kEventDurationMillisecond;
-#else
-      timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-#endif
-
-#if TARGET_API_MAC_CARBON
-      /* Handle new events */
+
       if (!mac_convert_event_ref (eventRef, &er))
-	{
-	  /* There used to be a handler for the kEventMouseWheelMoved
-	     event here.  But as of Mac OS X 10.4, this kind of event
-	     is not directly posted to the main event queue by
-	     two-finger scrolling on the trackpad.  Instead, some
-	     private event is posted and it is converted to a wheel
-	     event by the default handler for the application target.
-	     The converted one can be received by a Carbon event
-	     handler installed on a window target.  */
-	  read_socket_inev = &inev;
-	  SendEventToEventTarget (eventRef, toolbox_dispatcher);
-	  read_socket_inev = NULL;
-	}
-      else
-#endif /* TARGET_API_MAC_CARBON */
+	goto OTHER;
+#else  /* !TARGET_API_MAC_CARBON */
+      timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
+#endif  /* !TARGET_API_MAC_CARBON */
+
       switch (er.what)
 	{
 	case mouseDown:
@@ -10761,10 +11169,14 @@
 	    int tool_bar_p = 0;
 
 #if TARGET_API_MAC_CARBON
+	    OSStatus err;
+
 	    /* This is needed to send mouse events like aqua window
 	       buttons to the correct handler.  */
-	    if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-		!= eventNotHandledErr)
+	    read_socket_inev = &inev;
+	    err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+	    read_socket_inev = NULL;
+	    if (err != eventNotHandledErr)
 	      break;
 #endif
 	    last_mouse_glyph_frame = 0;
@@ -10813,16 +11225,19 @@
 		  {
 		    ControlPartCode control_part_code;
 		    ControlRef ch;
-		    Point mouse_loc = er.where;
+		    Point mouse_loc;
 #ifdef MAC_OSX
 		    ControlKind control_kind;
 #endif
 
 		    f = mac_window_to_frame (window_ptr);
 		    /* convert to local coordinates of new window */
-		    SetPortWindowPort (window_ptr);
-
-		    GlobalToLocal (&mouse_loc);
+		    mouse_loc.h = (er.where.h
+				   - (f->left_pos
+				      + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+		    mouse_loc.v = (er.where.v
+				   - (f->top_pos
+				      + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
 #if TARGET_API_MAC_CARBON
 		    ch = FindControlUnderMouse (mouse_loc, window_ptr,
 						&control_part_code);
@@ -11008,33 +11423,15 @@
 	  }
 	  break;
 
+#if !TARGET_API_MAC_CARBON
 	case updateEvt:
-#if TARGET_API_MAC_CARBON
-	  if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-	      != eventNotHandledErr)
-	    break;
-#else
 	  do_window_update ((WindowRef) er.message);
-#endif
 	  break;
+#endif
 
 	case osEvt:
-#if TARGET_API_MAC_CARBON
-	  if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-	      != eventNotHandledErr)
-	    break;
-#endif
 	  switch ((er.message >> 24) & 0x000000FF)
 	    {
-	    case suspendResumeMessage:
-#if USE_MAC_TSM
-	      if (er.message & resumeFlag)
-		mac_tsm_resume ();
-	      else
-		mac_tsm_suspend ();
-#endif
-	      break;
-
 	    case mouseMovedMessage:
 #if !TARGET_API_MAC_CARBON
 	      SetRectRgn (mouse_region, er.where.h, er.where.v,
@@ -11058,12 +11455,14 @@
 	      if (f)
 		{
 		  WindowRef wp = FRAME_MAC_WINDOW (f);
-		  Point mouse_pos = er.where;
-
-		  SetPortWindowPort (wp);
-
-		  GlobalToLocal (&mouse_pos);
-
+		  Point mouse_pos;
+
+		  mouse_pos.h = (er.where.h
+				 - (f->left_pos
+				    + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+		  mouse_pos.v = (er.where.v
+				 - (f->top_pos
+				    + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
 		  if (dpyinfo->grabbed && tracked_scroll_bar)
 #ifdef USE_TOOLKIT_SCROLL_BARS
 		    x_scroll_bar_handle_drag (wp, tracked_scroll_bar,
@@ -11111,6 +11510,9 @@
 	      if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
 		do_help = 1;
 	      break;
+
+	    default:
+	      goto OTHER;
 	    }
 	  break;
 
@@ -11118,11 +11520,6 @@
 	  {
 	    WindowRef window_ptr = (WindowRef) er.message;
 
-#if TARGET_API_MAC_CARBON
-	    if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
-		!= eventNotHandledErr)
-	      break;
-#endif
 	    if (window_ptr == tip_window)
 	      {
 		HideWindow (tip_window);
@@ -11130,21 +11527,26 @@
 	      }
 
 	    if (!is_emacs_window (window_ptr))
-	      break;
+	      goto OTHER;
+
+	    f = mac_window_to_frame (window_ptr);
 
 	    if ((er.modifiers & activeFlag) != 0)
 	      {
 		/* A window has been activated */
-		Point mouse_loc = er.where;
+		Point mouse_loc;
 
 		x_detect_focus_change (dpyinfo, &er, &inev);
 
-		SetPortWindowPort (window_ptr);
-		GlobalToLocal (&mouse_loc);
+		mouse_loc.h = (er.where.h
+			       - (f->left_pos
+				  + FRAME_OUTER_TO_INNER_DIFF_X (f)));
+		mouse_loc.v = (er.where.v
+			       - (f->top_pos
+				  + FRAME_OUTER_TO_INNER_DIFF_Y (f)));
 		/* Window-activated event counts as mouse movement,
 		   so update things that depend on mouse position.  */
-		note_mouse_movement (mac_window_to_frame (window_ptr),
-				     &mouse_loc);
+		note_mouse_movement (f, &mouse_loc);
 	      }
 	    else
 	      {
@@ -11169,7 +11571,6 @@
 
 		x_detect_focus_change (dpyinfo, &er, &inev);
 
-		f = mac_window_to_frame (window_ptr);
 		if (f == dpyinfo->mouse_face_mouse_frame)
 		  {
 		    /* If we move outside the frame, then we're
@@ -11192,218 +11593,26 @@
 	case keyDown:
 	case keyUp:
 	case autoKey:
-	  {
-	    int keycode = (er.message & keyCodeMask) >> 8;
-	    static SInt16 last_key_script = -1;
-	    SInt16 current_key_script;
-	    UInt32 modifiers = er.modifiers, mapped_modifiers;
-
-#ifdef MAC_OSX
-	    GetEventParameter (eventRef, kEventParamKeyModifiers,
-			       typeUInt32, NULL,
-			       sizeof (UInt32), NULL, &modifiers);
-#endif
-	    mapped_modifiers = mac_mapped_modifiers (modifiers);
-
-#if defined (MAC_OSX) || USE_MAC_TSM
-	    /* 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 (!(mapped_modifiers
-		  & ~(mac_pass_command_to_system ? cmdKey : 0)
-		  & ~(mac_pass_control_to_system ? controlKey : 0)))
-	      {
-		OSStatus err;
-
-		read_socket_inev = &inev;
-		err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
-		read_socket_inev = NULL;
-		if (err != eventNotHandledErr)
-		  break;
-	      }
-#endif
-	    if (er.what == keyUp)
-	      break;
-
-	    ObscureCursor ();
-
-	    f = mac_focus_frame (dpyinfo);
-
-	    if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
-		&& !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
-	      {
-		clear_mouse_face (dpyinfo);
-		dpyinfo->mouse_face_hidden = 1;
-	      }
-
-	    current_key_script = GetScriptManagerVariable (smKeyScript);
-	    if (last_key_script != current_key_script)
-	      {
-		struct input_event event;
-
-		EVENT_INIT (event);
-		event.kind = LANGUAGE_CHANGE_EVENT;
-		event.arg = Qnil;
-		event.code = current_key_script;
-		event.timestamp = timestamp;
-		kbd_buffer_store_event (&event);
-		count++;
-		last_key_script = current_key_script;
-	      }
-
-#if USE_MAC_TSM
-	    if (inev.kind != NO_EVENT)
-	      break;
-#endif
-
-#ifdef MAC_OSX
-	    if (mapped_modifiers & kEventKeyModifierFnMask
-		&& keycode <= 0x7f
-		&& fn_keycode_to_keycode_table[keycode])
-	      keycode = fn_keycode_to_keycode_table[keycode];
-#endif
-	    if (keycode <= 0x7f && keycode_to_xkeysym_table [keycode])
-	      {
-		inev.kind = NON_ASCII_KEYSTROKE_EVENT;
-		inev.code = 0xff00 | keycode_to_xkeysym_table [keycode];
-#ifdef MAC_OSX
-		if (modifiers & kEventKeyModifierFnMask
-		    && keycode <= 0x7f
-		    && fn_keycode_to_keycode_table[keycode] == keycode)
-		  modifiers &= ~kEventKeyModifierFnMask;
-#endif
-	      }
-	    else if (mapped_modifiers)
-	      {
-		/* translate the keycode back to determine the
-		   original key */
-#ifdef MAC_OSX
-		UCKeyboardLayout *uchr_ptr = NULL;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
-		OSStatus err;
-		KeyboardLayoutRef layout;
-
-		err = KLGetCurrentKeyboardLayout (&layout);
-		if (err == noErr)
-		  KLGetKeyboardLayoutProperty (layout, kKLuchrData,
-					       (const void **) &uchr_ptr);
+	  ObscureCursor ();
+
+	  f = mac_focus_frame (dpyinfo);
+	  XSETFRAME (inev.frame_or_window, f);
+
+	  /* If mouse-highlight is an integer, input clears out mouse
+	     highlighting.  */
+	  if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+	      && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+	    {
+	      clear_mouse_face (dpyinfo);
+	      dpyinfo->mouse_face_hidden = 1;
+	    }
+#if TARGET_API_MAC_CARBON
+	  goto OTHER;
 #else
-		static SInt16 last_key_layout_id = 0;
-		static Handle uchr_handle = (Handle)-1;
-		SInt16 current_key_layout_id =
-		  GetScriptVariable (current_key_script, smScriptKeys);
-
-		if (uchr_handle == (Handle)-1
-		    || last_key_layout_id != current_key_layout_id)
-		  {
-		    uchr_handle = GetResource ('uchr', current_key_layout_id);
-		    last_key_layout_id = current_key_layout_id;
-		  }
-		if (uchr_handle)
-		  uchr_ptr = (UCKeyboardLayout *)*uchr_handle;
-#endif
-
-		if (uchr_ptr)
-		  {
-		    OSStatus status;
-		    UInt16 key_action = er.what - keyDown;
-		    UInt32 modifier_key_state =
-		      (modifiers & ~mapped_modifiers) >> 8;
-		    UInt32 keyboard_type = LMGetKbdType ();
-		    SInt32 dead_key_state = 0;
-		    UniChar code;
-		    UniCharCount actual_length;
-
-		    status = UCKeyTranslate (uchr_ptr,
-					     keycode, key_action,
-					     modifier_key_state,
-					     keyboard_type,
-					     kUCKeyTranslateNoDeadKeysMask,
-					     &dead_key_state,
-					     1, &actual_length, &code);
-		    if (status == noErr && actual_length == 1)
-		      mac_set_unicode_keystroke_event (code, &inev);
-		  }
-#endif	/* MAC_OSX */
-
-		if (inev.kind == NO_EVENT)
-		  {
-		    /* 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.  */
-		    /* Mask off modifier keys that are mapped to some
-		       Emacs modifiers.  */
-		    int new_modifiers = er.modifiers & ~mapped_modifiers;
-		    /* set high byte of keycode to modifier high byte*/
-		    int new_keycode = keycode | new_modifiers;
-		    Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
-		    unsigned long some_state = 0;
-		    UInt32 new_char_code;
-
-		    new_char_code = KeyTranslate (kchr_ptr, new_keycode,
-						  &some_state);
-		    if (new_char_code == 0)
-		      /* Seems like a dead key.  Append up-stroke.  */
-		      new_char_code = KeyTranslate (kchr_ptr,
-						    new_keycode | 0x80,
-						    &some_state);
-		    if (new_char_code)
-		      {
-			inev.kind = ASCII_KEYSTROKE_EVENT;
-			inev.code = new_char_code & 0xff;
-		      }
-		  }
-	      }
-
-	    if (inev.kind == NO_EVENT)
-	      {
-		inev.kind = ASCII_KEYSTROKE_EVENT;
-		inev.code = er.message & charCodeMask;
-	      }
-
-	    inev.modifiers = mac_to_emacs_modifiers (modifiers);
-	    inev.modifiers |= (extra_keyboard_modifiers
-			       & (meta_modifier | alt_modifier
-				  | hyper_modifier | super_modifier));
-	    XSETFRAME (inev.frame_or_window, f);
-
-#if TARGET_API_MAC_CARBON
-	    if (inev.kind == ASCII_KEYSTROKE_EVENT
-		&& inev.code >= 0x80 && inev.modifiers)
-	      {
-		OSStatus err;
-		TextEncoding encoding = kTextEncodingMacRoman;
-		TextToUnicodeInfo ttu_info;
-
-		UpgradeScriptInfoToTextEncoding (current_key_script,
-						 kTextLanguageDontCare,
-						 kTextRegionDontCare,
-						 NULL, &encoding);
-		err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
-		if (err == noErr)
-		  {
-		    UniChar code;
-		    Str255 pstr;
-		    ByteCount unicode_len;
-
-		    pstr[0] = 1;
-		    pstr[1] = inev.code;
-		    err = ConvertFromPStringToUnicode (ttu_info, pstr,
-						       sizeof (UniChar),
-						       &unicode_len, &code);
-		    if (err == noErr && unicode_len == sizeof (UniChar))
-		      mac_set_unicode_keystroke_event (code, &inev);
-		    DisposeTextToUnicodeInfo (&ttu_info);
-		  }
-	      }
-#endif
-	  }
+	  do_keystroke (er.what, er.message & charCodeMask,
+			(er.message & keyCodeMask) >> 8,
+			er.modifiers, timestamp, &inev);
+#endif
 	  break;
 
 	case kHighLevelEvent:
@@ -11411,6 +11620,16 @@
 	  break;
 
 	default:
+	OTHER:
+#if TARGET_API_MAC_CARBON
+	  {
+	    OSStatus err;
+
+	    read_socket_inev = &inev;
+	    err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+	    read_socket_inev = NULL;
+	  }
+#endif
 	  break;
 	}
 #if TARGET_API_MAC_CARBON
@@ -11880,11 +12099,7 @@
 
 #if TARGET_API_MAC_CARBON
 
-#ifdef MAC_OSX
-  init_service_handler ();
-#endif	/* MAC_OSX */
-
-  init_command_handler ();
+  install_application_handler ();
 
   init_menu_bar ();