(require 'quail)
(define-ccl-program utf-8-ccl-encode
`(4 (if (r0 < ?\x80)
((write r0))
(if (r0 < #x800)
((write ((r0 >> 6) | ?\xC0))
(write ((r0 & ?\x3F) | ?\x80)))
(if (r0 < #x10000)
((write ((r0 >> 12) | ?\xE0))
(write (((r0 >> 6) & ?\x3F) | ?\x80))
(write ((r0 & ?\x3F) | ?\x80)))
(if (r0 < #x200000)
((write ((r0 >> 18) | ?\xF0))
(write (((r0 >> 12) & ?\x3F) | ?\x80))
(write (((r0 >> 6) & ?\x3F) | ?\x80))
(write ((r0 & ?\x3F) | ?\x80)))
(if (r0 < #x4000000)
((write ((r0 >> 24) | ?\xF8))
(write (((r0 >> 18) & ?\x3F) | ?\x80))
(write (((r0 >> 12) & ?\x3F) | ?\x80))
(write (((r0 >> 6) & ?\x3F) | ?\x80))
(write ((r0 & ?\x3F) | ?\x80)))
((write ((r0 >> 30) | ?\xFC))
(write (((r0 >> 24) & ?\x3F) | ?\x80))
(write (((r0 >> 18) & ?\x3F) | ?\x80))
(write (((r0 >> 12) & ?\x3F) | ?\x80))
(write (((r0 >> 6) & ?\x3F) | ?\x80))
(write ((r0 & ?\x3F) | ?\x80))))))))))
(defun ucs-input-insert-char (char)
(insert char)
(move-overlay quail-overlay (overlay-start quail-overlay) (point)))
(defun ucs-input-method (key)
(if (or buffer-read-only
(and (/= key ?U) (/= key ?u)))
(list key)
(quail-setup-overlays nil)
(ucs-input-insert-char key)
(let ((modified-p (buffer-modified-p))
(buffer-undo-list t)
(input-method-function nil)
(echo-keystrokes 0)
(help-char nil)
(events (list key))
(str " "))
(unwind-protect
(catch 'non-digit
(progn
(dotimes (i 4)
(let ((seq (read-key-sequence nil))
key)
(if (and (stringp seq)
(= 1 (length seq))
(setq key (aref seq 0))
(memq key '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a
?b ?c ?d ?e ?f ?A ?B ?C ?D ?E ?F)))
(progn
(push key events)
(ucs-input-insert-char key))
(quail-delete-region)
(throw 'non-digit (append (reverse events)
(listify-key-sequence seq))))))
(quail-delete-region)
(let* ((n (string-to-number (apply 'string
(cdr (nreverse events)))
16))
(c (decode-char 'ucs n)))
(if c
(list c)
(error "Character U+%04X is not yet supported" n)))))
(quail-delete-overlays)
(set-buffer-modified-p modified-p)
(run-hooks 'input-method-after-insert-chunk-hook)))))
(defun ucs-input-activate (&optional arg)
"Activate UCS input method.
With arg, activate UCS input method if and only if arg is positive.
While this input method is active, the variable
`input-method-function' is bound to the function `ucs-input-method'."
(if (and arg
(< (prefix-numeric-value arg) 0))
(unwind-protect
(progn
(quail-hide-guidance)
(quail-delete-overlays)
(setq describe-current-input-method-function nil))
(kill-local-variable 'input-method-function))
(setq inactivate-current-input-method-function 'ucs-input-inactivate)
(setq describe-current-input-method-function 'ucs-input-help)
(quail-delete-overlays)
(if (eq (selected-window) (minibuffer-window))
(add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer))
(set (make-local-variable 'input-method-function)
'ucs-input-method)))
(defun ucs-input-inactivate ()
"Inactivate UCS input method."
(interactive)
(ucs-input-activate -1))
(defun ucs-input-help ()
(interactive)
(with-output-to-temp-buffer "*Help*"
(princ "\
Input method: ucs (mode line indicator:U+)
Input as Unicode: U<hex> or u<hex>, where <hex> is a four-digit hex number.")))
(provide 'uni-input)