Last active
August 29, 2015 14:09
-
-
Save rzl24ozi/68c29ac4fe64f1aa8887 to your computer and use it in GitHub Desktop.
add w32-ime support to emacs with Windows GUI and various modifications
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- ./configure.ac.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./configure.ac 2015-04-11 07:27:30.430112300 +0900 | |
@@ -263,6 +263,12 @@ | |
OPTION_DEFAULT_OFF([ns],[use NeXTstep (Cocoa or GNUstep) windowing system]) | |
OPTION_DEFAULT_OFF([w32], [use native MS Windows GUI in a Cygwin build]) | |
+OPTION_DEFAULT_ON([w32-ime], [don't compile with W32-IME support]) | |
+OPTION_DEFAULT_ON([reconversion], [don't compile with RECONVERSION support]) | |
+OPTION_DEFAULT_ON([documentfeed], [don't compile with DOCUMENTFEED support]) | |
+ | |
+OPTION_DEFAULT_ON([cmigemo], [don't compile with CMIGEMO support]) | |
+ | |
OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console]) | |
OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support]) | |
OPTION_DEFAULT_ON([gconf],[don't compile with GConf support]) | |
@@ -2236,7 +2242,7 @@ | |
### Use -lrsvg-2 if available, unless `--with-rsvg=no' is specified. | |
HAVE_RSVG=no | |
-if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" = "mingw32"; then | |
+if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes"; then | |
if test "${with_rsvg}" != "no"; then | |
RSVG_REQUIRED=2.11.0 | |
RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED" | |
@@ -5006,6 +5012,50 @@ | |
acl_summary=no | |
fi | |
+USE_W32_IME=no | |
+if test "${HAVE_W32}" = "yes"; then | |
+ if test "${with_w32_ime}" != "no"; then | |
+ USE_W32_IME=yes | |
+ AC_DEFINE(USE_W32_IME, 1, [Define to support W32-IME.]) | |
+ | |
+ RECONVERSION=no | |
+ if test "${with_reconversion}" != "no"; then | |
+ AC_CACHE_CHECK([whether RECONVERTSTRING is declared], | |
+ emacs_cv_have_reconvertstring, | |
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ | |
+#include <windows.h> | |
+#include <imm.h>]], [[RECONVERTSTRING]])], | |
+ emacs_cv_have_reconvertstring=yes, emacs_cv_have_reconvertstring=no)]) | |
+ if test "$emacs_cv_have_reconvertstring" = "yes"; then | |
+ RECONVERSION=yes | |
+ AC_DEFINE(RECONVERSION, 1, [Define to support RECONVERSION.]) | |
+ AC_DEFINE(HAVE_RECONVERTSTRING, 1, [Define to 1 if you have RECONVERTSTRING.]) | |
+ | |
+ DOCUMENTFEED=no | |
+ if test "${with_documentfeed}" != "no"; then | |
+ AC_CHECK_DECL(IMR_DOCUMENTFEED, HAVE_IMR_DOCUMENTFEED=yes, | |
+ HAVE_IMR_DOCUMENTFEED=no,[[ | |
+#include <windows.h> | |
+#include <imm.h>]]) | |
+ if test "$ac_cv_have_decl_IMR_DOCUMENTFEED" = "yes"; then | |
+ DOCUMENTFEED=yes | |
+ AC_DEFINE(DOCUMENTFEED, 1, [Define to support DOCUMENTFEED.]) | |
+ AC_DEFINE(HAVE_IMR_DOCUMENTFEED, 1, [Define to 1 if you have IMR_DOCUMENTFEED.]) | |
+ fi | |
+ fi | |
+ fi | |
+ fi | |
+ fi | |
+fi | |
+ | |
+HAVE_CMIGEMO=no | |
+if test "${with_cmigemo}" != "no"; then | |
+ AC_CHECK_HEADER(migemo.h, HAVE_CMIGEMO=yes) | |
+ if test "${HAVE_CMIGEMO}" = "yes"; then | |
+ AC_DEFINE(HAVE_CMIGEMO, 1, [Define to 1 if you have the "migemo.h" header file.]) | |
+ fi | |
+fi | |
+ | |
echo " | |
Configured for \`${canonical}'. | |
@@ -5056,6 +5106,20 @@ | |
echo " Does Emacs directly use zlib? ${HAVE_ZLIB}" | |
echo " Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS}" | |
+ | |
+if test "${HAVE_W32}" = "yes"; then | |
+ echo \ | |
+ " Does Emacs support W32-IME? ${USE_W32_IME}" | |
+ if test "${USE_W32_IME}" = "yes"; then | |
+ echo \ | |
+ " Does Emacs support RECONVERSION? ${RECONVERSION}" | |
+ if test "${RECONVERSION}" = "yes"; then | |
+ echo \ | |
+ " Does Emacs support DOCUMENTFEED? ${DOCUMENTFEED}" | |
+ fi | |
+ fi | |
+fi | |
+echo " Does Emacs use a cmigemo library? ${HAVE_CMIGEMO}" | |
echo | |
if test -n "${EMACSDATA}"; then | |
--- ./lib-src/make-docfile.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./lib-src/make-docfile.c 2015-04-11 07:27:30.436116800 +0900 | |
@@ -50,6 +50,7 @@ | |
#endif /* WINDOWSNT */ | |
#ifdef DOS_NT | |
+#include <mbstring.h> | |
/* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this | |
is really just insurance. | |
@@ -209,10 +210,18 @@ | |
{ | |
char *tmp; | |
+#ifdef DOS_NT | |
+ for (tmp = filename; *tmp; tmp = _mbsinc (tmp)) | |
+#else | |
for (tmp = filename; *tmp; tmp++) | |
+#endif | |
{ | |
if (IS_DIRECTORY_SEP (*tmp)) | |
+#ifdef DOS_NT | |
+ filename = _mbsinc (tmp); | |
+#else | |
filename = tmp + 1; | |
+#endif | |
} | |
putc (037, outfile); | |
--- ./lib-src/ntlib.c.orig 2015-02-02 02:27:17.000000000 +0900 | |
+++ ./lib-src/ntlib.c 2015-04-11 07:27:30.445112900 +0900 | |
@@ -370,7 +370,7 @@ | |
} | |
else | |
{ | |
- if (IS_DIRECTORY_SEP (name[len-1])) | |
+ if (IS_DIRECTORY_SEP (*_mbsdec(name, name + len))) | |
name[len - 1] = 0; | |
fh = FindFirstFile (name, &wfd); | |
--- ./lib-src/ntlib.h.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./lib-src/ntlib.h 2015-04-11 07:27:30.453111600 +0900 | |
@@ -90,6 +90,7 @@ | |
#define locking _locking | |
#define logb _logb | |
#define _longjmp longjmp | |
+#undef lseek | |
#define lseek _lseek | |
#define popen _popen | |
#define pclose _pclose | |
--- ./lisp/cedet/cedet-cscope.el.orig 2015-02-02 02:27:17.000000000 +0900 | |
+++ ./lisp/cedet/cedet-cscope.el 2015-04-11 07:27:30.477113600 +0900 | |
@@ -77,7 +77,7 @@ | |
"Create a CScope database at the current directory. | |
FLAGS are additional flags to pass to cscope beyond the | |
options -cR." | |
- (cedet-cscope-call (append (list "-cR") flags))) | |
+ (cedet-cscope-call (append (list "-bcR") flags))) | |
(defun cedet-cscope-call (flags) | |
"Call CScope with the list of FLAGS." | |
@@ -151,7 +151,7 @@ | |
nil) | |
(with-current-buffer b | |
(goto-char (point-min)) | |
- (re-search-forward "cscope: version \\([0-9.]+\\)" nil t) | |
+ (re-search-forward "cscope\\(?:\\.exe\\)?: version \\([0-9.]+\\)" nil t) | |
(setq rev (match-string 1)) | |
(if (inversion-check-version rev nil cedet-cscope-min-version) | |
(if noerror | |
--- ./lisp/image.el.orig 2015-02-02 02:27:17.000000000 +0900 | |
+++ ./lisp/image.el 2015-04-11 07:27:30.481113200 +0900 | |
@@ -126,6 +126,15 @@ | |
:type '(repeat (choice directory variable)) | |
:initialize 'custom-initialize-delay) | |
+;;;###autoload | |
+(defcustom image-fit-option-alist nil | |
+ "Alist of (IMAGE-TYPE . FIT-OPTION) pairs used by image loader to specify image size. | |
+the FIT-OPTION is one of 'never, 'frame, 'width-or-height, 'width or 'height. | |
+Note: All image loaders are not supporting this `fit' capability. | |
+" | |
+ :type 'sexp | |
+ :initialize 'custom-initialize-default | |
+ :group 'image) | |
(defun image-load-path-for-library (library image &optional path no-error) | |
"Return a suitable search path for images used by LIBRARY. | |
--- /dev/null 2015-04-11 07:27:55.000000000 +0900 | |
+++ ./lisp/international/w32-ime.el 2015-04-11 07:27:30.485113300 +0900 | |
@@ -0,0 +1,201 @@ | |
+;;;;; w32-ime.el ---- Meadow features for NTEmacs. | |
+;; | |
+;; Author H.Miyashita | |
+;; | |
+;;;;; | |
+ | |
+(defgroup W32-IME nil | |
+ "w32-ime" | |
+ :group 'emacs) | |
+ | |
+(defvar w32-last-selection nil | |
+ "It is stored the last data from Emacs.") | |
+ | |
+;---------- | |
+ | |
+(defvar w32-ime-on-hook nil | |
+ "Functions to eval when IME is turned on at least. | |
+Even if IME state is not changed, these functiona are maybe called.") | |
+(defvar w32-ime-off-hook nil | |
+ "Functions to eval when IME is turned off at least. | |
+Even if IME state is not changed, these functiona are maybe called.") | |
+(defvar w32-ime-buffer-switch-p t | |
+ "If this variable is nil, IME control when buffer is switched is disabled.") | |
+(defvar w32-ime-show-mode-line t | |
+ "When t, mode line indicates IME state.") | |
+(defvar w32-ime-mode-line-state-indicator "[O]" | |
+ "This is shown at the mode line. It is regarded as state of ime.") | |
+(make-variable-buffer-local 'w32-ime-mode-line-state-indicator) | |
+(put 'w32-ime-mode-line-state-indicator 'permanent-local t) | |
+(defvar w32-ime-mode-line-state-indicator-list '("-" "[|]" "[O]") | |
+ "List of IME state indicator string.") | |
+(defvar w32-ime-mode-line-format-original nil | |
+ "Original mode line format.") | |
+ | |
+;; | |
+;; Section: IME | |
+;; | |
+ | |
+;; ;; This is temporal solution. In the future, we will prepare | |
+;; ;; dynamic configuration. | |
+;; (defvar w32-ime-coding-system-language-environment-alist | |
+;; '(("Japanese" . japanese-shift-jis) | |
+;; ("Chinese-GB" . chinese-iso-8bit) | |
+;; ("Chinese-BIG5" . chinese-big5) | |
+;; ("Korean" . korean-iso-8bit))) | |
+ | |
+;; | |
+;; IME state indicator | |
+;; | |
+(global-set-key [kanji] 'ignore) | |
+(global-set-key [compend] 'ignore) | |
+ | |
+(defun wrap-function-to-control-ime | |
+ (function interactive-p interactive-arg &optional suffix) | |
+ "Wrap FUNCTION, and IME control is enabled when FUNCTION is called. | |
+An original function is saved to FUNCTION-SUFFIX when suffix is string. | |
+If SUFFIX is nil, \"-original\" is added. " | |
+ (let ((original-function | |
+ (intern (concat (symbol-name function) | |
+ (if suffix suffix "-original"))))) | |
+ (cond | |
+ ((not (fboundp original-function)) | |
+ (fset original-function | |
+ (symbol-function function)) | |
+ (fset function | |
+ (list | |
+ 'lambda '(&rest arguments) | |
+ (when interactive-p | |
+ (list 'interactive interactive-arg)) | |
+ `(cond | |
+ ((and (ime-get-mode) | |
+ (equal current-input-method "W32-IME")) | |
+ (ime-force-off) | |
+ (unwind-protect | |
+ (apply ',original-function arguments) | |
+ (when (and (not (ime-get-mode)) | |
+ (equal current-input-method "W32-IME")) | |
+ (ime-force-on)))) | |
+ (t | |
+ (apply ',original-function arguments))))))))) | |
+ | |
+(defvar w32-ime-toroku-region-yomigana nil | |
+ "* if this variable is string, toroku-region regard this value as yomigana.") | |
+ | |
+(defun w32-ime-toroku-region (begin end) | |
+ (interactive "r") | |
+ (let ((string (buffer-substring begin end)) | |
+ (w32-ime-buffer-switch-p nil) | |
+ (reading w32-ime-toroku-region-yomigana)) | |
+ (unless (stringp reading) | |
+ (w32-set-ime-mode 'hiragana) | |
+ (setq reading | |
+ (read-multilingual-string | |
+ (format "Input reading of \"%s\": " string) nil "W32-IME"))) | |
+ (w32-ime-register-word-dialog reading string))) | |
+ | |
+;; for IME management system. | |
+ | |
+(defun w32-ime-sync-state (window) | |
+ (when w32-ime-buffer-switch-p | |
+ (with-current-buffer (window-buffer window) | |
+ (let* ((frame (window-frame window)) | |
+ (ime-state (ime-get-mode))) | |
+ (cond | |
+ ((and (not ime-state) | |
+ (equal current-input-method "W32-IME")) | |
+ (ime-force-on nil) | |
+ (run-hooks 'w32-ime-on-hook)) | |
+ ((and ime-state | |
+ (not (equal current-input-method "W32-IME"))) | |
+;;; (when (= (w32-ime-undetermined-string-length) 0) | |
+ (ime-force-off nil) | |
+ (run-hooks 'w32-ime-off-hook))))))) | |
+ | |
+(defun w32-ime-set-selected-window-buffer-hook (oldbuf newwin newbuf) | |
+ (w32-ime-sync-state newwin)) | |
+ | |
+(defun w32-ime-select-window-hook (old new) | |
+ (w32-ime-sync-state new)) | |
+ | |
+(defun w32-ime-mode-line-update () | |
+ (cond | |
+ (w32-ime-show-mode-line | |
+ (unless (window-minibuffer-p (selected-window)) | |
+ (setq w32-ime-mode-line-state-indicator | |
+ (nth (if (ime-get-mode) 1 2) | |
+ w32-ime-mode-line-state-indicator-list)))) | |
+ (t | |
+ (setq w32-ime-mode-line-state-indicator | |
+ (nth 0 w32-ime-mode-line-state-indicator-list)))) | |
+ (force-mode-line-update)) | |
+ | |
+(defun w32-ime-init-mode-line-display () | |
+ (unless (member 'w32-ime-mode-line-state-indicator mode-line-format) | |
+ (setq w32-ime-mode-line-format-original | |
+ (default-value 'mode-line-format)) | |
+ (if (and (stringp (car mode-line-format)) | |
+ (string= (car mode-line-format) "-")) | |
+ (setq-default mode-line-format | |
+ (cons "" | |
+ (cons 'w32-ime-mode-line-state-indicator | |
+ (cdr mode-line-format)))) | |
+ (setq-default mode-line-format | |
+ (cons "" | |
+ (cons 'w32-ime-mode-line-state-indicator | |
+ mode-line-format)))) | |
+ (force-mode-line-update t))) | |
+ | |
+(defun w32-ime-initialize () | |
+ (when (and (or (eq system-type 'windows-nt) (eq system-type 'cygwin)) | |
+ (eq window-system 'w32) | |
+ (featurep 'w32-ime)) | |
+ (w32-ime-init-mode-line-display) | |
+ (w32-ime-mode-line-update) | |
+ (add-hook 'select-window-functions | |
+ 'w32-ime-select-window-hook) | |
+ (add-hook 'set-selected-window-buffer-functions | |
+ 'w32-ime-set-selected-window-buffer-hook) | |
+ (define-key global-map [kanji] 'toggle-input-method))) | |
+;; (set-keyboard-coding-system 'utf-8))) | |
+ | |
+(defun w32-ime-uninitialize () | |
+ (when (and (or (eq system-type 'windows-nt) (eq system-type 'cygwin)) | |
+ (eq window-system 'w32) | |
+ (featurep 'w32-ime)) | |
+ (setq-default mode-line-format | |
+ w32-ime-mode-line-format-original) | |
+ (force-mode-line-update t) | |
+ (remove-hook 'select-window-functions | |
+ 'w32-ime-select-window-hook) | |
+ (remove-hook 'set-selected-window-buffer-functions | |
+ 'w32-ime-set-selected-window-buffer-hook) | |
+ (define-key global-map [kanji] 'ignore))) | |
+ | |
+(defun w32-ime-exit-from-minibuffer () | |
+ (deactivate-input-method) | |
+ (when (<= (minibuffer-depth) 1) | |
+ (remove-hook 'minibuffer-exit-hook 'w32-ime-exit-from-minibuffer))) | |
+ | |
+(defun w32-ime-state-switch (&optional arg) | |
+ (if arg | |
+ (progn | |
+ (setq deactivate-current-input-method-function | |
+ 'w32-ime-state-switch) | |
+ (run-hooks 'input-method-activate-hook) | |
+ (run-hooks 'w32-ime-on-hook) | |
+ (setq describe-current-input-method-function nil) | |
+ (when (eq (selected-window) (minibuffer-window)) | |
+ (add-hook 'minibuffer-exit-hook 'w32-ime-exit-from-minibuffer)) | |
+ (ime-force-on)) | |
+ (setq current-input-method nil) | |
+ (run-hooks 'input-method-deactivate-hook) | |
+ (run-hooks 'w32-ime-off-hook) | |
+ (setq describe-current-input-method-function nil) | |
+ (ime-force-off)) | |
+ (w32-ime-mode-line-update)) | |
+ | |
+(register-input-method "W32-IME" "Japanese" 'w32-ime-state-switch "" | |
+ "W32 System IME") | |
+ | |
+(provide 'w32-ime) | |
--- ./lisp/language/japan-util.el.orig 2015-02-02 02:27:17.000000000 +0900 | |
+++ ./lisp/language/japan-util.el 2015-04-11 07:27:30.491115400 +0900 | |
@@ -31,9 +31,11 @@ | |
(defun setup-japanese-environment-internal () | |
;; By default, we use 'japanese-iso-8bit for file names. But, the | |
;; following prefer-coding-system will override it. | |
- (if (memq system-type '(windows-nt ms-dos cygwin)) | |
+ (if (memq system-type '(windows-nt ms-dos)) | |
(prefer-coding-system 'japanese-shift-jis) | |
- (prefer-coding-system 'japanese-iso-8bit)) | |
+ (if (eq system-type 'cygwin) | |
+ (prefer-coding-system 'utf-8) | |
+ (prefer-coding-system 'japanese-iso-8bit))) | |
(use-cjk-char-width-table 'ja_JP)) | |
(defconst japanese-kana-table | |
--- ./lisp/loadup.el.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./lisp/loadup.el 2015-04-11 07:27:30.494115700 +0900 | |
@@ -250,6 +250,7 @@ | |
(load "term/w32-win") | |
(load "disp-table") | |
(load "w32-common-fns") | |
+ (load "international/w32-ime") | |
(when (eq system-type 'windows-nt) | |
(load "w32-fns") | |
(load "ls-lisp") | |
--- ./lisp/startup.el.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./lisp/startup.el 2015-04-11 07:27:30.499116000 +0900 | |
@@ -595,6 +595,7 @@ | |
(put 'user-full-name 'standard-value | |
(list (default-value 'user-full-name))) | |
;; If the PWD environment variable isn't accurate, delete it. | |
+ (set-language-environment "japanese") | |
(let ((pwd (getenv "PWD"))) | |
(and (stringp pwd) | |
;; Use FOO/., so that if FOO is a symlink, file-attributes | |
@@ -1630,7 +1631,7 @@ | |
(defun fancy-splash-head () | |
"Insert the head part of the splash screen into the current buffer." | |
(let* ((image-file (fancy-splash-image-file)) | |
- (img (create-image image-file)) | |
+ (img (create-image image-file nil nil :fit 'never)) | |
(image-width (and img (car (image-size img)))) | |
(window-width (window-width))) | |
(when img | |
--- ./nt/inc/sys/socket.h.orig 2015-02-02 02:27:17.000000000 +0900 | |
+++ ./nt/inc/sys/socket.h 2015-04-11 07:27:30.502115800 +0900 | |
@@ -99,7 +99,11 @@ | |
#define recvfrom sys_recvfrom | |
#define sendto sys_sendto | |
+#ifdef __MINGW64__ | |
+SOCKET sys_socket(int af, int type, int protocol); | |
+#else | |
int sys_socket(int af, int type, int protocol); | |
+#endif | |
int sys_bind (int s, const struct sockaddr *addr, int namelen); | |
int sys_connect (int s, const struct sockaddr *addr, int namelen); | |
u_short sys_htons (u_short hostshort); | |
--- /dev/null 2015-04-11 07:27:56.000000000 +0900 | |
+++ ./sample/lisp/site-init.el 2015-04-11 07:27:30.510115100 +0900 | |
@@ -0,0 +1,19 @@ | |
+;; | |
+;; image options | |
+;; | |
+(setq image-library-alist | |
+ '((xpm "libxpm.dll" "xpm4.dll" "libXpm-nox4.dll") | |
+ (png "libpng14-14.dll" "libpng14.dll" "libpng15.dll") | |
+ (jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll" | |
+ "libjpeg-8.dll" "jpegdll.dll") | |
+ (tiff "libtiff3.dll" "libtiff.dll" "libtiff-3.dll") | |
+ (gif "giflib4.dll" "libungif4.dll" "libungif.dll") | |
+ (svg "librsvg-2-2.dll" "librsvg2.dll") | |
+ (gdk-pixbuf "libgdk_pixbuf-2.0-0.dll" "gdk_pixbuf-2-vs9.dll") | |
+ (glib "libglib-2.0-0.dll" "glib-2-vs9.dll" ) | |
+ (gobject "libgobject-2.0-0.dll" "gobject-2-vs9.dll"))) | |
+ | |
+(setq image-fit-option-alist | |
+ '((jpeg . frame) | |
+ (svg . width-or-height))) | |
+ | |
--- /dev/null 2015-04-11 07:27:57.000000000 +0900 | |
+++ ./sample/lisp/site-start.el 2015-04-11 07:27:30.515116900 +0900 | |
@@ -0,0 +1,10 @@ | |
+;; | |
+;; create init.el for japanese user | |
+;; | |
+(when (and (not noninteractive) | |
+ (eq (window-system) 'w32) | |
+ (= (w32-get-default-locale-id) 1041)) ; japanese? | |
+ (add-hook 'after-init-hook | |
+ #'(lambda () | |
+ (unless (file-exists-p user-init-file) | |
+ (load-library "ezsetup"))))) | |
\ No newline at end of file | |
--- /dev/null 2015-04-11 07:27:57.000000000 +0900 | |
+++ ./site-lisp/cmigemo.el 2015-04-11 07:27:30.524115400 +0900 | |
@@ -0,0 +1,811 @@ | |
+;;; migemo.el --- Japanese incremental search through dynamic pattern expansion | |
+ | |
+;; $Id: migemo.el.in,v 1.9 2012/06/24 04:09:59 kaworu Exp $ | |
+;; Copyright (C) Satoru Takabayashi | |
+ | |
+;; Author: Satoru Takabayashi <satoru-t@is.aist-nara.ac.jp> | |
+;; URL: https://github.com/emacs-jp/migemo | |
+;; Version: 1.9 | |
+;; Keywords: | |
+ | |
+;; This file is free software; you can redistribute it and/or modify | |
+;; it under the terms of the GNU General Public License as published by | |
+;; the Free Software Foundation; either version 2, or (at your option) | |
+;; any later version. | |
+ | |
+;; This file is distributed in the hope that it will be useful, | |
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+;; GNU General Public License for more details. | |
+ | |
+;; You should have received a copy of the GNU General Public License | |
+;; along with GNU Emacs; see the file COPYING. If not, write to | |
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
+;; Boston, MA 02111-1307, USA. | |
+ | |
+;;; Commentary: | |
+ | |
+;; | |
+ | |
+;;; Code: | |
+(defgroup migemo nil | |
+ "migemo - Japanese incremental search trough dynamic pattern expansion." | |
+ :group 'matching) | |
+ | |
+(defcustom migemo-cmigemo-library "cmigemo.dll" | |
+ "*Name or full path of the cmigemo dynamic library." | |
+ :group 'migemo | |
+ :type 'string) | |
+ | |
+(defcustom migemo-command "ruby" | |
+ "*Name or full path of the executable for running migemo." | |
+ :group 'migemo | |
+ :type '(choice (const :tag "Ruby Migemo" "ruby") | |
+ (const :tag "CMIGEMO" "cmigemo") | |
+ (string :tag "Other"))) | |
+ | |
+;; -t emacs for specifying the type of regular expression. | |
+;; "-i" "\a" for searching a word over multi-lines. | |
+(defcustom migemo-options '("-S" "migemo" "-t" "emacs" "-i" "\a") | |
+ "*Options for migemo command." | |
+ :group 'migemo | |
+ :type '(repeat string)) | |
+ | |
+(defcustom migemo-white-space-regexp "[ ¡¡\t\r\n]*" | |
+ "*Regexp representing white spaces." | |
+ :group 'migemo | |
+ :type 'string) | |
+ | |
+;; for C/Migemo | |
+;; (setq migemo-command "cmigemo") | |
+;; (setq migemo-options '("-q" "--emacs" "-i" "\g")) | |
+;; (setq migemo-dictionary "somewhere/migemo/euc-jp/migemo-dict") | |
+;; (setq migemo-user-dictionary nil) | |
+;; (setq migemo-regex-dictionary nil)) | |
+ | |
+(defcustom migemo-directory | |
+ (if (eq system-type 'windows-nt) | |
+ (concat data-directory "migemo") | |
+ "/usr/local/share/migemo") | |
+ "*Directory where migemo files are placed" | |
+ :group 'migemo | |
+ :type 'directory) | |
+ | |
+(defcustom migemo-isearch-enable-p t | |
+ "*Enable the migemo feature on isearch or not." | |
+ :group 'migemo | |
+ :type 'boolean) | |
+ | |
+(defcustom migemo-dictionary | |
+ (expand-file-name (concat "utf-8" "/migemo-dict") migemo-directory) | |
+ "*Migemo dictionary file." | |
+ :group 'migemo | |
+ :type '(file :must-match t)) | |
+ | |
+(defcustom migemo-user-dictionary nil | |
+ "*Migemo user dictionary file." | |
+ :group 'migemo | |
+ :type '(choice (file :must-match t) | |
+ (const :tag "Do not use" nil))) | |
+ | |
+(defcustom migemo-regex-dictionary nil | |
+ "*Migemo regex dictionary file." | |
+ :group 'migemo | |
+ :type '(choice (file :must-match t) | |
+ (const :tag "Do not use" nil))) | |
+ | |
+(defcustom migemo-pre-conv-function nil | |
+ "*Function of migemo pre-conversion." | |
+ :group 'migemo | |
+ :type '(choice (const :tag "Do not use" nil) | |
+ function)) | |
+ | |
+(defcustom migemo-after-conv-function nil | |
+ "*Function of migemo after-conversion." | |
+ :group 'migemo | |
+ :type '(choice (const :tag "Do not use" nil) | |
+ function)) | |
+ | |
+(defcustom migemo-coding-system | |
+ (with-no-warnings | |
+ (if (>= emacs-major-version 20) | |
+ (if (featurep 'mule) | |
+ (if (string-match "XEmacs" emacs-version) | |
+ (cond | |
+ ((memq 'euc-japan-unix (coding-system-list)) 'euc-japan-unix) | |
+ ((memq 'euc-jp-unix (coding-system-list)) 'euc-jp-unix)) | |
+ 'euc-japan-unix)) | |
+ (and (boundp 'MULE) *euc-japan*unix))) | |
+ "*Default coding system for migemo.el" | |
+ :group 'migemo | |
+ :type 'coding-system) | |
+ | |
+(defcustom migemo-use-pattern-alist nil | |
+ "*Use pattern cache." | |
+ :group 'migemo | |
+ :type 'boolean) | |
+ | |
+(defcustom migemo-use-frequent-pattern-alist nil | |
+ "*Use frequent patttern cache." | |
+ :group 'migemo | |
+ :type 'boolean) | |
+ | |
+(defcustom migemo-pattern-alist-length 512 | |
+ "*Maximal length of migemo-pattern-alist." | |
+ :group 'migemo | |
+ :type 'integer) | |
+ | |
+(defcustom migemo-pattern-alist-file "~/.migemo-pattern" | |
+ "*Path of migemo alist file. If nil, don't save and restore the file." | |
+ :group 'migemo | |
+ :type 'file) | |
+ | |
+(defcustom migemo-frequent-pattern-alist-file "~/.migemo-frequent" | |
+ "*Path of migemo frequent alist file. If nil, don't save and restore the file." | |
+ :group 'migemo | |
+ :type 'file) | |
+ | |
+(defcustom migemo-accept-process-output-timeout-msec 5 | |
+ "*Timeout of migemo process communication." | |
+ :group 'migemo | |
+ :type 'integer) | |
+ | |
+(defcustom migemo-isearch-min-length 1 | |
+ "*Minimum length of word to start isearch." | |
+ :group 'migemo | |
+ :type 'integer) | |
+ | |
+(defconst migemo-mw32-input-method (and (featurep 'meadow) "MW32-IME") | |
+ "Support \"MW32-IME\" for Meadow.") | |
+ | |
+;; internal variables | |
+(defvar migemo-process nil) | |
+(defvar migemo-buffer nil) | |
+(defvar migemo-current-input-method nil) | |
+(defvar migemo-search-pattern nil) | |
+(defvar migemo-pattern-alist nil) | |
+(defvar migemo-frequent-pattern-alist nil) | |
+(defconst migemo-emacs21p (and (> emacs-major-version 20) (not (featurep 'xemacs)))) | |
+(defvar migemo-search-pattern-alist nil) | |
+(defvar migemo-do-isearch nil) | |
+(defvar cmigemo-initialized nil) | |
+ | |
+(defconst coding-system-for-japanese | |
+ (let ((cs (cdr (assoc 'coding-system | |
+ (assoc "Japanese" language-info-alist))))) | |
+ (append | |
+ (mapcar | |
+ #'(lambda (c) | |
+ (intern-soft (concat (symbol-name c) "-unix"))) cs) | |
+ (mapcar | |
+ #'(lambda (c) | |
+ (intern-soft (concat (symbol-name c) "-dos"))) cs) | |
+ (mapcar | |
+ #'(lambda (c) | |
+ (intern-soft (concat (symbol-name c) "-mac"))) cs)))) | |
+ | |
+;; For warnings of byte-compile. Following functions are defined in XEmacs | |
+(declare-function set-process-input-coding-system "code-process") | |
+(declare-function set-process-output-coding-system "code-process") | |
+ | |
+(defsubst migemo-search-pattern-get (string) | |
+ (let ((pattern (cdr (assoc string migemo-search-pattern-alist)))) | |
+ (unless pattern | |
+ (setq pattern (migemo-get-pattern string)) | |
+ (setq migemo-search-pattern-alist | |
+ (cons (cons string pattern) | |
+ migemo-search-pattern-alist))) | |
+ pattern)) | |
+ | |
+(defun migemo-toggle-isearch-enable () | |
+ (interactive) | |
+ (setq migemo-isearch-enable-p (not migemo-isearch-enable-p)) | |
+ (message (if migemo-isearch-enable-p | |
+ "t" | |
+ "nil"))) | |
+ | |
+(defun migemo-start-process (name buffer program args) | |
+ (let ((proc (apply 'start-process name buffer program args))) | |
+ (if (fboundp 'set-process-coding-system) | |
+ (set-process-coding-system proc | |
+ migemo-coding-system | |
+ migemo-coding-system) | |
+ (set-process-input-coding-system proc migemo-coding-system) | |
+ (set-process-output-coding-system proc migemo-coding-system)) | |
+ proc)) | |
+ | |
+(defun migemo-init () | |
+ (when (and migemo-use-frequent-pattern-alist | |
+ migemo-frequent-pattern-alist-file | |
+ (null migemo-frequent-pattern-alist)) | |
+ (setq migemo-frequent-pattern-alist | |
+ (migemo-pattern-alist-load migemo-frequent-pattern-alist-file))) | |
+ (when (and migemo-use-pattern-alist | |
+ migemo-pattern-alist-file | |
+ (null migemo-pattern-alist)) | |
+ (setq migemo-pattern-alist | |
+ (migemo-pattern-alist-load migemo-pattern-alist-file))) | |
+ ;; C/Migemo begin | |
+ (if (fboundp 'cmigemo-open) | |
+ (when (not cmigemo-initialized) | |
+ (setq cmigemo-initialized | |
+ (cmigemo-open migemo-dictionary)) | |
+ (if (consp migemo-user-dictionary) | |
+ (dolist (d migemo-user-dictionary) | |
+ (cmigemo-load d)) | |
+ (cmigemo-load migemo-user-dictionary))) | |
+ ;; !!!WARNING!!! the following block has original indent | |
+ (or (and migemo-process | |
+ (eq (process-status migemo-process) 'run)) | |
+ (let ((options | |
+ (delq nil | |
+ (append migemo-options | |
+ (when (and migemo-user-dictionary | |
+ (file-exists-p migemo-user-dictionary)) | |
+ (list "-u" migemo-user-dictionary)) | |
+ (when (and migemo-regex-dictionary | |
+ (file-exists-p migemo-regex-dictionary)) | |
+ (list "-r" migemo-regex-dictionary)) | |
+ (list "-d" migemo-dictionary))))) | |
+ (setq migemo-buffer (get-buffer-create " *migemo*")) | |
+ (setq migemo-process (migemo-start-process | |
+ "migemo" migemo-buffer migemo-command options)) | |
+ (set-process-query-on-exit-flag migemo-process nil) | |
+ t)))) | |
+ ;; C/Migemo end | |
+ | |
+(defun migemo-replace-in-string (string from to) | |
+ (with-temp-buffer | |
+ (insert string) | |
+ (goto-char (point-min)) | |
+ (let ((migemo-do-isearch nil)) | |
+ (while (search-forward from nil t) | |
+ (replace-match to nil t))) | |
+ (buffer-substring (point-min) (point-max)))) | |
+ | |
+(defun migemo-get-pattern (word) | |
+ (cond | |
+ ((< (length word) migemo-isearch-min-length) | |
+ "") | |
+ (t | |
+ (let (deactivate-mark pattern freq alst) | |
+ (set-text-properties 0 (length word) nil word) | |
+ (migemo-init) | |
+ (when (and migemo-pre-conv-function | |
+ (functionp migemo-pre-conv-function)) | |
+ (setq word (funcall migemo-pre-conv-function word))) | |
+ (setq pattern | |
+ (cond | |
+ ((setq freq (and migemo-use-frequent-pattern-alist | |
+ (assoc word migemo-frequent-pattern-alist))) | |
+ (cdr freq)) | |
+ ((setq alst (and migemo-use-pattern-alist | |
+ (assoc word migemo-pattern-alist))) | |
+ (setq migemo-pattern-alist (cons alst (delq alst migemo-pattern-alist))) | |
+ (cdr alst)) | |
+ (t | |
+ ;; C/Migemo begin | |
+ (if (fboundp 'cmigemo-open) | |
+ (setq pattern (cmigemo-query word)) | |
+ ;; !!!WARNING!!! the following block has original indent | |
+ (with-current-buffer (process-buffer migemo-process) | |
+ (delete-region (point-min) (point-max)) | |
+ (process-send-string migemo-process (concat word "\n")) | |
+ (while (not (and (> (point-max) 1) | |
+ (eq (char-after (1- (point-max))) ?\n))) | |
+ (accept-process-output migemo-process | |
+ 0 migemo-accept-process-output-timeout-msec)) | |
+ (setq pattern (buffer-substring (point-min) (1- (point-max)))))) | |
+ ;; C/Migemo end | |
+ (when (and (memq system-type '(windows-nt OS/2 emx)) | |
+ (> (length pattern) 1) | |
+ (eq ?\r (aref pattern (1- (length pattern))))) | |
+ (setq pattern (substring pattern 0 -1))) | |
+ (when migemo-use-pattern-alist | |
+ (setq migemo-pattern-alist | |
+ (cons (cons word pattern) migemo-pattern-alist)) | |
+ (when (and migemo-pattern-alist-length | |
+ (> (length migemo-pattern-alist) | |
+ (* migemo-pattern-alist-length 2))) | |
+ (setcdr (nthcdr (1- (* migemo-pattern-alist-length 2)) | |
+ migemo-pattern-alist) nil))) | |
+ pattern))) | |
+ (if (and migemo-after-conv-function | |
+ (functionp migemo-after-conv-function)) | |
+ (funcall migemo-after-conv-function word pattern) | |
+ (migemo-replace-in-string pattern "\a" migemo-white-space-regexp)))))) | |
+ | |
+(defun migemo-pattern-alist-load (file) | |
+ "Load migemo alist file." | |
+ (setq file (expand-file-name file)) | |
+ (when (file-readable-p file) | |
+ (with-temp-buffer | |
+ (let ((coding-system-for-read migemo-coding-system) | |
+ (buffer-file-coding-system migemo-coding-system))) | |
+ (insert-file-contents file) | |
+ (goto-char (point-min)) | |
+ (condition-case err | |
+ (read (current-buffer)) | |
+ (error | |
+ (message "Error while reading %s; %s" | |
+ (file-name-nondirectory file) | |
+ (error-message-string err)) | |
+ nil))))) | |
+ | |
+(defun migemo-pattern-alist-save (&optional clear) | |
+ "Save migemo alist file." | |
+ (interactive) | |
+ (when (and migemo-use-pattern-alist | |
+ migemo-pattern-alist-file | |
+ (or migemo-pattern-alist clear)) | |
+ (let ((file (expand-file-name migemo-pattern-alist-file))) | |
+ (when (file-writable-p file) | |
+ (when clear | |
+ (setq migemo-pattern-alist nil)) | |
+ (when (and migemo-pattern-alist-length | |
+ (> (length migemo-pattern-alist) migemo-pattern-alist-length)) | |
+ (setcdr (nthcdr (1- migemo-pattern-alist-length) | |
+ migemo-pattern-alist) nil)) | |
+ (with-temp-buffer | |
+ (let ((coding-system-for-write migemo-coding-system) | |
+ (buffer-file-coding-system migemo-coding-system)) | |
+ (if (fboundp 'pp) | |
+ (pp migemo-pattern-alist (current-buffer)) | |
+ (prin1 migemo-pattern-alist (current-buffer))) | |
+ (write-region (point-min) (point-max) file nil 'nomsg))) | |
+ (setq migemo-pattern-alist nil))))) | |
+ | |
+(defun migemo-kill () | |
+ "Kill migemo process" | |
+ (interactive) | |
+ ;; C/Migemo begin | |
+ (if (fboundp 'cmigemo-open) | |
+ (when cmigemo-initialized | |
+ (cmigemo-close)) | |
+ ;; !!!WARNING!!! the following block has original indent | |
+ (when (and migemo-process (eq (process-status migemo-process) 'run)) | |
+ (kill-process migemo-process) | |
+ (setq migemo-process nil) | |
+ (when (get-buffer migemo-buffer) | |
+ (kill-buffer migemo-buffer))))) | |
+ ;; C/Migemo end | |
+ | |
+(defun migemo-pattern-alist-clear () | |
+ "Clear migemo alist data & file." | |
+ (interactive) | |
+ (migemo-kill) | |
+ (migemo-pattern-alist-save 'clear) | |
+ (migemo-init)) | |
+ | |
+(defun migemo-frequent-pattern-make (fcfile) | |
+ "Create frequent pattern from `frequent-chars'." | |
+ (interactive "ffrequent-chars: ") | |
+ (migemo-pattern-alist-save 'clear) | |
+ (when migemo-frequent-pattern-alist-file | |
+ (migemo-kill) | |
+ (migemo-init) | |
+ (let ((file (expand-file-name migemo-frequent-pattern-alist-file)) | |
+ (migemo-use-pattern-alist nil) | |
+ (migemo-use-frequent-pattern-alist nil) | |
+ (migemo-after-conv-function (lambda (_x y) y)) | |
+ word) | |
+ (setq migemo-frequent-pattern-alist nil) | |
+ (with-temp-buffer | |
+ (let ((coding-system-for-write migemo-coding-system) | |
+ (buffer-file-coding-system migemo-coding-system))) | |
+ (insert-file-contents fcfile) | |
+ (goto-char (point-min)) | |
+ (message "Make frequently pattern...") | |
+ (while (not (eobp)) | |
+ (when (looking-at "^[a-z]+$") | |
+ (setq word (match-string 0)) | |
+ (message "Make frequently pattern...%s" word) | |
+ (setq migemo-frequent-pattern-alist | |
+ (cons (cons word (migemo-get-pattern word)) | |
+ migemo-frequent-pattern-alist))) | |
+ (forward-line 1)) | |
+ (when (file-writable-p file) | |
+ (setq migemo-frequent-pattern-alist | |
+ (nreverse migemo-frequent-pattern-alist)) | |
+ (erase-buffer) | |
+ (if (fboundp 'pp) | |
+ (pp migemo-frequent-pattern-alist (current-buffer)) | |
+ (prin1 migemo-frequent-pattern-alist (current-buffer))) | |
+ (write-region (point-min) (point-max) file nil 'nomsg))) | |
+ (migemo-kill) | |
+ (migemo-init) | |
+ (message "Make frequently pattern...done")))) | |
+ | |
+(defun migemo-expand-pattern () "\ | |
+Expand the Romaji sequences on the left side of the cursor | |
+into the migemo's regexp pattern." | |
+ (interactive) | |
+ (let ((pos (point))) | |
+ (goto-char (- pos 1)) | |
+ (if (re-search-backward "[^-a-zA-Z]" (line-beginning-position) t) | |
+ (forward-char 1) | |
+ (beginning-of-line)) | |
+ (let* ((str (buffer-substring-no-properties (point) pos)) | |
+ (jrpat (migemo-get-pattern str))) | |
+ (delete-region (point) pos) | |
+ (insert jrpat)))) | |
+ | |
+(defun migemo-forward (word &optional bound noerror count) | |
+ (interactive "sSearch: \nP\nP") | |
+ (if (delq 'ascii (find-charset-string word)) | |
+ (setq migemo-search-pattern word) | |
+ (setq migemo-search-pattern (migemo-search-pattern-get word))) | |
+ (search-forward-regexp migemo-search-pattern bound noerror count)) | |
+ | |
+(defun migemo-backward (word &optional bound noerror count) | |
+ (interactive "sSearch backward: \nP\nP") | |
+ (if (delq 'ascii (find-charset-string word)) | |
+ (setq migemo-search-pattern word) | |
+ (setq migemo-search-pattern (migemo-search-pattern-get word))) | |
+ (if (null migemo-do-isearch) | |
+ (search-backward-regexp migemo-search-pattern bound noerror count) | |
+ (or (and (not (eq this-command 'isearch-repeat-backward)) | |
+ (not (get-char-property (point) 'invisible (current-buffer))) | |
+ (or (and (looking-at migemo-search-pattern) | |
+ (match-beginning 0)) | |
+ (and (not (eq (point) (point-min))) | |
+ (progn (forward-char -1) | |
+ (and (looking-at migemo-search-pattern) | |
+ (match-beginning 0)))))) | |
+ (search-backward-regexp migemo-search-pattern bound noerror count)))) | |
+ | |
+;; experimental | |
+;; (define-key global-map "\M-;" 'migemo-dabbrev-expand) | |
+(defcustom migemo-dabbrev-display-message nil | |
+ "*Display dabbrev message to minibuffer." | |
+ :group 'migemo | |
+ :type 'boolean) | |
+ | |
+(defcustom migemo-dabbrev-ol-face 'highlight | |
+ "*Face of migemo-dabbrev overlay." | |
+ :group 'migemo | |
+ :type 'face) | |
+ | |
+(defvar migemo-dabbrev-pattern nil) | |
+(defvar migemo-dabbrev-start-point nil) | |
+(defvar migemo-dabbrev-search-point nil) | |
+(defvar migemo-dabbrev-pre-patterns nil) | |
+(defvar migemo-dabbrev-ol nil) | |
+(defun migemo-dabbrev-expand-done () | |
+ (remove-hook 'pre-command-hook 'migemo-dabbrev-expand-done) | |
+ (unless (eq last-command this-command) | |
+ (setq migemo-search-pattern-alist nil) | |
+ (setq migemo-dabbrev-pre-patterns nil)) | |
+ (when migemo-dabbrev-ol | |
+ (delete-overlay migemo-dabbrev-ol))) | |
+ | |
+(defun migemo-dabbrev-expand () | |
+ (interactive) | |
+ (let ((end-pos (point)) | |
+ matched-start matched-string) | |
+ (if (eq last-command this-command) | |
+ (goto-char migemo-dabbrev-search-point) | |
+ (goto-char (- end-pos 1)) | |
+ (if (re-search-backward "[^a-z-]" (line-beginning-position) t) | |
+ (forward-char 1) | |
+ (beginning-of-line)) | |
+ (setq migemo-search-pattern-alist nil) | |
+ (setq migemo-dabbrev-start-point (point)) | |
+ (setq migemo-dabbrev-search-point (point)) | |
+ (setq migemo-dabbrev-pattern | |
+ (buffer-substring-no-properties (point) end-pos)) | |
+ (setq migemo-dabbrev-pre-patterns nil)) | |
+ (if (catch 'found | |
+ (while (if (> migemo-dabbrev-search-point migemo-dabbrev-start-point) | |
+ (and (migemo-forward migemo-dabbrev-pattern (point-max) t) | |
+ (setq migemo-dabbrev-search-point (match-end 0))) | |
+ (if (migemo-backward migemo-dabbrev-pattern (point-min) t) | |
+ (setq migemo-dabbrev-search-point (match-beginning 0)) | |
+ (goto-char migemo-dabbrev-start-point) | |
+ (forward-word 1) | |
+ (message (format "Trun back for `%s'" migemo-dabbrev-pattern)) | |
+ (and (migemo-forward migemo-dabbrev-pattern (point-max) t) | |
+ (setq migemo-dabbrev-search-point (match-end 0))))) | |
+ (setq matched-start (match-beginning 0)) | |
+ (unless (re-search-forward ".\\>" (line-end-position) t) | |
+ (end-of-line)) | |
+ (setq matched-string (buffer-substring-no-properties matched-start (point))) | |
+ (unless (member matched-string migemo-dabbrev-pre-patterns) | |
+ (let ((matched-end (point)) | |
+ (str (copy-sequence matched-string)) | |
+ lstart lend) | |
+ (if (and (pos-visible-in-window-p matched-start) | |
+ (pos-visible-in-window-p matched-end)) | |
+ (progn | |
+ (if migemo-dabbrev-ol | |
+ (move-overlay migemo-dabbrev-ol matched-start (point)) | |
+ (setq migemo-dabbrev-ol (make-overlay matched-start (point)))) | |
+ (overlay-put migemo-dabbrev-ol 'evaporate t) | |
+ (overlay-put migemo-dabbrev-ol 'face migemo-dabbrev-ol-face)) | |
+ (when migemo-dabbrev-ol | |
+ (delete-overlay migemo-dabbrev-ol)) | |
+ (when migemo-dabbrev-display-message | |
+ (save-excursion | |
+ (save-restriction | |
+ (goto-char matched-start) | |
+ (setq lstart (progn (beginning-of-line) (point))) | |
+ (setq lend (progn (end-of-line) (point))) | |
+ (if migemo-emacs21p | |
+ (put-text-property 0 (length str) | |
+ 'face migemo-dabbrev-ol-face str) | |
+ (setq str (concat "¡Ú" str "¡Û"))) | |
+ (message "(%d): %s%s%s" | |
+ (count-lines (point-min) matched-start) | |
+ (buffer-substring-no-properties lstart matched-start) | |
+ str | |
+ (buffer-substring-no-properties matched-end lend))))))) | |
+ (throw 'found t)) | |
+ (goto-char migemo-dabbrev-search-point))) | |
+ (progn | |
+ (setq migemo-dabbrev-pre-patterns | |
+ (cons matched-string migemo-dabbrev-pre-patterns)) | |
+ (delete-region migemo-dabbrev-start-point end-pos) | |
+ (forward-char 1) | |
+ (goto-char migemo-dabbrev-start-point) | |
+ (insert matched-string)) | |
+ (goto-char end-pos) | |
+ (message (format "No dynamic expansion for `%s' found" | |
+ migemo-dabbrev-pattern))) | |
+ (add-hook 'pre-command-hook 'migemo-dabbrev-expand-done))) | |
+ | |
+;; Use migemo-{forward,backward} instead of search-{forward,backward}. | |
+(defadvice isearch-search (around migemo-search-ad activate) | |
+ "adviced by migemo." | |
+ (when migemo-isearch-enable-p | |
+ (setq migemo-do-isearch t)) | |
+ (unwind-protect | |
+ ad-do-it | |
+ (setq migemo-do-isearch nil))) | |
+ | |
+(defadvice isearch-search-and-update (around migemo-search-ad activate) | |
+ "adviced by migemo." | |
+ (let ((isearch-adjusted isearch-adjusted)) | |
+ (when (and migemo-isearch-enable-p | |
+ (not isearch-forward) (not isearch-regexp) (not isearch-word)) | |
+ ;; don't use 'looking-at' | |
+ (setq isearch-adjusted t)) | |
+ ad-do-it)) | |
+ | |
+(defadvice search-forward (around migemo-search-ad activate) | |
+ "adviced by migemo." | |
+ (if migemo-do-isearch | |
+ (setq ad-return-value | |
+ (migemo-forward (ad-get-arg 0) (ad-get-arg 1) (ad-get-arg 2) (ad-get-arg 3))) | |
+ ad-do-it)) | |
+ | |
+(defadvice search-backward (around migemo-search-ad activate) | |
+ "adviced by migemo." | |
+ (if migemo-do-isearch | |
+ (setq ad-return-value | |
+ (migemo-backward (ad-get-arg 0) (ad-get-arg 1) (ad-get-arg 2) (ad-get-arg 3))) | |
+ ad-do-it)) | |
+ | |
+(when (and (boundp 'isearch-regexp-lax-whitespace) | |
+ (fboundp 're-search-forward-lax-whitespace) | |
+ (fboundp 'search-forward-lax-whitespace)) | |
+ (setq isearch-search-fun-function 'isearch-search-fun-migemo) | |
+ | |
+ (defun isearch-search-fun-migemo () | |
+ "Return default functions to use for the search with migemo." | |
+ (cond | |
+ (isearch-word | |
+ (lambda (string &optional bound noerror count) | |
+ ;; Use lax versions to not fail at the end of the word while | |
+ ;; the user adds and removes characters in the search string | |
+ ;; (or when using nonincremental word isearch) | |
+ (let* ((state-string-func (if (fboundp 'isearch--state-string) | |
+ 'isearch--state-string | |
+ 'isearch-string-state)) | |
+ (lax (not (or isearch-nonincremental | |
+ (eq (length isearch-string) | |
+ (length (funcall state-string-func (car isearch-cmds)))))))) | |
+ (funcall | |
+ (if isearch-forward #'re-search-forward #'re-search-backward) | |
+ (if (functionp isearch-word) | |
+ (funcall isearch-word string lax) | |
+ (word-search-regexp string lax)) | |
+ bound noerror count)))) | |
+ ((and isearch-regexp isearch-regexp-lax-whitespace | |
+ search-whitespace-regexp) | |
+ (if isearch-forward | |
+ 're-search-forward-lax-whitespace | |
+ 're-search-backward-lax-whitespace)) | |
+ (isearch-regexp | |
+ (if isearch-forward 're-search-forward 're-search-backward)) | |
+ ((and (if (boundp 'isearch-lax-whitespace) isearch-lax-whitespace t) | |
+ search-whitespace-regexp migemo-do-isearch) | |
+ (if isearch-forward 'migemo-forward 'migemo-backward)) | |
+ ((and (if (boundp 'isearch-lax-whitespace) isearch-lax-whitespace t) | |
+ search-whitespace-regexp) | |
+ (if isearch-forward 'search-forward-lax-whitespace | |
+ 'search-backward-lax-whitespace)) | |
+ (migemo-do-isearch | |
+ (if isearch-forward 'migemo-forward 'migemo-backward)) | |
+ (t | |
+ (if isearch-forward 'search-forward 'search-backward)))) | |
+ ) | |
+ | |
+(defun japanese-p (coding-system-list) | |
+ (cond ((atom coding-system-list) nil) | |
+ ((member (car coding-system-list) | |
+ coding-system-for-japanese) | |
+ t) | |
+ (t (japanese-p (cdr coding-system-list))))) | |
+ | |
+;; Turn off input-method automatically when C-s or C-r are typed. | |
+(defadvice isearch-mode (before migemo-search-ad activate) | |
+ "adviced by migemo." | |
+ (unless (local-variable-p 'migemo-isearch-enable-p) | |
+ (set (make-local-variable 'migemo-isearch-enable-p) | |
+ (japanese-p (detect-coding-with-language-environment | |
+ (point-min) (point-max) "japanese")))) | |
+ (setq migemo-search-pattern nil) | |
+ (setq migemo-search-pattern-alist nil)) | |
+ | |
+(defadvice isearch-done (after migemo-search-ad activate) | |
+ "adviced by migemo." | |
+ (setq migemo-search-pattern nil) | |
+ (setq migemo-search-pattern-alist nil)) | |
+ | |
+(defcustom migemo-message-prefix-face 'highlight | |
+ "*Face of minibuffer prefix" | |
+ :group 'migemo | |
+ :type 'face) | |
+ | |
+(defadvice isearch-message-prefix (after migemo-status activate) | |
+ "adviced by migemo." | |
+ (let ((ret ad-return-value) | |
+ (str "[MIGEMO]")) | |
+ (when migemo-emacs21p | |
+ (put-text-property 0 (length str) 'face migemo-message-prefix-face str)) | |
+ (when (and migemo-isearch-enable-p | |
+ (not (or isearch-regexp isearch-word))) | |
+ (setq ad-return-value (concat str " " ret))))) | |
+ | |
+;;;; for isearch-lazy-highlight (Emacs 21) | |
+;; Avoid byte compile warningsfor other emacsen | |
+(defvar isearch-lazy-highlight-wrapped) | |
+(defvar isearch-lazy-highlight-start) | |
+(defvar isearch-lazy-highlight-end) | |
+ | |
+(defun migemo-isearch-lazy-highlight-search () | |
+ "Search ahead for the next or previous match, for lazy highlighting. | |
+Attempt to do the search exactly the way the pending isearch would. | |
+This function used with Megemo feature." | |
+ (let ((case-fold-search isearch-case-fold-search) | |
+ (choices (cond (isearch-word | |
+ '(word-search-forward word-search-backward)) | |
+ (isearch-regexp | |
+ '(re-search-forward re-search-backward)) | |
+ (migemo-isearch-enable-p | |
+ '(re-search-forward re-search-backward t)) | |
+ (t | |
+ '(search-forward search-backward)))) | |
+ (pattern isearch-string)) | |
+ (when (nth 2 choices) | |
+ (setq pattern (migemo-search-pattern-get isearch-string))) | |
+ (funcall (if isearch-forward | |
+ (nth 0 choices) (nth 1 choices)) | |
+ pattern | |
+ (if isearch-forward | |
+ (if isearch-lazy-highlight-wrapped | |
+ isearch-lazy-highlight-start | |
+ (window-end)) | |
+ (if isearch-lazy-highlight-wrapped | |
+ isearch-lazy-highlight-end | |
+ (window-start))) | |
+ t))) | |
+ | |
+(when (fboundp 'isearch-lazy-highlight-search) | |
+ (defalias 'isearch-lazy-highlight-search 'migemo-isearch-lazy-highlight-search)) | |
+ | |
+;;;; for isearch-highlightify-region (XEmacs 21) | |
+(when (fboundp 'isearch-highlightify-region) | |
+ (defadvice isearch-highlightify-region (around migemo-highlightify-region | |
+ activate) | |
+ "adviced by migemo." | |
+ (if migemo-isearch-enable-p | |
+ (let ((isearch-string (migemo-search-pattern-get isearch-string)) | |
+ (isearch-regexp t)) | |
+ ad-do-it) | |
+ ad-do-it))) | |
+ | |
+;; supports C-w C-d for GNU emacs only [migemo:00171] | |
+(when (and (not (featurep 'xemacs)) | |
+ (fboundp 'isearch-yank-line)) | |
+ (add-hook 'isearch-mode-hook | |
+ (lambda () | |
+ (define-key isearch-mode-map "\C-d" 'migemo-isearch-yank-char) | |
+ (define-key isearch-mode-map "\C-w" 'migemo-isearch-yank-word) | |
+ (define-key isearch-mode-map "\C-y" 'migemo-isearch-yank-line) | |
+ (define-key isearch-mode-map "\M-m" 'migemo-isearch-toggle-migemo))) | |
+ | |
+ (defun migemo-isearch-toggle-migemo () | |
+ "Toggle migemo mode in isearch." | |
+ (interactive) | |
+ (unless (or isearch-regexp isearch-word) | |
+ (discard-input) | |
+ (setq migemo-isearch-enable-p (not migemo-isearch-enable-p))) | |
+ (when (fboundp 'isearch-lazy-highlight-new-loop) | |
+ (let ((isearch-lazy-highlight-last-string nil)) | |
+ (condition-case nil | |
+ (isearch-lazy-highlight-new-loop) | |
+ (error | |
+ (isearch-lazy-highlight-new-loop nil nil))))) | |
+ (isearch-message)) | |
+ | |
+ (defun migemo-isearch-yank-char () | |
+ "Pull next character from buffer into search string with migemo." | |
+ (interactive) | |
+ (when (and migemo-isearch-enable-p | |
+ (not isearch-regexp) isearch-other-end) | |
+ (setq isearch-string (buffer-substring-no-properties | |
+ isearch-other-end (point))) | |
+ (setq isearch-message isearch-string)) | |
+ (let ((search-upper-case (unless migemo-isearch-enable-p | |
+ search-upper-case))) | |
+ (isearch-yank-string | |
+ (save-excursion | |
+ (and (not isearch-forward) isearch-other-end | |
+ (goto-char isearch-other-end)) | |
+ (buffer-substring-no-properties (point) | |
+ (progn (forward-char 1) (point))))))) | |
+ | |
+ (defun migemo-isearch-yank-word () | |
+ "Pull next character from buffer into search string with migemo." | |
+ (interactive) | |
+ (when (and migemo-isearch-enable-p | |
+ (not isearch-regexp) isearch-other-end) | |
+ (setq isearch-string (buffer-substring-no-properties | |
+ isearch-other-end (point))) | |
+ (setq isearch-message isearch-string)) | |
+ (let ((search-upper-case (unless migemo-isearch-enable-p | |
+ search-upper-case))) | |
+ (isearch-yank-string | |
+ (save-excursion | |
+ (and (not isearch-forward) isearch-other-end | |
+ (goto-char isearch-other-end)) | |
+ (buffer-substring-no-properties (point) | |
+ (progn (forward-word 1) (point))))))) | |
+ | |
+ (defun migemo-isearch-yank-line () | |
+ "Pull next character from buffer into search string with migemo." | |
+ (interactive) | |
+ (when (and migemo-isearch-enable-p | |
+ (not isearch-regexp) isearch-other-end) | |
+ (setq isearch-string (buffer-substring-no-properties | |
+ isearch-other-end (point))) | |
+ (setq isearch-message isearch-string)) | |
+ (let ((search-upper-case (unless migemo-isearch-enable-p | |
+ search-upper-case))) | |
+ (isearch-yank-string | |
+ (save-excursion | |
+ (and (not isearch-forward) isearch-other-end | |
+ (goto-char isearch-other-end)) | |
+ (buffer-substring-no-properties (point) | |
+ (line-end-position)))))) | |
+) | |
+ | |
+(if (and (not (fboundp 'cmigemo-open)) | |
+ (fboundp 'load-dynamic-library)) | |
+ (load-dynamic-library migemo-cmigemo-library)) | |
+ | |
+(add-hook 'kill-emacs-hook 'migemo-pattern-alist-save) | |
+ | |
+(provide 'cmigemo) | |
+ | |
+;; sample | |
+;; 0123 abcd ABCD ¤Ò¤é¤¬¤Ê ¥«¥¿¥«¥Ê ´Á»ú !"[#\$]%^&_':`(;)<*=+>,?-@./{|}~ | |
+ | |
+;; Local Variables: | |
+;; coding: euc-japan-unix | |
+;; lexical-binding: t | |
+;; indent-tabs-mode: nil | |
+;; End: | |
+ | |
+;;; migemo.el ends here | |
--- /dev/null 2015-04-11 07:27:57.000000000 +0900 | |
+++ ./site-lisp/cp5022x.el 2015-04-11 07:27:30.531116300 +0900 | |
@@ -0,0 +1,156 @@ | |
+;;; cp5022x.el --- cp50220, cp50221, cp50222 coding system | |
+ | |
+;; Copyright (C) 2008 ARISAWA Akihiro | |
+ | |
+;; Author: ARISAWA Akihiro <ari@mbf.ocn.ne.jp> | |
+;; Keywords: languages, cp50220, cp50221, cp50222, cp51932, cp932 | |
+ | |
+;; This file is free software; you can redistribute it and/or modify | |
+;; it under the terms of the GNU General Public License as published by | |
+;; the Free Software Foundation; either version 3, or (at your option) | |
+;; any later version. | |
+ | |
+;; This file is distributed in the hope that it will be useful, | |
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+;; GNU General Public License for more details. | |
+ | |
+;; You should have received a copy of the GNU General Public License | |
+;; along with GNU Emacs; see the file COPYING. If not, write to | |
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
+;; Boston, MA 02110-1301, USA. | |
+ | |
+;;; Commentary: | |
+ | |
+;; This program requires Mule-6.0 or later. | |
+ | |
+;;; Code: | |
+ | |
+;; http://unicode.org/reports/tr30/datafiles/WidthFolding.txt | |
+(define-translation-table | |
+ 'cp50220-jisx0201-katakana-to-zenkaku | |
+ '(;; Half-width to generic width (singletons) | |
+ (#xFF61 . #x3002) ;; 。 â ã HALFWIDTH IDEOGRAPHIC FULL STOP â IDEOGRAPHIC FULL STOP | |
+ (#xFF62 . #x300C) ;; ï½¢ â ã HALFWIDTH LEFT CORNER BRACKET â LEFT CORNER BRACKET | |
+ (#xFF63 . #x300D) ;; ï½£ â ã HALFWIDTH RIGHT CORNER BRACKET â RIGHT CORNER BRACKET | |
+ (#xFF64 . #x3001) ;; 、 â ã HALFWIDTH IDEOGRAPHIC COMMA â IDEOGRAPHIC COMMA | |
+ ;; Half-witdh to generic Katakana (singletons) | |
+ (#xFF65 . #x30FB) ;; ï½¥ â ã» HALFWIDTH KATAKANA MIDDLE DOT â KATAKANA MIDDLE DOT | |
+ (#xFF66 . #x30F2) ;; ヲ â ã² HALFWIDTH KATAKANA LETTER WO â KATAKANA LETTER WO | |
+ (#xFF67 . #x30A1) ;; ァ â ã¡ HALFWIDTH KATAKANA LETTER SMALL A â KATAKANA LETTER SMALL A | |
+ (#xFF68 . #x30A3) ;; ィ â 㣠HALFWIDTH KATAKANA LETTER SMALL I â KATAKANA LETTER SMALL I | |
+ (#xFF69 . #x30A5) ;; ゥ â 㥠HALFWIDTH KATAKANA LETTER SMALL U â KATAKANA LETTER SMALL U | |
+ (#xFF6A . #x30A7) ;; ェ â 㧠HALFWIDTH KATAKANA LETTER SMALL E â KATAKANA LETTER SMALL E | |
+ (#xFF6B . #x30A9) ;; ォ â ã© HALFWIDTH KATAKANA LETTER SMALL O â KATAKANA LETTER SMALL O | |
+ (#xFF6C . #x30E3) ;; ャ â 㣠HALFWIDTH KATAKANA LETTER SMALL YA â KATAKANA LETTER SMALL YA | |
+ (#xFF6D . #x30E5) ;; ï½ â 㥠HALFWIDTH KATAKANA LETTER SMALL YU â KATAKANA LETTER SMALL YU | |
+ (#xFF6E . #x30E7) ;; ï½® â 㧠HALFWIDTH KATAKANA LETTER SMALL YO â KATAKANA LETTER SMALL YO | |
+ (#xFF6F . #x30C3) ;; ッ â ã HALFWIDTH KATAKANA LETTER SMALL TU â KATAKANA LETTER SMALL TU | |
+ (#xFF70 . #x30FC) ;; ï½° â ã¼ HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK â KATAKANA-HIRAGANA PROLONGED SOUND MARK | |
+ (#xFF71 . #x30A2) ;; ï½± â 㢠HALFWIDTH KATAKANA LETTER A â KATAKANA LETTER A | |
+ (#xFF72 . #x30A4) ;; ï½² â 㤠HALFWIDTH KATAKANA LETTER I â KATAKANA LETTER I | |
+ (#xFF73 . #x30A6) ;; ï½³ â 㦠HALFWIDTH KATAKANA LETTER U â KATAKANA LETTER U | |
+ (#xFF74 . #x30A8) ;; ï½´ â 㨠HALFWIDTH KATAKANA LETTER E â KATAKANA LETTER E | |
+ (#xFF75 . #x30AA) ;; ï½µ â 㪠HALFWIDTH KATAKANA LETTER O â KATAKANA LETTER O | |
+ (#xFF76 . #x30AB) ;; カ â ã« HALFWIDTH KATAKANA LETTER KA â KATAKANA LETTER KA | |
+ (#xFF77 . #x30AD) ;; ï½· â ã HALFWIDTH KATAKANA LETTER KI â KATAKANA LETTER KI | |
+ (#xFF78 . #x30AF) ;; ク â 㯠HALFWIDTH KATAKANA LETTER KU â KATAKANA LETTER KU | |
+ (#xFF79 . #x30B1) ;; ï½¹ â ã± HALFWIDTH KATAKANA LETTER KE â KATAKANA LETTER KE | |
+ (#xFF7A . #x30B3) ;; コ â ã³ HALFWIDTH KATAKANA LETTER KO â KATAKANA LETTER KO | |
+ (#xFF7B . #x30B5) ;; ï½» â ãµ HALFWIDTH KATAKANA LETTER SA â KATAKANA LETTER SA | |
+ (#xFF7C . #x30B7) ;; ï½¼ â ã· HALFWIDTH KATAKANA LETTER SI â KATAKANA LETTER SI | |
+ (#xFF7D . #x30B9) ;; ï½½ â ã¹ HALFWIDTH KATAKANA LETTER SU â KATAKANA LETTER SU | |
+ (#xFF7E . #x30BB) ;; ï½¾ â ã» HALFWIDTH KATAKANA LETTER SE â KATAKANA LETTER SE | |
+ (#xFF7F . #x30BD) ;; ソ â ã½ HALFWIDTH KATAKANA LETTER SO â KATAKANA LETTER SO | |
+ (#xFF80 . #x30BF) ;; ï¾ â ã¿ HALFWIDTH KATAKANA LETTER TA â KATAKANA LETTER TA | |
+ (#xFF81 . #x30C1) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER TI â KATAKANA LETTER TI | |
+ (#xFF82 . #x30C4) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER TU â KATAKANA LETTER TU | |
+ (#xFF83 . #x30C6) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER TE â KATAKANA LETTER TE | |
+ (#xFF84 . #x30C8) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER TO â KATAKANA LETTER TO | |
+ (#xFF85 . #x30CA) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER NA â KATAKANA LETTER NA | |
+ (#xFF86 . #x30CB) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER NI â KATAKANA LETTER NI | |
+ (#xFF87 . #x30CC) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER NU â KATAKANA LETTER NU | |
+ (#xFF88 . #x30CD) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER NE â KATAKANA LETTER NE | |
+ (#xFF89 . #x30CE) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER NO â KATAKANA LETTER NO | |
+ (#xFF8A . #x30CF) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER HA â KATAKANA LETTER HA | |
+ (#xFF8B . #x30D2) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER HI â KATAKANA LETTER HI | |
+ (#xFF8C . #x30D5) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER HU â KATAKANA LETTER HU | |
+ (#xFF8D . #x30D8) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER HE â KATAKANA LETTER HE | |
+ (#xFF8E . #x30DB) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER HO â KATAKANA LETTER HO | |
+ (#xFF8F . #x30DE) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER MA â KATAKANA LETTER MA | |
+ (#xFF90 . #x30DF) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER MI â KATAKANA LETTER MI | |
+ (#xFF91 . #x30E0) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER MU â KATAKANA LETTER MU | |
+ (#xFF92 . #x30E1) ;; ï¾ â ã¡ HALFWIDTH KATAKANA LETTER ME â KATAKANA LETTER ME | |
+ (#xFF93 . #x30E2) ;; ï¾ â 㢠HALFWIDTH KATAKANA LETTER MO â KATAKANA LETTER MO | |
+ (#xFF94 . #x30E4) ;; ï¾ â 㤠HALFWIDTH KATAKANA LETTER YA â KATAKANA LETTER YA | |
+ (#xFF95 . #x30E6) ;; ï¾ â 㦠HALFWIDTH KATAKANA LETTER YU â KATAKANA LETTER YU | |
+ (#xFF96 . #x30E8) ;; ï¾ â 㨠HALFWIDTH KATAKANA LETTER YO â KATAKANA LETTER YO | |
+ (#xFF97 . #x30E9) ;; ï¾ â ã© HALFWIDTH KATAKANA LETTER RA â KATAKANA LETTER RA | |
+ (#xFF98 . #x30EA) ;; ï¾ â 㪠HALFWIDTH KATAKANA LETTER RI â KATAKANA LETTER RI | |
+ (#xFF99 . #x30EB) ;; ï¾ â ã« HALFWIDTH KATAKANA LETTER RU â KATAKANA LETTER RU | |
+ (#xFF9A . #x30EC) ;; ï¾ â 㬠HALFWIDTH KATAKANA LETTER RE â KATAKANA LETTER RE | |
+ (#xFF9B . #x30ED) ;; ï¾ â ã HALFWIDTH KATAKANA LETTER RO â KATAKANA LETTER RO | |
+ (#xFF9C . #x30EF) ;; ï¾ â 㯠HALFWIDTH KATAKANA LETTER WA â KATAKANA LETTER WA | |
+ (#xFF9D . #x30F3) ;; ï¾ â ã³ HALFWIDTH KATAKANA LETTER N â KATAKANA LETTER N | |
+; (#xFF9E . #x3099) ;; ï¾ â ã HALFWIDTH KATAKANA VOICED SOUND MARK â COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK | |
+; (#xFF9F . #x309A) ;; ï¾ â ã HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK â COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK | |
+ (#xFF9E . #x309B) ;; ï¾ â ã HALFWIDTH KATAKANA VOICED SOUND MARK â KATAKANA-HIRAGANA VOICED SOUND MARK | |
+ (#xFF9F . #x309C) ;; ï¾ â ã HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK â KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK | |
+ )) | |
+ | |
+(define-coding-system 'cp50220 | |
+ "CP50220 (Microsoft iso-2022-jp for mail)" | |
+ :coding-type 'iso-2022 | |
+ :mnemonic ?J | |
+ :designation [(ascii japanese-jisx0208-1978 japanese-jisx0208 | |
+ latin-jisx0201 katakana-jisx0201) | |
+ nil nil nil] | |
+ :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation) | |
+ :charset-list '(ascii japanese-jisx0208 | |
+ japanese-jisx0208-1978 latin-jisx0201 | |
+ katakana-jisx0201) | |
+ :decode-translation-table '(cp51932-decode japanese-ucs-jis-to-cp932-map) | |
+ :encode-translation-table '(cp50220-jisx0201-katakana-to-zenkaku | |
+ cp51932-encode japanese-ucs-cp932-to-jis-map)) | |
+ | |
+(define-coding-system 'cp50221 | |
+ "CP50221 (Microsoft iso-2022-jp)" | |
+ :coding-type 'iso-2022 | |
+ :mnemonic ?J | |
+ :designation [(ascii japanese-jisx0208-1978 japanese-jisx0208 | |
+ latin-jisx0201 katakana-jisx0201) | |
+ nil nil nil] | |
+ :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation) | |
+ :charset-list '(ascii japanese-jisx0208 | |
+ japanese-jisx0208-1978 latin-jisx0201 | |
+ katakana-jisx0201) | |
+ :decode-translation-table '(cp51932-decode japanese-ucs-jis-to-cp932-map) | |
+ :encode-translation-table '(cp51932-encode japanese-ucs-cp932-to-jis-map)) | |
+ | |
+(define-coding-system 'cp50222 | |
+ "CP50222 (Microsoft iso-2022-jp)" | |
+ :coding-type 'iso-2022 | |
+ :mnemonic ?J | |
+ :designation [(ascii japanese-jisx0208-1978 japanese-jisx0208 | |
+ latin-jisx0201) | |
+ katakana-jisx0201 nil nil] | |
+ :flags '(short ascii-at-eol ascii-at-cntl 7-bit designation) | |
+ :charset-list '(ascii japanese-jisx0208 | |
+ japanese-jisx0208-1978 latin-jisx0201 | |
+ katakana-jisx0201) | |
+ :decode-translation-table '(cp51932-decode japanese-ucs-jis-to-cp932-map) | |
+ :encode-translation-table '(cp51932-encode japanese-ucs-cp932-to-jis-map)) | |
+ | |
+(define-coding-system 'cp51932 | |
+ "CP51932 (Microsoft euc-jp)" | |
+ :coding-type 'iso-2022 | |
+ :mnemonic ?E | |
+ :designation [ascii japanese-jisx0208 katakana-jisx0201 nil] | |
+ :flags '(short ascii-at-eol ascii-at-cntl single-shift) | |
+ :charset-list '(ascii latin-jisx0201 japanese-jisx0208 | |
+ katakana-jisx0201) | |
+ :decode-translation-table '(cp51932-decode japanese-ucs-jis-to-cp932-map) | |
+ :encode-translation-table '(cp51932-encode japanese-ucs-cp932-to-jis-map)) | |
+ | |
+(provide 'cp5022x) | |
+;;; cp5022x.el ends here | |
--- /dev/null 2015-04-11 07:27:58.000000000 +0900 | |
+++ ./site-lisp/ezsetup.el 2015-04-11 07:27:30.542118200 +0900 | |
@@ -0,0 +1,104 @@ | |
+;; | |
+;; | |
+;; | |
+(when (and (= (w32-get-default-locale-id) 1041) ; japanese? | |
+ (not (file-exists-p user-init-file))) | |
+ (require 'cus-edit) | |
+ (let ((user-init-file | |
+ (expand-file-name "init.el" user-emacs-directory)) | |
+ (cust-vars | |
+ `((default-frame-alist . | |
+ ,(cons | |
+ '(font . "fontset-std:std") | |
+ (cons '(ime-cursor-color . "SkyBlue") | |
+ default-frame-alist))) | |
+ (current-language-environment . "Japanese")))) | |
+ | |
+ (mapc #'(lambda (l) | |
+ (let ((symbol (car l)) | |
+ (value (cdr l))) | |
+ (put symbol 'saved-value | |
+ (list (custom-quote value))))) | |
+ cust-vars) | |
+ | |
+ (with-temp-buffer | |
+ (if (member "Migu 1M" (font-family-list)) | |
+ (insert ";; | |
+;; ãã©ã³ã | |
+;; | |
+(dolist (spec '((10 . \"small\") | |
+ (12 . \"std\") | |
+ (14 . \"large\"))) | |
+ | |
+ (let* ((ff \"Migu 1M\") | |
+ (sz (car spec)) | |
+ (fs (create-fontset-from-ascii-font | |
+ (format \"-*-%s-normal-*-*-*-%g-*\" ff sz) nil ff))) | |
+ | |
+ (dolist (sn '(katakana-jisx0201 | |
+ japanese-jisx0208 | |
+ japanese-jisx0212)) | |
+ (set-fontset-font fs sn (cons ff \"iso10646-1\")) | |
+ (add-to-list 'fontset-alias-alist | |
+ (cons fs (format \"fontset-std:%s\" (cdr spec)))))))")) | |
+ | |
+ (insert ";; | |
+;; æ¥æ¬èªã³ã¼ã | |
+;; | |
+(load-library \"ja-coding\") | |
+;; | |
+;; ã¢ã¼ãã©ã¤ã³ã«IMEã®ç¶æ ã表示 | |
+;; | |
+(setq-default w32-ime-mode-line-state-indicator \"[--]\") | |
+(setq w32-ime-mode-line-state-indicator-list '(\"[--]\" \"[ã]\" \"[--]\")) | |
+ | |
+;; | |
+;; imeãµãã¼ã ã»ããã¢ãã | |
+;; | |
+(w32-ime-initialize) | |
+(require 'smart-ime) | |
+ | |
+;; | |
+;; MIGEMO | |
+;; | |
+(unless (boundp 'isearch-mode-map) | |
+ (load-library \"isearch\")) | |
+ | |
+(dolist (key (where-is-internal | |
+ 'toggle-input-method global-map nil nil | |
+ (command-remapping 'toggle-input-method))) | |
+ (when (= (length key) 1) | |
+ (define-key isearch-mode-map | |
+ key 'migemo-isearch-toggle-migemo))) | |
+ | |
+(require 'cmigemo) | |
+ | |
+;; | |
+(custom-set-variables) | |
+ | |
+;; ã«ã¼ã½ã«è² | |
+;; custom-variableã®å¤ã使ãã®ã§ãã®ä½ç½®ã«è¨è¿°ãã | |
+(add-hook 'w32-ime-on-hook | |
+ `(lambda () (set-cursor-color ,(frame-parameter nil 'ime-cursor-color)))) | |
+(add-hook 'w32-ime-off-hook | |
+ `(lambda () (set-cursor-color ,(frame-parameter nil 'cursor-color))))") | |
+ (set-buffer-file-coding-system 'utf-8) | |
+ (custom-save-variables) | |
+ (write-file (expand-file-name "init.el" user-emacs-directory))) | |
+ (load-file user-init-file) | |
+ | |
+ (save-window-excursion | |
+ (with-temp-buffer | |
+ (pop-to-buffer (current-buffer)) | |
+ (insert "è¨å®ãã¡ã¤ã« ~/.emacs.d/init.elãä½æãã¾ããã | |
+以ä¸ã®ã«ã¹ã¿ã å¤æ°ãè¨å®ãã¾ããããããã®å¤æ°ã¯ | |
+M-x customize-variable<ENTER> | |
+ã®å¾ã«å¤æ°åãå ¥åããå¤æ´ãããã¨ãã§ãã¾ãã\n") | |
+ (mapc #'(lambda (l) | |
+ (insert | |
+ (format "%s: %s\n" (car l) (symbol-value (car l))))) | |
+ cust-vars) | |
+ (insert "ä½ããã¼ãæ¼ãã¦ãã ããã") | |
+ (read-char "? "))))) | |
+ | |
+ | |
--- /dev/null 2015-04-11 07:27:58.000000000 +0900 | |
+++ ./site-lisp/ja-coding.el 2015-04-11 07:27:30.547117100 +0900 | |
@@ -0,0 +1,81 @@ | |
+;; http://nijino.homelinux.net/emacs/emacs23-ja.html | |
+(cond | |
+ ((not (string< mule-version "6.0")) | |
+ | |
+ (coding-system-put 'euc-jp :encode-translation-table | |
+ (get 'japanese-ucs-cp932-to-jis-map 'translation-table)) | |
+ (coding-system-put 'iso-2022-jp :encode-translation-table | |
+ (get 'japanese-ucs-cp932-to-jis-map 'translation-table)) | |
+ (coding-system-put 'cp932 :encode-translation-table | |
+ (get 'japanese-ucs-jis-to-cp932-map 'translation-table)) | |
+ ;; charset 㨠coding-system ã®åªå 度è¨å® | |
+ (set-charset-priority 'ascii 'japanese-jisx0208 'latin-jisx0201 | |
+ 'katakana-jisx0201 'iso-8859-1 'cp1252 'unicode) | |
+ (set-coding-system-priority 'utf-8 'cp932 'euc-jp 'iso-2022-jp) | |
+ | |
+ ;; East Asian Ambiguous | |
+ (let ((width 2)) | |
+ (while (char-table-parent char-width-table) | |
+ (setq char-width-table (char-table-parent char-width-table))) | |
+ (let ((table (make-char-table nil))) | |
+ (dolist (range | |
+ '(#x00A1 #x00A4 (#x00A7 . #x00A8) #x00AA (#x00AD . #x00AE) | |
+ (#x00B0 . #x00B4) (#x00B6 . #x00BA) (#x00BC . #x00BF) | |
+ #x00C6 #x00D0 (#x00D7 . #x00D8) (#x00DE . #x00E1) #x00E6 | |
+ (#x00E8 . #x00EA) (#x00EC . #x00ED) #x00F0 | |
+ (#x00F2 . #x00F3) (#x00F7 . #x00FA) #x00FC #x00FE | |
+ #x0101 #x0111 #x0113 #x011B (#x0126 . #x0127) #x012B | |
+ (#x0131 . #x0133) #x0138 (#x013F . #x0142) #x0144 | |
+ (#x0148 . #x014B) #x014D (#x0152 . #x0153) | |
+ (#x0166 . #x0167) #x016B #x01CE #x01D0 #x01D2 #x01D4 | |
+ #x01D6 #x01D8 #x01DA #x01DC #x0251 #x0261 #x02C4 #x02C7 | |
+ (#x02C9 . #x02CB) #x02CD #x02D0 (#x02D8 . #x02DB) #x02DD | |
+ #x02DF (#x0300 . #x036F) (#x0391 . #x03A9) | |
+ (#x03B1 . #x03C1) (#x03C3 . #x03C9) #x0401 | |
+ (#x0410 . #x044F) #x0451 #x2010 (#x2013 . #x2016) | |
+ (#x2018 . #x2019) (#x201C . #x201D) (#x2020 . #x2022) | |
+ (#x2024 . #x2027) #x2030 (#x2032 . #x2033) #x2035 #x203B | |
+ #x203E #x2074 #x207F (#x2081 . #x2084) #x20AC #x2103 | |
+ #x2105 #x2109 #x2113 #x2116 (#x2121 . #x2122) #x2126 | |
+ #x212B (#x2153 . #x2154) (#x215B . #x215E) | |
+ (#x2160 . #x216B) (#x2170 . #x2179) (#x2190 . #x2199) | |
+ (#x21B8 . #x21B9) #x21D2 #x21D4 #x21E7 #x2200 | |
+ (#x2202 . #x2203) (#x2207 . #x2208) #x220B #x220F #x2211 | |
+ #x2215 #x221A (#x221D . #x2220) #x2223 #x2225 | |
+ (#x2227 . #x222C) #x222E (#x2234 . #x2237) | |
+ (#x223C . #x223D) #x2248 #x224C #x2252 (#x2260 . #x2261) | |
+ (#x2264 . #x2267) (#x226A . #x226B) (#x226E . #x226F) | |
+ (#x2282 . #x2283) (#x2286 . #x2287) #x2295 #x2299 #x22A5 | |
+ #x22BF #x2312 (#x2460 . #x24E9) (#x24EB . #x254B) | |
+ (#x2550 . #x2573) (#x2580 . #x258F) (#x2592 . #x2595) | |
+ (#x25A0 . #x25A1) (#x25A3 . #x25A9) (#x25B2 . #x25B3) | |
+ (#x25B6 . #x25B7) (#x25BC . #x25BD) (#x25C0 . #x25C1) | |
+ (#x25C6 . #x25C8) #x25CB (#x25CE . #x25D1) | |
+ (#x25E2 . #x25E5) #x25EF (#x2605 . #x2606) #x2609 | |
+ (#x260E . #x260F) (#x2614 . #x2615) #x261C #x261E #x2640 | |
+ #x2642 (#x2660 . #x2661) (#x2663 . #x2665) | |
+ (#x2667 . #x266A) (#x266C . #x266D) #x266F #x273D | |
+ (#x2776 . #x277F) (#xE000 . #xF8FF) (#xFE00 . #xFE0F) | |
+ #xFFFD | |
+ )) | |
+ (set-char-table-range table range width)) | |
+ (optimize-char-table table) | |
+ (set-char-table-parent table char-width-table) | |
+ (setq char-width-table table))) | |
+ | |
+ ;; æ©ç¨®ä¾åæå | |
+ (require 'cp5022x))) | |
+ | |
+;; emacs-w3m | |
+(eval-after-load "w3m" | |
+ '(when (coding-system-p 'cp51932) | |
+ (add-to-list 'w3m-compatible-encoding-alist '(euc-jp . cp51932)))) | |
+;; Gnus | |
+(eval-after-load "mm-util" | |
+ '(when (coding-system-p 'cp50220) | |
+ (add-to-list 'mm-charset-override-alist '(iso-2022-jp . cp50220)))) | |
+;; SEMI (cf. http://d.hatena.ne.jp/kiwanami/20091103/1257243524) | |
+(eval-after-load "mcs-20" | |
+ '(when (coding-system-p 'cp50220) | |
+ (add-to-list 'mime-charset-coding-system-alist | |
+ '(iso-2022-jp . cp50220)))) | |
\ No newline at end of file | |
--- /dev/null 2015-04-11 07:27:58.000000000 +0900 | |
+++ ./site-lisp/smart-ime.el 2015-04-11 07:27:30.553117700 +0900 | |
@@ -0,0 +1,173 @@ | |
+;;; smart-ime.el - smart Input Method | |
+;; | |
+;; Copyright (C) 2011 HIROSHI OOTA | |
+ | |
+;; Author: HIROSHI OOTA | |
+;; Keywords: convenience | |
+ | |
+;; This program is free software; you can redistribute it and/or | |
+;; modify it under the terms of the GNU General Public License as | |
+;; published by the Free Software Foundation; either version 3, or (at | |
+;; your option) any later version. | |
+ | |
+;; This program is distributed in the hope that it will be useful, but | |
+;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
+;; General Public License for more details. | |
+ | |
+;; You should have received a copy of the GNU General Public License | |
+;; along with GNU Emacs; see the file COPYING. If not, write to the | |
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
+;; Boston, MA 02110-1301, USA. | |
+ | |
+;;; Commentary: | |
+;; | |
+;; smart-im frees you from the frustration about IM. | |
+;; It disables an IM automatically according to a situation. | |
+ | |
+;;; Install: | |
+;; Put this file into load-path'ed directory, and byte compile it if | |
+;; desired. And put the following expression into your ~/.emacs. | |
+;; | |
+;; (require 'smart-ime) | |
+ | |
+;; Todo: | |
+ | |
+;;; Code: | |
+ | |
+;; variable | |
+(defvar sime-saved-input-method nil) | |
+(make-variable-buffer-local 'sime-saved-input-method) | |
+(set-default 'sime-saved-input-method nil) | |
+ | |
+(defun sime-activate-input-method () | |
+ (setq sime-saved-input-method (list current-input-method)) | |
+ (inactivate-input-method)) | |
+(defun sime-inactivate-input-method () | |
+ (when sime-saved-input-method | |
+ (activate-input-method (car sime-saved-input-method)) | |
+ (setq sime-saved-input-method nil))) | |
+ | |
+;; | |
+;; minibuffer | |
+(add-hook 'minibuffer-setup-hook 'sime-activate-input-method) | |
+(add-hook 'minibuffer-exit-hook 'sime-inactivate-input-method) | |
+;; | |
+;; incremental search | |
+(add-hook 'isearch-mode-hook 'sime-activate-input-method) | |
+(add-hook 'isearch-mode-end-hook 'sime-inactivate-input-method) | |
+ | |
+;; | |
+;; query-replace, query-replace-regexp, query-replace-regexp-eval ... | |
+(defadvice perform-replace | |
+ (around sime-ad-perform-replace compile activate) | |
+ (let ((im current-input-method)) | |
+ (if (or (not im) | |
+ (not (ad-get-arg 2))) | |
+ ad-do-it | |
+ (inactivate-input-method) | |
+ ad-do-it | |
+ (activate-input-method im)))) | |
+ | |
+;; | |
+;; read-passwd | |
+(defadvice read-passwd | |
+ (around sime-ad-read-passwd compile activate) | |
+ (let ((sime-ad-toggle-ime-mapped-key-list nil) | |
+ (im current-input-method)) | |
+ (dolist (k (where-is-internal | |
+ 'toggle-input-method overriding-local-map nil nil | |
+ (command-remapping 'toggle-input-method))) | |
+ (when (integerp (aref k 0)) | |
+ (setq sime-ad-toggle-ime-mapped-key-list | |
+ (cons (aref k 0) sime-ad-toggle-ime-mapped-key-list)))) | |
+ | |
+ (ad-enable-advice 'read-key 'around 'sime-ad-read-key) | |
+ (ad-activate 'read-key) | |
+ (inactivate-input-method) | |
+ ad-do-it | |
+ (activate-input-method im) | |
+ (ad-disable-advice 'read-key 'around 'sime-ad-read-key) | |
+ (ad-activate 'read-key))) | |
+ | |
+(defadvice read-key | |
+ (around sime-ad-read-key compile) | |
+ (let ((flag t) | |
+ (msg (current-message))) | |
+ (while flag | |
+ ad-do-it | |
+ (if (not (memq ad-return-value | |
+ sime-ad-toggle-ime-mapped-key-list)) | |
+ (setq flag nil) | |
+ (toggle-input-method) | |
+ (message msg))))) | |
+ | |
+;; | |
+;; universal-argument | |
+(defun sime-universal-toggle-input-method (arg) | |
+ (interactive "P") | |
+ (if (consp arg) | |
+ (universal-argument-other-key arg) | |
+ (toggle-input-method) | |
+ (setq prefix-arg arg | |
+ universal-argument-num-events | |
+ (length (this-command-keys))))) | |
+ | |
+; patch universal-argument-map after init | |
+(add-hook | |
+ 'after-init-hook | |
+ #'(lambda () | |
+ (require 'simple) | |
+ (dolist (key (where-is-internal | |
+ 'toggle-input-method global-map nil nil | |
+ (command-remapping 'toggle-input-method))) | |
+ (when (= (length key) 1) | |
+ (define-key | |
+ universal-argument-map | |
+ key 'sime-universal-toggle-input-method))))) | |
+ | |
+(defadvice universal-argument | |
+ (after sime-ad-universal-argument compile activate) | |
+ (setq sime-saved-input-method | |
+ (or sime-saved-input-method | |
+ (list current-input-method))) | |
+ (inactivate-input-method)) | |
+ | |
+(defadvice restore-overriding-map | |
+ (after sime-ad-restore-overriding-map compile activate) | |
+ (when sime-saved-input-method | |
+ (activate-input-method (car sime-saved-input-method)) | |
+ (setq sime-saved-input-method nil))) | |
+ | |
+;; a keyboard which has no KANJI-KEY | |
+;; entering/leaving KANJI-mode key-sequence is <kanji><M-kanji> | |
+;; then we should pass prefix-arg to next command. | |
+(global-set-key | |
+ [M-kanji] | |
+ #'(lambda (arg) | |
+ (interactive "P") | |
+ (setq prefix-arg arg))) | |
+ | |
+;; | |
+;; others | |
+(defmacro wrap-function-to-control-input-method (fcn) | |
+ `(defadvice ,fcn (around | |
+ ,(make-symbol (concat "sime-ad-" (symbol-name fcn))) | |
+ compile activate) | |
+ (let ((im current-input-method)) | |
+ (inactivate-input-method) | |
+ ad-do-it | |
+ (activate-input-method im)))) | |
+ | |
+(wrap-function-to-control-input-method map-y-or-n-p) | |
+(wrap-function-to-control-input-method y-or-n-p) | |
+(wrap-function-to-control-input-method read-key-sequence) | |
+ | |
+;; disable W32-IME control during processing the timer handler | |
+(defadvice timer-event-handler | |
+ (around sime-ad-timer-event-handler compile activate) | |
+ (let ((w32-ime-buffer-switch-p nil)) | |
+ ad-do-it)) | |
+ | |
+(provide 'smart-ime) | |
+;; -*- mode: Emacs-Lisp; coding: euc-jp-unix -*- | |
--- ./src/alloc.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/alloc.c 2015-04-11 07:27:30.561118400 +0900 | |
@@ -30,6 +30,13 @@ | |
#ifdef HAVE_PTHREAD | |
#include <pthread.h> | |
#endif | |
+#ifdef WINDOWSNT | |
+#if (defined(_MSC_VER) && _MSC_VER >= 1600) || defined(__MINGW32__) | |
+#include <stdint.h> | |
+#else | |
+#include <crtdefs.h> | |
+#endif | |
+#endif | |
#include "lisp.h" | |
#include "process.h" | |
@@ -336,6 +343,9 @@ | |
/* Base address of stack. Set in main. */ | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+TLS | |
+#endif | |
Lisp_Object *stack_base; | |
/* Root of the tree describing allocated Lisp memory. */ | |
@@ -655,9 +665,31 @@ | |
# define MALLOC_BLOCK_INPUT malloc_block_input () | |
# define MALLOC_UNBLOCK_INPUT malloc_unblock_input () | |
#else | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+CRITICAL_SECTION alloc_critical_section; | |
+# define MALLOC_BLOCK_INPUT \ | |
+ do \ | |
+ { \ | |
+ if (dwMainThreadId == GetCurrentThreadId ()) \ | |
+ block_input (); \ | |
+ w32_apc_mutex_acquire(); \ | |
+ EnterCriticalSection(&alloc_critical_section); \ | |
+ } \ | |
+ while (0) | |
+# define MALLOC_UNBLOCK_INPUT \ | |
+ do \ | |
+ { \ | |
+ LeaveCriticalSection(&alloc_critical_section); \ | |
+ w32_apc_mutex_release(); \ | |
+ if (dwMainThreadId == GetCurrentThreadId ()) \ | |
+ unblock_input (); \ | |
+ } \ | |
+ while (0) | |
+#else | |
# define MALLOC_BLOCK_INPUT ((void) 0) | |
# define MALLOC_UNBLOCK_INPUT ((void) 0) | |
#endif | |
+#endif | |
#define MALLOC_PROBE(size) \ | |
do { \ | |
@@ -3757,6 +3789,10 @@ | |
/* This used to call error, but if we've run out of memory, we could | |
get infinite recursion trying to build the string. */ | |
xsignal (Qnil, Vmemory_signal_data); | |
+#ifdef EMACSDEBUG | |
+ if (noninteractive) | |
+ abort(); | |
+#endif | |
} | |
/* If we released our reserve (due to running out of memory), | |
@@ -5320,6 +5356,34 @@ | |
return obj; | |
} | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+static VOID CALLBACK mark_stack_stub(ULONG_PTR ev) | |
+{ | |
+ mark_stack (); | |
+ SetEvent((HANDLE)ev); | |
+} | |
+ | |
+static void w32_mark_stack() | |
+{ | |
+ static HANDLE ev; | |
+ static int inilialized = 0; | |
+ | |
+ if (hWindowsThread == NULL) | |
+ return; | |
+ | |
+ if (!inilialized) { | |
+ if ((ev = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) | |
+ abort(); | |
+ inilialized = 1; | |
+ } | |
+ ResetEvent(ev); | |
+ | |
+ if (QueueUserAPC(mark_stack_stub, hWindowsThread, (ULONG_PTR)ev) == 0) | |
+ abort (); | |
+ | |
+ WaitForSingleObject(ev, INFINITE); | |
+} | |
+#endif | |
/*********************************************************************** | |
@@ -5582,6 +5646,10 @@ | |
message1_nolog ("Garbage collecting..."); | |
block_input (); | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+ w32_apc_mutex_acquire(); | |
+ EnterCriticalSection(&alloc_critical_section); | |
+#endif | |
shrink_regexp_cache (); | |
@@ -5607,6 +5675,9 @@ | |
#if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \ | |
|| GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS) | |
mark_stack (); | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+ w32_mark_stack(); | |
+#endif | |
#else | |
{ | |
register struct gcpro *tail; | |
@@ -5663,6 +5734,10 @@ | |
gc_in_progress = 0; | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+ w32_apc_mutex_release(); | |
+ LeaveCriticalSection(&alloc_critical_section); | |
+#endif | |
unblock_input (); | |
consing_since_gc = 0; | |
--- ./src/callproc.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/callproc.c 2015-04-11 07:27:30.567120000 +0900 | |
@@ -30,6 +30,9 @@ | |
#include "lisp.h" | |
+#ifdef DOS_NT | |
+#include <mbstring.h> | |
+#endif | |
#ifdef WINDOWSNT | |
#define NOMINMAX | |
#include <sys/socket.h> /* for fcntl */ | |
@@ -1236,6 +1239,10 @@ | |
at least check. */ | |
if (chdir (temp) < 0) | |
_exit (EXIT_CANCELED); | |
+ | |
+ /* Strip trailing slashes for PWD, but leave "/" and "//" alone. */ | |
+ while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1])) | |
+ temp[--i] = 0; | |
#else /* DOS_NT */ | |
/* Get past the drive letter, so that d:/ is left alone. */ | |
if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2])) | |
@@ -1243,11 +1250,11 @@ | |
temp += 2; | |
i -= 2; | |
} | |
-#endif /* DOS_NT */ | |
/* Strip trailing slashes for PWD, but leave "/" and "//" alone. */ | |
- while (i > 2 && IS_DIRECTORY_SEP (temp[i - 1])) | |
+ while (i > 2 && IS_DIRECTORY_SEP (*_mbsdec(temp, temp + i))) | |
temp[--i] = 0; | |
+#endif /* DOS_NT */ | |
} | |
/* Set `env' to a vector of the strings in the environment. */ | |
--- /dev/null 2015-04-11 07:27:59.000000000 +0900 | |
+++ ./src/cmigemo.c 2015-04-11 07:27:30.576125800 +0900 | |
@@ -0,0 +1,460 @@ | |
+#ifdef NULL | |
+#undef NULL | |
+#endif | |
+#include <config.h> | |
+#ifdef HAVE_CMIGEMO | |
+#include <setjmp.h> | |
+ | |
+#include "lisp.h" | |
+#include "charset.h" | |
+#include "coding.h" | |
+ | |
+#ifdef WINDOWSNT | |
+#include <windows.h> | |
+#define MIGEMO_DLL "migemo.dll" | |
+#else | |
+#ifdef CYGWIN | |
+#define MIGEMO_DLL "cygmigemo1.dll" | |
+#else | |
+#define MIGEMO_DLL "libmigemo.so" | |
+#endif | |
+#include <stdio.h> | |
+#include <dlfcn.h> | |
+#endif | |
+ | |
+#include "migemo.h" | |
+ | |
+/* from cmigemo charset.h */ | |
+enum { | |
+ CHARSET_NONE = 0, | |
+ CHARSET_CP932 = 1, | |
+ CHARSET_EUCJP = 2, | |
+ CHARSET_UTF8 = 3, | |
+}; | |
+typedef int (*charset_proc_int2char)(unsigned int, unsigned char*); | |
+#define CHARSET_PROC_INT2CHAR charset_proc_int2char | |
+ | |
+/* from cmigemo charset.c */ | |
+#define BUFLEN_DETECT 4096 | |
+static int cp932_int2char(unsigned int in, unsigned char* out) | |
+{ | |
+ if (in >= 0x100) | |
+ { | |
+ if (out) | |
+ { | |
+ out[0] = (unsigned char)((in >> 8) & 0xFF); | |
+ out[1] = (unsigned char)(in & 0xFF); | |
+ } | |
+ return 2; | |
+ } | |
+ else | |
+ return 0; | |
+} | |
+static int eucjp_int2char(unsigned int in, unsigned char* out) | |
+{ | |
+ /* CP932ã¨å 容ã¯åãã ãå°æ¥JISX0213ã«å¯¾å¿ãããããã«åé¢ãã¦ãã */ | |
+ if (in >= 0x100) | |
+ { | |
+ if (out) | |
+ { | |
+ out[0] = (unsigned char)((in >> 8) & 0xFF); | |
+ out[1] = (unsigned char)(in & 0xFF); | |
+ } | |
+ return 2; | |
+ } | |
+ else | |
+ return 0; | |
+} | |
+static int utf8_int2char(unsigned int in, unsigned char* out) | |
+{ | |
+ if (in < 0x80) | |
+ return 0; | |
+ if (in < 0x800) | |
+ { | |
+ if (out) | |
+ { | |
+ out[0] = 0xc0 + (in >> 6); | |
+ out[1] = 0x80 + ((in >> 0) & 0x3f); | |
+ } | |
+ return 2; | |
+ } | |
+ if (in < 0x10000) | |
+ { | |
+ if (out) | |
+ { | |
+ out[0] = 0xe0 + (in >> 12); | |
+ out[1] = 0x80 + ((in >> 6) & 0x3f); | |
+ out[2] = 0x80 + ((in >> 0) & 0x3f); | |
+ } | |
+ return 3; | |
+ } | |
+ if (in < 0x200000) | |
+ { | |
+ if (out) | |
+ { | |
+ out[0] = 0xf0 + (in >> 18); | |
+ out[1] = 0x80 + ((in >> 12) & 0x3f); | |
+ out[2] = 0x80 + ((in >> 6) & 0x3f); | |
+ out[3] = 0x80 + ((in >> 0) & 0x3f); | |
+ } | |
+ return 4; | |
+ } | |
+ if (in < 0x4000000) | |
+ { | |
+ if (out) | |
+ { | |
+ out[0] = 0xf8 + (in >> 24); | |
+ out[1] = 0x80 + ((in >> 18) & 0x3f); | |
+ out[2] = 0x80 + ((in >> 12) & 0x3f); | |
+ out[3] = 0x80 + ((in >> 6) & 0x3f); | |
+ out[4] = 0x80 + ((in >> 0) & 0x3f); | |
+ } | |
+ return 5; | |
+ } | |
+ else | |
+ { | |
+ if (out) | |
+ { | |
+ out[0] = 0xf8 + (in >> 30); | |
+ out[1] = 0x80 + ((in >> 24) & 0x3f); | |
+ out[2] = 0x80 + ((in >> 18) & 0x3f); | |
+ out[3] = 0x80 + ((in >> 12) & 0x3f); | |
+ out[4] = 0x80 + ((in >> 6) & 0x3f); | |
+ out[5] = 0x80 + ((in >> 0) & 0x3f); | |
+ } | |
+ return 6; | |
+ } | |
+} | |
+static int | |
+charset_detect_buf(const unsigned char* buf, int len) | |
+{ | |
+ int sjis = 0, smode = 0; | |
+ int euc = 0, emode = 0, eflag = 0; | |
+ int utf8 = 0, umode = 0, ufailed = 0; | |
+ int i; | |
+ for (i = 0; i < len; ++i) | |
+ { | |
+ unsigned char c = buf[i]; | |
+ // SJISã§ãããã®ãã§ã㯠| |
+ if (smode) | |
+ { | |
+ if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)) | |
+ ++sjis; | |
+ smode = 0; | |
+ } | |
+ else if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xf0)) | |
+ smode = 1; | |
+ // EUCã§ãããã®ãã§ã㯠| |
+ eflag = 0xa1 <= c && c <= 0xfe; | |
+ if (emode) | |
+ { | |
+ if (eflag) | |
+ ++euc; | |
+ emode = 0; | |
+ } | |
+ else if (eflag) | |
+ emode = 1; | |
+ // UTF8ã§ãããã®ãã§ã㯠| |
+ if (!ufailed) | |
+ { | |
+ if (umode < 1) | |
+ { | |
+ if ((c & 0x80) != 0) | |
+ { | |
+ if ((c & 0xe0) == 0xc0) | |
+ umode = 1; | |
+ else if ((c & 0xf0) == 0xe0) | |
+ umode = 2; | |
+ else if ((c & 0xf8) == 0xf0) | |
+ umode = 3; | |
+ else if ((c & 0xfc) == 0xf8) | |
+ umode = 4; | |
+ else if ((c & 0xfe) == 0xfc) | |
+ umode = 5; | |
+ else | |
+ { | |
+ ufailed = 1; | |
+ --utf8; | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ if ((c & 0xc0) == 0x80) | |
+ { | |
+ ++utf8; | |
+ --umode; | |
+ } | |
+ else | |
+ { | |
+ --utf8; | |
+ umode = 0; | |
+ ufailed = 1; | |
+ } | |
+ } | |
+ if (utf8 < 0) | |
+ utf8 = 0; | |
+ } | |
+ } | |
+ // æçµçã«ä¸çªå¾ç¹ã®é«ãã¨ã³ã³ã¼ããè¿ã | |
+ if (euc > sjis && euc > utf8) | |
+ return CHARSET_EUCJP; | |
+ else if (!ufailed && utf8 > euc && utf8 > sjis) | |
+ return CHARSET_UTF8; | |
+ else if (sjis > euc && sjis > utf8) | |
+ return CHARSET_CP932; | |
+ else | |
+ return CHARSET_NONE; | |
+} | |
+static int | |
+charset_detect_file(const char* path) | |
+{ | |
+ int charset = CHARSET_NONE; | |
+ FILE* fp; | |
+ if ((fp = fopen(path, "rt")) != NULL) | |
+ { | |
+ unsigned char buf[BUFLEN_DETECT]; | |
+ size_t len = fread(buf, sizeof(buf[0]), sizeof(buf), fp); | |
+ fclose(fp); | |
+ if (len > 0 && len <= INT_MAX) | |
+ charset = charset_detect_buf(buf, (int)len); | |
+ } | |
+ return charset; | |
+} | |
+/**/ | |
+ | |
+migemo* (*migemo_open_)(const char*); | |
+void (*migemo_close_)(migemo*); | |
+unsigned char* (*migemo_query_)(migemo*, unsigned char*); | |
+void (*migemo_release_)(migemo*, unsigned char*); | |
+ | |
+int (*migemo_set_operator_)(migemo*, int, unsigned char*); | |
+int (*migemo_is_enable_)(migemo*); | |
+int (*migemo_load_)(migemo*, int, char *); | |
+void (*migemo_setproc_char2int_)(migemo*, MIGEMO_PROC_CHAR2INT); | |
+void (*migemo_setproc_int2char_)(migemo*, MIGEMO_PROC_INT2CHAR); | |
+ | |
+static migemo *pmigemo = NULL; | |
+#ifdef WINDOWSNT | |
+static HMODULE hMigemo = NULL; | |
+#else | |
+static void *hMigemo = NULL; | |
+#endif | |
+ | |
+static int int2char(unsigned int in, unsigned char* out, | |
+ CHARSET_PROC_INT2CHAR proc) | |
+{ | |
+ switch (in) { | |
+ case '.': case '*': case '+': case '?': | |
+ case '[': case ']': case '^': case '$': | |
+ case '\\': | |
+ if (!out) | |
+ return 0; | |
+ out[0] = '\\'; | |
+ out[1] = in; | |
+ return 2; | |
+ default: | |
+ break; | |
+ } | |
+ return (*proc)(in, out); | |
+} | |
+ | |
+static int eucjp(unsigned int in, unsigned char* out) | |
+{ | |
+ return int2char(in, out, eucjp_int2char); | |
+} | |
+ | |
+static int cp932(unsigned int in, unsigned char* out) | |
+{ | |
+ return int2char(in, out, cp932_int2char); | |
+} | |
+ | |
+static int utf8(unsigned int in, unsigned char* out) | |
+{ | |
+ return int2char(in, out, utf8_int2char); | |
+} | |
+ | |
+static int charset; | |
+ | |
+static MIGEMO_PROC_INT2CHAR getproc(int charset) | |
+{ | |
+ | |
+ switch (charset) { | |
+ case CHARSET_CP932: | |
+ return cp932; | |
+ break; | |
+ case CHARSET_EUCJP: | |
+ return eucjp; | |
+ break; | |
+ case CHARSET_UTF8: | |
+ return utf8; | |
+ break; | |
+ default: | |
+ break; | |
+ } | |
+ return NULL; | |
+} | |
+ | |
+DEFUN ("cmigemo-open", Fcmigemo_open, Scmigemo_open, 1, 1, 0, | |
+ doc: /* open cmigemo with DICTIONARY.*/ ) | |
+ (Lisp_Object dictionary) | |
+{ | |
+ static int coding_system_initialized = 0; | |
+ MIGEMO_PROC_INT2CHAR int2char; | |
+ | |
+ if (pmigemo) | |
+ error ("cmigemo already opened"); | |
+ | |
+ CHECK_STRING(dictionary); | |
+ | |
+#ifdef WINDOWSNT | |
+ hMigemo = LoadLibrary(MIGEMO_DLL); | |
+#else | |
+ hMigemo = dlopen(MIGEMO_DLL, RTLD_NOW); | |
+#endif | |
+ if (hMigemo == NULL) | |
+ error (MIGEMO_DLL ": can't load"); | |
+ | |
+#ifdef WINDOWSNT | |
+#define GETPROC(n, t) do { \ | |
+ migemo_ ## n ## _ = (t) GetProcAddress(hMigemo, "migemo_" # n); \ | |
+} while(0) | |
+#else | |
+#define GETPROC(n, t) do { \ | |
+ migemo_ ## n ## _ = (t) dlsym(hMigemo, "migemo_" # n); \ | |
+} while(0) | |
+#endif | |
+ | |
+ GETPROC(open, migemo* (*)(const char*)); | |
+ GETPROC(close, void (*)(migemo*)); | |
+ GETPROC(query, unsigned char* (*)(migemo*, unsigned char*)); | |
+ GETPROC(release, void (*)(migemo*, unsigned char*)); | |
+ GETPROC(set_operator, int (*)(migemo*, int, unsigned char*)); | |
+ GETPROC(is_enable, int (*)(migemo*)); | |
+ GETPROC(load, int (*)(migemo*, int, char *)); | |
+ GETPROC(setproc_char2int, void (*)(migemo*, MIGEMO_PROC_CHAR2INT)); | |
+ GETPROC(setproc_int2char, void (*)(migemo*, MIGEMO_PROC_INT2CHAR)); | |
+ | |
+ if (!(pmigemo = migemo_open_(SDATA(dictionary))) || | |
+ !migemo_is_enable_(pmigemo)) { | |
+ pmigemo = NULL; | |
+ error("could not open cmigemo"); | |
+ } | |
+ migemo_set_operator_(pmigemo, MIGEMO_OPINDEX_OR, "\\|"); | |
+ migemo_set_operator_(pmigemo, MIGEMO_OPINDEX_NEST_IN, "\\("); | |
+ migemo_set_operator_(pmigemo, MIGEMO_OPINDEX_NEST_OUT, "\\)"); | |
+ migemo_set_operator_(pmigemo, MIGEMO_OPINDEX_NEWLINE, "\\s-*"); | |
+ | |
+ charset = charset_detect_file(SDATA(dictionary)); | |
+ | |
+ if ((int2char = getproc(charset)) != NULL) | |
+ migemo_setproc_int2char_(pmigemo, int2char); | |
+ | |
+ return Qt; | |
+} | |
+ | |
+DEFUN ("cmigemo-close", Fcmigemo_close, Scmigemo_close, 0, 0, 0, | |
+ doc: /*close cmigemo.*/) | |
+ (void) | |
+{ | |
+ if (!pmigemo) | |
+ error ("cmigemo was not opened"); | |
+ migemo_close_(pmigemo); | |
+ pmigemo = NULL; | |
+#ifdef WINDOWSNT | |
+ FreeLibrary(hMigemo); | |
+#else | |
+ dlclose(hMigemo); | |
+#endif | |
+ hMigemo = NULL; | |
+ return Qt; | |
+} | |
+ | |
+DEFUN ("cmigemo-query", Fcmigemo_query, Scmigemo_query, 1, 1, 0, | |
+ doc: /*query cmigemo about WORD.*/) | |
+ (Lisp_Object word) | |
+{ | |
+ char *ans; | |
+ Lisp_Object temp; | |
+ struct gcpro gcpro1; | |
+ | |
+ if (!pmigemo) | |
+ error ("cmigemo was not opened"); | |
+ | |
+ CHECK_STRING(word); | |
+ | |
+ GCPRO1(temp); | |
+ temp = word; | |
+ | |
+ if (STRING_MULTIBYTE (temp)) | |
+ switch (charset) { | |
+ default: | |
+ case CHARSET_CP932: | |
+ temp = code_convert_string_norecord(temp, intern("sjis"), 1); | |
+ break; | |
+ case CHARSET_EUCJP: | |
+ temp = code_convert_string_norecord(temp, intern("euc-japan"), 1); | |
+ break; | |
+ case CHARSET_UTF8: | |
+ break; | |
+ } | |
+ | |
+ ans = migemo_query_(pmigemo, SDATA(temp)); | |
+ | |
+ if (!ans) | |
+ temp = Qnil; | |
+ else | |
+ switch (charset) { | |
+ default: | |
+ case CHARSET_CP932: | |
+ temp = code_convert_string_norecord(temp = build_string(ans), | |
+ intern("sjis"), 0); | |
+ break; | |
+ case CHARSET_EUCJP: | |
+ temp = code_convert_string_norecord(temp = build_string(ans), | |
+ intern("euc-japan"), 0); | |
+ break; | |
+ case CHARSET_UTF8: | |
+ temp = build_string(ans); | |
+ break; | |
+ } | |
+ UNGCPRO; | |
+ migemo_release_(pmigemo, ans); | |
+ return temp; | |
+} | |
+ | |
+DEFUN ("cmigemo-load", Fcmigemo_load, Scmigemo_load, 1, 1, 0, | |
+ doc: /*load a sub DICTIONARY.*/) | |
+ (Lisp_Object dictionary) | |
+{ | |
+ MIGEMO_PROC_INT2CHAR int2char; | |
+ | |
+ if (!pmigemo) | |
+ error ("cmigemo was not opened"); | |
+ | |
+ CHECK_STRING(dictionary); | |
+ | |
+ if (migemo_load_(pmigemo, MIGEMO_DICTID_MIGEMO, | |
+ SDATA(dictionary)) == MIGEMO_DICTID_INVALID) | |
+ error("migemo_load invalid dict %s", dictionary); | |
+ | |
+ /* | |
+ * Migemo_load resets int2char proc, | |
+ * then we set it again. | |
+ */ | |
+ | |
+ int2char = getproc(charset); | |
+ migemo_setproc_int2char_(pmigemo, int2char); | |
+ | |
+ return Qt; | |
+} | |
+ | |
+void | |
+syms_of_cmigemo () | |
+{ | |
+ defsubr(&Scmigemo_open); | |
+ defsubr(&Scmigemo_close); | |
+ defsubr(&Scmigemo_query); | |
+ defsubr(&Scmigemo_load); | |
+} | |
+#endif /* HAVE_CMIGEMO */ | |
--- ./src/doprnt.c.orig 2015-02-02 02:27:17.000000000 +0900 | |
+++ ./src/doprnt.c 2015-04-11 07:27:30.582120600 +0900 | |
@@ -155,9 +155,9 @@ | |
if (format_end == 0) | |
format_end = format + strlen (format); | |
- fmtcpy = (format_end - format < sizeof (fixed_buffer) - 1 | |
+ fmtcpy = (format_end - format + 1 + 1 < sizeof (fixed_buffer) | |
? fixed_buffer | |
- : SAFE_ALLOCA (format_end - format + 1)); | |
+ : SAFE_ALLOCA (format_end - format + 1 + 1)); | |
bufsize--; | |
--- ./src/emacs.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/emacs.c 2015-04-11 07:27:30.589121000 +0900 | |
@@ -208,6 +208,10 @@ | |
static void sort_args (int argc, char **argv); | |
static void syms_of_emacs (void); | |
+#ifdef HAVE_CMIGEMO | |
+extern void syms_of_cmigemo (void); | |
+#endif | |
+ | |
/* C89 needs each string be at most 509 characters, so the usage | |
strings below are split to not overflow this limit. */ | |
static char const *const usage_message[] = | |
@@ -768,6 +772,13 @@ | |
atexit (close_output_streams); | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+ { | |
+ extern CRITICAL_SECTION alloc_critical_section; | |
+ InitializeCriticalSection(&alloc_critical_section); | |
+ } | |
+#endif | |
+ | |
sort_args (argc, argv); | |
argc = 0; | |
while (argv[argc]) argc++; | |
@@ -1523,6 +1534,10 @@ | |
syms_of_profiler (); | |
+#ifdef HAVE_CMIGEMO | |
+ syms_of_cmigemo (); | |
+#endif /* HAVE_CMIGEMO */ | |
+ | |
keys_of_casefiddle (); | |
keys_of_cmds (); | |
keys_of_buffer (); | |
--- ./src/frame.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/frame.c 2015-04-11 07:27:30.596121900 +0900 | |
@@ -2744,6 +2744,9 @@ | |
{"fullscreen", &Qfullscreen}, | |
{"font-backend", &Qfont_backend}, | |
{"alpha", &Qalpha}, | |
+#ifdef USE_W32_IME | |
+ {"ime-font", &Qime_font}, | |
+#endif /* USE_W32_IME */ | |
{"sticky", &Qsticky}, | |
{"tool-bar-position", &Qtool_bar_position}, | |
}; | |
--- ./src/frame.h.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/frame.h 2015-04-11 07:27:30.604123000 +0900 | |
@@ -1217,6 +1217,9 @@ | |
extern Lisp_Object Qbuffer_predicate; | |
extern Lisp_Object Qcursor_color, Qcursor_type; | |
extern Lisp_Object Qfont; | |
+#ifdef USE_W32_IME | |
+extern Lisp_Object Qime_font; | |
+#endif /* USE_W32_IME */ | |
extern Lisp_Object Qbackground_color, Qforeground_color; | |
extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top; | |
extern Lisp_Object Qinternal_border_width; | |
--- ./src/image.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/image.c 2015-04-11 07:27:30.613127900 +0900 | |
@@ -536,6 +536,10 @@ | |
static struct image_type *image_types; | |
+/* "Alist of (IMAGE-TYPE . FIT-OPTION) pairs used by image loader to specify image size. */ | |
+ | |
+//static Lisp_Object Vimage_fit_option_alist; | |
+ | |
/* The symbol `xbm' which is used as the type symbol for XBM images. */ | |
static Lisp_Object Qxbm; | |
@@ -544,6 +548,7 @@ | |
Lisp_Object QCascent, QCmargin, QCrelief; | |
Lisp_Object QCconversion; | |
+Lisp_Object QCfit; | |
static Lisp_Object QCheuristic_mask; | |
static Lisp_Object QCcolor_symbols; | |
static Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask, QCgeometry; | |
@@ -617,6 +622,102 @@ | |
return p; | |
} | |
+Lisp_Object Qnever, Qframe, Qwidth_or_height; | |
+ | |
+static void image_error (const char *, Lisp_Object, Lisp_Object); | |
+static int get_fit_size(Lisp_Object opt, const struct frame *f, | |
+ int *w, int *h, | |
+ Lisp_Object image_type, int rise_error) | |
+{ | |
+ if (NILP(opt)) | |
+ return 0; | |
+ | |
+ if (EQ(opt, Qnever)) { | |
+ *w = *h = 0; | |
+ } else if (EQ(opt, Qframe)) { | |
+ *w = FRAME_PIXEL_WIDTH (f) - FRAME_CONFIG_SCROLL_BAR_WIDTH (f) - FRAME_SCROLL_BAR_AREA_WIDTH (f); | |
+ *h = FRAME_PIXEL_HEIGHT (f); | |
+ } else if (EQ(opt, Qwidth_or_height)) { | |
+ *w = -(FRAME_PIXEL_WIDTH (f) - FRAME_CONFIG_SCROLL_BAR_WIDTH (f) - FRAME_SCROLL_BAR_AREA_WIDTH (f)); | |
+ *h = -FRAME_PIXEL_HEIGHT (f); | |
+ } else if (EQ(opt, Qwidth)) { | |
+ *w = FRAME_PIXEL_WIDTH (f) - FRAME_CONFIG_SCROLL_BAR_WIDTH (f) - FRAME_SCROLL_BAR_AREA_WIDTH (f); | |
+ *h = 0; | |
+ } else if (EQ(opt, Qheight)) { | |
+ *w = 0; | |
+ *h = FRAME_PIXEL_HEIGHT (f); | |
+ } else { | |
+ if (rise_error) | |
+ xsignal2 (Qnil, build_string("unknown fit type"), opt); | |
+ else | |
+ image_error ("Invalid fit option for %s", image_type, Qnil); | |
+ return -1; | |
+ } | |
+ return 1; | |
+} | |
+ | |
+static Lisp_Object image_spec_value (Lisp_Object, Lisp_Object, bool *); | |
+static int | |
+lookup_fit_size(Lisp_Object image_type, | |
+ const struct frame *f, | |
+ const struct image *img, | |
+ int *w, int *h, int rise_error) | |
+{ | |
+ Lisp_Object a, err, pred; | |
+ static const struct frame f_ = {0}; | |
+ int w_, h_; | |
+ int r; | |
+ | |
+// assert(SYMBOLP (image_type)); | |
+ | |
+ if (img && | |
+ (r = get_fit_size(image_spec_value(img->spec, QCfit, NULL), | |
+ f, w, h, image_type, rise_error)) != 0) | |
+ return r; | |
+ | |
+#if 0 | |
+ if (!CONSP (err = Vimage_fit_option_alist)) { | |
+ pred = Qconsp; | |
+ goto error; | |
+ } | |
+#endif | |
+ | |
+ for (a = Vimage_fit_option_alist; !NILP(a); a = XCDR(a)) { | |
+ Lisp_Object o; | |
+ { | |
+ Lisp_Object e = XCAR(a); | |
+ | |
+ if (!CONSP(err = e)) { | |
+ pred = Qconsp; | |
+ goto error; | |
+ } | |
+ | |
+ if (!EQ(XCAR(e), image_type)) | |
+ continue; | |
+ o = XCDR(e); | |
+ } | |
+ | |
+ if (!SYMBOLP(err = o)) { | |
+ pred = Qsymbolp; | |
+ goto error; | |
+ } | |
+ if (f) | |
+ return get_fit_size(o, f, w, h, image_type, rise_error); | |
+ get_fit_size(o, &f_, &w_, &h_, image_type, rise_error); | |
+ } | |
+ | |
+ /* not found */ | |
+ if (f) | |
+ *w = *h = 0; | |
+ return 0; | |
+ | |
+ error: | |
+ if (rise_error) | |
+ wrong_type_argument(pred, err); | |
+ else | |
+ image_error ("Invalid fit option for %s", image_type, Qnil); | |
+ return -1; | |
+} | |
/* Value is true if OBJECT is a valid Lisp image specification. A | |
valid image specification is a list whose car is the symbol | |
@@ -3096,6 +3197,8 @@ | |
#define XImage xpm_XImage | |
#define Display xpm_Display | |
#define PIXEL_ALREADY_TYPEDEFED | |
+#undef close | |
+#undef open | |
#include "X11/xpm.h" | |
#undef FOR_MSW | |
#undef XColor | |
@@ -6483,6 +6586,10 @@ | |
XImagePtr ximg = NULL; | |
unsigned long *colors; | |
int width, height; | |
+ int fit_width = 0, fit_height = 0; | |
+ | |
+ if (lookup_fit_size (Qjpeg, f, img, &fit_width, &fit_height, !0) < 0) | |
+ return 0; | |
/* Open the JPEG file. */ | |
specified_file = image_spec_value (img->spec, QCfile, NULL); | |
@@ -6560,6 +6667,43 @@ | |
fn_jpeg_read_header (&mgr->cinfo, 1); | |
+#define JPEG8C_UNIT 8 | |
+ | |
+ if (fit_width > 0 && fit_height == 0) { | |
+ if (mgr->cinfo.image_width > fit_width) { /* fit to width */ | |
+ mgr->cinfo.scale_num = ((double) fit_width / mgr->cinfo.image_width) * JPEG8C_UNIT; | |
+ mgr->cinfo.scale_denom = JPEG8C_UNIT; | |
+ } | |
+ } else if (fit_width == 0 && fit_height > 0) { | |
+ if (mgr->cinfo.image_height > fit_height) { /* fit to width */ | |
+ mgr->cinfo.scale_num = ((double)fit_height / mgr->cinfo.image_height) * JPEG8C_UNIT; | |
+ mgr->cinfo.scale_denom = JPEG8C_UNIT; | |
+ } | |
+ } else if (fit_width > 0 && fit_height > 0) { /* fit to frame */ | |
+ if (mgr->cinfo.image_width > fit_width || | |
+ mgr->cinfo.image_height > fit_height) { | |
+ if ((double)fit_width / mgr->cinfo.image_width < | |
+ (double)fit_height / mgr->cinfo.image_height) { | |
+ mgr->cinfo.scale_num = ((double)fit_width / mgr->cinfo.image_width) * JPEG8C_UNIT; | |
+ } else { | |
+ mgr->cinfo.scale_num = ((double)fit_height / mgr->cinfo.image_height) * JPEG8C_UNIT; | |
+ mgr->cinfo.scale_denom = JPEG8C_UNIT; | |
+ } | |
+ } | |
+ } else if (fit_width < 0 && fit_height < 0) { /* fit to width or height */ | |
+ if (mgr->cinfo.image_width > -fit_width && | |
+ mgr->cinfo.image_height > -fit_height) { | |
+ if ((double)-fit_width / mgr->cinfo.image_width > | |
+ (double)-fit_height / mgr->cinfo.image_height) { | |
+ mgr->cinfo.scale_num = ((double)-fit_width / mgr->cinfo.image_width) * JPEG8C_UNIT; | |
+ mgr->cinfo.scale_denom = JPEG8C_UNIT; | |
+ } else { | |
+ mgr->cinfo.scale_num = ((double)-fit_height / mgr->cinfo.image_height) * JPEG8C_UNIT; | |
+ mgr->cinfo.scale_denom = JPEG8C_UNIT; | |
+ } | |
+ } | |
+ } | |
+ | |
/* Customize decompression so that color quantization will be used. | |
Start decompression. */ | |
mgr->cinfo.quantize_colors = 1; | |
@@ -8512,6 +8656,12 @@ | |
{ | |
bool success_p = 0; | |
Lisp_Object file_name; | |
+ int w, h; | |
+ | |
+#if 0 | |
+ if (lookup_fit_size(Qjpeg, NULL, NULL, NULL, NULL, !0) < 0) | |
+ return 0; | |
+#endif | |
/* If IMG->spec specifies a file name, create a non-file spec from it. */ | |
file_name = image_spec_value (img->spec, QCfile, NULL); | |
@@ -8722,6 +8872,7 @@ | |
LOAD_IMGLIB_FN (library, rsvg_handle_write); | |
LOAD_IMGLIB_FN (library, rsvg_handle_close); | |
LOAD_IMGLIB_FN (library, rsvg_handle_get_pixbuf); | |
+ LOAD_IMGLIB_FN (library, rsvg_handle_set_size_callback); | |
LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_width); | |
LOAD_IMGLIB_FN (gdklib, gdk_pixbuf_get_height); | |
@@ -8749,6 +8900,7 @@ | |
#define fn_rsvg_handle_write rsvg_handle_write | |
#define fn_rsvg_handle_close rsvg_handle_close | |
#define fn_rsvg_handle_get_pixbuf rsvg_handle_get_pixbuf | |
+#define fn_rsvg_handle_set_size_callback rsvg_handle_set_size_callback | |
#define fn_gdk_pixbuf_get_width gdk_pixbuf_get_width | |
#define fn_gdk_pixbuf_get_height gdk_pixbuf_get_height | |
@@ -8819,6 +8971,48 @@ | |
return success_p; | |
} | |
+static void rsvg_size_callback (gint *width, | |
+ gint *height, | |
+ gpointer user_data) | |
+{ | |
+ int *fit_size = (int *)user_data; | |
+ | |
+ /* | |
+ * 0, 0: never | |
+ * 0, +: fit to height | |
+ * +, 0: fit to width | |
+ * +, +: fit to frame | |
+ * -, -: fit to width or height | |
+ */ | |
+ if (fit_size[0] > 0 && fit_size[1] == 0) { | |
+ *height *= (double)fit_size[0] / *width; | |
+ *width = (gint)fit_size[0]; | |
+ } else if (fit_size[0] == 0 && fit_size[1] > 0) { | |
+ *width *= (double)fit_size[1] / *height; | |
+ *height = (gint)fit_size[1]; | |
+ } else if (fit_size[0] > 0 && fit_size[1] > 0) { /* fit to frame */ | |
+ if ((double)fit_size[0] / *width < (double)fit_size[1] / *height) { | |
+ /* fit to width */ | |
+ *height *= (double)fit_size[0] / *width; | |
+ *width = (gint)fit_size[0]; | |
+ } else { | |
+ /* fit to height */ | |
+ *width *= (double)fit_size[1] / *height; | |
+ *height = (gint)fit_size[1]; | |
+ } | |
+ } else if (fit_size[0] < 0 && fit_size[1] < 0) { /* fit to width or height */ | |
+ if ((double)-fit_size[0] / *width < (double)-fit_size[1] / *height) { | |
+ /* fit to height */ | |
+ *width *= (double)-fit_size[1] / *height; | |
+ *height = (gint)-fit_size[1]; | |
+ } else { | |
+ /* fit to width */ | |
+ *height *= (double)-fit_size[0] / *width; | |
+ *width = (gint)-fit_size[0]; | |
+ } | |
+ } | |
+} | |
+ | |
/* svg_load_image is a helper function for svg_load, which does the | |
actual loading given contents and size, apart from frame and image | |
structures, passed from svg_load. | |
@@ -8845,6 +9039,10 @@ | |
XColor background; | |
int x; | |
int y; | |
+ int fit_size[2] = {0, 0}; | |
+ | |
+ if (lookup_fit_size(Qsvg, f, img, fit_size, fit_size+1, 0) < 0) | |
+ return 0; | |
#if ! GLIB_CHECK_VERSION (2, 36, 0) | |
/* g_type_init is a glib function that must be called prior to | |
@@ -8855,6 +9053,9 @@ | |
/* Make a handle to a new rsvg object. */ | |
rsvg_handle = fn_rsvg_handle_new (); | |
+ if (fit_size[0] || fit_size[1]) | |
+ fn_rsvg_handle_set_size_callback(rsvg_handle, rsvg_size_callback, fit_size, NULL); | |
+ | |
/* Parse the contents argument and fill in the rsvg_handle. */ | |
fn_rsvg_handle_write (rsvg_handle, contents, size, &err); | |
if (err) goto rsvg_error; | |
@@ -9438,6 +9639,7 @@ | |
DEFSYM (QCmatrix, ":matrix"); | |
DEFSYM (QCcolor_adjustment, ":color-adjustment"); | |
DEFSYM (QCmask, ":mask"); | |
+ DEFSYM (QCfit, ":fit"); | |
DEFSYM (Qlaplace, "laplace"); | |
DEFSYM (Qemboss, "emboss"); | |
@@ -9484,12 +9686,26 @@ | |
); | |
#endif | |
+ DEFVAR_LISP ("image-fit-option-alist", Vimage_fit_option_alist, | |
+ doc: /* Alist of (IMAGE-TYPE . FIT-OPTION) pairs used by image loader to specify image size. | |
+the FIT-OPTION is one of 'never, 'frame, 'width-or-height, 'width or 'height. | |
+Note: All image loaders are not supporting this `fit' capability. */); | |
+ Vimage_fit_option_alist = Qnil; | |
+ | |
DEFSYM (Qpbm, "pbm"); | |
ADD_IMAGE_TYPE (Qpbm); | |
DEFSYM (Qxbm, "xbm"); | |
ADD_IMAGE_TYPE (Qxbm); | |
+ Qnever = intern_c_string("never"); | |
+ staticpro (&Qnever); | |
+ Qframe = intern_c_string("frame"); | |
+ staticpro (&Qframe); | |
+ Qwidth_or_height = intern_c_string("width-or-height"); | |
+ staticpro (&Qwidth_or_height); | |
+ | |
+ | |
#if defined (HAVE_XPM) || defined (HAVE_NS) | |
DEFSYM (Qxpm, "xpm"); | |
ADD_IMAGE_TYPE (Qxpm); | |
@@ -9523,7 +9739,7 @@ | |
#if defined (HAVE_RSVG) | |
DEFSYM (Qsvg, "svg"); | |
ADD_IMAGE_TYPE (Qsvg); | |
-#ifdef HAVE_NTGUI | |
+#if defined HAVE_NTGUI && !defined CYGWIN | |
/* Other libraries used directly by svg code. */ | |
DEFSYM (Qgdk_pixbuf, "gdk-pixbuf"); | |
DEFSYM (Qglib, "glib"); | |
--- ./src/keyboard.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/keyboard.c 2015-04-11 07:27:30.625123200 +0900 | |
@@ -4779,7 +4779,11 @@ | |
"junja", /* VK_JUNJA 0x17 */ | |
"final", /* VK_FINAL 0x18 */ | |
"kanji", /* VK_KANJI/VK_HANJA 0x19 */ | |
+#ifdef USE_W32_IME | |
+ "compend", /* VK_COMPEND 0x1A */ | |
+#else | |
0, /* 0x1A */ | |
+#endif /* USE_W32_IME */ | |
"escape", /* VK_ESCAPE 0x1B */ | |
"convert", /* VK_CONVERT 0x1C */ | |
"non-convert", /* VK_NONCONVERT 0x1D */ | |
@@ -8851,6 +8855,13 @@ | |
{ | |
ptrdiff_t count = SPECPDL_INDEX (); | |
+ /* To control IME */ | |
+#ifdef USE_W32_IME | |
+ extern Lisp_Object Fime_force_on (), Fime_force_off (), Fime_get_mode (); | |
+ Lisp_Object VIME_command_off_flag = Qnil; | |
+ Lisp_Object IME_command_loop_flag = Qnil; | |
+#endif /* USE_W32_IME */ | |
+ | |
/* How many keys there are in the current key sequence. */ | |
int t; | |
@@ -8966,6 +8977,12 @@ | |
keybuf[0..mock_input] holds the sequence we should reread. */ | |
replay_sequence: | |
+#ifdef USE_W32_IME | |
+/* If key sequences are to replay, IME_loop_flag should not be set. | |
+ Because event has never been occured. */ | |
+ IME_command_loop_flag = Qnil; | |
+#endif /* USE_W32_IME */ | |
+ | |
starting_buffer = current_buffer; | |
first_unbound = bufsize + 1; | |
@@ -9045,6 +9062,16 @@ | |
goto replay_sequence; | |
} | |
+#ifdef USE_W32_IME | |
+ if (!NILP (IME_command_loop_flag) && NILP (VIME_command_off_flag)) | |
+ { | |
+ VIME_command_off_flag = Fime_get_mode (); | |
+ if (!NILP (VIME_command_off_flag)) | |
+ Fime_force_off (Qnil); | |
+ } | |
+ IME_command_loop_flag = Qt; | |
+#endif /* USE_W32_IME */ | |
+ | |
if (t >= bufsize) | |
error ("Key sequence too long"); | |
@@ -9708,6 +9735,12 @@ | |
? Fcommand_remapping (read_key_sequence_cmd, Qnil, Qnil) | |
: Qnil; | |
+ /* to control IME */ | |
+#ifdef USE_W32_IME | |
+ if (!NILP (VIME_command_off_flag)) | |
+ Fime_force_on (Qnil); | |
+#endif /* USE_W32_IME */ | |
+ | |
unread_switch_frame = delayed_switch_frame; | |
unbind_to (count, Qnil); | |
--- ./src/lisp.h.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/lisp.h 2015-04-11 07:27:30.637122000 +0900 | |
@@ -286,6 +286,17 @@ | |
# define USE_LSB_TAG true | |
# endif | |
# endif | |
+# if defined (_MSC_VER) | |
+# define ALIGN_BITS_0 1 | |
+# define ALIGN_BITS_1 2 | |
+# define ALIGN_BITS_2 4 | |
+# define ALIGN_BITS_3 8 | |
+# define ALIGN_BITS_4 16 | |
+# define ALIGN_BITS_(x) ALIGN_BITS_ ## x | |
+# define ALIGN_BITS(x) ALIGN_BITS_(x) | |
+# define DECL_ALIGN(type, var) \ | |
+ type __declspec (align(ALIGN_BITS(GCTYPEBITS))) var | |
+# endif | |
# endif | |
#endif | |
#ifdef USE_LSB_TAG | |
@@ -3652,7 +3663,26 @@ | |
#endif | |
extern const char *pending_malloc_warning; | |
extern Lisp_Object zero_vector; | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
extern Lisp_Object *stack_base; | |
+#else /* USE_W32_CALL_LISP_THREAD */ | |
+#ifndef TLS | |
+#ifdef _MSC_VER | |
+#define TLS __declspec( thread ) | |
+#else | |
+#ifdef __GNUC__ | |
+#define TLS __thread | |
+#else | |
+#define TLS | |
+#endif | |
+#endif | |
+#endif | |
+#ifdef __GNUC__ | |
+extern TLS Lisp_Object *stack_base; | |
+#else | |
+TLS extern Lisp_Object *stack_base; | |
+#endif | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
extern EMACS_INT consing_since_gc; | |
extern EMACS_INT gc_relative_threshold; | |
extern EMACS_INT memory_full_cons_threshold; | |
--- ./src/lisp.mk.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/lisp.mk 2015-04-11 07:27:30.646122500 +0900 | |
@@ -152,6 +152,7 @@ | |
$(lispsource)/term/w32-win.elc \ | |
$(lispsource)/ls-lisp.elc \ | |
$(lispsource)/disp-table.elc \ | |
+ $(lispsource)/international/w32-ime.elc \ | |
$(lispsource)/w32-common-fns.elc \ | |
$(lispsource)/dos-w32.elc \ | |
$(lispsource)/w32-fns.elc \ | |
--- ./src/Makefile.in.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/Makefile.in 2015-04-11 07:27:30.650126500 +0900 | |
@@ -355,7 +355,7 @@ | |
process.o gnutls.o callproc.o \ | |
region-cache.o sound.o atimer.o \ | |
doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \ | |
- profiler.o decompress.o \ | |
+ profiler.o decompress.o cmigemo.o \ | |
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ | |
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) | |
obj = $(base_obj) $(NS_OBJC_OBJ) | |
--- ./src/w32.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32.c 2015-04-11 07:27:30.658123200 +0900 | |
@@ -332,7 +332,7 @@ | |
GetProcessTimes_Proc get_process_times_fn = NULL; | |
-#ifdef _UNICODE | |
+#if defined(_UNICODE) || defined(UNICODE) | |
const char * const LookupAccountSid_Name = "LookupAccountSidW"; | |
#else | |
const char * const LookupAccountSid_Name = "LookupAccountSidA"; | |
@@ -2030,7 +2030,7 @@ | |
Otherwise, the default group name was already set to | |
"None" in globals_of_w32. */ | |
if (lookup_account_sid (NULL, group_token.PrimaryGroup, | |
- gname, &glength, NULL, &dlength, | |
+ gname, &glength, domain, &dlength, | |
&user_type)) | |
strcpy (dflt_group_name, gname); | |
} | |
@@ -2530,6 +2530,7 @@ | |
for (i = 0; i < imax ; i++) | |
{ | |
const char *tmp = tempdirs[i]; | |
+ struct stat b; | |
if (*tmp == '$') | |
tmp = getenv (tmp + 1); | |
@@ -2809,6 +2810,8 @@ | |
filename_from_ansi (astartup_dir, startup_dir); | |
} | |
+ dostounix_filename (startup_dir); | |
+ | |
{ | |
static char modname[MAX_PATH]; | |
@@ -3216,7 +3219,7 @@ | |
while (name < path) | |
*str++ = *name++; /* skip past UNC header */ | |
- while ((c = *name++)) | |
+ for (; c = *name; name = _mbsinc(name)) | |
{ | |
switch ( c ) | |
{ | |
@@ -3235,9 +3238,9 @@ | |
but leave . and .. as they are. This allows .emacs | |
to be read as _emacs, for example. */ | |
- if (! *name || | |
- *name == '.' || | |
- IS_DIRECTORY_SEP (*name)) | |
+ if (! name[1] || | |
+ name[1] == '.' || | |
+ IS_DIRECTORY_SEP (name[1])) | |
{ | |
*str++ = '.'; | |
dots--; | |
@@ -3263,11 +3266,20 @@ | |
break; | |
case '~': | |
case '#': /* don't lose these, they're important */ | |
- if ( ! left ) | |
- str[-1] = c; /* replace last character of part */ | |
+ if ( ! left ) { | |
+ char *p = _mbsdec(shortname, str); | |
+ left += str - p; | |
+ *p++ = c; /* replace last character of part */ | |
+ str = p; | |
+ } | |
/* FALLTHRU */ | |
default: | |
- if ( left && 'A' <= c && c <= 'Z' ) | |
+ if (IsDBCSLeadByte(c) && left > 1) { | |
+ *str++ = c; | |
+ *str++ = name[1]; | |
+ left -= 2; | |
+ dots = 0; /* started a path component */ | |
+ } else if ( left && 'A' <= c && c <= 'Z' ) | |
{ | |
*str++ = tolower (c); /* map to lower case (looks nicer) */ | |
left--; | |
@@ -3293,13 +3305,19 @@ | |
static int | |
is_exec (const char * name) | |
{ | |
+ char * ext = getenv("PATHEXT"); | |
char * p = strrchr (name, '.'); | |
+ size_t l; | |
+ | |
+ ext = ext | |
+ ? (char *) _mbslwr(strcpy(alloca(strlen(ext) + 1), ext)) | |
+ : ".exe;.com;.bat;.cmd"; | |
+ | |
return | |
(p != NULL | |
- && (xstrcasecmp (p, ".exe") == 0 || | |
- xstrcasecmp (p, ".com") == 0 || | |
- xstrcasecmp (p, ".bat") == 0 || | |
- xstrcasecmp (p, ".cmd") == 0)); | |
+ && (p = _mbslwr(strcpy(alloca((l = strlen(p)) + 1), p))) != NULL | |
+ && (p = strstr(ext, p)) != NULL | |
+ && (p[l] == ';' || p[l] == 0)); | |
} | |
/* Emulate the Unix directory procedures opendir, closedir, and | |
@@ -6853,7 +6871,7 @@ | |
dlength = sizeof (domain); | |
result = | |
lookup_account_sid (NULL, group_token.PrimaryGroup, | |
- gname, &glength, NULL, &dlength, | |
+ gname, &glength, domain, &dlength, | |
&user_type); | |
if (result) | |
w32_add_to_cache (group_token.PrimaryGroup, | |
@@ -7290,7 +7308,11 @@ | |
static int socket_to_fd (SOCKET s); | |
+#ifdef __MINGW64__ | |
+SOCKET | |
+#else | |
int | |
+#endif | |
sys_socket (int af, int type, int protocol) | |
{ | |
SOCKET s; | |
@@ -8081,7 +8103,7 @@ | |
{ | |
int nchars; | |
int to_read; | |
- DWORD waiting; | |
+ unsigned long waiting; | |
char * orig_buffer = buffer; | |
if (fd < 0) | |
@@ -8155,8 +8177,10 @@ | |
if (fd_info[fd].flags & FILE_PIPE) | |
{ | |
- PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL); | |
- to_read = min (waiting, (DWORD) count); | |
+ DWORD w; | |
+ PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &w, NULL); | |
+ waiting = w; /* avoid cast, because cast to DWORD is danger */ | |
+ to_read = min (waiting, count); | |
if (to_read > 0) | |
nchars += _read (fd, buffer, to_read); | |
@@ -8823,14 +8847,14 @@ | |
int needed; | |
sprintf (buffer, | |
- "The Emacs Windows initialization file \"%s.el\" " | |
+ TEXT ("The Emacs Windows initialization file \"%s.el\" " | |
"could not be found in your Emacs installation. " | |
"Emacs checked the following directories for this file:\n" | |
"\n%s\n\n" | |
"When Emacs cannot find this file, it usually means that it " | |
"was not installed properly, or its distribution file was " | |
"not unpacked properly.\nSee the README.W32 file in the " | |
- "top-level Emacs directory for more information.", | |
+ "top-level Emacs directory for more information."), | |
init_file_name, load_path); | |
needed = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, buffer, | |
-1, NULL, 0); | |
@@ -8853,7 +8877,7 @@ | |
} | |
MessageBox (NULL, | |
msg, | |
- "Emacs Abort Dialog", | |
+ TEXT ("Emacs Abort Dialog"), | |
MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL); | |
/* Use the low-level system abort. */ | |
abort (); | |
@@ -8876,6 +8900,9 @@ | |
term_winsock (); | |
term_w32select (); | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+ w32_apc_mutex_term(); | |
+#endif | |
} | |
void | |
@@ -8897,6 +8924,14 @@ | |
if (getenv ("PRELOAD_WINSOCK") != NULL) | |
init_winsock (TRUE); | |
+ /* remove current directory from dll search path */ | |
+ { | |
+ BOOL (WINAPI * pSetDllDirectory)(LPCTSTR) = (BOOL (WINAPI *)(LPCTSTR)) | |
+ GetProcAddress(GetModuleHandle ("kernel32.dll"), "SetDllDirectoryA"); | |
+ if (pSetDllDirectory) | |
+ pSetDllDirectory(""); | |
+ } | |
+ | |
/* Initial preparation for subprocess support: replace our standard | |
handles with non-inheritable versions. */ | |
{ | |
@@ -8984,6 +9019,10 @@ | |
/* Reset the volume info cache. */ | |
volume_cache = NULL; | |
} | |
+ | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+ w32_apc_mutex_init(); | |
+#endif | |
} | |
/* | |
@@ -9370,4 +9409,58 @@ | |
} | |
#endif /* HAVE_GNUTLS */ | |
+Lisp_Object | |
+w32_get_memory_info (void) | |
+{ | |
+ PROCESS_MEMORY_COUNTERS_EX pmc = {sizeof(PROCESS_MEMORY_COUNTERS_EX)}; | |
+ MEMORY_STATUS_EX msx = {sizeof(MEMORY_STATUS_EX)}; | |
+ OSVERSIONINFO osi = {sizeof(OSVERSIONINFO)}; | |
+ | |
+ int os_version; | |
+ struct gcpro gcpro1, gcpro2; | |
+ Lisp_Object pm, sm; | |
+ | |
+ if (GetVersionEx(&osi) == 0) | |
+ return Qnil; | |
+ | |
+ os_version = (osi.dwMajorVersion << 8) | osi.dwMinorVersion ; | |
+ if (os_version < 0x501) | |
+ pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS); | |
+ | |
+ if (global_memory_status_ex(&msx) == 0 || | |
+ get_process_memory_info(GetCurrentProcess(), | |
+ (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc)) == 0) | |
+ return Qnil; | |
+ | |
+ GCPRO2(sm, pm); | |
+ | |
+ sm = Qnil; | |
+ sm = Fcons(make_fixnum_or_float(msx.ullAvailExtendedVirtual), sm); | |
+ sm = Fcons(make_fixnum_or_float(msx.ullAvailVirtual), sm); | |
+ sm = Fcons(make_fixnum_or_float(msx.ullTotalVirtual), sm); | |
+ sm = Fcons(make_fixnum_or_float(msx.ullAvailPageFile), sm); | |
+ sm = Fcons(make_fixnum_or_float(msx.ullTotalPageFile), sm); | |
+ sm = Fcons(make_fixnum_or_float(msx.ullAvailPhys), sm); | |
+ sm = Fcons(make_fixnum_or_float(msx.ullTotalPhys), sm); | |
+ sm = Fcons(make_fixnum_or_float(msx.dwMemoryLoad), sm); | |
+ | |
+ pm = Qnil; | |
+ if (os_version >= 0x501) | |
+ pm = Fcons(make_fixnum_or_float(pmc.PrivateUsage), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.PeakPagefileUsage), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.PagefileUsage), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.QuotaNonPagedPoolUsage), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.QuotaPeakNonPagedPoolUsage), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.QuotaPagedPoolUsage), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.QuotaPeakPagedPoolUsage), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.WorkingSetSize), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.PeakWorkingSetSize), pm); | |
+ pm = Fcons(make_fixnum_or_float(pmc.PageFaultCount), pm); | |
+ pm = Fcons(pm, Qnil); | |
+ | |
+ sm = Fcons(sm, pm); | |
+ | |
+ RETURN_UNGCPRO(Fcons(make_fixnum_or_float(reserved_heap_size), sm)); | |
+} | |
+ | |
/* end of w32.c */ | |
--- ./src/w32.h.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32.h 2015-04-11 07:27:30.667123700 +0900 | |
@@ -29,6 +29,15 @@ | |
/* File descriptor set emulation. */ | |
/* MSVC runtime library has limit of 64 descriptors by default */ | |
+ | |
+#ifdef _MSC_VER | |
+#define TLS __declspec( thread ) | |
+#else | |
+#ifdef __GNUC__ | |
+#define TLS __thread | |
+#endif | |
+#endif | |
+ | |
#define FD_SETSIZE 64 | |
typedef struct { | |
unsigned int bits[FD_SETSIZE / 32]; | |
@@ -218,4 +227,13 @@ | |
const void* buf, size_t sz); | |
#endif /* HAVE_GNUTLS */ | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+extern void w32_apc_mutex_init (void); | |
+extern void w32_apc_mutex_term (void); | |
+extern void w32_apc_mutex_acquire (void); | |
+extern void w32_apc_mutex_release (void); | |
+#endif | |
+ | |
+extern Lisp_Object w32_get_memory_info (void); | |
+ | |
#endif /* EMACS_W32_H */ | |
--- ./src/w32fns.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32fns.c 2015-04-11 07:27:30.688132700 +0900 | |
@@ -68,9 +68,13 @@ | |
#include <ctype.h> | |
#include <winspool.h> | |
#include <objbase.h> | |
+#include <shlobj.h> | |
#include <dlgs.h> | |
#include <imm.h> | |
+#ifndef CYGWIN | |
+#include <mbstring.h> | |
+#endif | |
#include "font.h" | |
#include "w32font.h" | |
@@ -79,6 +83,13 @@ | |
#define FOF_NO_CONNECTED_ELEMENTS 0x2000 | |
#endif | |
+#ifdef IME_UNICODE | |
+#define __T(x) L ## x | |
+#define _T(x) __T(x) | |
+#else | |
+#define _T(x) x | |
+#endif | |
+ | |
void syms_of_w32fns (void); | |
void globals_of_w32fns (void); | |
@@ -89,6 +100,26 @@ | |
extern const char *map_w32_filename (const char *, const char **); | |
extern char * w32_strerror (int error_no); | |
+#if defined (RECONVERSION) || defined (DOCUMENTFEED) | |
+#ifdef IME_UNICODE | |
+#define CHRSZ sizeof(short) | |
+#else | |
+#define CHRSZ sizeof(char) | |
+#endif | |
+#endif | |
+ | |
+#if defined (RECONVERSION) && defined (USE_W32_IME) | |
+#define RECONV_LENG 100 | |
+#define DOCFEED_LENG 100 | |
+static LRESULT w32_get_ime_reconversion_string (HWND, RECONVERTSTRING*); | |
+static BOOL w32_perform_reconversion (HWND, RECONVERTSTRING*); | |
+#endif | |
+ | |
+#if defined (DOCUMENTFEED) && defined (USE_W32_IME) | |
+#define DOCFEED_CSTR_LENG 64 | |
+static LRESULT w32_get_ime_documentfeed_string (HWND, RECONVERTSTRING*); | |
+#endif | |
+ | |
/* If non-NULL, a handle to a frame where to display the hourglass cursor. */ | |
static HWND hourglass_hwnd = NULL; | |
@@ -98,6 +129,50 @@ | |
Lisp_Object Qsuppress_icon; | |
Lisp_Object Qundefined_color; | |
+ | |
+#ifdef USE_W32_IME | |
+Lisp_Object Qw32_ime_buffer_switch_p; | |
+// Lisp_Object Vw32_ime_composition_window; | |
+Lisp_Object Qime_font; | |
+static int set_ime_font = 0; | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+static LOGFONT ime_logfont = {0}; | |
+#endif | |
+static int IME_event_off_count; | |
+Lisp_Object Fime_get_mode(); | |
+const char * const ImmGetOpenStatus_Name = "ImmGetOpenStatus"; | |
+const char * const ImmSetOpenStatus_Name = "ImmSetOpenStatus"; | |
+const char * const ImmSetCompositionWindow_Name = "ImmSetCompositionWindow"; | |
+const char * const ImmGetContext_Name = "ImmGetContext"; | |
+const char * const ImmGetConversionStatus_Name = "ImmGetConversionStatus"; | |
+const char * const ImmSetConversionStatus_Name = "ImmSetConversionStatus"; | |
+const char * const ImmNotifyIME_Name = "ImmNotifyIME"; | |
+ | |
+const char * const ImmReleaseContext_Name = "ImmReleaseContext"; | |
+const char * const ImmCreateContext_Name = "ImmCreateContext"; | |
+const char * const ImmDestroyContext_Name = "ImmDestroyContext"; | |
+const char * const ImmAssociateContext_Name = "ImmAssociateContext"; | |
+const char * const ImmGetHotKey_Name = "ImmGetHotKey"; | |
+const char * const ImmGetProperty_Name = "ImmGetProperty"; | |
+#ifdef IME_UNICODE | |
+const char * const ImmGetCompositionString_Name = "ImmGetCompositionStringW"; | |
+const char * const ImmSetCompositionString_Name = "ImmSetCompositionStringW"; | |
+const char * const ImmSetCompositionFont_Name = "ImmSetCompositionFontA"; /* LOGFONTA */ | |
+const char * const ImmGetConversionList_Name = "ImmGetConversionListW"; | |
+const char * const ImmConfigureIME_Name = "ImmConfigureIMEW"; | |
+const char * const ImmGetCandidateList_Name = "ImmGetCandidateListW"; | |
+const char * const ImmGetCandidateListCount_Name = "ImmGetCandidateListCountW"; | |
+#else | |
+const char * const ImmGetCompositionString_Name = "ImmGetCompositionStringA"; | |
+const char * const ImmSetCompositionString_Name = "ImmSetCompositionStringA"; | |
+const char * const ImmSetCompositionFont_Name = "ImmSetCompositionFontA"; | |
+const char * const ImmGetConversionList_Name = "ImmGetConversionListA"; | |
+const char * const ImmConfigureIME_Name = "ImmConfigureIMEA"; | |
+const char * const ImmGetCandidateList_Name = "ImmGetCandidateListA"; | |
+const char * const ImmGetCandidateListCount_Name = "ImmGetCandidateListCountA"; | |
+#endif | |
+#endif | |
+ | |
Lisp_Object Qcancel_timer; | |
Lisp_Object Qfont_param; | |
Lisp_Object Qhyper; | |
@@ -171,12 +246,14 @@ | |
typedef BOOL (WINAPI * TrackMouseEvent_Proc) | |
(IN OUT LPTRACKMOUSEEVENT lpEventTrack); | |
+#ifndef USE_W32_IME | |
typedef LONG (WINAPI * ImmGetCompositionString_Proc) | |
(IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen); | |
typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window); | |
typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context); | |
typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, | |
IN COMPOSITIONFORM *form); | |
+#endif /* !USE_W32_IME */ | |
typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); | |
typedef BOOL (WINAPI * GetMonitorInfo_Proc) | |
(IN HMONITOR monitor, OUT struct MONITOR_INFO* info); | |
@@ -188,10 +265,12 @@ | |
(IN HDC hdc, IN RECT *rcClip, IN MonitorEnum_Proc fnEnum, IN LPARAM dwData); | |
TrackMouseEvent_Proc track_mouse_event_fn = NULL; | |
+#ifndef USE_W32_IME | |
ImmGetCompositionString_Proc get_composition_string_fn = NULL; | |
ImmGetContext_Proc get_ime_context_fn = NULL; | |
ImmReleaseContext_Proc release_ime_context_fn = NULL; | |
ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; | |
+#endif /* !USE_W32_IME */ | |
MonitorFromPoint_Proc monitor_from_point_fn = NULL; | |
GetMonitorInfo_Proc get_monitor_info_fn = NULL; | |
MonitorFromWindow_Proc monitor_from_window_fn = NULL; | |
@@ -203,8 +282,10 @@ | |
extern AppendMenuW_Proc unicode_append_menu; | |
#endif /* NTGUI_UNICODE */ | |
+#ifndef USE_W32_IME | |
/* Flag to selectively ignore WM_IME_CHAR messages. */ | |
static int ignore_ime_char = 0; | |
+#endif | |
/* W95 mousewheel handler */ | |
unsigned int msh_mousewheel = 0; | |
@@ -238,6 +319,11 @@ | |
static void w32_show_hourglass (struct frame *); | |
static void w32_hide_hourglass (void); | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+/* Function prototypes for APC */ | |
+static Lisp_Object w32_call_lisp_thread (Lisp_Object (*)(Lisp_Object), void *arg); | |
+#endif | |
+ | |
#ifdef WINDOWSNT | |
/* From w32inevt.c */ | |
extern int faked_key; | |
@@ -266,6 +352,22 @@ | |
static unsigned int sound_type = 0xFFFFFFFF; | |
#define MB_EMACS_SILENT (0xFFFFFFFF - 1) | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+static void *cons2ptr(Lisp_Object c) | |
+{ | |
+ return (void *) (XFASTINT(XCAR(c)) << sizeof(EMACS_INT) /2 * 8 | | |
+ XFASTINT(XCDR(c)) & ((EMACS_INT)1 << | |
+ sizeof(EMACS_INT) /2 * 8) - 1); | |
+} | |
+ | |
+static Lisp_Object ptr2cons(const void *p) | |
+{ | |
+ return Fcons(make_number((EMACS_INT)p >> sizeof(EMACS_UINT)/2*8), | |
+ make_number((EMACS_INT)p & | |
+ ((EMACS_INT)1 << sizeof(EMACS_UINT)/2*8)-1)); | |
+} | |
+#endif | |
+ | |
/* Let the user specify a display with a frame. | |
nil stands for the selected frame--or, if that is not a w32 frame, | |
the first display on the list. */ | |
@@ -337,6 +439,21 @@ | |
void x_set_title (struct frame *, Lisp_Object, Lisp_Object); | |
void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object); | |
+#ifdef USE_W32_IME | |
+static void w32_set_ime_conv_window (HWND, struct frame *); | |
+static void w32_set_ime_status (HWND, int); | |
+static int w32_get_ime_status (HWND); | |
+static int w32_set_ime_mode (HWND, int, int); | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+void w32_set_ime_logfont (HWND, struct frame *); | |
+static void w32_set_ime_font (HWND); | |
+#else | |
+static void w32_set_ime_font (HWND, struct frame *); | |
+#endif | |
+static BOOL w32_get_ime_composition_string (HWND); | |
+static LRESULT CALLBACK conversion_agent_wndproc (HWND, UINT, WPARAM, LPARAM); | |
+static int initialize_conversion_agent (void); | |
+#endif /* USE_W32_IME */ | |
@@ -1886,14 +2003,14 @@ | |
Cursor | |
w32_load_cursor (LPCTSTR name) | |
{ | |
- /* Try first to load cursor from application resource. */ | |
- Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL), | |
- name, IMAGE_CURSOR, 0, 0, | |
+ /* Try first to load a shared predefined cursor. */ | |
+ Cursor cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0, | |
LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED); | |
if (!cursor) | |
{ | |
- /* Then try to load a shared predefined cursor. */ | |
- cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0, | |
+ /* Then try to load cursor from application resource. */ | |
+ cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL), | |
+ name, IMAGE_CURSOR, 0, 0, | |
LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED); | |
} | |
return cursor; | |
@@ -1985,12 +2102,20 @@ | |
if (hwnd) | |
{ | |
+ static int initialized = 0; | |
+ | |
SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f)); | |
SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f)); | |
SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f)); | |
SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f)); | |
SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f)); | |
+ if (!initialized && (w32_major_version > 6 || w32_major_version >= 6 && w32_minor_version >= 2)) | |
+ { | |
+ ShowWindow (hwnd, SW_MINIMIZE); ShowWindow (hwnd, SW_RESTORE); | |
+ initialized = 1; | |
+ } | |
+ | |
/* Enable drag-n-drop. */ | |
DragAcceptFiles (hwnd, TRUE); | |
@@ -2463,6 +2588,25 @@ | |
*/ | |
+ | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+/* enable APC */ | |
+static BOOL w32_getmessage(LPMSG msg, HWND hwnd, | |
+ UINT msg_low, UINT msg_high) | |
+{ | |
+ BOOL ret; | |
+ DWORD v; | |
+ /* some message was marked as seened. so we should peek message queue */ | |
+ while ((ret = (w32_unicode_gui ? PeekMessageW : PeekMessageA)(msg, hwnd, msg_low, msg_high, PM_REMOVE)) == 0) | |
+ while ((v = MsgWaitForMultipleObjectsEx | |
+ (0, NULL, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE)) != WAIT_OBJECT_0) | |
+ if (v != WAIT_IO_COMPLETION) | |
+ abort(); | |
+ | |
+ return (msg->message != WM_QUIT) ? ret : 0; | |
+} | |
+#endif | |
+ | |
/* Main message dispatch loop. */ | |
static void | |
@@ -2474,7 +2618,11 @@ | |
msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
while ((w32_unicode_gui ? GetMessageW : GetMessageA) (&msg, NULL, 0, 0)) | |
+#else | |
+ while (w32_getmessage (&msg, NULL, 0, 0)) | |
+#endif | |
{ | |
/* DebPrint (("w32_msg_pump: %s time:%u\n", */ | |
@@ -2687,7 +2835,13 @@ | |
{ | |
MSG msg; | |
deferred_msg dummy_buf; | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+#if GC_MARK_STACK | |
+ Lisp_Object dummy; | |
+ stack_base = &dummy; | |
+#endif | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
/* Ensure our message queue is created */ | |
PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); | |
@@ -2822,10 +2976,16 @@ | |
f = x_window_to_frame (dpyinfo, hwnd); | |
if (f) | |
{ | |
+#if 0 | |
HDC hdc = get_frame_dc (f); | |
GetUpdateRect (hwnd, &wmsg.rect, FALSE); | |
w32_clear_rect (f, hdc, &wmsg.rect); | |
release_frame_dc (f, hdc); | |
+#else | |
+ HDC hdc = (HDC)wParam; | |
+ GetUpdateRect (hwnd, &wmsg.rect, FALSE); | |
+ w32_clear_rect (f, hdc, &wmsg.rect); | |
+#endif | |
#if defined (W32_DEBUG_DISPLAY) | |
DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n", | |
@@ -3149,6 +3309,24 @@ | |
TranslateMessage (&windows_msg); | |
goto dflt; | |
} | |
+#ifdef USE_W32_IME | |
+ else | |
+ { | |
+ MSG ime_undo_test_msg; | |
+ | |
+ if (wParam == VK_BACK | |
+ && ctrl_modifier == w32_get_key_modifiers (wParam, lParam) | |
+ && w32_get_ime_status (hwnd) != 0 | |
+ && PeekMessage (&ime_undo_test_msg, hwnd, WM_KEYDOWN, WM_KEYDOWN, PM_NOYIELD | PM_NOREMOVE) != 0 | |
+ && ime_undo_test_msg.wParam == VK_BACK | |
+ && ime_undo_test_msg.lParam == 0x40000001 | |
+ ) | |
+ { | |
+ post_character_message (hwnd, msg, wParam, lParam, 0); | |
+ break; | |
+ } | |
+ } | |
+#endif | |
/* Fall through */ | |
@@ -3168,6 +3346,7 @@ | |
w32_get_key_modifiers (wParam, lParam)); | |
break; | |
+#ifndef USE_W32_IME | |
case WM_UNICHAR: | |
/* WM_UNICHAR looks promising from the docs, but the exact | |
circumstances in which TranslateMessage sends it is one of those | |
@@ -3286,6 +3465,7 @@ | |
case WM_IME_ENDCOMPOSITION: | |
ignore_ime_char = 0; | |
goto dflt; | |
+#endif /* USE_W32_IME */ | |
/* Simulate middle mouse button events when left and right buttons | |
are used together, but only if user has two button mouse. */ | |
@@ -4074,8 +4254,86 @@ | |
case WM_EMACS_FILENOTIFY: | |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | |
return 1; | |
+#ifdef USE_W32_IME | |
+ case WM_IME_NOTIFY: | |
+ if (wParam == IMN_SETOPENSTATUS) | |
+ { | |
+ if (w32_get_ime_status(hwnd)){ | |
+ struct frame *f = x_window_to_frame (dpyinfo, hwnd); | |
+ if (f) { | |
+ set_ime_font = 0; | |
+ w32_set_ime_conv_window (hwnd, f); | |
+ } | |
+ } | |
+ if (!IME_event_off_count) | |
+ my_post_msg (&wmsg, hwnd, WM_MULE_IME_STATUS, 0, 0); | |
+ else | |
+ IME_event_off_count--; | |
+ } | |
+ goto dflt; | |
+ | |
+ case WM_IME_STARTCOMPOSITION: | |
+ { | |
+ struct frame *f = x_window_to_frame (dpyinfo, hwnd); | |
+ if (f && !set_ime_font) | |
+ { | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+ my_post_msg (&wmsg, hwnd, WM_MULE_IME_SET_FONT, (WPARAM) f, 0); | |
+#else /* USE_W32_CALL_LISP_THREAD */ | |
+ w32_set_ime_font(hwnd, f); | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
+ set_ime_font = 1; | |
+ } | |
+ } | |
+ goto dflt; | |
+ | |
+ case WM_IME_SETCONTEXT: | |
+ set_ime_font = 0; | |
+ goto dflt; | |
+ | |
+ case WM_IME_COMPOSITION: | |
+ if (lParam & GCS_RESULTSTR) | |
+ if (w32_get_ime_composition_string (hwnd)) | |
+ return 0; | |
+ else | |
+ break; | |
+ goto dflt; | |
+ | |
+#ifdef RECONVERSION | |
+ case WM_IME_REQUEST: | |
+ if (wParam == IMR_RECONVERTSTRING) | |
+ { | |
+ if (!ime_enable_reconversion || !w32_get_ime_status (hwnd)) | |
+ return 0; | |
+ if (lParam) | |
+ return w32_get_ime_reconversion_string (hwnd, | |
+ (RECONVERTSTRING*) lParam); | |
+ else | |
+ return sizeof (RECONVERTSTRING) + (RECONV_LENG * 2 + 1) * CHRSZ; | |
+ } | |
+#ifdef DOCUMENTFEED | |
+ else if (wParam == IMR_DOCUMENTFEED) | |
+ { | |
+ if (!ime_enable_document_feed) | |
+ return 0; | |
+ if (lParam) | |
+ return w32_get_ime_documentfeed_string (hwnd, | |
+ (RECONVERTSTRING*) lParam); | |
+ else | |
+ return sizeof (RECONVERTSTRING) + (DOCFEED_LENG * 2 + DOCFEED_CSTR_LENG + 1) * CHRSZ; | |
+ } | |
+#endif | |
+ goto dflt; | |
+#endif | |
+#endif /* USE_W32_IME */ | |
default: | |
+ | |
+#ifdef USE_W32_IME | |
+ if (MESSAGE_IMM_COM_P(msg)) | |
+ return conversion_agent_wndproc (hwnd, msg, wParam, lParam); | |
+#endif /* USE_W32_IME */ | |
+ | |
/* Check for messages registered at runtime. */ | |
if (msg == msh_mousewheel) | |
{ | |
@@ -4348,7 +4606,8 @@ | |
{ | |
int i; | |
static char *names[] | |
- = { "Courier New-10", | |
+ = { "MS Gothic-12", | |
+ "Courier New-10", | |
"-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1", | |
"-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1", | |
"Fixedsys", | |
@@ -4370,6 +4629,10 @@ | |
x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil)); | |
} | |
x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); | |
+#ifdef USE_W32_IME | |
+ x_default_parameter (f, parms, Qime_font, Qnil, | |
+ "ime-font", "IME-Font", RES_TYPE_STRING); | |
+#endif | |
} | |
DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |
@@ -6486,6 +6749,17 @@ | |
return 0; | |
} | |
+#ifndef CYGWIN | |
+static int CALLBACK | |
+browse_folder_callback(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData) | |
+{ | |
+ if(uMsg==BFFM_INITIALIZED){ | |
+ SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,lpData); | |
+ } | |
+ return 0; | |
+} | |
+#endif | |
+ | |
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0, | |
doc: /* Read file name, prompting with PROMPT in directory DIR. | |
Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file | |
@@ -6510,6 +6784,10 @@ | |
BOOL file_opened = FALSE; | |
Lisp_Object orig_dir = dir; | |
Lisp_Object orig_prompt = prompt; | |
+#ifndef CYGWIN | |
+ Lisp_Object file = Qnil; | |
+ ptrdiff_t count = SPECPDL_INDEX (); | |
+#endif | |
/* If we compile with _WIN32_WINNT set to 0x0400 (for NT4 | |
compatibility) we end up with the old file dialogs. Define a big | |
@@ -6551,6 +6829,9 @@ | |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; | |
GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, filename); | |
+#ifndef CYGWIN | |
+ if (NILP (only_dir_p)) | |
+#endif | |
{ | |
struct gcpro gcpro1, gcpro2; | |
GCPRO2 (orig_dir, orig_prompt); /* There is no GCPRON, N>6. */ | |
@@ -6726,14 +7007,14 @@ | |
block_input (); | |
if (use_unicode) | |
{ | |
- file_details_w->lpfnHook = file_dialog_callback; | |
+ file_details_w->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback; | |
file_opened = GetOpenFileNameW (file_details_w); | |
} | |
#ifndef NTGUI_UNICODE | |
else | |
{ | |
- file_details_a->lpfnHook = file_dialog_callback; | |
+ file_details_a->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback; | |
file_opened = GetOpenFileNameA (file_details_a); | |
} | |
@@ -6786,6 +7067,69 @@ | |
UNGCPRO; | |
} | |
+#ifndef CYGWIN | |
+ else | |
+ { | |
+ BROWSEINFO bi = { | |
+ FRAME_W32_WINDOW (f), | |
+ NULL, | |
+ SDATA (filename), | |
+ SDATA (prompt), | |
+#ifdef BIF_EDITBOX | |
+ (!NILP (mustmatch) ? 0 : BIF_EDITBOX) | | |
+#endif | |
+#ifdef BIF_BROWSEINCLUDEFILES | |
+ BIF_BROWSEINCLUDEFILES | | |
+#endif | |
+#ifdef BIF_BROWSEINCLUDEURLS | |
+ BIF_BROWSEINCLUDEURLS | | |
+#endif | |
+#ifdef BIF_NEWDIALOGSTYLE | |
+ BIF_NEWDIALOGSTYLE | | |
+#endif | |
+#ifdef BIF_UAHINT | |
+ BIF_UAHINT | | |
+#endif | |
+#ifdef BIF_RETURNONLYFSDIRS | |
+ BIF_RETURNONLYFSDIRS | | |
+#endif | |
+ BIF_BROWSEFORCOMPUTER, | |
+ (BFFCALLBACK)browse_folder_callback, | |
+ (LPARAM) SDATA (dir), | |
+ 0 | |
+ }; | |
+ LPITEMIDLIST pidl = NULL; | |
+ | |
+ /* Prevent redisplay. */ | |
+ specbind (Qinhibit_redisplay, Qt); | |
+ block_input (); | |
+ | |
+ pidl = SHBrowseForFolder(&bi); | |
+ if (pidl) { | |
+ SHGetPathFromIDList(pidl, SDATA (filename)); | |
+ CoTaskMemFree(pidl); | |
+ } | |
+ | |
+ unblock_input (); | |
+ | |
+ if (pidl) | |
+ { | |
+ memcpy (filename_buf_a, SDATA (filename), SBYTES (filename) + 1); | |
+ dostounix_filename (filename_buf_a); | |
+ | |
+ file = DECODE_FILE (build_string (filename_buf_a)); | |
+ } | |
+ /* User cancelled the dialog without making a selection. */ | |
+ else if (!CommDlgExtendedError ()) | |
+ file = Qnil; | |
+ /* An error occurred, fallback on reading from the mini-buffer. */ | |
+ else | |
+ file = Fcompleting_read (prompt, intern ("read-file-name-internal"), | |
+ dir, mustmatch, dir, Qfile_name_history, | |
+ default_filename, Qnil); | |
+ file = unbind_to (count, file); | |
+ } | |
+#endif | |
/* Make "Cancel" equivalent to C-g. */ | |
if (NILP (filename)) | |
@@ -6895,6 +7239,1470 @@ | |
/*********************************************************************** | |
+ Input Method Editor | |
+ ***********************************************************************/ | |
+#ifdef USE_W32_IME | |
+BOOL fIME = FALSE; | |
+ | |
+typedef BOOL (WINAPI *IMMGETOPENSTATUSPROC)(HIMC); | |
+IMMGETOPENSTATUSPROC ImmGetOpenStatusProc; | |
+ | |
+typedef BOOL (WINAPI *IMMSETOPENSTATUSPROC)(HIMC, BOOL); | |
+IMMSETOPENSTATUSPROC ImmSetOpenStatusProc; | |
+ | |
+typedef BOOL (WINAPI *IMMSETCOMPOSITIONWINDOWPROC)(HIMC, LPCOMPOSITIONFORM); | |
+IMMSETCOMPOSITIONWINDOWPROC ImmSetCompositionWindowProc; | |
+ | |
+typedef LONG (WINAPI *IMMGETCOMPOSITIONSTRINGPROC) | |
+ (HIMC, DWORD, LPVOID, DWORD); | |
+IMMGETCOMPOSITIONSTRINGPROC ImmGetCompositionStringProc; | |
+ | |
+typedef LONG (WINAPI *IMMSETCOMPOSITIONSTRINGPROC) | |
+ (HIMC, DWORD, LPCVOID, DWORD, LPCVOID, DWORD); | |
+IMMSETCOMPOSITIONSTRINGPROC ImmSetCompositionStringProc; | |
+ | |
+typedef BOOL (WINAPI *IMMSETCOMPOSITIONFONTPROC) (HIMC, LPLOGFONTA); | |
+IMMSETCOMPOSITIONFONTPROC ImmSetCompositionFontProc; | |
+ | |
+typedef HIMC (WINAPI *IMMGETCONTEXTPROC)(HWND); | |
+IMMGETCONTEXTPROC ImmGetContextProc; | |
+ | |
+typedef BOOL (WINAPI *IMMGETCONVERSIONSTATUSPROC)(HIMC, LPDWORD, LPDWORD); | |
+IMMGETCONVERSIONSTATUSPROC ImmGetConversionStatusProc; | |
+ | |
+typedef BOOL (WINAPI *IMMSETCONVERSIONSTATUSPROC)(HIMC, DWORD, DWORD); | |
+IMMSETCONVERSIONSTATUSPROC ImmSetConversionStatusProc; | |
+ | |
+typedef BOOL (WINAPI *IMMGETCONVERSIONLISTPROC) | |
+ (HKL, HIMC, LPCTSTR, LPCANDIDATELIST, DWORD, UINT); | |
+IMMGETCONVERSIONLISTPROC ImmGetConversionListProc; | |
+ | |
+typedef BOOL (WINAPI *IMMCONFIGUREIMEPROC)(HKL, HWND, DWORD, LPVOID); | |
+IMMCONFIGUREIMEPROC ImmConfigureIMEProc; | |
+ | |
+typedef BOOL (WINAPI *IMMNOTIFYIMEPROC)(HIMC, DWORD, DWORD, DWORD); | |
+IMMNOTIFYIMEPROC ImmNotifyIMEProc; | |
+ | |
+typedef BOOL (WINAPI *IMMRELEASECONTEXTPROC)(HWND, HIMC); | |
+IMMRELEASECONTEXTPROC ImmReleaseContextProc; | |
+ | |
+typedef HIMC (WINAPI *IMMCREATECONTEXTPROC)(void); | |
+IMMCREATECONTEXTPROC ImmCreateContextProc; | |
+ | |
+typedef BOOL (WINAPI *IMMDESTROYCONTEXTPROC)(HIMC); | |
+IMMDESTROYCONTEXTPROC ImmDestroyContextProc; | |
+ | |
+typedef HIMC (WINAPI *IMMASSOCIATECONTEXTPROC) (HWND, HIMC); | |
+IMMASSOCIATECONTEXTPROC ImmAssociateContextProc; | |
+ | |
+typedef BOOL (WINAPI *IMMGETCANDIDATELISTPROC) | |
+ (HIMC, DWORD, LPCANDIDATELIST, DWORD); | |
+IMMGETCANDIDATELISTPROC ImmGetCandidateListProc; | |
+ | |
+typedef BOOL (WINAPI *IMMGETCANDIDATELISTCOUNTPROC) (HIMC, LPDWORD); | |
+IMMGETCANDIDATELISTCOUNTPROC ImmGetCandidateListCountProc; | |
+ | |
+typedef BOOL (WINAPI *IMMGETHOTKEYPROC)(DWORD, LPUINT, LPUINT, LPHKL); | |
+IMMGETHOTKEYPROC ImmGetHotKeyProc; | |
+ | |
+typedef BOOL (WINAPI *IMMGETPROPERTYPROC)(HKL, DWORD); | |
+IMMGETPROPERTYPROC ImmGetPropertyProc; | |
+ | |
+// Lisp_Object Vime_control; | |
+ | |
+static void | |
+w32_set_ime_conv_window (hwnd, f) | |
+ HWND hwnd; | |
+ struct frame *f; | |
+{ | |
+ if (fIME && !NILP (Vime_control)) | |
+ { | |
+ HIMC himc; | |
+ COMPOSITIONFORM compform; | |
+ struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); | |
+ | |
+ /* If Vw32_ime_composition_window is set, try it. */ | |
+ if (!NILP (Vw32_ime_composition_window) | |
+ && WINDOWP (Vw32_ime_composition_window) | |
+ && WINDOW_FRAME (XWINDOW (Vw32_ime_composition_window)) | |
+ == WINDOW_FRAME (w)) | |
+ w = XWINDOW (Vw32_ime_composition_window); | |
+ | |
+ himc = (ImmGetContextProc) (hwnd); | |
+ compform.dwStyle = CFS_RECT; | |
+ | |
+ compform.ptCurrentPos.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); | |
+ | |
+ compform.ptCurrentPos.y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y); | |
+#if 0 | |
+ if (FRAME_FONT (f)->vertical_centering == 1) | |
+ compform.ptCurrentPos.y += FRAME_FONT (f)->baseline_offset; | |
+#endif | |
+ | |
+ compform.rcArea.left = (WINDOW_BOX_LEFT_EDGE_X (w) | |
+ + WINDOW_LEFT_MARGIN_WIDTH (w) | |
+ + WINDOW_LEFT_FRINGE_WIDTH (w)); | |
+ | |
+ compform.rcArea.top = (WINDOW_TOP_EDGE_Y (w) | |
+ + WINDOW_HEADER_LINE_HEIGHT (w)); | |
+ | |
+ compform.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w) | |
+ - WINDOW_RIGHT_MARGIN_WIDTH (w) | |
+ - WINDOW_RIGHT_FRINGE_WIDTH (w)) + 1; | |
+ | |
+ compform.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w) | |
+ - WINDOW_MODE_LINE_HEIGHT (w)); | |
+ | |
+ (ImmSetCompositionWindowProc) (himc, &compform); | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+ } | |
+} | |
+ | |
+static void | |
+w32_set_ime_status (hwnd, openp) | |
+ HWND hwnd; | |
+ int openp; | |
+{ | |
+ HIMC himc; | |
+ | |
+ himc = (ImmGetContextProc) (hwnd); | |
+ (ImmSetOpenStatusProc) (himc, openp); | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+} | |
+ | |
+static int | |
+w32_get_ime_status (hwnd) | |
+ HWND hwnd; | |
+{ | |
+ HIMC himc; | |
+ int ret; | |
+ | |
+ himc = (ImmGetContextProc) (hwnd); | |
+ ret = (ImmGetOpenStatusProc) (himc); | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+ | |
+ return ret; | |
+} | |
+ | |
+static int | |
+w32_set_ime_mode (hwnd, mode, mask) | |
+ HWND hwnd; | |
+ int mode; | |
+ int mask; | |
+{ | |
+ HIMC himc; | |
+ DWORD cmode, smode; | |
+ | |
+ himc = (ImmGetContextProc) (hwnd); | |
+ if (!(ImmGetConversionStatusProc) (himc, &cmode, &smode)) | |
+ return 0; | |
+ | |
+ cmode = (cmode & (~mask)) | (mode & mask); | |
+ | |
+ (ImmSetConversionStatusProc) (himc, cmode, smode); | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+ | |
+ return 1; | |
+} | |
+ | |
+static BOOL | |
+w32_get_ime_composition_string (hwnd) | |
+ HWND hwnd; | |
+{ | |
+ HIMC hIMC; | |
+ int size; | |
+ HANDLE himestr; | |
+#ifdef IME_UNICODE | |
+ LPWSTR lpstr; | |
+#else | |
+ LPSTR lpstr; | |
+#endif | |
+ | |
+ struct frame *f; | |
+ | |
+ hIMC = (ImmGetContextProc) (hwnd); | |
+ if (!hIMC) | |
+ return FALSE; | |
+ | |
+ size = (ImmGetCompositionStringProc) (hIMC, GCS_RESULTSTR, NULL, 0); | |
+#ifdef IME_UNICODE | |
+ size += sizeof (WCHAR); | |
+#else | |
+ size += sizeof (CHAR); | |
+#endif | |
+ himestr = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, size); | |
+ if (!himestr) | |
+ abort (); | |
+ | |
+ (ImmGetCompositionStringProc) (hIMC, GCS_RESULTSTR, himestr, size); | |
+ (ImmReleaseContextProc) (hwnd, hIMC); | |
+ { | |
+ W32Msg wmsg; | |
+ f = SELECTED_FRAME (); | |
+ my_post_msg (&wmsg, hwnd, WM_MULE_IME_REPORT, | |
+ (WPARAM) himestr, (LPARAM) f); | |
+ } | |
+ return TRUE; | |
+} | |
+ | |
+#ifdef RECONVERSION | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+struct get_reconversion_string_arg { | |
+ WPARAM wparam; | |
+ RECONVERTSTRING *reconv; /* in */ | |
+#ifdef IME_UNICODE | |
+ unsigned short *compstr; /* in */ | |
+#else | |
+ unsigned char *compstr; /* in */ | |
+#endif | |
+ DWORD size; /* in,out */ | |
+}; | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
+ | |
+static EMACS_INT compstr_beginning_pos(int max_char) | |
+{ | |
+ EMACS_INT bol, point = PT, pt; | |
+ for (bol = XFASTINT(Fline_beginning_position(Qnil)), pt = PT; | |
+ PT >= bol && PT > point - max_char; ) { | |
+ pt = PT; | |
+ if (NILP(Fforward_word (make_number (-1)))) | |
+ break; | |
+ } | |
+ Fgoto_char (make_number(point)); | |
+ return pt; | |
+} | |
+ | |
+static EMACS_INT compstr_end_pos(int max_char) | |
+{ | |
+ EMACS_INT eol, point = PT, pt; | |
+ | |
+ for (eol = XFASTINT(Fline_end_position(Qnil)), pt = PT; | |
+ PT <= eol && PT < point + max_char;) { | |
+ pt = PT; | |
+ if (NILP(Fforward_word (make_number (1)))) | |
+ break; | |
+ } | |
+ Fgoto_char (make_number(point)); | |
+ return pt; | |
+} | |
+ | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+static LRESULT | |
+get_reconversion_string (HWND hwnd, | |
+ RECONVERTSTRING *reconv, | |
+ unsigned short *compstr) | |
+{ | |
+ EMACS_INT pt, pt_byte, start, end, len, t_start, t_end, compstr_len; | |
+ W32Msg wmsg; | |
+ | |
+ if (!NILP (BVAR (current_buffer, read_only))) | |
+ return 0; | |
+ | |
+ pt = PT; | |
+ pt_byte = PT_BYTE; | |
+ | |
+ if (compstr) | |
+ { | |
+ t_start = PT; | |
+ start = compstr_beginning_pos (DOCFEED_LENG); | |
+ end = compstr_end_pos (DOCFEED_LENG); | |
+ } | |
+ else if (!NILP (BVAR (current_buffer, mark_active)) | |
+ && !NILP (Vtransient_mark_mode)) | |
+ { | |
+ if (marker_position (BVAR (current_buffer, mark)) < PT) | |
+ { | |
+ t_start = marker_position (BVAR (current_buffer, mark)); | |
+ t_end = PT; | |
+ } | |
+ else | |
+ { | |
+ t_start = PT; | |
+ t_end = marker_position (BVAR (current_buffer, mark)); | |
+ } | |
+ Fgoto_char (make_number (t_end)); | |
+ while (!NILP (Fbolp ()) && t_start < PT) | |
+ Fforward_char (make_number (-1)); | |
+ if (t_start >= PT) | |
+ return 0; | |
+ t_end = PT; | |
+ } | |
+ else | |
+ { | |
+ if (NILP (Feobp ())) | |
+ Fforward_char (make_number (1)); | |
+ if (!NILP (Fforward_word (make_number (-1)))) | |
+ t_start = PT; | |
+ else | |
+ { | |
+ SET_PT_BOTH (pt, pt_byte); | |
+ return 0; | |
+ } | |
+ Fforward_word (make_number (1)); | |
+ t_end = PT; | |
+ SET_PT_BOTH (pt, pt_byte); | |
+ if (t_end < PT) | |
+ return 0; | |
+ } | |
+ | |
+ if (!compstr) | |
+ { | |
+ if (t_start == t_end) | |
+ return 0; | |
+ | |
+ Fgoto_char (make_number (t_start)); | |
+ start = compstr_beginning_pos (RECONV_LENG); | |
+ Fgoto_char (make_number (t_end)); | |
+ end = compstr_end_pos (RECONV_LENG); | |
+ } | |
+ | |
+ len = end - start; | |
+ if (reconv) | |
+ { | |
+ int pos; | |
+ WCHAR *s; | |
+ | |
+ s = (WCHAR *) (reconv + 1); | |
+ | |
+ for (pos = start; pos < t_start; pos++) | |
+ *s++ = (WCHAR) FETCH_CHAR (CHAR_TO_BYTE (pos)); | |
+ | |
+ if (compstr) | |
+ { | |
+ for (compstr_len = 0; compstr[compstr_len]; compstr_len++) | |
+ *s++ = compstr[compstr_len]; | |
+ | |
+ len += compstr_len; | |
+ } | |
+ else | |
+ compstr_len = t_end - t_start; | |
+ | |
+ for (; pos < end; pos++) | |
+ *s++ = (WCHAR) FETCH_CHAR (CHAR_TO_BYTE (pos)); | |
+ | |
+ *s = 0; | |
+ } | |
+ else | |
+ { | |
+ SET_PT_BOTH (pt, pt_byte); | |
+ if (compstr) | |
+ { | |
+ for (compstr_len = 0; compstr[compstr_len]; compstr_len++) | |
+ ; | |
+ | |
+ len += compstr_len; | |
+ } | |
+ return (sizeof (RECONVERTSTRING) + (len + 1) * CHRSZ); | |
+ } | |
+ | |
+ reconv->dwStrOffset = sizeof (RECONVERTSTRING); | |
+ reconv->dwStrLen = len; | |
+ reconv->dwCompStrOffset = | |
+ reconv->dwTargetStrOffset = (t_start - start) * CHRSZ; | |
+ reconv->dwCompStrLen = | |
+ reconv->dwTargetStrLen = compstr_len; | |
+ | |
+ if (!compstr) | |
+ my_post_msg (&wmsg, hwnd, WM_MULE_IME_DEL_RANGE, (WPARAM) t_start, (LPARAM) t_end); | |
+ | |
+ return (reconv->dwSize = sizeof (RECONVERTSTRING) + (len + 1) * CHRSZ); | |
+} | |
+ | |
+static LRESULT | |
+w32_get_ime_reconversion_string (HWND hwnd, | |
+ RECONVERTSTRING *reconv) | |
+{ | |
+ return get_reconversion_string (hwnd, reconv, NULL); | |
+} | |
+#else /* USE_W32_CALL_LISP_THREAD */ | |
+static Lisp_Object | |
+get_reconversion_string (Lisp_Object arg_) | |
+{ | |
+ struct get_reconversion_string_arg *arg = cons2ptr(arg_); | |
+ EMACS_INT pt, pt_byte, point, start, end, len, | |
+ t_start, t_end, del_start, del_end, compstr_len = 0; | |
+ Lisp_Object str; | |
+ struct gcpro gcpro1; | |
+ | |
+ if (!NILP (BVAR (current_buffer, read_only))) { | |
+ arg->size = 0; | |
+ return Qnil; | |
+ } | |
+ | |
+ pt = PT; | |
+ pt_byte = PT_BYTE; | |
+ | |
+ if (arg->compstr) { /* DOCUMENT_FEED */ | |
+#ifdef DOCUMENTFEED | |
+ t_start = compstr_beginning_pos(DOCFEED_LENG); | |
+ t_end = compstr_end_pos(DOCFEED_LENG); | |
+ point = PT; | |
+#endif | |
+ } else if (!NILP (BVAR (current_buffer, mark_active)) | |
+ && !NILP (Vtransient_mark_mode)) { | |
+ if (marker_position (BVAR (current_buffer, mark)) < PT) { | |
+ t_start = marker_position (BVAR (current_buffer, mark)); | |
+ point = t_end = PT; | |
+ } else { | |
+ point = t_start = PT; | |
+ t_end = marker_position (BVAR (current_buffer, mark)); | |
+ } | |
+ Fgoto_char(make_number(t_end)); | |
+ while (!NILP(Fbolp()) && t_start < PT) | |
+ Fforward_char(make_number(-1)); | |
+ if (t_start >= PT) | |
+ return Qnil; | |
+ t_end = PT; | |
+ } else { | |
+ point = PT; | |
+ | |
+ while (!NILP(Fbolp()) && NILP(Fbobp())) | |
+ Fforward_char(make_number(1)); | |
+ if (!NILP(Fbobp())) | |
+ return Qnil; | |
+ | |
+ t_end = PT; | |
+ Fforward_word (make_number (-1)); | |
+ t_start = PT; | |
+ } | |
+ if (t_start == t_end) { | |
+ arg->size = 0; | |
+ return Qnil; | |
+ } | |
+ | |
+ if (arg->compstr) { | |
+ start = t_start; | |
+ end = t_end; | |
+ t_start = point - t_start; | |
+ } else { | |
+ | |
+ start = compstr_beginning_pos(RECONV_LENG); | |
+ end = compstr_end_pos(RECONV_LENG); | |
+ | |
+ del_start = t_start; | |
+ del_end = t_end; | |
+ | |
+ t_start -= start; | |
+ t_end -= start; | |
+ } | |
+ | |
+ GCPRO1(str); | |
+ str = make_buffer_string (start, end, 1); | |
+ | |
+#ifdef IME_UNICODE | |
+ len = end - start; | |
+ if (arg->reconv) { | |
+ int pos; | |
+ WCHAR *uc_code, *s; | |
+ | |
+ uc_code = (WCHAR *) (arg->reconv + 1); | |
+ s = uc_code; | |
+ | |
+ for (pos = 0; pos < t_start; pos++) | |
+ *s++ = (WCHAR) XFASTINT(Faref(str, make_number(pos))); | |
+ | |
+ if (arg->compstr) | |
+ for (compstr_len = 0; arg->compstr[compstr_len]; compstr_len++) | |
+ *s++ = arg->compstr[compstr_len]; | |
+ | |
+ for (; pos < len; pos++) | |
+ *s++ = (WCHAR) XFASTINT(Faref(str, make_number(pos))); | |
+ | |
+ *s = 0; | |
+ } else { | |
+ if (arg->compstr) | |
+ for (compstr_len = 0; arg->compstr[compstr_len]; compstr_len++) | |
+ ; | |
+ } | |
+ | |
+#define STROFFSET(s,o) ((o) * CHRSZ) | |
+#define STRSIZE(s, b, e) ((e) - (b)) | |
+#else /* IME_UNICODE */ | |
+ if (!arg->reconv | |
+ && !NILP (Ftext_property_any (make_number (0), | |
+ Flength (str), | |
+ intern ("read-only"), | |
+ Qt, | |
+ str))) { | |
+ SET_PT_BOTH (pt, pt_byte); | |
+ UNGCPRO; | |
+ return Qt; /* Cannot signal here */ | |
+ } | |
+ str = ENCODE_SYSTEM (str); | |
+ | |
+ len = SBYTES(str); | |
+ if (arg->compstr) | |
+ compstr_len = strlen(arg->compstr); | |
+ | |
+#define STROFFSET(s,o) (_mbsninc(SDATA(s), (o)) - SDATA(s)) | |
+#define STRSIZE(s, b, e) (_mbsninc(SDATA(s), (e)) - _mbsninc(SDATA(s), (b))) | |
+ | |
+ if (arg->reconv) { | |
+ if (arg->compstr) { | |
+ LPSTR s = (LPSTR)(arg->reconv + 1); | |
+ strncpy(s, SDATA(str), STROFFSET(str, t_start)); | |
+ strcpy(s + STROFFSET(str, t_start), arg->compstr); | |
+ strcpy(s + STROFFSET(str, t_start) + compstr_len, | |
+ SDATA(str) + STROFFSET(str, t_start)); | |
+ } else | |
+ strcpy ((LPSTR)(arg->reconv + 1), SDATA(str)); | |
+ } | |
+#endif | |
+ | |
+ if (arg->reconv) { | |
+ arg->reconv->dwStrOffset = sizeof (RECONVERTSTRING); | |
+ arg->reconv->dwStrLen = len + compstr_len; | |
+ | |
+ if (arg->compstr) { | |
+ arg->reconv->dwCompStrOffset = | |
+ arg->reconv->dwTargetStrOffset = STROFFSET(str, t_start); | |
+ arg->reconv->dwCompStrLen = | |
+ arg->reconv->dwTargetStrLen = compstr_len; | |
+ | |
+ } else { | |
+ arg->reconv->dwTargetStrOffset = | |
+ arg->reconv->dwCompStrOffset = STROFFSET(str, t_start); | |
+ arg->reconv->dwTargetStrLen = | |
+ arg->reconv->dwCompStrLen = STRSIZE(str, t_start, t_end); | |
+ | |
+ del_range(del_start, del_end); | |
+ Fgoto_char (make_number(del_start)); | |
+ } | |
+ } else { | |
+ SET_PT_BOTH (pt, pt_byte); | |
+ } | |
+ arg->size = sizeof(RECONVERTSTRING) + (len + compstr_len + 1) * CHRSZ; | |
+ if (arg->reconv != NULL && arg->compstr != NULL) | |
+ arg->compstr[0] = 0; | |
+ | |
+ UNGCPRO; | |
+ return Qt; | |
+} | |
+ | |
+static LRESULT | |
+w32_get_ime_reconversion_string(HWND hwnd, | |
+ RECONVERTSTRING *reconv) | |
+{ | |
+ struct get_reconversion_string_arg grs = | |
+ {IMR_RECONVERTSTRING, reconv, NULL, 0}; | |
+ | |
+ if (NILP(w32_call_lisp_thread(get_reconversion_string, &grs))) | |
+ return 0; | |
+ return reconv->dwSize; | |
+} | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
+#endif /* RECONVERSION */ | |
+ | |
+#if defined(DOCUMENTFEED) | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+static LRESULT | |
+w32_get_ime_documentfeed_string (HWND hwnd, | |
+ RECONVERTSTRING *reconv) | |
+{ | |
+ unsigned short ime_compstr[DOCFEED_CSTR_LENG]; | |
+ HIMC hIMC; | |
+ LONG l; | |
+ | |
+ if (hIMC = (ImmGetContextProc) (hwnd)) | |
+ { | |
+ if ((ImmGetCompositionStringProc) (hIMC, GCS_COMPSTR, NULL, 0) | |
+ >= DOCFEED_CSTR_LENG * CHRSZ) | |
+ { | |
+ (ImmReleaseContextProc) (hwnd, hIMC); | |
+ return 0; | |
+ } | |
+ | |
+ switch (l = (ImmGetCompositionStringProc) | |
+ (hIMC, GCS_COMPSTR, ime_compstr, | |
+ (DOCFEED_CSTR_LENG - 1) * CHRSZ)) | |
+ { | |
+ case IMM_ERROR_NODATA: | |
+ case IMM_ERROR_GENERAL: | |
+ ime_compstr[0] = 0; | |
+ break; | |
+ default: | |
+ ime_compstr[l / CHRSZ] = 0; | |
+ break; | |
+ } | |
+ (ImmReleaseContextProc) (hwnd, hIMC); | |
+ | |
+ return get_reconversion_string (hwnd, reconv, ime_compstr); | |
+ } | |
+ | |
+ return 0; | |
+} | |
+#else /* USE_W32_CALL_LISP_THREAD */ | |
+static LRESULT | |
+w32_get_ime_documentfeed_string(HWND hwnd, | |
+ RECONVERTSTRING *reconv) | |
+{ | |
+#ifdef IME_UNICODE | |
+ unsigned short ime_compstr[DOCFEED_CSTR_LENG]; | |
+#else | |
+ unsigned char ime_compstr[DOCFEED_CSTR_LENG]; | |
+#endif | |
+ struct get_reconversion_string_arg grs = | |
+ {IMR_DOCUMENTFEED, reconv, ime_compstr, 0} ; | |
+ HIMC himc; | |
+ LONG l; | |
+ | |
+ if (!(himc = (ImmGetContextProc) (hwnd))) | |
+ return 0; | |
+ | |
+ if (ImmGetCompositionStringProc(himc, GCS_COMPSTR, NULL, 0) | |
+ >= DOCFEED_CSTR_LENG * CHRSZ) { | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+ return 0; | |
+ } | |
+ | |
+ switch (l = (ImmGetCompositionStringProc) | |
+ (himc, GCS_COMPSTR, ime_compstr, | |
+ (DOCFEED_CSTR_LENG - 1) * CHRSZ)) { | |
+ | |
+ case IMM_ERROR_NODATA: | |
+ case IMM_ERROR_GENERAL: | |
+ ime_compstr[0] = 0; | |
+ break; | |
+ default: | |
+ ime_compstr[l / CHRSZ] = 0; | |
+ break; | |
+ } | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+ | |
+ grs.size = l; | |
+ | |
+ if (NILP(w32_call_lisp_thread(get_reconversion_string, &grs))) | |
+ return 0; | |
+ return reconv->dwSize; | |
+} | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
+#endif /* DOCUMENTFEED */ | |
+ | |
+void | |
+w32_ime_control_init (void) | |
+{ | |
+ HMODULE hImm32; | |
+ HMODULE hUser32; | |
+ | |
+ hImm32 = GetModuleHandle ("IMM32.DLL"); | |
+ if (!hImm32) | |
+ hImm32 = LoadLibrary ("IMM32.DLL"); | |
+ | |
+ fIME = FALSE; | |
+ Vime_control = Qnil; | |
+ IME_event_off_count = 0; | |
+ | |
+ if (hImm32) | |
+ { | |
+ ImmGetOpenStatusProc = | |
+ (IMMGETOPENSTATUSPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmGetOpenStatus_Name); | |
+ ImmSetOpenStatusProc = | |
+ (IMMSETOPENSTATUSPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmSetOpenStatus_Name); | |
+ ImmSetCompositionWindowProc = | |
+ (IMMSETCOMPOSITIONWINDOWPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmSetCompositionWindow_Name); | |
+ ImmGetContextProc = | |
+ (IMMGETCONTEXTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmGetContext_Name); | |
+ ImmGetConversionStatusProc = | |
+ (IMMGETCONVERSIONSTATUSPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmGetConversionStatus_Name); | |
+ ImmSetConversionStatusProc = | |
+ (IMMSETCONVERSIONSTATUSPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmSetConversionStatus_Name); | |
+ ImmNotifyIMEProc = | |
+ (IMMNOTIFYIMEPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmNotifyIME_Name); | |
+ ImmReleaseContextProc = | |
+ (IMMRELEASECONTEXTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmReleaseContext_Name); | |
+ ImmCreateContextProc = | |
+ (IMMCREATECONTEXTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmCreateContext_Name); | |
+ ImmDestroyContextProc = | |
+ (IMMDESTROYCONTEXTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmDestroyContext_Name); | |
+ ImmAssociateContextProc = | |
+ (IMMASSOCIATECONTEXTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmAssociateContext_Name); | |
+ ImmGetHotKeyProc = | |
+ (IMMGETHOTKEYPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmGetHotKey_Name); | |
+ ImmGetPropertyProc = | |
+ (IMMGETPROPERTYPROC) | |
+ GetProcAddress (hImm32, ImmGetProperty_Name); | |
+ ImmGetCompositionStringProc = | |
+ (IMMGETCOMPOSITIONSTRINGPROC) | |
+ GetProcAddress (hImm32, ImmGetCompositionString_Name); | |
+ ImmSetCompositionStringProc = | |
+ (IMMSETCOMPOSITIONSTRINGPROC) | |
+ GetProcAddress (hImm32, ImmSetCompositionString_Name); | |
+ ImmSetCompositionFontProc = | |
+ (IMMSETCOMPOSITIONFONTPROC) | |
+ GetProcAddress (hImm32, ImmSetCompositionFont_Name); | |
+ ImmGetConversionListProc = | |
+ (IMMGETCONVERSIONLISTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmGetConversionList_Name); | |
+ ImmConfigureIMEProc = | |
+ (IMMCONFIGUREIMEPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmConfigureIME_Name); | |
+ ImmGetCandidateListProc = | |
+ (IMMGETCANDIDATELISTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmGetCandidateList_Name); | |
+ ImmGetCandidateListCountProc = | |
+ (IMMGETCANDIDATELISTCOUNTPROC) | |
+ GetProcAddress (hImm32, | |
+ ImmGetCandidateListCount_Name); | |
+ | |
+ if (ImmGetOpenStatusProc && | |
+ ImmSetOpenStatusProc && | |
+ ImmSetCompositionWindowProc && | |
+ ImmGetCompositionStringProc && | |
+ ImmSetCompositionStringProc && | |
+ ImmSetCompositionFontProc && | |
+ ImmGetPropertyProc && | |
+ ImmGetContextProc && | |
+ ImmGetConversionStatusProc && | |
+ ImmSetConversionStatusProc && | |
+ ImmGetConversionListProc && | |
+ ImmConfigureIMEProc && | |
+ ImmNotifyIMEProc && | |
+ ImmReleaseContextProc && | |
+ ImmCreateContextProc && | |
+ ImmDestroyContextProc && | |
+ ImmAssociateContextProc && | |
+ ImmGetCandidateListProc && | |
+ ImmGetCandidateListCountProc && | |
+ ImmGetHotKeyProc) | |
+ { | |
+ fIME = TRUE; | |
+ Vime_control = Qt; | |
+ } | |
+ } | |
+} | |
+ | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+struct apc_data { | |
+ Lisp_Object (*func)(Lisp_Object); | |
+ Lisp_Object val; | |
+ void *arg; | |
+ HANDLE ev; | |
+}; | |
+ | |
+static Lisp_Object apc_error_handler (Lisp_Object arg) | |
+{ | |
+ return Qnil; | |
+} | |
+ | |
+static VOID CALLBACK apc_func_stub(ULONG_PTR data_) | |
+{ | |
+ struct apc_data *apc_data = (struct apc_data *)data_; | |
+ Lisp_Object arg = ptr2cons(apc_data->arg); | |
+ struct gcpro gcpro1; | |
+ | |
+ GCPRO1(arg); | |
+ apc_data->val = | |
+ internal_condition_case_1 | |
+ (apc_data->func, arg, Qt, apc_error_handler); | |
+ | |
+ UNGCPRO; | |
+ SetEvent(apc_data->ev); | |
+} | |
+ | |
+static Lisp_Object w32_call_lisp_thread | |
+(Lisp_Object (*func)(Lisp_Object), void *arg) | |
+{ | |
+ struct apc_data apc_data = { | |
+ func, Qnil, arg, | |
+ CreateEvent(NULL, FALSE, FALSE, NULL) | |
+ }; | |
+ DWORD v; | |
+ deferred_msg dummy = {0}; | |
+ | |
+ dummy.completed = 1; | |
+ | |
+ | |
+ w32_apc_mutex_acquire(); | |
+ if (apc_data.ev == NULL) | |
+ abort(); | |
+ | |
+ if (QueueUserAPC(apc_func_stub, | |
+ hMainThread, (ULONG_PTR)&apc_data) == 0) | |
+ abort (); | |
+ | |
+ while ((v = MsgWaitForMultipleObjectsEx | |
+ (1, &apc_data.ev, INFINITE, QS_SENDMESSAGE, MWMO_ALERTABLE)) != WAIT_OBJECT_0) | |
+ if (v == WAIT_OBJECT_0 + 1) | |
+ w32_msg_pump(&dummy); | |
+ else if (v != WAIT_IO_COMPLETION) | |
+ abort(); | |
+ | |
+ w32_apc_mutex_release(); | |
+ return apc_data.val; | |
+} | |
+#endif | |
+ | |
+#ifdef HAVE_NTGUI | |
+EXFUN (Ffont_at, 3); | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+static int | |
+need_set_ime_font (PLOGFONT p) | |
+{ | |
+ if (!p || | |
+ (p->lfHeight == ime_logfont.lfHeight | |
+ && p->lfWidth == ime_logfont.lfWidth | |
+ && p->lfEscapement == ime_logfont.lfEscapement | |
+ && p->lfOrientation == ime_logfont.lfOrientation | |
+ && p->lfWeight == ime_logfont.lfWeight | |
+ && p->lfItalic == ime_logfont.lfItalic | |
+ && p->lfUnderline == ime_logfont.lfUnderline | |
+ && p->lfStrikeOut == ime_logfont.lfStrikeOut | |
+ && p->lfCharSet == ime_logfont.lfCharSet | |
+ && p->lfOutPrecision == ime_logfont.lfOutPrecision | |
+ && p->lfClipPrecision == ime_logfont.lfClipPrecision | |
+ && p->lfQuality == ime_logfont.lfQuality | |
+ && p->lfPitchAndFamily == ime_logfont.lfPitchAndFamily | |
+ && strncmp (p->lfFaceName, ime_logfont.lfFaceName, LF_FACESIZE) == 0)) | |
+ return 0; | |
+ else | |
+ return 1; | |
+} | |
+void | |
+w32_set_ime_logfont (hwnd, f) | |
+ HWND hwnd; | |
+ struct frame *f; | |
+{ | |
+ Lisp_Object ime_font = Qnil, temp = Qnil, font = Qnil, family; | |
+ struct gcpro gcpro1, gcpro2; | |
+ extern Lisp_Object QCfamily; | |
+ int fsid = -1; | |
+ LOGFONT logfont = {0}; | |
+ | |
+ if (!IsWindow (hwnd)) | |
+ return; | |
+ | |
+ if (!fIME || NILP(Vime_control)) | |
+ return; | |
+ | |
+ GCPRO2(font, temp); | |
+ | |
+ if (STRINGP(ime_font = get_frame_param (f, Qime_font)) | |
+ /* fontset */ | |
+ && ((fsid = fs_query_fontset(ime_font, 0)) >= 0 | |
+ && !NILP(font = fontset_ascii(fsid)) | |
+ && !NILP(font = font_spec_from_name(font)) | |
+ && !NILP(temp = Ffontset_font(temp, make_number(0x3042), Qnil)) | |
+ && !NILP(family = XCAR(temp)) | |
+ /* font */ | |
+ || !NILP(font = font_spec_from_name(ime_font)) | |
+ && SYMBOLP(family = AREF (font, FONT_FAMILY_INDEX)) | |
+ && STRINGP(family = SYMBOL_NAME(family))) | |
+ | |
+ /* use font object */ | |
+ /* frame-parameter */ | |
+ || (FONTP(font = ime_font) | |
+ /* frame fontset */ | |
+ || ((fsid = FRAME_FONTSET(f)) >= 0 | |
+ && !NILP(font = | |
+ Ffont_at(make_number(0), Qnil, | |
+ temp = Fchar_to_string(make_number(0x3042)))))) | |
+ && SYMBOLP(family = Ffont_get(font, QCfamily)) | |
+ && STRINGP(family = SYMBOL_NAME(family)) | |
+ && !NILP(font = copy_font_spec(font))) { | |
+ Lisp_Object tail; | |
+ | |
+ fill_in_logfont (f, &logfont, font); | |
+ | |
+ logfont.lfWidth = 0; | |
+ | |
+ family = ENCODE_SYSTEM(family); | |
+ | |
+ strcpy(logfont.lfFaceName, SDATA(family)); | |
+ | |
+ /* rescale */ | |
+ for (tail = Vface_font_rescale_alist; CONSP (tail); tail = XCDR (tail)) { | |
+ temp = XCAR (tail); | |
+ if (!FLOATP (XCDR (temp))) | |
+ continue; | |
+ | |
+ if (STRINGP (XCAR (temp))) { | |
+ if (fast_string_match_ignore_case (XCAR (temp), family) >= 0) { | |
+ logfont.lfHeight *= XFLOAT_DATA (XCDR (temp)); | |
+ break; | |
+ } | |
+ } else if (FONT_SPEC_P (XCAR (temp))) { | |
+ Lisp_Object name; | |
+ if (!NILP(name = Ffont_get(XCAR (temp), QCfamily)) && | |
+ STRINGP(name) && | |
+ xstrcasecmp(SDATA(name), SDATA(family)) == 0) { | |
+ logfont.lfHeight *= XFLOAT_DATA (XCDR (temp)); | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ } else { | |
+ HFONT hfont = FONT_HANDLE (FRAME_FONT (f)); | |
+ GetObject (hfont, sizeof (logfont), &logfont); | |
+ } | |
+ UNGCPRO; | |
+ | |
+ if (need_set_ime_font (&logfont)) | |
+ { | |
+ ime_logfont = logfont; | |
+ PostMessage (hwnd, WM_MULE_IMM_SET_IMEFONT, (WPARAM) f, 0); | |
+ } | |
+} | |
+static void | |
+w32_set_ime_font (hwnd) | |
+ HWND hwnd; | |
+{ | |
+ HIMC himc; | |
+ | |
+ if (!fIME || NILP (Vime_control)) | |
+ return; | |
+ | |
+ himc = (ImmGetContextProc) (hwnd); | |
+ if (!himc) | |
+ return; | |
+ (ImmSetCompositionFontProc) (himc, &ime_logfont); | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+} | |
+#else /* USE_W32_CALL_LISP_THREAD */ | |
+ | |
+struct get_imefont_arg { | |
+ HWND hwnd; | |
+ struct frame *f; | |
+ LOGFONT lf; | |
+}; | |
+ | |
+static Lisp_Object | |
+w32_get_ime_font (Lisp_Object arg_) | |
+{ | |
+ struct get_imefont_arg *arg = cons2ptr(arg_); | |
+ | |
+ Lisp_Object ime_font = Qnil, temp = Qnil, font = Qnil, family; | |
+ struct gcpro gcpro1, gcpro2; | |
+ extern Lisp_Object QCfamily; | |
+ int fsid = -1; | |
+ | |
+ if (!fIME || NILP(Vime_control)) | |
+ return Qnil; | |
+ | |
+ GCPRO2(font, temp); | |
+ | |
+ if (STRINGP(ime_font = get_frame_param (arg->f, Qime_font)) | |
+ /* fontset */ | |
+ && ((fsid = fs_query_fontset(ime_font, 0)) >= 0 | |
+ && !NILP(font = fontset_ascii(fsid)) | |
+ && !NILP(font = font_spec_from_name(font)) | |
+ && !NILP(temp = Ffontset_font(temp, make_number(0x3042), Qnil)) | |
+ && !NILP(family = XCAR(temp)) | |
+ /* font */ | |
+ || !NILP(font = font_spec_from_name(ime_font)) | |
+ && SYMBOLP(family = AREF (font, FONT_FAMILY_INDEX)) | |
+ && STRINGP(family = SYMBOL_NAME(family))) | |
+ | |
+ /* use font object */ | |
+ /* frame-parameter */ | |
+ || (FONTP(font = ime_font) | |
+ /* frame fontset */ | |
+ || ((fsid = FRAME_FONTSET(arg->f)) >= 0 | |
+ && !NILP(font = | |
+ Ffont_at(make_number(0), Qnil, | |
+ temp = Fchar_to_string(make_number(0x3042)))))) | |
+ && SYMBOLP(family = Ffont_get(font, QCfamily)) | |
+ && STRINGP(family = SYMBOL_NAME(family)) | |
+ && !NILP(font = copy_font_spec(font))) { | |
+ Lisp_Object tail; | |
+ | |
+ fill_in_logfont (arg->f, &arg->lf, font); | |
+ arg->lf.lfWidth = 0; | |
+ | |
+ family = ENCODE_SYSTEM(family); | |
+ | |
+#ifdef _MSC_VER | |
+ strcpy_s(arg->lf.lfFaceName, | |
+ sizeof(arg->lf.lfFaceName), SDATA(family)); | |
+#else | |
+ strcpy(arg->lf.lfFaceName, SDATA(family)); | |
+#endif | |
+ | |
+ /* rescale if ime font isn't ascii*/ | |
+ for (tail = Vface_font_rescale_alist; CONSP (tail); tail = XCDR (tail)) { | |
+ temp = XCAR (tail); | |
+ if (!FLOATP (XCDR (temp))) | |
+ continue; | |
+ | |
+ if (STRINGP (XCAR (temp))) { | |
+ if (fast_string_match_ignore_case (XCAR (temp), family) >= 0) { | |
+ arg->lf.lfHeight *= XFLOAT_DATA (XCDR (temp)); | |
+ break; | |
+ } | |
+ } else if (FONT_SPEC_P (XCAR (temp))) { | |
+ Lisp_Object name; | |
+ if (!NILP(name = Ffont_get(XCAR (temp), QCfamily)) && | |
+ STRINGP(name) && | |
+ xstrcasecmp(SDATA(name), SDATA(family)) == 0) { | |
+ arg->lf.lfHeight *= XFLOAT_DATA (XCDR (temp)); | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ } else { | |
+ HFONT hfont = FONT_HANDLE (FRAME_FONT (arg->f)); | |
+ GetObject (hfont, sizeof (arg->lf), &arg->lf); | |
+ } | |
+ UNGCPRO; | |
+ | |
+ return Qt; | |
+} | |
+ | |
+static void | |
+w32_set_ime_font (hwnd, f) | |
+ HWND hwnd; | |
+ struct frame *f; | |
+{ | |
+ HIMC himc; | |
+ struct get_imefont_arg gia = { | |
+ hwnd, f, {0} | |
+ }; | |
+ | |
+ if (NILP(w32_call_lisp_thread(w32_get_ime_font, &gia)) || | |
+ !(himc = (ImmGetContextProc) (hwnd))) | |
+ return; | |
+ | |
+ (ImmSetCompositionFontProc) (himc, &gia.lf); | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+} | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
+#endif /* HAVE_NTGUI */ | |
+ | |
+static LRESULT CALLBACK | |
+conversion_agent_wndproc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) | |
+/* HWND hwnd; | |
+ UINT message; | |
+ WPARAM wparam; | |
+ LPARAM lparam; */ | |
+{ | |
+ HIMC himc, holdimc; | |
+ | |
+ switch (message) | |
+ { | |
+ case WM_MULE_IMM_SET_STATUS: | |
+ if (InSendMessage()) | |
+ ReplyMessage(1); | |
+ w32_set_ime_status (hwnd, (int) wparam); | |
+ break; | |
+ | |
+ case WM_MULE_IMM_GET_STATUS: | |
+ return w32_get_ime_status (hwnd); | |
+ | |
+ case WM_MULE_IMM_SET_MODE: | |
+ return w32_set_ime_mode (hwnd, (int) wparam, (int) lparam); | |
+ | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+ case WM_MULE_IMM_SET_IMEFONT: | |
+ w32_set_ime_font (hwnd); | |
+#endif | |
+ case WM_MULE_IMM_SET_CONVERSION_WINDOW: | |
+ if (w32_get_ime_status (hwnd)) | |
+ w32_set_ime_conv_window (hwnd, (struct frame *) wparam); | |
+ break; | |
+ | |
+#ifdef RECONVERSION | |
+ case WM_MULE_IMM_PERFORM_RECONVERSION: | |
+ if (ime_enable_reconversion) | |
+ w32_perform_reconversion(hwnd, (RECONVERTSTRING*)lparam); | |
+ break; | |
+#endif | |
+ | |
+#if 0 | |
+ case WM_MULE_IMM_GET_COMPOSITION_STRING: | |
+ return w32_get_ime_composition_string (hwnd); | |
+#endif | |
+ | |
+ default: | |
+ return DefWindowProc (hwnd, message, wparam, lparam); | |
+ } | |
+ return 0; | |
+} | |
+ | |
+ | |
+/* | |
+ Emacs Lisp function entries | |
+*/ | |
+ | |
+DEFUN ("ime-force-on", Fime_force_on, Sime_force_on, 0, 1, 0, | |
+ doc: /* Force status of IME open. */) | |
+ (Lisp_Object eventp) | |
+{ | |
+ if (fIME && !NILP (Vime_control)) | |
+ { | |
+ HIMC himc; | |
+ HWND hwnd; | |
+ | |
+ if (!NILP (Fime_get_mode ())) | |
+ return Qnil; | |
+#ifdef HAVE_NTGUI | |
+ if (NILP (eventp)) | |
+ IME_event_off_count++; | |
+ hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ()); | |
+#else | |
+ hwnd = hwndConsole; | |
+#endif | |
+ SendMessage (hwnd, WM_MULE_IMM_SET_STATUS, 1, 0); | |
+ } | |
+ return Qnil; | |
+} | |
+ | |
+DEFUN ("ime-force-off", Fime_force_off, Sime_force_off, 0, 1, 0, | |
+ doc: /* Force status of IME close. */) | |
+ (Lisp_Object eventp) | |
+{ | |
+ if (fIME && !NILP (Vime_control)) | |
+ { | |
+ HIMC himc; | |
+ HWND hwnd; | |
+ | |
+ if (NILP (Fime_get_mode ())) | |
+ return Qnil; | |
+#ifdef HAVE_NTGUI | |
+ if (NILP (eventp)) | |
+ IME_event_off_count++; | |
+ hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ()); | |
+#else | |
+ hwnd = hwndConsole; | |
+#endif | |
+ SendMessage (hwnd, WM_MULE_IMM_SET_STATUS, 0, 0); | |
+ } | |
+ return Qnil; | |
+} | |
+ | |
+DEFUN ("ime-get-mode", Fime_get_mode, Sime_get_mode, 0, 0, "", | |
+ doc: /* Get IME status. | |
+t means status of IME is open. nil means it is close. */) | |
+ (void) | |
+{ | |
+ if (fIME && !NILP (Vime_control)) | |
+ { | |
+ HWND hwnd; | |
+ int result; | |
+ | |
+#ifdef HAVE_NTGUI | |
+ hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ()); | |
+#else | |
+ hwnd = hwndConsole; | |
+#endif | |
+ result = SendMessage (hwnd, WM_MULE_IMM_GET_STATUS, 0, 0); | |
+ | |
+ return result ? Qt : Qnil; | |
+ } | |
+ else | |
+ return Qnil; | |
+} | |
+ | |
+DEFUN ("w32-set-ime-mode", | |
+ Fw32_set_ime_mode, | |
+ Sw32_set_ime_mode, 1, 2, 0, | |
+ doc: /* Set IME mode to MODE. If FRAME is omitted, the selected frame is used. */) | |
+ (Lisp_Object mode, Lisp_Object frame) | |
+{ | |
+ struct frame *f; | |
+ | |
+ if (NILP (frame)) | |
+ { | |
+ f = SELECTED_FRAME (); | |
+ } | |
+ else | |
+ { | |
+ CHECK_FRAME (frame); | |
+ f = XFRAME (frame); | |
+ } | |
+ if (fIME && !NILP (Vime_control)) | |
+ { | |
+ HWND hwnd; | |
+ int ret; | |
+ int newmode, mask; | |
+ | |
+ newmode = 0; | |
+ mask = 0; | |
+ | |
+ hwnd = FRAME_W32_WINDOW (f); | |
+ | |
+ if (EQ (mode, intern ("katakana"))) | |
+ { | |
+ newmode |= IME_CMODE_KATAKANA; | |
+ mask |= IME_CMODE_KATAKANA; | |
+ } | |
+ else if (EQ (mode, intern ("hiragana"))) | |
+ { | |
+ newmode &= ~IME_CMODE_KATAKANA; | |
+ mask |= IME_CMODE_KATAKANA; | |
+ } | |
+ else if (EQ (mode, intern ("kanji"))) | |
+ { | |
+ newmode |= IME_CMODE_HANJACONVERT; | |
+ mask |= IME_CMODE_HANJACONVERT; | |
+ } | |
+ else if (EQ (mode, intern ("nokanji"))) | |
+ { | |
+ newmode &= ~IME_CMODE_HANJACONVERT; | |
+ mask |= IME_CMODE_HANJACONVERT; | |
+ } | |
+ else if (EQ (mode, intern ("code"))) | |
+ { | |
+ newmode |= IME_CMODE_CHARCODE; | |
+ mask |= IME_CMODE_CHARCODE; | |
+ } | |
+ else if (EQ (mode, intern ("nocode"))) | |
+ { | |
+ newmode &= ~IME_CMODE_CHARCODE; | |
+ mask |= IME_CMODE_CHARCODE; | |
+ } | |
+ else if (EQ (mode, intern ("non-convert"))) | |
+ { | |
+ newmode |= IME_CMODE_NOCONVERSION; | |
+ mask |= IME_CMODE_NOCONVERSION; | |
+ } | |
+ else if (EQ (mode, intern ("convert"))) | |
+ { | |
+ newmode &= ~IME_CMODE_NOCONVERSION; | |
+ mask |= IME_CMODE_NOCONVERSION; | |
+ } | |
+ else | |
+ error ("unknown mode!!"); | |
+ | |
+ ret = SendMessage (hwnd, WM_MULE_IMM_SET_MODE, | |
+ (WPARAM) newmode, (LPARAM) mask); | |
+ | |
+ if (!ret) | |
+ return Qnil; | |
+ | |
+ return Qt; | |
+ } | |
+ return Qnil; | |
+} | |
+ | |
+DEFUN ("w32-ime-register-word-dialog", | |
+ Fw32_ime_register_word_dialog, | |
+ Sw32_ime_register_word_dialog, 2, 2, 0, | |
+ doc: /* Open IME regist word dialog. */) | |
+ (Lisp_Object reading, Lisp_Object word) | |
+{ | |
+ HKL hkl; | |
+ int reading_len, word_len; | |
+ REGISTERWORD regword; | |
+ Lisp_Object encoded_reading, encoded_word; | |
+ | |
+ CHECK_STRING (reading); | |
+ CHECK_STRING (word); | |
+ | |
+ if (fIME && !NILP (Vime_control) && ImmConfigureIMEProc) | |
+ { | |
+ hkl = GetKeyboardLayout (0); | |
+ encoded_reading = Fencode_coding_string (reading, | |
+ Vlocale_coding_system, | |
+ Qnil, Qnil); | |
+ reading_len = SBYTES (encoded_reading); | |
+ regword.lpReading = SDATA (encoded_reading); | |
+ | |
+ encoded_word = Fencode_coding_string (word, | |
+ Vlocale_coding_system, | |
+ Qnil, Qnil); | |
+ word_len = SBYTES (encoded_word); | |
+ regword.lpWord = SDATA (encoded_word); | |
+ (ImmConfigureIMEProc) (hkl, FRAME_W32_WINDOW (SELECTED_FRAME ()), | |
+ IME_CONFIG_REGISTERWORD, ®word); | |
+ } | |
+ return Qnil; | |
+} | |
+ | |
+DEFUN ("ime-get-property", Fime_get_property, Sime_get_property, 1, 1, 0, | |
+ doc: /* Retrieves the property and capabilities of the IME associated with the specified input locale. | |
+INDEX is one of igp-property, igp-conversion, igp-sentence, igp-ui, igp-setcompstr, igp-select of igp-getimeversion*/) | |
+ (Lisp_Object index) | |
+{ | |
+ int i; | |
+ Lisp_Object val; | |
+ DWORD v; | |
+ struct gcpro gcpro1; | |
+ | |
+ static const struct { | |
+ const char *name; | |
+ DWORD index; | |
+ } index_map[] = { | |
+ {"property", IGP_PROPERTY}, | |
+ {"conversion", IGP_CONVERSION}, | |
+ {"sentence", IGP_SENTENCE}, | |
+ {"ui", IGP_UI}, | |
+ {"setcompstr", IGP_SETCOMPSTR}, | |
+ {"select", IGP_SELECT}, | |
+ {"getimeversion", IGP_GETIMEVERSION}, | |
+ }, prop_map[] = { | |
+ {"at-caret", IME_PROP_AT_CARET}, | |
+ {"special-ui", IME_PROP_SPECIAL_UI}, | |
+ {"candlist-start-from-1", IME_PROP_CANDLIST_START_FROM_1}, | |
+ {"unicode", IME_PROP_UNICODE}, | |
+ {"complete-on-unselect", IME_PROP_COMPLETE_ON_UNSELECT}, | |
+ }, ui_map[] = { | |
+ {"rot2700", UI_CAP_2700}, | |
+ {"rot90", UI_CAP_ROT90}, | |
+ {"rotany", UI_CAP_ROTANY}, | |
+ }, setcompstr_map[] = { | |
+ {"compstr", SCS_CAP_COMPSTR}, | |
+ {"makeread", SCS_CAP_MAKEREAD}, | |
+ {"setreconvertstring", SCS_CAP_SETRECONVERTSTRING}, | |
+ }, select_map[] = { | |
+ {"conversion", SELECT_CAP_CONVERSION}, | |
+ {"sentence", SELECT_CAP_SENTENCE}, | |
+ }, imeversion_map[] = { | |
+ {"ver-0310", IMEVER_0310}, | |
+ {"ver-0400", IMEVER_0400}, | |
+ }; | |
+ | |
+ CHECK_SYMBOL(index); | |
+ for (i = 0; i < sizeof(index_map) / sizeof(index_map[0]); i++) | |
+ if (EQ(index, intern(index_map[i].name))) | |
+ break; | |
+ if (i >= sizeof(index_map) / sizeof(index_map[0])) | |
+ return Qnil; | |
+ | |
+ v = (*ImmGetPropertyProc)(GetKeyboardLayout(0), index_map[i].index); | |
+ val = Qnil; | |
+ GCPRO1(val); | |
+#define MAKE_CAP_LIST(map) do { \ | |
+ int j; \ | |
+ for (j = sizeof(map) / sizeof(map[0]) - 1; j >= 0 ; j--) \ | |
+ if (v & map[j].index) \ | |
+ val = Fcons(intern(map[j].name), val); \ | |
+} while(0) | |
+ | |
+ switch (index_map[i].index) { | |
+ case IGP_PROPERTY: | |
+ MAKE_CAP_LIST(prop_map); | |
+ break; | |
+ case IGP_UI: | |
+ MAKE_CAP_LIST(ui_map); | |
+ break; | |
+ case IGP_SETCOMPSTR: | |
+ MAKE_CAP_LIST(setcompstr_map); | |
+ break; | |
+ case IGP_SELECT: | |
+ MAKE_CAP_LIST(select_map); | |
+ break; | |
+ case IGP_GETIMEVERSION: | |
+ MAKE_CAP_LIST(imeversion_map); | |
+ break; | |
+ } | |
+ UNGCPRO; | |
+ return val; | |
+} | |
+ | |
+#ifdef RECONVERSION | |
+BOOL w32_perform_reconversion(HWND hwnd, RECONVERTSTRING *reconv) | |
+{ | |
+ struct frame *f = SELECTED_FRAME (); | |
+ HIMC himc; | |
+ BOOL result = FALSE; | |
+ | |
+ himc = (ImmGetContextProc) (hwnd); | |
+ if (!himc) { | |
+ xfree(reconv); | |
+ return FALSE; | |
+ } | |
+ | |
+ if ((*ImmSetCompositionStringProc) (himc, | |
+ SCS_QUERYRECONVERTSTRING, | |
+ reconv, reconv->dwSize, | |
+ NULL, 0 ) | |
+ && (*ImmSetCompositionStringProc) (himc, | |
+ SCS_SETRECONVERTSTRING, | |
+ reconv, reconv->dwSize, | |
+ NULL, 0)) { | |
+ /* Set the position of candidate list dialog. */ | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+ w32_set_ime_conv_window (hwnd, f); | |
+ result = TRUE; | |
+ } else | |
+ (ImmReleaseContextProc) (hwnd, himc); | |
+ xfree(reconv); | |
+ return result; | |
+} | |
+ | |
+DEFUN ("w32-ime-perform-reconversion", | |
+ Fw32_ime_perform_reconversion, | |
+ Sw32_ime_perform_reconversion, 0, 0, "", | |
+ doc: /* perfom ime reconversion. */) | |
+ (void) | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+{ | |
+ HWND hwnd = FRAME_W32_WINDOW(SELECTED_FRAME()); | |
+ DWORD size; | |
+ RECONVERTSTRING *reconv; | |
+ | |
+ if (!ime_enable_reconversion || | |
+ NILP(Fime_get_mode())) | |
+ return Qnil; | |
+ | |
+ if ((size = get_reconversion_string (hwnd, NULL, NULL)) | |
+ && (reconv = xmalloc (size)) != NULL | |
+ && (memset (reconv, 0, size), (reconv->dwSize = size)) | |
+ && get_reconversion_string (hwnd, reconv, NULL)) | |
+ PostMessage(hwnd, WM_MULE_IMM_PERFORM_RECONVERSION, 0, (LPARAM) reconv); | |
+ | |
+ return Qt; | |
+} | |
+#else /* USE_W32_CALL_LISP_THREAD */ | |
+{ | |
+ Lisp_Object temp; | |
+ struct gcpro gcpro1; | |
+ struct get_reconversion_string_arg grs = {0, NULL, NULL, 0}; | |
+ | |
+ if (!ime_enable_reconversion || | |
+ NILP(Fime_get_mode())) | |
+ return Qnil; | |
+ | |
+ GCPRO1(temp); | |
+ | |
+ if (!NILP(get_reconversion_string(temp = ptr2cons(&grs))) | |
+ && grs.size > 0 | |
+ && (grs.reconv = xmalloc(grs.size)) != NULL | |
+ && (memset(grs.reconv, 0, grs.size), | |
+ (grs.reconv->dwSize = grs.size)) | |
+ && !NILP(get_reconversion_string(temp))) { | |
+ | |
+ // del_range(grs.start, grs.end); | |
+ | |
+ PostMessage(FRAME_W32_WINDOW(SELECTED_FRAME()), | |
+ WM_MULE_IMM_PERFORM_RECONVERSION, 0, (LPARAM)grs.reconv); | |
+ } | |
+ UNGCPRO; | |
+ return Qt; | |
+} | |
+#endif /* USE_W32_CALL_LISP_THREAD */ | |
+#endif | |
+ | |
+#endif /* USE_W32_IME */ | |
+ | |
+ | |
+/*********************************************************************** | |
w32 specialized functions | |
***********************************************************************/ | |
@@ -7595,7 +9403,9 @@ | |
{ | |
if (IS_DIRECTORY_SEP (*name) && --slashes == 0) | |
break; | |
- *str++ = *name++; | |
+ *str = *name; | |
+ str = _mbsinc(str); | |
+ name = _mbsinc(name); | |
} | |
while ( *name ); | |
@@ -7771,6 +9581,37 @@ | |
return DECODE_FILE (build_unibyte_string (pname_buf)); | |
} | |
+ | |
+DEFUN ("w32-memory-info", Fw32_memory_info, Sw32_memory_info, | |
+ 0, 0, 0, doc: /* Retrieves information about the memory usage. | |
+return value is a list of | |
+ | |
+reserved_heap_size | |
+ | |
+GlobalMemoryStatusEx: | |
+ MemoryLoad; | |
+ TotalPhys; | |
+ AvailPhys; | |
+ TotalPageFile; | |
+ AvailPageFile; | |
+ TotalVirtual; | |
+ AvailVirtual; | |
+ AvailExtendedVirtual; | |
+ | |
+GetProcessMemoryInfo: | |
+ PageFaultCount; | |
+ PeakWorkingSetSize; | |
+ WorkingSetSize; | |
+ QuotaPeakPagedPoolUsage; | |
+ QuotaPagedPoolUsage; | |
+ QuotaPeakNonPagedPoolUsage; | |
+ QuotaNonPagedPoolUsage; | |
+ PagefileUsage; | |
+ PeakPagefileUsage; | |
+ PrivateUsage; (Xp or above) */) (void) | |
+{ | |
+ return w32_get_memory_info (); | |
+} | |
#endif /* WINDOWSNT */ | |
@@ -8115,6 +9956,9 @@ | |
x_set_fullscreen, | |
x_set_font_backend, | |
x_set_alpha, | |
+#ifdef USE_W32_IME | |
+ 0, /* ime-font */ | |
+#endif /* USE_W32_IME */ | |
0, /* x_set_sticky */ | |
0, /* x_set_tool_bar_position */ | |
}; | |
@@ -8129,6 +9973,10 @@ | |
DEFSYM (Qsuppress_icon, "suppress-icon"); | |
DEFSYM (Qundefined_color, "undefined-color"); | |
+#ifdef USE_W32_IME | |
+ DEFSYM (Qw32_ime_buffer_switch_p, "w32-ime-buffer-switch-p"); | |
+ DEFSYM (Qime_font, "ime-font"); | |
+#endif /* USE_W32_IME */ | |
DEFSYM (Qcancel_timer, "cancel-timer"); | |
DEFSYM (Qhyper, "hyper"); | |
DEFSYM (Qsuper, "super"); | |
@@ -8405,6 +10253,27 @@ | |
only be necessary if the default setting causes problems. */); | |
w32_strict_painting = 1; | |
+#ifdef USE_W32_IME | |
+#ifdef RECONVERSION | |
+ DEFVAR_BOOL ("ime-enable-reconversion", ime_enable_reconversion, | |
+ doc: /* Non-nil enables IME reconversion capability. */); | |
+ ime_enable_reconversion = 1; | |
+#endif | |
+#ifdef DOCUMENTFEED | |
+ DEFVAR_BOOL ("ime-enable-document-feed", ime_enable_document_feed, | |
+ doc: /* Non-nil enables IME document feed capability. */); | |
+ ime_enable_document_feed = 1; | |
+#endif | |
+ DEFVAR_LISP ("ime-control", Vime_control, doc: /* IME control flag. */); | |
+ Vime_control = Qnil; | |
+ | |
+ DEFVAR_LISP ("w32-ime-composition-window", | |
+ Vw32_ime_composition_window, | |
+ doc: /* If this is a window of current frame, IME composition window appears on the | |
+window instead of current window. */); | |
+ Vw32_ime_composition_window = Qnil; | |
+#endif /* USE_W32_IME */ | |
+ | |
#if 0 /* TODO: Port to W32 */ | |
defsubr (&Sx_change_window_property); | |
defsubr (&Sx_delete_window_property); | |
@@ -8449,6 +10318,20 @@ | |
defsubr (&Sw32_frame_rect); | |
defsubr (&Sw32_battery_status); | |
defsubr (&Sw32__menu_bar_in_use); | |
+#ifndef CYGWIN | |
+ defsubr (&Sw32_memory_info); | |
+#endif | |
+#ifdef USE_W32_IME | |
+ defsubr (&Sw32_set_ime_mode); | |
+ defsubr (&Sw32_ime_register_word_dialog); | |
+ defsubr (&Sime_force_on); | |
+ defsubr (&Sime_force_off); | |
+ defsubr (&Sime_get_mode); | |
+ defsubr (&Sime_get_property); | |
+#ifdef RECONVERSION | |
+ defsubr (&Sw32_ime_perform_reconversion); | |
+#endif | |
+#endif /* USE_W32_IME */ | |
#ifdef WINDOWSNT | |
defsubr (&Sfile_system_info); | |
@@ -8534,7 +10417,7 @@ | |
{ | |
int button; | |
button = MessageBox (NULL, | |
- "A fatal error has occurred!\n\n" | |
+ TEXT("A fatal error has occurred!\n\n" | |
"Would you like to attach a debugger?\n\n" | |
"Select:\n" | |
"YES -- to debug Emacs, or\n" | |
@@ -8544,7 +10427,7 @@ | |
"\n\n(type \"gdb -p <emacs-PID>\" and\n" | |
"\"continue\" inside GDB before clicking YES.)" | |
#endif | |
- , "Emacs Abort Dialog", | |
+ ), TEXT("Emacs Abort Dialog"), | |
MB_ICONEXCLAMATION | MB_TASKMODAL | |
| MB_SETFOREGROUND | MB_YESNO); | |
switch (button) | |
@@ -8662,6 +10545,7 @@ | |
enum_display_monitors_fn = (EnumDisplayMonitors_Proc) | |
GetProcAddress (user32_lib, "EnumDisplayMonitors"); | |
+#ifndef USE_W32_IME | |
{ | |
HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); | |
get_composition_string_fn = (ImmGetCompositionString_Proc) | |
@@ -8673,6 +10557,7 @@ | |
set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc) | |
GetProcAddress (imm32_lib, "ImmSetCompositionWindow"); | |
} | |
+#endif /* !USE_W32_IME */ | |
except_code = 0; | |
except_addr = 0; | |
@@ -8685,9 +10570,11 @@ | |
doc: /* The ANSI code page used by the system. */); | |
w32_ansi_code_page = GetACP (); | |
+#if !defined(USE_W32_CALL_LISP_THREAD) || defined(IME_UNICODE) | |
if (os_subtype == OS_NT) | |
w32_unicode_gui = 1; | |
else | |
+#endif | |
w32_unicode_gui = 0; | |
/* MessageBox does not work without this when linked to comctl32.dll 6.0. */ | |
@@ -8707,3 +10594,63 @@ | |
} | |
#endif /* NTGUI_UNICODE */ | |
+ | |
+ | |
+#ifdef USE_W32_CALL_LISP_THREAD | |
+#ifdef _MSC_VER | |
+#include <intrin.h> | |
+#pragma intrinsic(_InterlockedCompareExchange, _InterlockedExchange) | |
+#endif | |
+ | |
+static long apc_mutex; | |
+static HANDLE apc_mutex_ev; | |
+ | |
+void w32_apc_mutex_init(void) | |
+{ | |
+#if 0 | |
+ apc_mutex = 0; | |
+ apc_mutex_ev = CreateEvent(NULL, FALSE, FALSE, NULL); | |
+#endif | |
+} | |
+ | |
+void w32_apc_mutex_term(void) | |
+{ | |
+#if 0 | |
+ CloseHandle(apc_mutex_ev); | |
+#endif | |
+} | |
+ | |
+void w32_apc_mutex_acquire(void) | |
+{ | |
+#if 0 | |
+ const DWORD tid = GetCurrentThreadId(); | |
+ const BOOL proc_msg = dwWindowsThreadId == tid; | |
+ DWORD locker, v; | |
+ deferred_msg dummy = {0}; | |
+ MSG msg; | |
+ dummy.completed = 1; | |
+ | |
+ while ((locker = | |
+ InterlockedCompareExchange(&apc_mutex, tid, 0)) != 0 | |
+ && locker != tid) | |
+ while ((v = proc_msg | |
+ ? MsgWaitForMultipleObjectsEx | |
+ (1, &apc_mutex_ev, INFINITE, | |
+ QS_ALLINPUT | QS_ALLPOSTMESSAGE, MWMO_ALERTABLE) | |
+ : WaitForSingleObjectEx(apc_mutex_ev, INFINITE, TRUE)) | |
+ != WAIT_OBJECT_0) | |
+ if (v == WAIT_OBJECT_0 + 1) | |
+ w32_msg_pump(&dummy); | |
+ else if (v != WAIT_IO_COMPLETION) | |
+ abort(); | |
+#endif | |
+} | |
+ | |
+void w32_apc_mutex_release(void) | |
+{ | |
+#if 0 | |
+ InterlockedExchange(&apc_mutex, 0); | |
+ SetEvent(apc_mutex_ev); | |
+#endif | |
+} | |
+#endif | |
--- ./src/w32font.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32font.c 2015-04-11 07:27:30.699125900 +0900 | |
@@ -102,7 +102,10 @@ | |
/* Font spacing symbols - defined in font.c. */ | |
extern Lisp_Object Qc, Qp, Qm; | |
-static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object); | |
+#ifndef USE_W32_IME | |
+static | |
+#endif | |
+void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object); | |
static BYTE w32_antialias_type (Lisp_Object); | |
static Lisp_Object lispy_antialias_type (BYTE); | |
@@ -1962,7 +1965,10 @@ | |
} | |
/* Fill in all the available details of LOGFONT from FONT_SPEC. */ | |
-static void | |
+#ifndef USE_W32_IME | |
+static | |
+#endif | |
+void | |
fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec) | |
{ | |
Lisp_Object tmp, extra; | |
--- ./src/w32font.h.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32font.h 2015-04-11 07:27:30.705127000 +0900 | |
@@ -83,6 +83,9 @@ | |
int uniscribe_check_otf (LOGFONT *font, Lisp_Object otf_spec); | |
Lisp_Object intern_font_name (char *); | |
+#ifdef USE_W32_IME | |
+void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object); | |
+#endif | |
extern void syms_of_w32font (void); | |
extern void globals_of_w32font (void); | |
--- ./src/w32heap.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32heap.c 2015-04-11 07:27:30.714128400 +0900 | |
@@ -60,6 +60,86 @@ | |
return data_region_end; | |
} | |
+#ifdef _WIN64 | |
+static char * | |
+allocate_heap (void) | |
+{ | |
+ /* Try to get as much as possible of the address range from the end of | |
+ the preload heap section up to the usable address limit. Since GNU | |
+ malloc can handle gaps in the memory it gets from sbrk, we can | |
+ simply set the sbrk pointer to the base of the new heap region. */ | |
+ MEMORYSTATUSEX msx = {sizeof(MEMORYSTATUSEX)}; | |
+ uintptr_t size = | |
+ (GlobalMemoryStatusEx(&msx) != 0) ? | |
+ msx.ullTotalPhys * 2 : (uintptr_t)256 * 1024 * 1024 * 1024; | |
+ uintptr_t decr, low_blocks, i; | |
+ void *ptr = NULL; | |
+ char *p, *hsize = getenv("EMACS_MAX_HEAP"), **ptr0; | |
+ | |
+ if (hsize) { | |
+ size = (EMACS_INT)strtol(hsize, &p, 10); | |
+ switch (*p == 0 ? 0 : tolower(*p)) { | |
+ case 'k': | |
+ size *= (EMACS_UINT)1024; | |
+ break; | |
+ case 'm': | |
+ size *= (EMACS_UINT)1024 * 1024; | |
+ break; | |
+ case 'g': | |
+ size *= (EMACS_UINT)1024 * 1024 * 1024; | |
+ break; | |
+ case 't': | |
+ size *= (EMACS_UINT)1024 * 1024 * 1024 * 1024; | |
+ break; | |
+ default: | |
+ return NULL; | |
+ } | |
+ } | |
+ | |
+ if (size > (EMACS_UINT)16 * 1024 * 1024 * 1024) // 16G | |
+ decr = (EMACS_UINT)1 * 1024 * 1024 * 1024; // 1G | |
+ else if (size > (EMACS_UINT)4 * 1024 * 1024 * 1024) // 4G | |
+ decr = (EMACS_UINT)128 * 1024 * 1024; // 128MB | |
+ else if (size > (EMACS_UINT)1 * 1024 * 1024 * 1024) // 1G | |
+ decr = (EMACS_UINT)128 * 1024 * 1024; // 64MB | |
+ else | |
+ decr = (EMACS_UINT)16 * 1024 * 1024; // 16MB | |
+ | |
+ /* | |
+ * gmalloc expect sbrk is grater than preload_heap. | |
+ * we'll preserve the regions below preload_head. | |
+ */ | |
+ if ((low_blocks = (uintptr_t) | |
+ RVA_TO_PTR(preload_heap_section->VirtualAddress) / size) > 0) { | |
+ ptr0 = alloca(sizeof(void *) * low_blocks); | |
+ for (i = 0; i < low_blocks; i++) | |
+ if ((ptr0[i] = | |
+ VirtualAlloc (NULL, size, MEM_RESERVE , PAGE_NOACCESS)) > | |
+ (char *) RVA_TO_PTR(preload_heap_section->VirtualAddress)) { | |
+ VirtualFree(ptr0[i], size, MEM_RELEASE); | |
+ ptr0[i] = NULL; | |
+ break; | |
+ } | |
+ while (i < low_blocks) | |
+ ptr0[i++] = NULL; | |
+ } | |
+ | |
+ for (ptr = NULL; !ptr && size > 0; size -= decr) | |
+ { | |
+ reserved_heap_size = size; | |
+ ptr = VirtualAlloc (NULL, | |
+ get_reserved_heap_size (), | |
+ MEM_RESERVE , PAGE_NOACCESS); | |
+ } | |
+ | |
+ /* free preserved region */ | |
+ for (i = 0; i < low_blocks; i++) | |
+ if (ptr0[i]) | |
+ VirtualFree(ptr0[i], size, MEM_RELEASE); | |
+ | |
+ return ptr; | |
+} | |
+#else | |
#if !USE_LSB_TAG | |
static char * | |
allocate_heap (void) | |
@@ -119,6 +199,7 @@ | |
return ptr; | |
} | |
#endif /* USE_LSB_TAG */ | |
+#endif /* !_WIN64 */ | |
/* Emulate Unix sbrk. Note that ralloc.c expects the return value to | |
--- ./src/w32proc.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32proc.c 2015-04-11 07:27:30.722127100 +0900 | |
@@ -43,7 +43,7 @@ | |
#undef kill | |
#include <windows.h> | |
-#if defined(__GNUC__) && !defined(__MINGW64__) | |
+#if defined(__GNUC__) && !defined(_W64) | |
/* This definition is missing from mingw.org headers, but not MinGW64 | |
headers. */ | |
extern BOOL WINAPI IsValidLocale (LCID, DWORD); | |
@@ -66,6 +66,8 @@ | |
#include "dispextern.h" /* for xstrcasecmp */ | |
#include "coding.h" | |
+#include <mbstring.h> | |
+ | |
#define RVA_TO_PTR(var,section,filedata) \ | |
((void *)((section)->PointerToRawData \ | |
+ ((DWORD_PTR)(var) - (section)->VirtualAddress) \ | |
@@ -1845,7 +1847,7 @@ | |
if (*p == 0) | |
need_quotes = 1; | |
- for ( ; *p; p++) | |
+ for ( ; *p; p = _mbsinc (p)) | |
{ | |
if (escape_char == '"' && *p == '\\') | |
/* If it's a Cygwin app, \ needs to be escaped. */ | |
@@ -1897,7 +1899,7 @@ | |
if (do_quoting) | |
{ | |
- for ( ; *p; p++) | |
+ for ( ; *p; p = _mbsinc (p)) | |
if ((strchr (sepchars, *p) != NULL) || *p == '"') | |
need_quotes = 1; | |
} | |
@@ -1925,7 +1927,7 @@ | |
*parg++ = *p++; | |
} | |
#else | |
- for ( ; *p; p++) | |
+ for ( ; *p; ) | |
{ | |
if (*p == '"') | |
{ | |
@@ -1940,12 +1942,15 @@ | |
} | |
else if (escape_char == '"' && *p == '\\') | |
*parg++ = '\\'; | |
- *parg++ = *p; | |
if (*p == escape_char && escape_char != '"') | |
escape_char_run++; | |
else | |
escape_char_run = 0; | |
+ { | |
+ char *px = _mbsinc (p); | |
+ while (px != p) *parg++ = *p++; | |
+ } | |
} | |
/* double escape chars before enclosing quote */ | |
while (escape_char_run > 0) | |
@@ -2240,7 +2245,11 @@ | |
errno = EINTR; | |
return -1; | |
} | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
else if (active == WAIT_TIMEOUT) | |
+#else | |
+ else if (active == WAIT_TIMEOUT || active == WAIT_IO_COMPLETION) | |
+#endif | |
{ | |
if (noninteractive) | |
{ | |
--- ./src/w32term.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32term.c 2015-04-11 07:27:30.733129100 +0900 | |
@@ -64,6 +64,7 @@ | |
#include "font.h" | |
#include "w32font.h" | |
+#pragma warning(error : 4013) | |
/* Fringe bitmaps. */ | |
@@ -4909,6 +4910,110 @@ | |
break; | |
#endif | |
+#ifdef USE_W32_IME | |
+ case WM_MULE_IME_STATUS: | |
+ f = x_window_to_frame (dpyinfo, msg.msg.hwnd); | |
+ | |
+ if (f && !f->iconified && f->visible) | |
+ { | |
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT; | |
+ inev.code = VK_KANJI; | |
+ inev.modifiers = 0; | |
+ XSETFRAME (inev.frame_or_window, f); | |
+ inev.timestamp = msg.msg.time; | |
+ } | |
+ break; | |
+ | |
+ case WM_MULE_IME_REPORT: | |
+ { | |
+#ifdef IME_UNICODE | |
+ LPWSTR lpStr; | |
+#else | |
+ LPSTR lpStr; | |
+#endif | |
+ struct input_event buf; | |
+ HANDLE hw32_ime_string = (HANDLE) msg.msg.wParam; | |
+ | |
+ f = (struct frame *) msg.msg.lParam; | |
+ if (f && !f->iconified && f->visible) | |
+ { | |
+#ifdef IME_UNICODE | |
+ lpStr = (LPWSTR) hw32_ime_string; | |
+#else | |
+ lpStr = (LPSTR) hw32_ime_string; | |
+#endif | |
+ while(lpStr) | |
+ { | |
+ wchar_t code; | |
+ | |
+ EVENT_INIT (buf); | |
+ XSETFRAME (buf.frame_or_window, f); | |
+ buf.timestamp = msg.msg.time; | |
+ buf.modifiers = 0; | |
+ if (*lpStr) | |
+ { | |
+#ifdef IME_UNICODE | |
+ if (*lpStr < 0x80) | |
+ buf.kind = ASCII_KEYSTROKE_EVENT; | |
+ else | |
+ buf.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; | |
+ if ((*lpStr & 0xFC00) == 0xD800 | |
+ && (*(lpStr + 1) & 0xFC00) == 0xDC00) | |
+ { | |
+ buf.code = 0x10000 | |
+ + (((*lpStr & 0x3FF) << 10) | |
+ | *(lpStr + 1) & 0x3FF); | |
+ lpStr++; | |
+ } | |
+ else | |
+ buf.code = *(lpStr++); | |
+#else | |
+ if (IsDBCSLeadByteEx (w32_keyboard_codepage, *lpStr)) { | |
+ if (!lpStr[1] || | |
+ !MultiByteToWideChar (w32_keyboard_codepage, 0, | |
+ lpStr, 2, &code, 1)) { | |
+ lpStr++; | |
+ continue; | |
+ } | |
+ lpStr += 2; | |
+ } else { | |
+ if (!MultiByteToWideChar (w32_keyboard_codepage, 0, | |
+ lpStr++, 1, &code, 1)) | |
+ continue; | |
+ } | |
+ buf.code = code; | |
+ buf.kind = buf.code < 0x80 ? | |
+ ASCII_KEYSTROKE_EVENT : MULTIBYTE_CHAR_KEYSTROKE_EVENT;; | |
+#endif | |
+ kbd_buffer_store_event (&buf); | |
+ } | |
+ else | |
+ { | |
+ buf.kind = NON_ASCII_KEYSTROKE_EVENT; | |
+ buf.code = VK_COMPEND; | |
+ kbd_buffer_store_event (&buf); | |
+ break; | |
+ } | |
+ } | |
+ HeapFree (GetProcessHeap (), 0, (LPVOID) hw32_ime_string); | |
+ } | |
+ } | |
+ break; | |
+ | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+ case WM_MULE_IME_DEL_RANGE: | |
+ del_range ((ptrdiff_t) msg.msg.wParam, (ptrdiff_t) msg.msg.lParam); | |
+ Fgoto_char (make_number (msg.msg.wParam)); | |
+ redisplay (); | |
+ break; | |
+ | |
+ case WM_MULE_IME_SET_FONT: | |
+ w32_set_ime_logfont (msg.msg.hwnd, (struct frame *) msg.msg.wParam); | |
+ break; | |
+#endif | |
+ | |
+#endif /* USE_W32_IME */ | |
+ | |
default: | |
/* Check for messages registered at runtime. */ | |
if (msg.msg.message == msh_mousewheel) | |
@@ -5274,7 +5379,12 @@ | |
w32_system_caret_hdr_height = WINDOW_HEADER_LINE_HEIGHT (w); | |
w32_system_caret_mode_height = WINDOW_MODE_LINE_HEIGHT (w); | |
+#ifdef USE_W32_IME | |
+ if (f && f == FRAME_DISPLAY_INFO (f)->x_highlight_frame) | |
+ PostMessage (hwnd, WM_MULE_IMM_SET_CONVERSION_WINDOW, (WPARAM) f, 0); | |
+#else | |
PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0); | |
+#endif | |
/* If the size of the active cursor changed, destroy the old | |
system caret. */ | |
@@ -6563,6 +6673,9 @@ | |
vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border | |
= GetSystemMetrics (SM_CYVSCROLL); | |
} | |
+#ifdef USE_W32_IME | |
+ w32_ime_control_init(); | |
+#endif /* USE_W32_IME */ | |
} | |
void | |
--- ./src/w32term.h.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/w32term.h 2015-04-11 07:27:30.743128300 +0900 | |
@@ -569,6 +569,8 @@ | |
#endif /* WM_MOUSEHWHEEL */ | |
#ifndef WM_APPCOMMAND | |
#define WM_APPCOMMAND 0x319 | |
+#endif | |
+#ifndef GET_APPCOMMAND_LPARAM | |
#define GET_APPCOMMAND_LPARAM(lParam) (HIWORD(lParam) & 0x7fff) | |
#endif | |
#ifndef WM_UNICHAR | |
@@ -605,14 +607,128 @@ | |
#define WM_EMACS_FILENOTIFY (WM_EMACS_START + 23) | |
#define WM_EMACS_END (WM_EMACS_START + 24) | |
-#define WND_FONTWIDTH_INDEX (0) | |
-#define WND_LINEHEIGHT_INDEX (4) | |
-#define WND_BORDER_INDEX (8) | |
-#define WND_SCROLLBAR_INDEX (12) | |
-#define WND_BACKGROUND_INDEX (16) | |
-#define WND_LAST_INDEX (20) | |
+#ifdef CYGWIN | |
+#undef USE_W32_CALL_LISP_THREAD | |
+#endif | |
+ | |
+#ifdef USE_W32_IME | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+#undef IME_UNICODE | |
+#define IME_UNICODE | |
+#endif | |
+ | |
+#ifndef VK_KANJI | |
+#define VK_KANJI 0x19 | |
+#endif | |
+#ifndef VK_KANA | |
+#define VK_KANA 0x15 | |
+#endif | |
+#define VK_COMPEND 0x1A | |
+ | |
+#ifdef RECONVERSION | |
+#ifndef WM_IME_REQUEST | |
+#define WM_IME_REQUEST 0x288 | |
+#endif | |
+#ifndef IMR_COMPOSITIONWINDOW | |
+#define IMR_COMPOSITIONWINDOW 0x0001 | |
+#endif | |
+#ifndef IMR_CANDIDATEWINDOW | |
+#define IMR_CANDIDATEWINDOW 0x0002 | |
+#endif | |
+#ifdef IMR_COMPOSITIONFONT | |
+#define IMR_COMPOSITIONFONT 0x0003 | |
+#endif | |
+#ifndef IMR_RECONVERTSTRING | |
+#define IMR_RECONVERTSTRING 0x0004 | |
+#endif | |
+#ifndef IMR_CONFIRMRECONVERTSTRING | |
+#define IMR_CONFIRMRECONVERTSTRING 0x0005 | |
+#endif | |
+#endif | |
+#ifndef IME_PROP_COMPLETE_ON_UNSELECT | |
+#define IME_PROP_COMPLETE_ON_UNSELECT 0x00100000 | |
+#endif | |
+#ifndef SCS_CAP_SETRECONVERTSTRING | |
+#define SCS_CAP_SETRECONVERTSTRING 0x00000004 | |
+#endif | |
+ | |
+/* For internal communications | |
+ from window procedure to event loop. */ | |
+#define WM_MULE_IME_REPORT (WM_USER+2200) | |
+#define WM_MULE_IME_STATUS (WM_USER+2201) | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
+#define WM_MULE_IME_DEL_RANGE (WM_USER+2202) | |
+#define WM_MULE_IME_SET_FONT (WM_USER+2203) | |
+#endif | |
+ | |
+/* For internal communications | |
+ from main thread to window procedure. */ | |
+#define WM_MULE_IMM_MESSAGE_START (WM_USER+2300) | |
+#define WM_MULE_IMM_SET_STATUS (WM_USER+2300) | |
+#define WM_MULE_IMM_GET_STATUS (WM_USER+2301) | |
+#if 0 | |
+#define WM_MULE_IMM_DEAL_WITH_CONTEXT (WM_USER+2302) | |
+#define WM_MULE_IMM_SET_COMPOSITION_STRING (WM_USER+2303) | |
+#endif | |
+#define WM_MULE_IMM_GET_COMPOSITION_STRING (WM_USER+2304) | |
+#define WM_MULE_IMM_SET_MODE (WM_USER+2305) | |
+#if 0 | |
+#define WM_MULE_IMM_NOTIFY (WM_USER+2310) | |
+#define WM_MULE_IMM_GET_UNDETERMINED_STRING_LENGTH (WM_USER+2320) | |
+#endif | |
+#define WM_MULE_IMM_SET_IMEFONT (WM_USER+2311) | |
+#define WM_MULE_IMM_SET_CONVERSION_WINDOW (WM_USER+2312) | |
+ | |
+#define WM_MULE_IMM_PERFORM_RECONVERSION (WM_USER+2320) | |
-#define WND_EXTRA_BYTES (WND_LAST_INDEX) | |
+#define WM_MULE_IMM_MESSAGE_END (WM_USER+2399) | |
+#define MESSAGE_IMM_COM_P(message) \ | |
+ (((message) >= WM_MULE_IMM_MESSAGE_START) && \ | |
+ ((message) <= WM_MULE_IMM_MESSAGE_END)) | |
+ | |
+#ifdef RECONVERSION | |
+#ifndef HAVE_RECONVERTSTRING | |
+typedef struct tagRECONVERTSTRING { | |
+ DWORD dwSize; | |
+ DWORD dwVersion; | |
+ DWORD dwStrLen; | |
+ DWORD dwStrOffset; | |
+ DWORD dwCompStrLen; | |
+ DWORD dwCompStrOffset; | |
+ DWORD dwTargetStrLen; | |
+ DWORD dwTargetStrOffset; | |
+} RECONVERTSTRING, *PRECONVERTSTRING; | |
+#endif | |
+#ifndef SCS_SETRECONVERTSTRING | |
+#define SCS_SETRECONVERTSTRING 0x00010000 | |
+#endif | |
+#ifndef SCS_QUERYRECONVERTSTRING | |
+#define SCS_QUERYRECONVERTSTRING 0x00020000 | |
+#endif | |
+#endif /* RECONVERSION */ | |
+#endif /* USE_W32_IME */ | |
+ | |
+#pragma pack(push, 4) | |
+struct wnd_extra { | |
+ LONG fontwidth; | |
+ LONG lineheight; | |
+ LONG border; | |
+ LONG scrollbar; | |
+ LONG background; | |
+}; | |
+#pragma pack(pop) | |
+ | |
+#ifndef offsetof | |
+#define offsetof(s,m) (size_t)&(((s *)0)->m) | |
+#endif | |
+#define WND_FONTWIDTH_INDEX offsetof(struct wnd_extra, fontwidth) | |
+#define WND_LINEHEIGHT_INDEX offsetof(struct wnd_extra, lineheight) | |
+#define WND_BORDER_INDEX offsetof(struct wnd_extra, border) | |
+#define WND_SCROLLBAR_INDEX offsetof(struct wnd_extra, scrollbar) | |
+#define WND_BACKGROUND_INDEX offsetof(struct wnd_extra, background) | |
+#define WND_LAST_INDEX (sizeof(struct wnd_extra)) | |
+ | |
+#define WND_EXTRA_BYTES (WND_LAST_INDEX) | |
extern DWORD dwWindowsThreadId; | |
extern HANDLE hWindowsThread; | |
@@ -794,3 +910,8 @@ | |
#ifdef CYGWIN | |
extern int w32_message_fd; | |
#endif /* CYGWIN */ | |
+ | |
+#ifdef USE_W32_IME | |
+extern void w32_set_ime_logfont (HWND, struct frame *); | |
+extern void w32_ime_control_init (void); | |
+#endif /* USE_W32_IME */ | |
--- ./src/w32xfns.c.orig 2015-02-02 02:27:17.000000000 +0900 | |
+++ ./src/w32xfns.c 2015-04-11 07:27:30.750130200 +0900 | |
@@ -178,12 +178,30 @@ | |
/* The while loop takes care of multiple sets */ | |
+#if !defined(USE_W32_CALL_LISP_THREAD) | |
while (!nQueue && bWait) | |
{ | |
leave_crit (); | |
WaitForSingleObject (input_available, INFINITE); | |
enter_crit (); | |
} | |
+#else | |
+ if (bWait) | |
+ while (!nQueue) | |
+ { | |
+ leave_crit (); | |
+ while (WaitForSingleObjectEx | |
+ (input_available, INFINITE, TRUE) == WAIT_IO_COMPLETION) | |
+ ; | |
+ enter_crit (); | |
+ } | |
+ else if (nQueue == 0) | |
+ { | |
+ leave_crit (); | |
+ SleepEx(0, TRUE); | |
+ enter_crit (); | |
+ } | |
+#endif | |
if (nQueue) | |
{ | |
--- ./src/window.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/window.c 2015-04-11 07:27:30.759130600 +0900 | |
@@ -132,6 +132,12 @@ | |
/* Same for window_scroll_line_based. */ | |
static EMACS_INT window_scroll_preserve_hpos; | |
static EMACS_INT window_scroll_preserve_vpos; | |
+#ifdef USE_W32_IME | |
+Lisp_Object Vset_selected_window_buffer_functions; | |
+Lisp_Object Qset_selected_window_buffer_functions; | |
+Lisp_Object Vselect_window_functions; | |
+Lisp_Object Qselect_window_functions; | |
+#endif /* USE_W32_IME */ | |
static void | |
CHECK_WINDOW_CONFIGURATION (Lisp_Object x) | |
@@ -474,6 +480,9 @@ | |
{ | |
register struct window *w; | |
struct frame *sf; | |
+#ifdef USE_W32_IME | |
+ Lisp_Object oldwin = selected_window; | |
+#endif /* USE_W32_IME */ | |
CHECK_LIVE_WINDOW (window); | |
@@ -526,6 +535,11 @@ | |
record_buffer (w->contents); | |
} | |
+#ifdef USE_W32_IME | |
+ if (!NILP (Vselect_window_functions)) | |
+ run_hook_with_args_2 (Qselect_window_functions, oldwin, window); | |
+#endif /* USE_W32_IME */ | |
+ | |
return window; | |
} | |
@@ -3561,6 +3575,18 @@ | |
set_window_buffer (window, buffer, 1, !NILP (keep_margins)); | |
+#ifdef USE_W32_IME | |
+ if (! NILP (Vset_selected_window_buffer_functions)) | |
+ { | |
+ Lisp_Object temp[4]; | |
+ temp[0] = Qset_selected_window_buffer_functions; | |
+ temp[1] = tem; | |
+ temp[2] = window; | |
+ temp[3] = buffer; | |
+ Frun_hook_with_args (4, temp); | |
+ } | |
+#endif /* USE_W32_IME */ | |
+ | |
return Qnil; | |
} | |
@@ -7247,6 +7273,10 @@ | |
Fput (Qscroll_down, Qscroll_command, Qt); | |
DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook"); | |
+#ifdef USE_W32_IME | |
+ DEFSYM (Qset_selected_window_buffer_functions, "set-selected-window-buffer-functions"); | |
+ DEFSYM (Qselect_window_functions, "select-window-functions"); | |
+#endif | |
DEFSYM (Qwindowp, "windowp"); | |
DEFSYM (Qwindow_configuration_p, "window-configuration-p"); | |
DEFSYM (Qwindow_live_p, "window-live-p"); | |
--- ./src/xdisp.c.orig 2015-04-02 16:23:06.000000000 +0900 | |
+++ ./src/xdisp.c 2015-04-11 07:27:30.776131800 +0900 | |
@@ -11683,8 +11683,24 @@ | |
/* Prepare for redisplay by updating menu-bar item lists when | |
appropriate. This can call eval. */ | |
+#ifdef USE_W32_IME | |
+static void prepare_menu_bars_0 (); | |
+static void | |
+prepare_menu_bars() | |
+{ | |
+ extern Lisp_Object Qw32_ime_buffer_switch_p; | |
+ int count = SPECPDL_INDEX (); | |
+ | |
+ specbind (Qw32_ime_buffer_switch_p, Qnil); | |
+ prepare_menu_bars_0 (); | |
+ unbind_to (count, Qnil); | |
+} | |
+static void | |
+prepare_menu_bars_0 () | |
+#else | |
static void | |
prepare_menu_bars (void) | |
+#endif | |
{ | |
bool all_windows = windows_or_buffers_changed || update_mode_lines; | |
bool some_windows = REDISPLAY_SOME_P (); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment