changeset 94307:df6f9d73861f

Merge from emacs--rel--22 Revision: emacs@sv.gnu.org/emacs--devo--0--patch-1126
author Miles Bader <miles@gnu.org>
date Thu, 24 Apr 2008 05:11:07 +0000
parents efca1113a630 (current diff) 1e3a4955a638 (diff)
children 1fde10271cb7
files lisp/ChangeLog lisp/term/mac-win.el src/ChangeLog src/macterm.c src/xdisp.c
diffstat 6 files changed, 626 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Thu Apr 24 04:30:42 2008 +0000
+++ b/lisp/ChangeLog	Thu Apr 24 05:11:07 2008 +0000
@@ -1,3 +1,7 @@
+2008-04-24  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* term/mac-win.el (mac-ts-active-input-buf): Move defvar to macterm.c.
+
 2008-04-24  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* emacs-lisp/easymenu.el (easy-menu-make-symbol): Don't wrap keyboard
--- a/lisp/term/mac-win.el	Thu Apr 24 04:30:42 2008 +0000
+++ b/lisp/term/mac-win.el	Thu Apr 24 05:11:07 2008 +0000
@@ -83,6 +83,7 @@
 (defvar mac-apple-event-map)
 (defvar mac-font-panel-mode)
 (defvar mac-ts-active-input-overlay)
+(defvar mac-ts-active-input-buf)
 (defvar x-invocation-args)
 (declare-function mac-code-convert-string "mac.c")
 (declare-function mac-coerce-ae-data "mac.c")
@@ -1926,8 +1927,6 @@
 ) ;; (fboundp 'mac-set-font-panel-visible-p)
 
 ;;; Text Services
-(defvar mac-ts-active-input-buf ""
-  "Byte sequence of the current Mac TSM active input area.")
 (defvar mac-ts-update-active-input-area-seqno 0
   "Number of processed update-active-input-area events.")
 (setq mac-ts-active-input-overlay (make-overlay 0 0))
--- a/src/ChangeLog	Thu Apr 24 04:30:42 2008 +0000
+++ b/src/ChangeLog	Thu Apr 24 05:11:07 2008 +0000
@@ -1,3 +1,32 @@
+2008-04-23  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* macterm.c (Vmac_ts_active_input_buf) [USE_MAC_TSM]: New variable.
+	(syms_of_macterm) [USE_MAC_TSM]: Defvar it.
+	(Qmouse_drag_overlay) [MAC_OSX]: New variable.
+	(syms_of_macterm) [MAC_OSX]: Intern and staticpro it.
+	(mac_get_selected_range, mac_store_buffer_text_to_unicode_chars)
+	(mac_ax_selected_text_range) [MAC_OSX]: New functions.
+	(mac_ax_number_of_characters) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+	Likewise.
+
+	* mactoolbox.c (Vmac_ts_active_input_buf) [USE_MAC_TSM]: Add extern.
+	(fast_find_position, x_y_to_hpos_vpos, mac_ax_selected_text_range):
+	(mac_ax_number_of_characters): Add externs.
+	(mac_get_selected_range, mac_store_buffer_text_to_unicode_chars)
+	[USE_MAC_TSM]: Likewise.
+	(mac_handle_text_input_event) [MAC_OSX]:
+	Handle kEventTextInputOffsetToPos for no active input area case.
+	Handle kEventTextInputPosToOffset and kEventTextInputGetSelectedText.
+	(mac_handle_document_access_event)
+	[MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: New function.
+	(install_application_handler) [MAC_OSX]: Register handlers for
+	kEventTextInputPosToOffset and kEventTextInputGetSelectedText.
+	(install_application_handler) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]:
+	Register mac_handle_document_access_event.
+
+	* xdisp.c (x_y_to_hpos_vpos, fast_find_position) [HAVE_CARBON]:
+	Make functions non-static.
+
 2008-04-23  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* fileio.c (Vread_file_name_function, Vread_file_name_predicate)
--- a/src/macterm.c	Thu Apr 24 04:30:42 2008 +0000
+++ b/src/macterm.c	Thu Apr 24 05:11:07 2008 +0000
@@ -9647,9 +9647,9 @@
 #endif
 #if USE_MAC_TSM
 static TSMDocumentID tsm_document_id;
-static Lisp_Object Qtext_input;
-static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
-static Lisp_Object Vmac_ts_active_input_overlay;
+Lisp_Object Qtext_input;
+Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
+Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf;
 extern Lisp_Object Qbefore_string;
 static Lisp_Object Vmac_ts_script_language_on_focus;
 static Lisp_Object saved_ts_script_language_on_focus;
@@ -9675,7 +9675,8 @@
 
 #ifdef MAC_OSX
 extern OSStatus install_service_handler ();
-static Lisp_Object Qservice, Qpaste, Qperform;
+Lisp_Object Qservice, Qpaste, Qperform;
+Lisp_Object Qmouse_drag_overlay;
 #endif
 #endif
 
@@ -9838,6 +9839,216 @@
   return result;
 }
 
+#ifdef MAC_OSX
+void
+mac_get_selected_range (w, range)
+     struct window *w;
+     CFRange *range;
+{
+  Lisp_Object overlay = find_symbol_value (Qmouse_drag_overlay);
+  struct buffer *b = XBUFFER (w->buffer);
+  int begv = BUF_BEGV (b), zv = BUF_ZV (b);
+  int start, end;
+
+  if (OVERLAYP (overlay)
+      && EQ (Foverlay_buffer (overlay), w->buffer)
+      && (start = XINT (Foverlay_start (overlay)),
+	  end = XINT (Foverlay_end (overlay)),
+	  start != end))
+    ;
+  else
+    {
+      if (w == XWINDOW (selected_window) && b == current_buffer)
+	start = PT;
+      else
+	start = marker_position (w->pointm);
+
+      if (NILP (Vtransient_mark_mode) || NILP (b->mark_active))
+	end = start;
+      else
+	{
+	  int mark_pos = marker_position (b->mark);
+
+	  if (start <= mark_pos)
+	    end = mark_pos;
+	  else
+	    {
+	      end = start;
+	      start = mark_pos;
+	    }
+	}
+    }
+
+  if (start != end)
+    {
+      if (start < begv)
+	start = begv;
+      else if (start > zv)
+	start = zv;
+
+      if (end < begv)
+	end = begv;
+      else if (end > zv)
+	end = zv;
+    }
+
+  range->location = start - begv;
+  range->length = end - start;
+}
+
+/* Store the text of the buffer BUF from START to END as Unicode
+   characters in CHARACTERS.  Return non-zero if successful.  */
+
+int
+mac_store_buffer_text_to_unicode_chars (buf, start, end, characters)
+     struct buffer *buf;
+     int start, end;
+     UniChar *characters;
+{
+  int start_byte, end_byte, char_count, byte_count;
+  struct coding_system coding;
+  unsigned char *dst = (unsigned char *) characters;
+
+  start_byte = buf_charpos_to_bytepos (buf, start);
+  end_byte = buf_charpos_to_bytepos (buf, end);
+  char_count = end - start;
+  byte_count = end_byte - start_byte;
+
+  if (setup_coding_system (
+#ifdef WORDS_BIG_ENDIAN
+			   intern ("utf-16be")
+#else
+			   intern ("utf-16le")
+#endif
+			   , &coding) < 0)
+    return 0;
+
+  coding.src_multibyte = !NILP (buf->enable_multibyte_characters);
+  coding.dst_multibyte = 0;
+  coding.mode |= CODING_MODE_LAST_BLOCK;
+  coding.composing = COMPOSITION_DISABLED;
+
+  if (BUF_GPT_BYTE (buf) <= start_byte || end_byte <= BUF_GPT_BYTE (buf))
+    encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst,
+		   byte_count, char_count * sizeof (UniChar));
+  else
+    {
+      int first_byte_count = BUF_GPT_BYTE (buf) - start_byte;
+
+      encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst,
+		     first_byte_count, char_count * sizeof (UniChar));
+      if (coding.result == CODING_FINISH_NORMAL)
+	encode_coding (&coding,
+		       BUF_BYTE_ADDRESS (buf, start_byte + first_byte_count),
+		       dst + coding.produced,
+		       byte_count - first_byte_count,
+		       char_count * sizeof (UniChar) - coding.produced);
+    }
+
+  if (coding.result != CODING_FINISH_NORMAL)
+    return 0;
+
+  return 1;
+}
+
+void
+mac_ax_selected_text_range (f, range)
+     struct frame *f;
+     CFRange *range;
+{
+  mac_get_selected_range (XWINDOW (f->selected_window), range);
+}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+unsigned int
+mac_ax_number_of_characters (f)
+     struct frame *f;
+{
+  struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer);
+
+  return BUF_ZV (b) - BUF_BEGV (b);
+}
+#endif
+#endif
+
+#if USE_MAC_TSM
+OSStatus
+mac_restore_keyboard_input_source ()
+{
+  OSStatus err = noErr;
+  ScriptLanguageRecord slrec, *slptr = NULL;
+
+  if (EQ (Vmac_ts_script_language_on_focus, Qt)
+      && EQ (saved_ts_script_language_on_focus, Qt))
+    slptr = &saved_ts_language;
+  else if (CONSP (Vmac_ts_script_language_on_focus)
+	   && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+	   && INTEGERP (XCDR (Vmac_ts_script_language_on_focus))
+	   && CONSP (saved_ts_script_language_on_focus)
+	   && EQ (XCAR (saved_ts_script_language_on_focus),
+		  XCAR (Vmac_ts_script_language_on_focus))
+	   && EQ (XCDR (saved_ts_script_language_on_focus),
+		  XCDR (Vmac_ts_script_language_on_focus)))
+    {
+      slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+      slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+      slptr = &slrec;
+    }
+
+  if (slptr)
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      err = SetDefaultInputMethodOfClass (saved_ts_component, slptr,
+					  kKeyboardInputMethodClass);
+#else
+      err = SetDefaultInputMethod (saved_ts_component, slptr);
+#endif
+      if (err == noErr)
+	err = SetTextServiceLanguage (slptr);
+
+      /* Seems to be needed on Mac OS X 10.2.  */
+      if (err == noErr)
+	KeyScript (slptr->fScript | smKeyForceKeyScriptMask);
+    }
+
+  return err;
+}
+
+void
+mac_save_keyboard_input_source ()
+{
+  OSStatus err;
+  ScriptLanguageRecord slrec, *slptr = NULL;
+
+  saved_ts_script_language_on_focus = Vmac_ts_script_language_on_focus;
+
+  if (EQ (Vmac_ts_script_language_on_focus, Qt))
+    {
+      err = GetTextServiceLanguage (&saved_ts_language);
+      if (err == noErr)
+	slptr = &saved_ts_language;
+    }
+  else if (CONSP (Vmac_ts_script_language_on_focus)
+	   && INTEGERP (XCAR (Vmac_ts_script_language_on_focus))
+	   && INTEGERP (XCDR (Vmac_ts_script_language_on_focus)))
+    {
+      slrec.fScript = XINT (XCAR (Vmac_ts_script_language_on_focus));
+      slrec.fLanguage = XINT (XCDR (Vmac_ts_script_language_on_focus));
+      slptr = &slrec;
+    }
+
+  if (slptr)
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
+      GetDefaultInputMethodOfClass (&saved_ts_component, slptr,
+				    kKeyboardInputMethodClass);
+#else
+      GetDefaultInputMethod (&saved_ts_component, slptr);
+#endif
+    }
+}
+#endif
+
 #if TARGET_API_MAC_CARBON
 /***** Code to handle C-g testing  *****/
 extern int quit_char;
@@ -12982,6 +13193,9 @@
   Qservice     = intern ("service");	  staticpro (&Qservice);
   Qpaste       = intern ("paste");	  staticpro (&Qpaste);
   Qperform     = intern ("perform");	  staticpro (&Qperform);
+
+  Qmouse_drag_overlay = intern ("mouse-drag-overlay");
+  staticpro (&Qmouse_drag_overlay);
 #endif
 #if USE_MAC_TSM
   Qtext_input = intern ("text-input");	staticpro (&Qtext_input);
@@ -13142,6 +13356,11 @@
     doc: /* Overlay used to display Mac TSM active input area.  */);
   Vmac_ts_active_input_overlay = Qnil;
 
+  DEFVAR_LISP ("mac-ts-active-input-buf", &Vmac_ts_active_input_buf,
+    doc: /* Byte sequence of the current Mac TSM active input area.  */);
+  /* `empty_string' is not ready yet on Mac OS Classic.  */
+  Vmac_ts_active_input_buf = build_string ("");
+
   DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus,
     doc: /* *How to change Mac TSM script/language when a frame gets focus.
 If the value is t, the input script and language are restored to those
--- a/src/mactoolbox.c	Thu Apr 24 04:30:42 2008 +0000
+++ b/src/mactoolbox.c	Thu Apr 24 05:11:07 2008 +0000
@@ -118,7 +118,7 @@
 static TSMDocumentID tsm_document_id;
 extern Lisp_Object Qtext_input;
 extern Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
-extern Lisp_Object Vmac_ts_active_input_overlay;
+extern Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf;
 extern Lisp_Object Qbefore_string;
 #endif
 
@@ -134,6 +134,14 @@
 							EventRef, UInt32,
 							const EventParamName *,
 							const EventParamType *));
+extern int fast_find_position P_ ((struct window *, int, int *, int *,
+				   int *, int *, Lisp_Object));
+extern struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
+					   int *, int *, int *, int *, int *));
+extern void mac_ax_selected_text_range P_ ((struct frame *, CFRange *));
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+extern unsigned int mac_ax_number_of_characters P_ ((struct frame *));
+#endif
 
 #if USE_MAC_TSM
 extern OSStatus mac_restore_keyboard_input_source P_ ((void));
@@ -374,6 +382,10 @@
 }
 
 #if USE_MAC_TSM
+extern void mac_get_selected_range P_ ((struct window *, CFRange *));
+extern int mac_store_buffer_text_to_unicode_chars P_ ((struct buffer *,
+						       int, int, UniChar *));
+
 static pascal OSStatus
 mac_handle_text_input_event (next_handler, event, data)
      EventHandlerCallRef next_handler;
@@ -512,43 +524,269 @@
 
     case kEventTextInputOffsetToPos:
       {
+	long byte_offset;
 	struct frame *f;
 	struct window *w;
 	Point p;
 
-	if (!OVERLAYP (Vmac_ts_active_input_overlay))
+	err = GetEventParameter (event, kEventParamTextInputSendTextOffset,
+				 typeLongInteger, NULL, sizeof (long), NULL,
+				 &byte_offset);
+	if (err != noErr)
 	  break;
 
-	/* Strictly speaking, this is not always correct because
-	   previous events may change some states about display.  */
-	if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+	if (STRINGP (Vmac_ts_active_input_buf)
+	    && SBYTES (Vmac_ts_active_input_buf) != 0)
 	  {
-	    /* Active input area is displayed around the current point.  */
-	    f = SELECTED_FRAME ();
-	    w = XWINDOW (f->selected_window);
-	  }
-	else if (WINDOWP (echo_area_window))
-	  {
-	    /* Active input area is displayed in the echo area.  */
-	    w = XWINDOW (echo_area_window);
-	    f = WINDOW_XFRAME (w);
+	    if (!OVERLAYP (Vmac_ts_active_input_overlay))
+	      break;
+
+	    /* Strictly speaking, this is not always correct because
+	       previous events may change some states about display.  */
+	    if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+	      {
+		/* Active input area is displayed around the current point.  */
+		f = SELECTED_FRAME ();
+		w = XWINDOW (f->selected_window);
+	      }
+	    else if (WINDOWP (echo_area_window))
+	      {
+		/* Active input area is displayed in the echo area.  */
+		w = XWINDOW (echo_area_window);
+		f = WINDOW_XFRAME (w);
+	      }
+	    else
+	      break;
+
+	    p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
+		   + 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))
+		   + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
 	  }
 	else
