emacs-inline.patchをEmacs HEAD（24.4.50.2）に当ててみました


[MacEmacs JP](http://sourceforge.jp/projects/macemacsjp/)で配布されている[emacs-inline.patch](http://sourceforge.jp/projects/macemacsjp/svn/view/inline_patch/trunk/emacs-inline.patch?view=co&revision=583&root=macemacsjp&pathrev=583)を[Emacs HEADのGitレポジトリ](http://git.sv.gnu.org/r/emacs.git)（24.4.50.2）に当ててみました。もちろんそのままではうまく当たりませんでしたが、手パッチを繰り返した結果が以下のdiffです。

```diff:emacs-inline-for-HEAD.patch
diff --git a/configure.ac b/configure.ac
index 084dccc..367b004 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1792,7 +1792,7 @@ if test "${HAVE_NS}" = yes; then
      INSTALL_ARCH_INDEP_EXTRA=
   fi
 
-  NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o $macfont_file"
+  NS_OBJC_OBJ="nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o $macfont_file macim.o"
 fi
 CFLAGS="$tmp_CFLAGS"
 CPPFLAGS="$tmp_CPPFLAGS"
@@ -4829,7 +4829,7 @@ case "$opsys" in
    ## 0x690 is the total size of 30 segment load commands (at 56
    ## each); under Cocoa 31 commands are required.
    if test "$HAVE_NS" = "yes"; then
-     libs_nsgui="-framework AppKit"
+     libs_nsgui="-framework AppKit -framework Carbon -framework Cocoa"
      if test "$NS_IMPL_COCOA" = "yes"; then
         libs_nsgui="$libs_nsgui -framework IOKit"
      fi
diff --git a/lisp/term/common-win.el b/lisp/term/common-win.el
index ba59c75..90f52c0 100644
--- a/lisp/term/common-win.el
+++ b/lisp/term/common-win.el
@@ -136,6 +136,7 @@ is not used)."
 	       (cons (logior (lsh 0 16)  12) 'ns-new-frame)
 	       (cons (logior (lsh 0 16)  13) 'ns-toggle-toolbar)
 	       (cons (logior (lsh 0 16)  14) 'ns-show-prefs)
+	       (cons (logior (lsh 0 16)  15) 'mac-change-input-method)
 	       ))))
     (set-terminal-parameter frame 'x-setup-function-keys t)))
 
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 47d953a..e122486 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -168,6 +168,7 @@ The properties returned may include `top', `left', `height', and `width'."
 (define-key global-map [ns-new-frame] 'make-frame)
 (define-key global-map [ns-toggle-toolbar] 'ns-toggle-toolbar)
 (define-key global-map [ns-show-prefs] 'customize)
+(define-key global-map [mac-change-input-method] 'mac-change-input-method)
 
 
 ;; Set up a number of aliases and other layers to pretend we're using
@@ -253,14 +254,30 @@ The properties returned may include `top', `left', `height', and `width'."
 ;; editing window.)
 
 (defface ns-working-text-face
-  '((t :underline t))
+  '((((background dark)) :underline "gray80")
+    (t :underline "gray20"))
   "Face used to highlight working text during compose sequence insert."
   :group 'ns)
 
+(defface ns-marked-text-face
+  '((((background dark)) :underline "gray80")
+    (t :underline "gray20"))
+  "Face used to highlight marked text during compose sequence insert."
+  :group 'ns)
+
+(defface ns-unmarked-text-face
+  '((((background dark)) :underline "gray20")
+    (t :underline "gray80"))
+  "Face used to highlight marked text during compose sequence insert."
+  :group 'ns)
+
 (defvar ns-working-overlay nil
   "Overlay used to highlight working text during compose sequence insert.
 When text is in th echo area, this just stores the length of the working text.")
 
+(defvar ns-marked-overlay nil
+  "Overlay used to highlight marked text during compose sequence insert.")
+
 (defvar ns-working-text)		; nsterm.m
 
 ;; Test if in echo area, based on mac-win.el 2007/08/26 unicode-2.
@@ -268,17 +285,19 @@ When text is in th echo area, this just stores the length of the working text.")
 (defun ns-in-echo-area ()
   "Whether, for purposes of inserting working composition text, the minibuffer
 is currently being used."
-  (or isearch-mode
-      (and cursor-in-echo-area (current-message))
-      ;; Overlay strings are not shown in some cases.
-      (get-char-property (point) 'invisible)
-      (and (not (bobp))
-	   (or (and (get-char-property (point) 'display)
-		    (eq (get-char-property (1- (point)) 'display)
-			(get-char-property (point) 'display)))
-	       (and (get-char-property (point) 'composition)
-		    (eq (get-char-property (1- (point)) 'composition)
-			(get-char-property (point) 'composition)))))))
+  (setq mac-in-echo-area
+	(or isearch-mode
+	    (and cursor-in-echo-area (current-message))
+	    ;; Overlay strings are not shown in some cases.
+	    (get-char-property (point) 'invisible)
+	    (and (not (bobp))
+		 (or (and (get-char-property (point) 'display)
+			  (eq (get-char-property (1- (point)) 'display)
+			      (get-char-property (point) 'display)))
+		     (and (get-char-property (point) 'composition)
+			  (eq (get-char-property (1- (point)) 'composition)
+			      (get-char-property (point) 'composition)))))))
+  mac-in-echo-area)
 
 ;; The 'interactive' here stays for subinvocations, so the ns-in-echo-area
 ;; always returns nil for some reason.  If this WASN'T the case, we could
@@ -308,19 +327,81 @@ The overlay is assigned the face `ns-working-text-face'."
 (defun ns-echo-working-text ()
   "Echo contents of `ns-working-text' in message display area.
 See `ns-insert-working-text'."
-  (ns-delete-working-text)
   (let* ((msg (current-message))
-	 (msglen (length msg))
-	 message-log-max)
+         (msglen (length msg))
+         message-log-max)
+    (if (integerp ns-working-overlay)
+	(progn
+	  (setq msg (substring msg 0 (- (length msg) ns-working-overlay)))
+	  (setq msglen (length msg))))
     (setq ns-working-overlay (length ns-working-text))
     (setq msg (concat msg ns-working-text))
     (put-text-property msglen (+ msglen ns-working-overlay)
-		       'face 'ns-working-text-face msg)
+                       'face 'ns-working-text-face msg)
+     (message "%s" msg)))
+
+(defun ns-put-marked-text (event)
+  (interactive "e")
+
+  (let ((pos (nth 1 event))
+	(len (nth 2 event)))
+    (if (ns-in-echo-area)
+	(ns-echo-marked-text pos len)
+      (ns-insert-marked-text pos len))))
+
+(defun ns-insert-marked-text (pos len)
+  "Insert contents of `ns-working-text' as UTF-8 string and mark with
+`ns-working-overlay' and `ns-marked-overlay'.  Any previously existing
+working text is cleared first. The overlay is assigned the faces
+`ns-working-text-face' and `ns-marked-text-face'."
+  (ns-delete-working-text)
+  (let ((start (point)))
+    (if (<= pos (length ns-working-text))
+      (progn
+	(put-text-property pos len 'face 'ns-working-text-face ns-working-text)
+	(insert ns-working-text)
+	(if (= len 0)
+	    (overlay-put (setq ns-working-overlay
+			       (make-overlay start (point) (current-buffer) nil t))
+			 'face 'ns-working-text-face)
+	  (overlay-put (setq ns-working-overlay
+			     (make-overlay start (point) (current-buffer) nil t))
+		       'face 'ns-unmarked-text-face)
+	  (overlay-put (setq ns-marked-overlay
+			     (make-overlay (+ start pos) (+ start pos len)
+					   (current-buffer) nil t))
+		       'face 'ns-marked-text-face))
+	(goto-char (+ start pos))))))
+
+(defun ns-echo-marked-text (pos len)
+  "Echo contents of `ns-working-text' in message display area.
+See `ns-insert-working-text'."
+  (let* ((msg (current-message))
+         (msglen (length msg))
+         message-log-max)
+    (when (integerp ns-working-overlay)
+      (setq msg (substring msg 0 (- (length msg) ns-working-overlay)))
+      (setq msglen (length msg)))
+    (setq ns-working-overlay (length ns-working-text))
+    (setq msg (concat msg ns-working-text))
+    (if (= len 0)
+        (put-text-property msglen (+ msglen ns-working-overlay)
+                           'face 'ns-working-text-face msg)
+      (put-text-property msglen (+ msglen ns-working-overlay)
+                         'face 'ns-unmarked-text-face msg)
+      (put-text-property (+ msglen pos) (+ msglen pos len)
+                         'face 'ns-marked-text-face msg))
     (message "%s" msg)))
 
 (defun ns-delete-working-text()
-  "Delete working text and clear `ns-working-overlay'."
+  "Delete working text and clear `ns-working-overlay' and `ns-marked-overlay'."
   (interactive)
+  (when (and (overlayp ns-marked-overlay)
+	     ;; Still alive
+	     (overlay-buffer ns-marked-overlay))
+    (with-current-buffer (overlay-buffer ns-marked-overlay)
+      (delete-overlay ns-marked-overlay)))
+  (setq ns-marked-overlay nil)
   (cond
    ((and (overlayp ns-working-overlay)
          ;; Still alive?
@@ -964,6 +1045,466 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
 (add-to-list 'window-system-initialization-alist '(ns . ns-initialize-window-system))
 
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Implementation of Input Method Extension for MacOS X
+;; written by Taiichi Hashimoto <taiichi2@mac.com>
+;;
+
+(defvar mac-input-method-parameters
+  '(
+    ("com.apple.inputmethod.Kotoeri.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Kotoeri.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Kotoeri.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Kotoeri.Japanese.FullWidthRoman"
+     (title . "Ａ")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Kotoeri.Japanese.HalfWidthKana"
+     (title . "ｱ")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.kotoeri.Ainu"
+     (title . "アイヌ")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Korean.2SetKorean"
+     (title . "가2")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Korean.3SetKorean"
+     (title . "가3")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Korean.390Sebulshik"
+     (title . "가5")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Korean.GongjinCheongRomaja"
+     (title . "가G")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Korean.HNCRomaja"
+     (title . "가H")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Tamil.AnjalIM"
+     (title . "Anjal")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.Tamil.Tamil99"
+     (title . "Tamil")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.VietnameseIM.VietnameseSimpleTelex"
+     (title . "ST")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.VietnameseIM.VietnameseTelex"
+     (title . "TX")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.VietnameseIM.VietnameseVNI"
+     (title . "VN")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.VietnameseIM.VietnameseVIQR"
+     (title . "VQ")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.SCIM.ITABC"
+     (title . "拼")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.SCIM.WBX"
+     (title . "型")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.SCIM.WBH"
+     (title . "画")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.TCIM.Zhuyin"
+     (title . "注")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.TCIM.Pinyin"
+     (title . "拼")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.TCIM.Cangjie"
+     (title . "倉")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.TCIM.Jianyi"
+     (title . "速")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.TCIM.Dayi"
+     (title . "易")
+     (cursor-color)
+     (cursor-type))
+    ("com.apple.inputmethod.TCIM.Hanin"
+     (title . "漢")
+     (cursor-color)
+     (cursor-type))
+    ("com.google.inputmethod.Japanese.Roman"
+     (title . "G")
+     (cursor-color)
+     (cursor-type))
+    ("com.google.inputmethod.Japanese.base"
+     (title . "ぐ")
+     (cursor-color)
+     (cursor-type))
+    ("com.google.inputmethod.Japanese.Katakana"
+     (title . "グ")
+     (cursor-color)
+     (cursor-type))
+    ("com.google.inputmethod.Japanese.FullWidthRoman"
+     (title . "Ｇ")
+     (cursor-color)
+     (cursor-type))
+    ("com.google.inputmethod.Japanese.HalfWidthKana"
+     (title . "ｸﾞ")
+     (cursor-color)
+     (cursor-type))
+    ("jp.monokakido.inputmethod.Kawasemi.Roman"
+     (title . "K")
+     (cursor-color)
+     (cursor-type))
+    ("jp.monokakido.inputmethod.Kawasemi.Japanese"
+     (title . "か")
+     (cursor-color)
+     (cursor-type))
+    ("jp.monokakido.inputmethod.Kawasemi.Japanese.Katakana"
+     (title . "カ")
+     (cursor-color)
+     (cursor-type))
+    ("jp.monokakido.inputmethod.Kawasemi.Japanese.FullWidthRoman"
+     (title . "Ｋ")
+     (cursor-color)
+     (cursor-type))
+    ("jp.monokakido.inputmethod.Kawasemi.Japanese.HalfWidthKana"
+     (title . "ｶ")
+     (cursor-color)
+     (cursor-type))
+    ("jp.monokakido.inputmethod.Kawasemi.Japanese.HalfWidthRoman"
+     (title . "_K")
+     (cursor-color)
+     (cursor-type))
+    ("jp.monokakido.inputmethod.Kawasemi.Japanese.Code"
+     (title . "C")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese.FullWidthRoman"
+     (title . "英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok21.Japanese.HalfWidthEiji"
+     (title . "半英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok22.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok22.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok22.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok22.Japanese.FullWidthRoman"
+     (title . "英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok22.Japanese.HalfWidthEiji"
+     (title . "半英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok23.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok23.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok23.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok23.Japanese.FullWidthRoman"
+     (title . "英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok23.Japanese.HalfWidthEiji"
+     (title . "半英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok24.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok24.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok24.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok24.Japanese.FullWidthRoman"
+     (title . "英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok24.Japanese.HalfWidthEiji"
+     (title . "半英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Roman"
+     (title . "A")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Japanese"
+     (title . "あ")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Japanese.Katakana"
+     (title . "ア")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Japanese.FullWidthRoman"
+     (title . "英")
+     (cursor-color)
+     (cursor-type))
+    ("com.justsystems.inputmethod.atok25.Japanese.HalfWidthEiji"
+     (title . "半英")
+     (cursor-color)
+     (cursor-type))
+    )
+  "Alist of Mac script code vs parameters for input method on MacOSX.")
+
+
+(defun mac-get-input-method-parameter (is key)
+  "Function to get a parameter of a input method."
+  (interactive)
+  (assq key (cdr (assoc is mac-input-method-parameters))))
+
+(defun mac-get-input-method-title (&optional input-source)
+  "Return input method title of input source.
+   If input-source is nil, return one of current frame."
+  (if input-source
+      (cdr (mac-get-input-method-parameter input-source 'title))
+    current-input-method-title))
+
+(defun mac-get-cursor-type (&optional input-source)
+  "Return cursor type of input source.
+   If input-source is nil, return one of current frame."
+  (if input-source
+      (or (cdr (mac-get-input-method-parameter input-source 'cursor-type))
+	  (cdr (assq 'cursor-type default-frame-alist))
+	  cursor-type)
+    (cdr (assq 'cursor-type (frame-parameters (selected-frame))))))
+
+(defun mac-get-cursor-color (&optional input-source)
+  "Return cursor color of input source.
+   If input-source is nil, return one of current frame."
+  (if input-source
+      (or (cdr (mac-get-input-method-parameter input-source 'cursor-color))
+	  (cdr (assq 'cursor-color default-frame-alist)))
+    (cdr (assq 'cursor-color (frame-parameters (selected-frame))))))
+
+
+(defun mac-set-input-method-parameter (is key value)
+  "Function to set a parameter of a input method."
+  (let* ((is-param (assoc is mac-input-method-parameters))
+         (param (assq key is-param)))
+    (if is-param
+	(if param
+	    (setcdr param value)
+	  (setcdr is-param (cons (cons key value) (cdr is-param))))
+      (setq mac-input-method-parameters
+	    (cons (list is (cons key value))
+		  mac-input-method-parameters)))))
+
+
+(defun mac-input-method-update (is)
+  "Funtion to update parameters of a input method."
+  (interactive)
+
+  (let ((title (mac-get-input-method-title is))
+        (type (mac-get-cursor-type is))
+        (color (mac-get-cursor-color is)))
+    (if (and title (not (equal title (mac-get-input-method-title))))
+	(setq current-input-method-title title))
+    (if (and type (not (equal type (mac-get-cursor-type))))
+	(setq cursor-type type))
+    (if (and color (not (equal color (mac-get-cursor-color))))
+	(set-cursor-color color))
+    (force-mode-line-update)
+    (if isearch-mode (isearch-update))))
+
+
+(defun mac-toggle-input-method (&optional arg)
+  "Function to toggle input method on MacOSX."
+  (interactive)
+
+  (if arg
+      (progn
+	(make-local-variable 'input-method-function)
+	(setq inactivate-current-input-method-function 'mac-toggle-input-method)
+	(setq input-method-function nil)
+	(setq describe-current-input-method-function nil)
+	(mac-toggle-input-source t))
+    (kill-local-variable 'input-method-function)
+    (setq describe-current-input-method-function nil)
+    (mac-toggle-input-source nil)))
+
+
+(defun mac-change-language-to-us ()
+  "Function to change language to us."
+  (interactive)
+  (mac-toggle-input-method nil))
+
+
+(defun mac-handle-input-method-change ()
+  "Function run when a input method change."
+  (interactive)
+
+  (if (equal default-input-method "MacOSX")
+      (let ((input-source (mac-get-current-input-source))
+	  (ascii-capable (mac-input-source-is-ascii-capable)))
+
+	(cond ((and (not current-input-method) (not ascii-capable))
+	       (set-input-method "MacOSX"))
+	      ((and (equal current-input-method "MacOSX") ascii-capable)
+	       (toggle-input-method nil)))
+	(mac-input-method-update input-source))))
+
+;;
+;; Emacs input method for input method on MacOSX.
+;;
+(register-input-method "MacOSX" "MacOSX" 'mac-toggle-input-method
+		       "Mac" "Input Method on MacOSX System")
+
+
+;;
+;; Minor mode of using input methods on MacOS X
+;;
+(define-minor-mode mac-input-method-mode
+  "Use input methods on MacOSX."
+  :init-value nil
+  :group 'ns
+  :global t
+
+  (if mac-input-method-mode
+      (progn
+	(setq default-input-method "MacOSX")
+	(add-hook 'minibuffer-setup-hook 'mac-change-language-to-us)
+	(mac-translate-from-yen-to-backslash))
+    (setq default-input-method nil)))
+
+;;
+;; Valiable and functions to pass key(shortcut) to system.
+;;
+(defvar mac-keys-passed-to-system nil
+  "A list of keys passed to system on MacOSX.")
+
+(defun mac-add-key-passed-to-system (key)
+  (let ((shift   '(shift shft))
+	(control '(control ctrl ctl))
+	(option  '(option opt alternate alt))
+	(command '(command cmd)))
+
+    (add-to-list 'mac-keys-passed-to-system
+		 (cond ((symbolp key)
+			(cond ((memq key shift)
+			       (cons ns-shift-key-mask nil))
+			      ((memq key control)
+			       (cons ns-control-key-mask nil))
+			      ((memq key option)
+			       (cons ns-alternate-key-mask nil))
+			      ((memq key command)
+			       (cons ns-command-key-mask nil))
+			      (t (cons nil nil))))
+		       ((numberp key) (cons 0 key))
+		       ((listp key)
+			(let ((l key) (k nil) (m 0))
+			  (while l
+			    (cond ((memq (car l) shift)
+				   (setq m (logior m ns-shift-key-mask)))
+				  ((memq (car l) control)
+				   (setq m (logior m ns-control-key-mask)))
+				  ((memq (car l) option)
+				   (setq m (logior m ns-alternate-key-mask)))
+				  ((memq (car l) command)
+				       (setq m (logior m ns-command-key-mask)))
+				  ((numberp (car l))
+				   (if (not k) (setq k (car l)))))
+			    (setq l (cdr l)))
+			  (cons m k)))
+		       (t (cons nil nil))))))
+
+
+;;
+;; Entry Emacs event for inline input method on MacOSX.
+;;
+(define-key special-event-map
+  [mac-change-input-method] 'mac-handle-input-method-change)
+
+;;
+;; Convert yen to backslash for JIS keyboard.
+;;
+(defun mac-translate-from-yen-to-backslash ()
+  ;; Convert yen to backslash for JIS keyboard.
+  (interactive)
+
+  (define-key global-map [165] nil)
+  (define-key global-map [2213] nil)
+  (define-key global-map [3420] nil)
+  (define-key global-map [67109029] nil)
+  (define-key global-map [67111077] nil)
+  (define-key global-map [8388773] nil)
+  (define-key global-map [134219941] nil)
+  (define-key global-map [75497596] nil)
+  (define-key global-map [201328805] nil)
+  (define-key function-key-map [165] [?\\])
+  (define-key function-key-map [2213] [?\\]) ;; for Intel
+  (define-key function-key-map [3420] [?\\]) ;; for PowerPC
+  (define-key function-key-map [67109029] [?\C-\\])
+  (define-key function-key-map [67111077] [?\C-\\])
+  (define-key function-key-map [8388773] [?\M-\\])
+  (define-key function-key-map [134219941] [?\M-\\])
+  (define-key function-key-map [75497596] [?\C-\M-\\])
+  (define-key function-key-map [201328805] [?\C-\M-\\])
+)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (provide 'ns-win)
 
 ;;; ns-win.el ends here
diff --git a/src/Makefile.in b/src/Makefile.in
index bda4623..e5649d0 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -365,7 +365,7 @@ obj = $(base_obj) $(NS_OBJC_OBJ)
 SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
   xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o fringe.o image.o \
   fontset.o dbusbind.o cygw32.o \
-  nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macfont.o \
+  nsterm.o nsfns.o nsmenu.o nsselect.o nsimage.o nsfont.o macfont.o macim.o \
   w32.o w32console.o w32fns.o w32heap.o w32inevt.o w32notify.o \
   w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
   w16select.o widget.o xfont.o ftfont.o xftfont.o ftxfont.o gtkutil.o \
diff --git a/src/keyboard.c b/src/keyboard.c
index dcf8913..f57c15c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3961,8 +3961,10 @@ kbd_buffer_get_event (KBOARD **kbp,
         {
           if (event->code == KEY_NS_PUT_WORKING_TEXT)
             obj = list1 (intern ("ns-put-working-text"));
-          else
+          else if (event->code == KEY_NS_UNPUT_WORKING_TEXT)
             obj = list1 (intern ("ns-unput-working-text"));
+          else if (event->code == KEY_NS_PUT_MARKED_TEXT)
+            obj = Fcons (intern ("ns-put-marked-text"), event->arg);
 	  kbd_fetch_ptr = event + 1;
           if (used_mouse_menu)
             *used_mouse_menu = 1;
@@ -11704,6 +11706,8 @@ keys_of_keyboard (void)
 			    "ns-put-working-text");
   initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text",
 			    "ns-unput-working-text");
+  initial_define_lispy_key (Vspecial_event_map, "ns-put-marked-text",
+			    "ns-put-marked-text");
   /* Here we used to use `ignore-event' which would simple set prefix-arg to
      current-prefix-arg, as is done in `handle-switch-frame'.
      But `handle-switch-frame is not run from the special-map.
diff --git a/src/macim.m b/src/macim.m
new file mode 100644
index 0000000..6545f5f
--- /dev/null
+++ b/src/macim.m
@@ -0,0 +1,173 @@
+/* Implementation of Input Method Extension for MacOS X.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Taiichi Hashimoto <taiichi2@mac.com>.
+*/
+
+#include "config.h"
+
+#ifdef NS_IMPL_COCOA
+
+#include <math.h>
+#include <sys/types.h>
+#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <Carbon/Carbon.h>
+
+#include "lisp.h"
+#include "blockinput.h"
+
+#include "termhooks.h"
+#include "keyboard.h"
+#include "buffer.h"
+
+//extern Lisp_Object Qcurrent_input_method;
+//extern int cursor_in_echo_area;
+static Lisp_Object Qmac_keys_passed_to_system;
+
+void mac_init_input_method ();
+int mac_pass_key_to_system (int code, int modifiers);
+int mac_pass_key_directly_to_emacs ();
+int mac_store_change_input_method_event ();
+
+DEFUN ("mac-input-source-is-ascii-capable", Fmac_input_source_is_ascii_capable, Smac_input_source_is_ascii_capable,
+       0, 0, 0,
+       doc: /* Is current input source ascii capable? */)
+     (void)
+{
+  TISInputSourceRef is = TISCopyCurrentKeyboardInputSource();
+  CFBooleanRef ret = TISGetInputSourceProperty(is, kTISPropertyInputSourceIsASCIICapable);
+
+  return CFBooleanGetValue(ret)? Qt : Qnil;
+}
+
+DEFUN ("mac-get-input-source-list", Fmac_get_input_source_list, Smac_get_input_source_list,
+       0, 0, 0,
+       doc: /* get input source list on MacOSX */)
+     (void)
+{
+  NSArray *is_list = (NSArray *)TISCreateInputSourceList(NULL, false);
+  int list_size = [is_list count];
+  Lisp_Object list[list_size];
+  int i;
+
+  for (i = 0; i < list_size; i++) {
+    TISInputSourceRef is = (TISInputSourceRef)[is_list objectAtIndex:i];
+    NSString *id = (NSString *)TISGetInputSourceProperty(is, kTISPropertyInputSourceID);
+    list[i] = make_string([id UTF8String],
+			  [id lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
+  }
+
+  return Flist(list_size, list);
+}
+
+DEFUN ("mac-get-current-input-source", Fmac_get_current_input_source, Smac_get_current_input_source,
+       0, 0, 0,
+       doc: /* get current input source on MacOSX */)
+     (void)
+{
+  TISInputSourceRef is = TISCopyCurrentKeyboardInputSource();
+  NSString *id = (NSString *)TISGetInputSourceProperty(is, kTISPropertyInputSourceID);
+
+  return make_string([id UTF8String],
+		     [id lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
+}
+
+DEFUN ("mac-toggle-input-source", Fmac_toggle_input_source, Smac_toggle_input_source,
+       1, 1, 0,
+       doc: /* toggle input source on MacOSX */)
+     (arg)
+     Lisp_Object arg;
+{
+  TISInputSourceRef is = NULL;
+
+  if (NILP (arg))
+    {
+      is = TISCopyCurrentASCIICapableKeyboardInputSource();
+    }
+  else
+    {
+      NSString *locale;
+      NSArray *languages = [NSLocale preferredLanguages];
+      if (languages != nil) {
+	  locale = [languages objectAtIndex:0];
+      } else {
+	  locale = [[NSLocale currentLocale]
+			objectForKey:NSLocaleLanguageCode];
+      }
+      is = TISCopyInputSourceForLanguage((CFStringRef)locale);
+    }
+  if (is) TISSelectInputSource(is);
+
+  return arg;
+}
+
+int
+mac_store_change_input_method_event ()
+{
+  Lisp_Object dim;
+  int ret = FALSE;
+
+  dim = Fsymbol_value (intern ("default-input-method"));
+  if (STRINGP (dim) && strcmp(SDATA (dim), "MacOSX") == 0)
+    {
+      ret = TRUE;
+    }
+
+  return ret;
+}
+
+int
+mac_pass_key_to_system (int code, int modifiers)
+{
+  Lisp_Object keys = Fsymbol_value (Qmac_keys_passed_to_system);
+  Lisp_Object m, k;
+
+  while (!NILP (keys))
+    {
+      m = XCAR (XCAR (keys));
+      k = XCDR (XCAR (keys));
+      keys = XCDR (keys);
+
+      if (NUMBERP (m) && modifiers == XINT (m))
+	if (NILP (k)
+	    || (NUMBERP (k) && code == XINT (k)))
+	  return TRUE;
+    }
+
+  return FALSE;
+}
+
+int
+mac_pass_key_directly_to_emacs (void)
+{
+
+  if (NILP (Fmac_input_source_is_ascii_capable()))
+    {
+      if (NILP (Vmac_use_input_method_on_system)
+	  || this_command_key_count
+	  || cursor_in_echo_area
+	  || !NILP (BVAR (current_buffer, read_only)))
+	return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+void mac_init_input_method (void)
+{
+  Qmac_keys_passed_to_system = intern ("mac-keys-passed-to-system");
+  staticpro (&Qmac_keys_passed_to_system);
+
+  DEFVAR_LISP ("mac-use-input-method-on-system", Vmac_use_input_method_on_system,
+               doc: /* If it is non-nil, use input method on system. */);
+  Vmac_use_input_method_on_system = Qt;
+
+  defsubr (&Smac_input_source_is_ascii_capable);
+  defsubr (&Smac_get_input_source_list);
+  defsubr (&Smac_get_current_input_source);
+  defsubr (&Smac_toggle_input_source);
+}
+#endif
diff --git a/src/nsfns.m b/src/nsfns.m
index 5f9588a..98866e6 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -546,7 +546,6 @@ x_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
   ns_set_name_internal (f, name);
 }
 
-
 void
 ns_set_name_as_filename (struct frame *f)
 {
@@ -2950,6 +2949,24 @@ be used as the image of the icon representing the frame.  */);
                doc: /* Toolkit version for NS Windowing.  */);
   Vns_version_string = ns_appkit_version_str ();
 
+
+  DEFVAR_LISP ("ns-shift-key-mask", Vns_shift_key_mask,
+               doc: /* Shift key mask defined in system. */);
+  Vns_shift_key_mask = make_number (NSShiftKeyMask);
+
+  DEFVAR_LISP ("ns-control-key-mask", Vns_control_key_mask,
+               doc: /* Control key mask defined in system. */);
+  Vns_control_key_mask = make_number (NSControlKeyMask);
+
+  DEFVAR_LISP ("ns-alternate-key-mask", Vns_alternate_key_mask,
+               doc: /* Alternate key mask defined in system. */);
+  Vns_alternate_key_mask = make_number (NSAlternateKeyMask);
+
+  DEFVAR_LISP ("ns-command-key-mask", Vns_command_key_mask,
+               doc: /* Command key mask defined in system. */);
+  Vns_command_key_mask = make_number (NSCommandKeyMask);
+
+
   defsubr (&Sns_read_file_name);
   defsubr (&Sns_get_resource);
   defsubr (&Sns_set_resource);
@@ -2993,6 +3010,10 @@ be used as the image of the icon representing the frame.  */);
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
 
+#ifdef NS_IMPL_COCOA
+  mac_init_input_method ();
+#endif
+
   as_status = 0;
   as_script = Qnil;
   as_result = 0;
diff --git a/src/nsterm.h b/src/nsterm.h
index d2c42c5..bd1eecf 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -482,6 +482,8 @@ extern EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
 #define KEY_NS_NEW_FRAME               ((1<<28)|(0<<16)|12)
 #define KEY_NS_TOGGLE_TOOLBAR          ((1<<28)|(0<<16)|13)
 #define KEY_NS_SHOW_PREFS              ((1<<28)|(0<<16)|14)
+#define KEY_MAC_CHANGE_INPUT_METHOD    ((1<<28)|(0<<16)|15)
+#define KEY_NS_PUT_MARKED_TEXT         ((1<<28)|(0<<16)|16)
 
 /* could use list to store these, but rest of emacs has a big infrastructure
    for managing a table of bitmap "records" */
diff --git a/src/nsterm.m b/src/nsterm.m
index 6b617be..3905f51 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4240,6 +4240,9 @@ ns_term_init (Lisp_Object display_name)
   /*   [[NSNotificationCenter defaultCenter] addObserver: NSApp
                                          selector: @selector (logNotification:)
                                              name: nil object: nil]; */
+  [[NSDistributedNotificationCenter defaultCenter] addObserver: NSApp
+					selector: @selector (changeInputMethod:)
+						   name: @"AppleSelectedInputSourcesChangedNotification" object: nil];
 
   dpyinfo = xzalloc (sizeof *dpyinfo);
 
@@ -4507,6 +4510,21 @@ ns_term_shutdown (int sig)
     NSLog (@"notification: '%@'", [notification name]);
 }
 
+- (void)changeInputMethod: (NSNotification *)notification
+{
+
+  struct frame *emacsframe = SELECTED_FRAME ();
+
+  if (mac_store_change_input_method_event())
+    {
+      if (!emacs_event)
+	return;
+      emacs_event->kind = NS_NONKEY_EVENT;
+      emacs_event->code = KEY_MAC_CHANGE_INPUT_METHOD;
+      emacs_event->modifiers = 0;
+      EV_TRAILER ((id)nil);
+    }
+}
 
 - (void)sendEvent: (NSEvent *)theEvent
 /* --------------------------------------------------------------------------
@@ -5260,7 +5278,8 @@ not_in_argv (NSString *arg)
              code, fnKeysym, flags, emacs_event->modifiers);
 
       /* if it was a function key or had modifiers, pass it directly to emacs */
-      if (fnKeysym || (emacs_event->modifiers
+      if (mac_pass_key_directly_to_emacs ()
+	  ||fnKeysym || (emacs_event->modifiers
                        && (emacs_event->modifiers != shift_modifier)
                        && [[theEvent charactersIgnoringModifiers] length] > 0))
 /*[[theEvent characters] length] */
@@ -5275,7 +5294,16 @@ not_in_argv (NSString *arg)
               ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT;
 
           emacs_event->code = code;
-          EV_TRAILER (theEvent);
+          if (emacs_event->kind == NON_ASCII_KEYSTROKE_EVENT
+              || !mac_pass_key_to_system (code, flags
+                                          & (NSShiftKeyMask
+                                             | NSControlKeyMask
+                                             | NSAlternateKeyMask
+                                             | NSCommandKeyMask)))
+            {
+              EV_TRAILER (theEvent);
+              return;
+            }
           processingCompose = NO;
           return;
         }
@@ -5377,10 +5405,19 @@ not_in_argv (NSString *arg)
            (unsigned long)selRange.length,
            (unsigned long)selRange.location);
 
-  if (workingText != nil)
-    [self deleteWorkingText];
   if ([str length] == 0)
-    return;
+    {
+      [self deleteWorkingText];
+      return;
+    }
+  else
+    {
+      if (workingText != nil) {
+	[workingText release];
+	workingText = nil;
+	processingCompose = NO;
+      }
+    }
 
   if (!emacs_event)
     return;
@@ -5390,7 +5427,9 @@ not_in_argv (NSString *arg)
   ns_working_text = build_string ([workingText UTF8String]);
 
   emacs_event->kind = NS_TEXT_EVENT;
-  emacs_event->code = KEY_NS_PUT_WORKING_TEXT;
+  emacs_event->code = KEY_NS_PUT_MARKED_TEXT;
+  emacs_event->arg = Fcons (make_number (selRange.location),
+			    Fcons (make_number (selRange.length), Qnil));
   EV_TRAILER ((id)nil);
 }
 
@@ -5445,15 +5484,23 @@ not_in_argv (NSString *arg)
 {
   NSRect rect;
   NSPoint pt;
-  struct window *win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe));
+  //  struct window *win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe));
+  struct window *win;
   if (NS_KEYLOG)
     NSLog (@"firstRectForCharRange request");
 
+  if (NILP (Vmac_in_echo_area))
+    win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe));
+    else if (WINDOWP (echo_area_window))
+    win = XWINDOW (echo_area_window);
+  else
+    win = XWINDOW (FRAME_SELECTED_WINDOW (emacsframe));
+
   rect.size.width = theRange.length * FRAME_COLUMN_WIDTH (emacsframe);
   rect.size.height = FRAME_LINE_HEIGHT (emacsframe);
   pt.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (win, win->phys_cursor.x);
   pt.y = WINDOW_TO_FRAME_PIXEL_Y (win, win->phys_cursor.y
-                                       +FRAME_LINE_HEIGHT (emacsframe));
+                                       +FRAME_LINE_HEIGHT (emacsframe)+2);
 
   pt = [self convertPoint: pt toView: nil];
   pt = [[self window] convertBaseToScreen: pt];
@@ -7719,6 +7766,10 @@ variable `x-use-underline-position-properties', which is usually at the
 baseline level.  The default value is nil.  */);
   x_underline_at_descent_line = 0;
 
+  DEFVAR_LISP ("mac-in-echo-area", Vmac_in_echo_area,
+               doc: /* state of cursor in echo area. */);
+  Vmac_in_echo_area = Qnil;
+
   /* Tell Emacs about this window system.  */
   Fprovide (Qns, Qnil);
 
diff --git a/src/termhooks.h b/src/termhooks.h
index f9bf9d7..b16c77d 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -49,8 +49,9 @@ enum output_method
   output_x_window,
   output_msdos_raw,
   output_w32,
+  output_mac,
   output_ns
-};
+} output_method;
 
 /* Input queue declarations and hooks.  */
 
```

以上のdiffは、EmacsのGitレポジトリを手元にcloneしてからspikeブランチを切ってspikeブランチにコミット、その後`git diff master spike`することで生成しています。パッチとしてはいつ当たらなくなるか分かりませんので、以前やったようにこのパッチを使ったEmacsのFormulaをHomebrewに対してpull requestする、といったことは考えていません。
なお、私は`brew diy`してからインストールしています。