-	  break;
-
-	p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
-	       + 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))
-	       + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
+	  {
+#ifndef MAC_OSX
+	    break;
+#else  /* MAC_OSX */
+	    CFRange sel_range;
+	    int charpos;
+	    int hpos, vpos, x, y;
+	    struct glyph_row *row;
+	    struct glyph *glyph;
+	    XFontStruct *font;
+
+	    f = mac_focus_frame (&one_mac_display_info);
+	    w = XWINDOW (f->selected_window);
+	    mac_get_selected_range (w, &sel_range);
+	    charpos = (BUF_BEGV (XBUFFER (w->buffer)) + sel_range.location
+		       + byte_offset / (long) sizeof (UniChar));
+
+	    if (!fast_find_position (w, charpos, &hpos, &vpos, &x, &y, Qnil))
+	      {
+		result = errOffsetInvalid;
+		break;
+	      }
+
+	    row = MATRIX_ROW (w->current_matrix, vpos);
+	    glyph = row->glyphs[TEXT_AREA] + hpos;
+	    if (glyph->type != CHAR_GLYPH || glyph->glyph_not_available_p)
+	      break;
+
+	    p.h = (WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x)
+		   + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
+	    p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, y)
+		   + row->visible_height
+		   + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
+
+	    font = FACE_FROM_ID (f, glyph->face_id)->font;
+	    if (font)
+	      {
+		Fixed point_size = Long2Fix (font->mac_fontsize);
+		short height = row->visible_height;
+		short ascent = row->ascent;
+
+		SetEventParameter (event,
+				   kEventParamTextInputReplyPointSize,
+				   typeFixed, sizeof (Fixed), &point_size);
+		SetEventParameter (event,
+				   kEventParamTextInputReplyLineHeight,
+				   typeShortInteger, sizeof (short), &height);
+		SetEventParameter (event,
+				   kEventParamTextInputReplyLineAscent,
+				   typeShortInteger, sizeof (short), &ascent);
+		if (font->mac_fontnum != -1)
+		  {
+		    OSStatus err1;
+		    FMFont fm_font;
+		    FMFontStyle style;
+
+		    err1 = FMGetFontFromFontFamilyInstance (font->mac_fontnum,
+							    font->mac_fontface,
+							    &fm_font, &style);
+		    if (err1 == noErr)
+		      SetEventParameter (event, kEventParamTextInputReplyFMFont,
+					 typeUInt32, sizeof (UInt32), &fm_font);
+		    else
+		      {
+			long qd_font = font->mac_fontnum;
+
+			SetEventParameter (event, kEventParamTextInputReplyFont,
+					   typeLongInteger, sizeof (long),
+					   &qd_font);
+		      }
+		  }
+		else if (font->mac_style)
+		  {
+		    OSStatus err1;
+		    ATSUFontID font_id;
+
+		    err1 = ATSUGetAttribute (font->mac_style, kATSUFontTag,
+					     sizeof (ATSUFontID), &font_id,
+					     NULL);
+		    if (err1 == noErr)
+		      SetEventParameter (event, kEventParamTextInputReplyFMFont,
+					 typeUInt32, sizeof (UInt32), &font_id);
+		  }
+		else
+		  abort ();
+	      }
+#endif	/* MAC_OSX */
+	  }
+
 	err = SetEventParameter (event, kEventParamTextInputReplyPoint,
-				 typeQDPoint, sizeof (typeQDPoint), &p);
+				 typeQDPoint, sizeof (Point), &p);
 	if (err == noErr)
 	  result = noErr;
       }
       break;
 
+#ifdef MAC_OSX
+    case kEventTextInputPosToOffset:
+      {
+	Point point;
+	Boolean leading_edge_p = true;
+	struct frame *f;
+	int x, y;
+	Lisp_Object window;
+	enum window_part part;
+	long region_class = kTSMOutsideOfBody, byte_offset = 0;
+
+	err = GetEventParameter (event, kEventParamTextInputSendCurrentPoint,
+				 typeQDPoint, NULL, sizeof (Point), NULL,
+				 &point);
+	if (err != noErr)
+	  break;
+
+	GetEventParameter (event, kEventParamTextInputReplyLeadingEdge,
+			   typeBoolean, NULL, sizeof (Boolean), NULL,
+			   &leading_edge_p);
+
+	f = mac_focus_frame (&one_mac_display_info);
+	x = point.h - (f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
+	y = point.v - (f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
+	window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
+	if (WINDOWP (window) && EQ (window, f->selected_window))
+	  {
+	    struct window *w;
+	    struct buffer *b;
+
+	    /* Convert to window-relative pixel coordinates.  */
+	    w = XWINDOW (window);
+	    frame_to_window_pixel_xy (w, &x, &y);
+
+	    /* Are we in a window whose display is up to date?
+	       And verify the buffer's text has not changed.  */
+	    b = XBUFFER (w->buffer);
+	    if (part == ON_TEXT
+		&& EQ (w->window_end_valid, w->buffer)
+		&& XINT (w->last_modified) == BUF_MODIFF (b)
+		&& XINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
+	      {
+		int hpos, vpos, area;
+		struct glyph *glyph;
+
+		/* Find the glyph under X/Y.  */
+		glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0, 0, &area);
+
+		if (glyph != NULL && area == TEXT_AREA)
+		  {
+		    byte_offset = ((glyph->charpos - BUF_BEGV (b))
+				   * sizeof (UniChar));
+		    region_class = kTSMInsideOfBody;
+		  }
+	      }
+	  }
+
+	err = SetEventParameter (event, kEventParamTextInputReplyRegionClass,
+				 typeLongInteger, sizeof (long),
+				 &region_class);
+	if (err == noErr)
+	  err = SetEventParameter (event, kEventParamTextInputReplyTextOffset,
+				   typeLongInteger, sizeof (long),
+				   &byte_offset);
+	if (err == noErr)
+	  result = noErr;
+      }
+      break;
+
+    case kEventTextInputGetSelectedText:
+      {
+	struct frame *f = mac_focus_frame (&one_mac_display_info);
+	struct window *w = XWINDOW (f->selected_window);
+	struct buffer *b = XBUFFER (w->buffer);
+	CFRange sel_range;
+	int start, end;
+	UniChar *characters, c;
+
+	if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
+	  /* Don't try to get buffer contents as the gap might be
+	     being altered. */
+	  break;
+
+	mac_get_selected_range (w, &sel_range);
+	if (sel_range.length == 0)
+	  {
+	    Boolean leading_edge_p;
+
+	    err = GetEventParameter (event,
+				     kEventParamTextInputReplyLeadingEdge,
+				     typeBoolean, NULL, sizeof (Boolean), NULL,
+				     &leading_edge_p);
+	    if (err != noErr)
+	      break;
+
+	    start = BUF_BEGV (b) + sel_range.location;
+	    if (!leading_edge_p)
+	      start--;
+	    end = start + 1;
+	    characters = &c;
+
+	    if (start < BUF_BEGV (b) || end > BUF_ZV (b))
+	      break;
+	  }
+	else
+	  {
+	    start = BUF_BEGV (b) + sel_range.location;
+	    end = start + sel_range.length;
+	    characters = xmalloc (sel_range.length * sizeof (UniChar));
+	  }
+
+	if (mac_store_buffer_text_to_unicode_chars (b, start, end, characters))
+	  err = SetEventParameter (event, kEventParamTextInputReplyText,
+				   typeUnicodeText,
+				   sel_range.length * sizeof (UniChar),
+				   characters);
+	if (characters != &c)
+	  xfree (characters);
+
+	if (err == noErr)
+	  result = noErr;
+      }
+      break;
+#endif	/* MAC_OSX */
+
     default:
       abort ();
     }
@@ -559,6 +797,86 @@
 					      names, types);
   return result;
 }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static pascal OSStatus
+mac_handle_document_access_event (next_handler, event, data)
+     EventHandlerCallRef next_handler;
+     EventRef event;
+     void *data;
+{
+  OSStatus err, result;
+  struct frame *f = mac_focus_frame (&one_mac_display_info);
+
+  result = CallNextEventHandler (next_handler, event);
+  if (result != eventNotHandledErr)
+    return result;
+
+  switch (GetEventKind (event))
+    {
+    case kEventTSMDocumentAccessGetLength:
+      {
+	CFIndex count = mac_ax_number_of_characters (f);
+
+	err = SetEventParameter (event, kEventParamTSMDocAccessCharacterCount,
+				 typeCFIndex, sizeof (CFIndex), &count);
+	if (err == noErr)
+	  result = noErr;
+      }
+      break;
+
+    case kEventTSMDocumentAccessGetSelectedRange:
+      {
+	CFRange sel_range;
+
+	mac_ax_selected_text_range (f, &sel_range);
+	err = SetEventParameter (event,
+				 kEventParamTSMDocAccessReplyCharacterRange,
+				 typeCFRange, sizeof (CFRange), &sel_range);
+	if (err == noErr)
+	  result = noErr;
+      }
+      break;
+
+    case kEventTSMDocumentAccessGetCharacters:
+      {
+	struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer);
+	CFRange range;
+	Ptr characters;
+	int start, end;
+
+	if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
+	  /* Don't try to get buffer contents as the gap might be
+	     being altered. */
+	  break;
+
+	err = GetEventParameter (event,
+				 kEventParamTSMDocAccessSendCharacterRange,
+				 typeCFRange, NULL, sizeof (CFRange), NULL,
+				 &range);
+	if (err == noErr)
+	  err = GetEventParameter (event,
+				   kEventParamTSMDocAccessSendCharactersPtr,
+				   typePtr, NULL, sizeof (Ptr), NULL,
+				   &characters);
+	if (err != noErr)
+	  break;
+
+	start = BUF_BEGV (b) + range.location;
+	end = start + range.length;
+	if (mac_store_buffer_text_to_unicode_chars (b, start, end,
+						    (UniChar *) characters))
+	  result = noErr;
+      }
+      break;
+
+    default:
+      abort ();
+    }
+
+  return result;
+}
+#endif
 #endif
 
 OSStatus
@@ -607,13 +925,32 @@
       static const EventTypeSpec specs[] =
 	{{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
 	 {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
-	 {kEventClassTextInput, kEventTextInputOffsetToPos}};
+	 {kEventClassTextInput, kEventTextInputOffsetToPos},
+#ifdef MAC_OSX
+	 {kEventClassTextInput, kEventTextInputPosToOffset},
+	 {kEventClassTextInput, kEventTextInputGetSelectedText}
+#endif
+	};
 
       err = InstallApplicationEventHandler (NewEventHandlerUPP
 					    (mac_handle_text_input_event),
 					    GetEventTypeCount (specs),
 					    specs, NULL, NULL);
     }
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+  if (err == noErr)
+    {
+      static const EventTypeSpec specs[] =
+	{{kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength},
+	 {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange},
+	 {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters}};
+
+      err = InstallApplicationEventHandler (mac_handle_document_access_event,
+					    GetEventTypeCount (specs),
+					    specs, NULL, NULL);
+    }
+#endif
 #endif
 
   if (err == noErr)
--- a/src/xdisp.c	Thu Apr 24 04:30:42 2008 +0000
+++ b/src/xdisp.c	Thu Apr 24 05:11:07 2008 +0000
@@ -1723,7 +1723,10 @@
    text, or we can't tell because W's current matrix is not up to
    date.  */
 
-static struct glyph *
+#ifndef HAVE_CARBON
+static
+#endif
+struct glyph *
 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
      struct window *w;
      int x, y;
@@ -22498,7 +22501,10 @@
 	 in 20.x as well, and I think it's too risky to install
 	 so near the release of 21.1.  2001-09-25 gerd.  */
 
-static int
+#ifndef HAVE_CARBON
+static
+#endif
+int
 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
      struct window *w;
      EMACS_INT charpos;