OSDN Git Service

import the last version of the original mayu extracted by following command:
authorU-i7\gimy <gimy@users.sourceforge.jp>
Thu, 11 Jun 2009 13:47:28 +0000 (22:47 +0900)
committerU-i7\gimy <gimy@users.sourceforge.jp>
Thu, 11 Jun 2009 13:47:28 +0000 (22:47 +0900)
cvs -d:pserver:anonymous@cvs1.sourceforge.net:/cvsroot/mayu export -D "2009-06-11" mayu

141 files changed:
.cvsignore [new file with mode: 0644]
104.mayu [new file with mode: 0644]
104on109.mayu [new file with mode: 0644]
109.mayu [new file with mode: 0644]
109on104.mayu [new file with mode: 0644]
Makefile [new file with mode: 0644]
array.h [new file with mode: 0644]
compiler_specific.h [new file with mode: 0644]
compiler_specific_func.cpp [new file with mode: 0644]
compiler_specific_func.h [new file with mode: 0644]
contrib/109onAX.mayu [new file with mode: 0644]
contrib/98x1.mayu [new file with mode: 0644]
contrib/DVORAKon109.mayu [new file with mode: 0644]
contrib/ax.mayu [new file with mode: 0644]
contrib/dvorak.mayu [new file with mode: 0644]
contrib/dvorak109.mayu [new file with mode: 0644]
contrib/keitai.mayu [new file with mode: 0644]
contrib/mayu-settings.txt [new file with mode: 0644]
d/.cvsignore [new file with mode: 0755]
d/Makefile [new file with mode: 0644]
d/README.txt [new file with mode: 0644]
d/SOURCES [new file with mode: 0644]
d/i386/.cvsignore [new file with mode: 0755]
d/i386/mayud.sys [new file with mode: 0755]
d/ioctl.h [new file with mode: 0755]
d/keyque.c [new file with mode: 0644]
d/log.c [new file with mode: 0755]
d/log.h [new file with mode: 0755]
d/mayud.c [new file with mode: 0644]
d/nt4/.cvsignore [new file with mode: 0755]
d/nt4/Makefile [new file with mode: 0644]
d/nt4/SOURCES [new file with mode: 0644]
d/nt4/i386/.cvsignore [new file with mode: 0755]
d/nt4/i386/mayudnt4.sys [new file with mode: 0755]
d/nt4/mayudnt4.c [new file with mode: 0644]
d/rescue/.cvsignore [new file with mode: 0755]
d/rescue/Makefile [new file with mode: 0755]
d/rescue/SOURCES [new file with mode: 0755]
d/rescue/i386/.cvsignore [new file with mode: 0755]
d/rescue/i386/mayudrsc.sys [new file with mode: 0755]
d/rescue/mayudrsc.c [new file with mode: 0755]
d/test.reg [new file with mode: 0644]
default.mayu [new file with mode: 0644]
dlgeditsetting.cpp [new file with mode: 0644]
dlgeditsetting.h [new file with mode: 0644]
dlginvestigate.cpp [new file with mode: 0644]
dlginvestigate.h [new file with mode: 0644]
dlglog.cpp [new file with mode: 0644]
dlglog.h [new file with mode: 0644]
dlgsetting.cpp [new file with mode: 0644]
dlgsetting.h [new file with mode: 0644]
dlgversion.cpp [new file with mode: 0644]
dlgversion.h [new file with mode: 0644]
doc++-header.html [new file with mode: 0644]
doc++.conf [new file with mode: 0644]
doc/CONTENTS-ja.html [new file with mode: 0644]
doc/CUSTOMIZE-ja.html [new file with mode: 0644]
doc/MANUAL-ja.html [new file with mode: 0644]
doc/README-ja.html [new file with mode: 0644]
doc/README.css [new file with mode: 0644]
doc/banner-ja.gif [new file with mode: 0755]
doc/edit-setting-ja.png [new file with mode: 0644]
doc/investigate-ja.png [new file with mode: 0644]
doc/log-ja.png [new file with mode: 0644]
doc/menu-ja.png [new file with mode: 0644]
doc/pause-ja.png [new file with mode: 0644]
doc/setting-ja.png [new file with mode: 0644]
doc/syntax.txt [new file with mode: 0644]
doc/target.png [new file with mode: 0644]
doc/version-ja.png [new file with mode: 0644]
dot.mayu [new file with mode: 0644]
driver.h [new file with mode: 0644]
emacsedit.mayu [new file with mode: 0644]
engine.cpp [new file with mode: 0644]
engine.h [new file with mode: 0644]
errormessage.h [new file with mode: 0644]
focus.cpp [new file with mode: 0644]
focus.h [new file with mode: 0644]
function.cpp [new file with mode: 0644]
function.h [new file with mode: 0644]
hook.cpp [new file with mode: 0644]
hook.h [new file with mode: 0644]
keyboard.cpp [new file with mode: 0644]
keyboard.h [new file with mode: 0644]
keymap.cpp [new file with mode: 0644]
keymap.h [new file with mode: 0644]
layoutmanager.cpp [new file with mode: 0644]
layoutmanager.h [new file with mode: 0644]
mayu-common.mak [new file with mode: 0644]
mayu-mode.el [new file with mode: 0644]
mayu-vc.mak [new file with mode: 0644]
mayu.cpp [new file with mode: 0644]
mayu.h [new file with mode: 0644]
mayu.rc [new file with mode: 0644]
mayuipc.h [new file with mode: 0644]
mayurc.h [new file with mode: 0644]
misc.h [new file with mode: 0644]
msgstream.h [new file with mode: 0644]
multithread.h [new file with mode: 0644]
parser.cpp [new file with mode: 0644]
parser.h [new file with mode: 0644]
r/mayu.ico [new file with mode: 0644]
r/mayudisabled.ico [new file with mode: 0644]
r/mayufile.ico [new file with mode: 0644]
r/target.cur [new file with mode: 0644]
registry.cpp [new file with mode: 0644]
registry.h [new file with mode: 0644]
s/.cvsignore [new file with mode: 0644]
s/Makefile [new file with mode: 0644]
s/afxres.h [new file with mode: 0644]
s/installer.cpp [new file with mode: 0644]
s/installer.h [new file with mode: 0644]
s/setup-common.mak [new file with mode: 0644]
s/setup-vc.mak [new file with mode: 0644]
s/setup.cpp [new file with mode: 0644]
s/setup.rc [new file with mode: 0644]
s/setuprc.h [new file with mode: 0644]
s/stub/afxres.h [new file with mode: 0755]
setting.cpp [new file with mode: 0644]
setting.h [new file with mode: 0644]
stringtool.cpp [new file with mode: 0644]
stringtool.h [new file with mode: 0644]
target.cpp [new file with mode: 0644]
target.h [new file with mode: 0644]
tools/checkversion [new file with mode: 0755]
tools/dos2unix [new file with mode: 0755]
tools/geniexpress [new file with mode: 0755]
tools/getcvsfiles [new file with mode: 0755]
tools/linkcheck [new file with mode: 0755]
tools/makedepend [new file with mode: 0755]
tools/makefunc [new file with mode: 0755]
tools/unix2dos [new file with mode: 0755]
ts4mayu/Makefile [new file with mode: 0755]
ts4mayu/thumbsense.mayu [new file with mode: 0755]
ts4mayu/ts4mayu.cpp [new file with mode: 0755]
ts4mayu/ts4mayu.def [new file with mode: 0755]
vc.mak [new file with mode: 0644]
vkeytable.cpp [new file with mode: 0644]
vkeytable.h [new file with mode: 0644]
windowstool.cpp [new file with mode: 0644]
windowstool.h [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..d0a907c
--- /dev/null
@@ -0,0 +1,10 @@
+functions.h
+*.aps
+*.opt
+*.tgz
+*.pdb
+mayu-*-src.tar.bz2
+outvc6_*
+outvc7_*
+outvc71_*
+outbcc_*
diff --git a/104.mayu b/104.mayu
new file mode 100644 (file)
index 0000000..a4b8bdf
--- /dev/null
+++ b/104.mayu
@@ -0,0 +1,263 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# MADO TSUKAI NO YUUTSU - 104.mayu
+# Copyright (C) 1999-2005, TAGA Nayuta <nayuta@users.sourceforge.net>
+#
+
+define KBD101
+define KBD102
+define KBD104
+define KBD105
+define KBD107
+define KBD108
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# 101/102/104/105/107/108 US keyboard definition
+#
+
+def key Esc Escape                     =    0x01
+def key _1                             =    0x02 # 1!
+def key _2                             =    0x03 # 2@
+def key _3                             =    0x04 # 3#
+def key _4                             =    0x05 # 4$
+def key _5                             =    0x06 # 5%
+def key _6                             =    0x07 # 6^
+def key _7                             =    0x08 # 7&
+def key _8                             =    0x09 # 8*
+def key _9                             =    0x0a # 9(
+def key _0                             =    0x0b # 0)
+def key HyphenMinus Hyphen Minus       =    0x0c # -_
+def key EqualsSign Equal               =    0x0d # =+
+def key BackSpace BS Back              =    0x0e
+def key Tab                            =    0x0f
+def key Q                              =    0x10
+def key ScanPreviousTrack PreviousTrack        = E0-0x10 # (Media Player)
+def key W                              =    0x11
+def key E                              =    0x12
+def key R                              =    0x13
+def key T                              =    0x14
+def key Y                              =    0x15
+def key U                              =    0x16
+def key I                              =    0x17
+def key O                              =    0x18
+def key P                              =    0x19
+def key ScanNextTrack NextTrack                = E0-0x19 # (Media Player)
+def key LeftSquareBracket OpenBracket  =    0x1a # [{
+def key RightSquareBracket CloseBracket        =    0x1b # ]}
+def key Enter Return                   =    0x1c
+def key NumEnter NumReturn             = E0-0x1c
+def key LeftControl LControl LCtrl     =    0x1d
+def key RightControl RControl RCtrl    = E0-0x1d
+def key Pause                          = E1-0x1d 0x45 # Pause
+def key A                              =    0x1e
+def key S                              =    0x1f
+def key D                              =    0x20
+def key Mute                           = E0-0x20 # (Media Player)
+def key F                              =    0x21
+def key ALCalculator                   = E0-0x21 # (N/A) Calculator 
+def key G                              =    0x22
+def key Play/Pause                     = E0-0x22 # (Media Player)
+def key H                              =    0x23
+def key J                              =    0x24
+def key Stop                           = E0-0x24 # (Media Player)
+def key K                              =    0x25
+def key L                              =    0x26
+def key Semicolon                      =    0x27 # ;:
+def key Apostrophe Quote               =    0x28 # '"
+def key GraveAccent BackQuote          =    0x29 # `~
+def key LeftShift LShift               =    0x2a
+# def ignore                           = E0-0x2a # what is this? (ignore)
+def key ReverseSolidus BackSlash       =    0x2b # \|
+def key Z                              =    0x2c
+def key X                              =    0x2d
+def key C                              =    0x2e
+def key VolumeDecrement VolumeDown     = E0-0x2e
+def key V                              =    0x2f
+def key B                              =    0x30
+def key VolumeIncrement VolumeUp       = E0-0x30
+def key N                              =    0x31
+def key M                              =    0x32
+def key ACHome Internet                        = E0-0x32 # (Internet Explorer)
+def key Comma                          =    0x33 # ,<
+def key FullStop Period                        =    0x34 # .>
+def key Solidus Slash                  =    0x35 # /?
+def key NumSolidus NumSlash            = E0-0x35 # Numpad /
+def key RightShift RShift              =    0x36
+def key NumAsterisk NumMultiply                =    0x37 # Numpad *
+def key PrintScreen Snapshot           = E0-0x37
+def key LeftAlt LAlt LMenu             =    0x38
+def key RightAlt RAlt RMenu            = E0-0x38
+def key Space                          =    0x39
+def key CapsLock Capital Caps          =    0x3a # CapsLock
+def key F1                             =    0x3b
+def key F2                             =    0x3c
+def key F3                             =    0x3d
+def key F4                             =    0x3e
+def key F5                             =    0x3f
+def key F6                             =    0x40
+def key F7                             =    0x41
+def key F8                             =    0x42
+def key F9                             =    0x43
+def key F10                            =    0x44
+def key NumLock                                =    0x45
+def key ScrollLock Scroll              =    0x46
+def key Break                          = E0-0x46 # Break
+def key Num7                           =    0x47 # Numpad 7
+def key Home                           = E0-0x47
+def key Num8                           =    0x48 # Numpad 8
+def key Up                             = E0-0x48
+def key Num9                           =    0x49 # Numpad 9
+def key PageUp Prior                   = E0-0x49
+def key NumHyphenMinus NumMinus                =    0x4a # Numpad -
+def key Num4                           =    0x4b # Numpad 4
+def key Left                           = E0-0x4b
+def key Num5                           =    0x4c # Numpad 5
+def key Num6                           =    0x4d # Numpad 6
+def key Right                          = E0-0x4d
+def key NumPlusSign NumPlus            =    0x4e # Numpad +
+def key Num1                           =    0x4f # Numpad 1
+def key End                            = E0-0x4f
+def key Num2                           =    0x50
+def key Down                           = E0-0x50
+def key Num3                           =    0x51
+def key PageDown Next                  = E0-0x51
+def key Num0                           =    0x52
+def key Insert                         = E0-0x52
+def key NumFullStop NumPeriod          =    0x53 # Numpad .
+def key Delete Del                     = E0-0x53
+def key SysRq                          =    0x54
+def key Less                           =    0x56 # < >
+def key F11                            =    0x57
+def key F12                            =    0x58
+def key LeftWindows LWindows LWin      = E0-0x5b
+def key RightWindows RWindows RWin     = E0-0x5c
+def key Applications Apps              = E0-0x5d
+def key PowerOff                       = E0-0x5e # Power off    (107 keyboard)
+def key Sleep                          = E0-0x5f # Sleep        (107 keyboard)
+def key WakeUp                         = E0-0x63 # Wake up      (107 keyboard)
+def key ACSearch                       = E0-0x65 # (Internet Explorer)
+def key ACBookmarks                    = E0-0x66 # (Internet Explorer)
+def key ACRefresh                      = E0-0x67 # (Internet Explorer)
+def key ACStop                         = E0-0x68 # (Internet Explorer)
+def key ACForward                      = E0-0x69 # (Internet Explorer)
+def key ACBack                         = E0-0x6a # (Internet Explorer)
+def key ALLocalBrowser                 = E0-0x6b # (N/A) My Computer 
+def key ALEmailReader Email            = E0-0x6c
+def key ALConsumerControlConfiguration = E0-0x6d # (N/A) Media Player
+
+
+
+
+
+# def overflow                         =    0xff # overflow (ignore)
+
+def sync                               =    0x7e # scan code used by &Sync
+
+def mod Shift  = LShift RShift
+def mod Alt    = LAlt RAlt
+def mod Control        = LControl RControl
+def mod Windows        = LWindows RWindows
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# define some key sequence
+#
+
+keyseq $ToggleIME              = A-BackQuote
+keyseq $CapsLock               = CapsLock
+
+keyseq $SPACE                  = ~S-*Space                     #  
+keyseq $EXCLAMATION_MARK       =  S-*_1                        # !
+keyseq $QUOTATION_MARK         =  S-*Apostrophe                # "
+keyseq $NUMBER_SIGN            =  S-*_3                        # #
+keyseq $DOLLAR_SIGN            =  S-*_4                        # $
+keyseq $PERCENT_SIGN           =  S-*_5                        # %
+keyseq $AMPERSAND              =  S-*_7                        # &
+keyseq $APOSTROPHE             = ~S-*Apostrophe                # '
+keyseq $LEFT_PARENTHESIS       =  S-*_9                        # (
+keyseq $RIGHT_PARENTHESIS      =  S-*_0                        # )
+keyseq $ASTERISK               =  S-*_8                        # *
+keyseq $PLUS_SIGN              =  S-*EqualsSign                # +
+keyseq $COMMA                  = ~S-*Comma                     # ,
+keyseq $HYPHEN-MINUS           = ~S-*HyphenMinus               # -
+keyseq $FULL_STOP              = ~S-*FullStop                  # .
+keyseq $SOLIDUS                        = ~S-*Solidus                   # /
+keyseq $DIGIT_ZERO             = ~S-*_0                        # 0
+keyseq $DIGIT_ONE              = ~S-*_1                        # 1
+keyseq $DIGIT_TWO              = ~S-*_2                        # 2
+keyseq $DIGIT_THREE            = ~S-*_3                        # 3
+keyseq $DIGIT_FOUR             = ~S-*_4                        # 4
+keyseq $DIGIT_FIVE             = ~S-*_5                        # 5
+keyseq $DIGIT_SIX              = ~S-*_6                        # 6
+keyseq $DIGIT_SEVEN            = ~S-*_7                        # 7
+keyseq $DIGIT_EIGHT            = ~S-*_8                        # 8
+keyseq $DIGIT_NINE             = ~S-*_9                        # 9
+keyseq $COLON                  =  S-*Semicolon                 # :
+keyseq $SEMICOLON              = ~S-*Semicolon                 # ;
+keyseq $LESS-THAN_SIGN         =  S-*Comma                     # <
+keyseq $EQUALS_SIGN            = ~S-*EqualsSign                # =
+keyseq $GREATER-THAN_SIGN      =  S-*FullStop                  # >
+keyseq $QUESTION_MARK          =  S-*Solidus                   # ?
+keyseq $COMMERCIAL_AT          =  S-*_2                        # @
+keyseq $LATIN_CAPITAL_LETTER_A =  S-*A                         # A
+keyseq $LATIN_CAPITAL_LETTER_B =  S-*B                         # B
+keyseq $LATIN_CAPITAL_LETTER_C =  S-*C                         # C
+keyseq $LATIN_CAPITAL_LETTER_D =  S-*D                         # D
+keyseq $LATIN_CAPITAL_LETTER_E =  S-*E                         # E
+keyseq $LATIN_CAPITAL_LETTER_F =  S-*F                         # F
+keyseq $LATIN_CAPITAL_LETTER_G =  S-*G                         # G
+keyseq $LATIN_CAPITAL_LETTER_H =  S-*H                         # H
+keyseq $LATIN_CAPITAL_LETTER_I =  S-*I                         # I
+keyseq $LATIN_CAPITAL_LETTER_J =  S-*J                         # J
+keyseq $LATIN_CAPITAL_LETTER_K =  S-*K                         # K
+keyseq $LATIN_CAPITAL_LETTER_L =  S-*L                         # L
+keyseq $LATIN_CAPITAL_LETTER_M =  S-*M                         # M
+keyseq $LATIN_CAPITAL_LETTER_N =  S-*N                         # N
+keyseq $LATIN_CAPITAL_LETTER_O =  S-*O                         # O
+keyseq $LATIN_CAPITAL_LETTER_P =  S-*P                         # P
+keyseq $LATIN_CAPITAL_LETTER_Q =  S-*Q                         # Q
+keyseq $LATIN_CAPITAL_LETTER_R =  S-*R                         # R
+keyseq $LATIN_CAPITAL_LETTER_S =  S-*S                         # S
+keyseq $LATIN_CAPITAL_LETTER_T =  S-*T                         # T
+keyseq $LATIN_CAPITAL_LETTER_U =  S-*U                         # U
+keyseq $LATIN_CAPITAL_LETTER_V =  S-*V                         # V
+keyseq $LATIN_CAPITAL_LETTER_W =  S-*W                         # W
+keyseq $LATIN_CAPITAL_LETTER_X =  S-*X                         # X
+keyseq $LATIN_CAPITAL_LETTER_Y =  S-*Y                         # Y
+keyseq $LATIN_CAPITAL_LETTER_Z =  S-*Z                         # Z
+keyseq $LEFT_SQUARE_BRACKET    = ~S-*LeftSquareBracket         # [
+keyseq $REVERSE_SOLIDUS                = ~S-*ReverseSolidus            # \
+keyseq $RIGHT_SQUARE_BRACKET   = ~S-*RightSquareBracket        # ]
+keyseq $CIRCUMFLEX_ACCENT      =  S-*_6                        # ^
+keyseq $LOW_LINE               =  S-*HyphenMinus               # _
+keyseq $GRAVE_ACCENT           = ~S-*GraveAccent               # `
+keyseq $LATIN_SMALL_LETTER_A   = ~S-*A                         # a
+keyseq $LATIN_SMALL_LETTER_B   = ~S-*B                         # b
+keyseq $LATIN_SMALL_LETTER_C   = ~S-*C                         # c
+keyseq $LATIN_SMALL_LETTER_D   = ~S-*D                         # d
+keyseq $LATIN_SMALL_LETTER_E   = ~S-*E                         # e
+keyseq $LATIN_SMALL_LETTER_F   = ~S-*F                         # f
+keyseq $LATIN_SMALL_LETTER_G   = ~S-*G                         # g
+keyseq $LATIN_SMALL_LETTER_H   = ~S-*H                         # h
+keyseq $LATIN_SMALL_LETTER_I   = ~S-*I                         # i
+keyseq $LATIN_SMALL_LETTER_J   = ~S-*J                         # j
+keyseq $LATIN_SMALL_LETTER_K   = ~S-*K                         # k
+keyseq $LATIN_SMALL_LETTER_L   = ~S-*L                         # l
+keyseq $LATIN_SMALL_LETTER_M   = ~S-*M                         # m
+keyseq $LATIN_SMALL_LETTER_N   = ~S-*N                         # n
+keyseq $LATIN_SMALL_LETTER_O   = ~S-*O                         # o
+keyseq $LATIN_SMALL_LETTER_P   = ~S-*P                         # p
+keyseq $LATIN_SMALL_LETTER_Q   = ~S-*Q                         # q
+keyseq $LATIN_SMALL_LETTER_R   = ~S-*R                         # r
+keyseq $LATIN_SMALL_LETTER_S   = ~S-*S                         # s
+keyseq $LATIN_SMALL_LETTER_T   = ~S-*T                         # t
+keyseq $LATIN_SMALL_LETTER_U   = ~S-*U                         # u
+keyseq $LATIN_SMALL_LETTER_V   = ~S-*V                         # v
+keyseq $LATIN_SMALL_LETTER_W   = ~S-*W                         # w
+keyseq $LATIN_SMALL_LETTER_X   = ~S-*X                         # x
+keyseq $LATIN_SMALL_LETTER_Y   = ~S-*Y                         # y
+keyseq $LATIN_SMALL_LETTER_Z   = ~S-*Z                         # z
+keyseq $LEFT_CURLY_BRACKET     =  S-*LeftSquareBracket         # {
+keyseq $VERTICAL_LINE          =  S-*ReverseSolidus            # |
+keyseq $RIGHT_CURLY_BRACKET    =  S-*RightSquareBracket        # }
+keyseq $TILDE                  =  S-*GraveAccent               # ~
diff --git a/104on109.mayu b/104on109.mayu
new file mode 100644 (file)
index 0000000..9fc2f80
--- /dev/null
@@ -0,0 +1,36 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - 104on109.mayu
+# Copyright (C) 1999-2005, TAGA Nayuta <nayuta@users.sourceforge.net>
+#
+
+define KBD104on109
+
+def subst ~S-*\94¼\8ap/\91S\8ap                = $GRAVE_ACCENT
+def subst  S-*\94¼\8ap/\91S\8ap                = $TILDE
+def subst  A-\94¼\8ap/\91S\8ap         = $ToggleIME
+def subst  S-*_2               = $COMMERCIAL_AT
+def subst  S-*_6               = $CIRCUMFLEX_ACCENT
+def subst  S-*_7               = $AMPERSAND
+def subst  S-*_8               = $ASTERISK
+def subst  S-*_9               = $LEFT_PARENTHESIS
+def subst  S-*_0               = $RIGHT_PARENTHESIS
+def subst  S-*Hyphen           = $LOW_LINE
+def subst ~S-*Caret            = $EQUALS_SIGN
+def subst  S-*Caret            = $PLUS_SIGN
+def subst ~S-*Atmark           = $LEFT_SQUARE_BRACKET
+def subst  S-*Atmark           = $LEFT_CURLY_BRACKET
+def subst ~S-*OpenBracket      = $RIGHT_SQUARE_BRACKET
+def subst  S-*OpenBracket      = $RIGHT_CURLY_BRACKET
+def subst ~S-*CloseBracket     = $REVERSE_SOLIDUS
+def subst  S-*CloseBracket     = $VERTICAL_LINE
+def subst  S-*Semicolon                = $COLON
+def subst ~S-*Colon            = $APOSTROPHE
+def subst  S-*Colon            = $QUOTATION_MARK
+def subst    *\96³\95Ï\8a·           = *Space
+def subst    *\95Ï\8a·             = *Space
+def subst    *\82Ð\82ç\82ª\82È         = *Space
+def subst    *\89p\90\94             = S-*\89p\90\94
+def subst *ReverseSolidus      = *RightShift
+
+keymap Global
+ mod shift += ReverseSolidus
diff --git a/109.mayu b/109.mayu
new file mode 100644 (file)
index 0000000..f8b37f8
--- /dev/null
+++ b/109.mayu
@@ -0,0 +1,316 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - 109.mayu
+# Copyright (C) 1999-2005, TAGA Nayuta <nayuta@users.sourceforge.net>
+#
+
+define KBD106
+define KBD109
+define KBD112
+
+
+
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# 109 \93ú\96{\8cê\83L\81[\83{\81[\83h\92è\8b`
+#
+
+def key Esc Escape                     =    0x01
+def key _1                             =    0x02 # 1!
+def key _2                             =    0x03 # 2"
+def key _3                             =    0x04 # 3#
+def key _4                             =    0x05 # 4$
+def key _5                             =    0x06 # 5%
+def key _6                             =    0x07 # 6&
+def key _7                             =    0x08 # 7'
+def key _8                             =    0x09 # 8(
+def key _9                             =    0x0a # 9)
+def key _0                             =    0x0b # 0
+def key HyphenMinus Hyphen Minus       =    0x0c # -=
+def key CircumflexAccent Caret         =    0x0d # ^~
+def key BackSpace BS Back              =    0x0e
+def key Tab                            =    0x0f
+def key Q                              =    0x10
+def key W                              =    0x11
+def key E                              =    0x12
+def key R                              =    0x13
+def key T                              =    0x14
+def key Y                              =    0x15
+def key U                              =    0x16
+def key I                              =    0x17
+def key O                              =    0x18
+def key P                              =    0x19
+def key CommercialAt Atmark            =    0x1a # @`
+def key LeftSquareBracket OpenBracket  =    0x1b # [{
+def key Enter Return                   =    0x1c
+def key LeftControl LControl LCtrl     =    0x1d
+def key A                              =    0x1e
+def key S                              =    0x1f
+def key D                              =    0x20
+def key F                              =    0x21
+def key G                              =    0x22
+def key H                              =    0x23
+def key J                              =    0x24
+def key K                              =    0x25
+def key L                              =    0x26
+def key Semicolon                      =    0x27 # ;+
+def key Colon                          =    0x28 # :*
+def key \94¼\8ap/\91S\8a\8a¿\8e\9a Kanji           =    0x29 # \94¼\8ap/\91S\8a\8a¿\8e\9a
+def key LeftShift LShift               =    0x2a
+def key RightSquareBracket CloseBracket        =    0x2b # ]}
+def key Z                              =    0x2c
+def key X                              =    0x2d
+def key C                              =    0x2e
+def key V                              =    0x2f
+def key B                              =    0x30
+def key N                              =    0x31
+def key M                              =    0x32
+def key Comma                          =    0x33 # ,<
+def key FullStop Period                        =    0x34 # .>
+def key Solidus Slash                  =    0x35 # /?
+def key RightShift RShift              =    0x36
+def key NumAsterisk NumMultiply                =    0x37 # \83e\83\93\83L\81[ *
+def key LeftAlt LAlt LMenu             =    0x38
+def key Space                          =    0x39
+def key \89p\90\94 Eisuu                     =    0x3a # \89p\90\94 CapsLock \8a¿\8e\9a\94Ô\8d\86
+def key F1                             =    0x3b
+def key F2                             =    0x3c
+def key F3                             =    0x3d
+def key F4                             =    0x3e
+def key F5                             =    0x3f
+def key F6                             =    0x40
+def key F7                             =    0x41
+def key F8                             =    0x42
+def key F9                             =    0x43
+def key F10                            =    0x44
+def key NumLock                                =    0x45
+def key ScrollLock Scroll              =    0x46
+def key Num7                           =    0x47 # \83e\83\93\83L\81[ 7
+def key Num8                           =    0x48 # \83e\83\93\83L\81[ 8
+def key Num9                           =    0x49 # \83e\83\93\83L\81[ 9
+
+def key NumHyphenMinus NumMinus                =    0x4a # \83e\83\93\83L\81[ -
+def key Num4                           =    0x4b # \83e\83\93\83L\81[ 4
+def key Num5                           =    0x4c # \83e\83\93\83L\81[ 5
+def key Num6                           =    0x4d # \83e\83\93\83L\81[ 6
+def key NumPlusSign NumPlus            =    0x4e # \83e\83\93\83L\81[ +
+def key Num1                           =    0x4f # \83e\83\93\83L\81[ 1
+def key Num2                           =    0x50
+def key Num3                           =    0x51
+def key Num0                           =    0x52
+def key NumFullStop NumPeriod          =    0x53 # \83e\83\93\83L\81[ .
+def key SysRq                          =    0x54
+
+def key F11                            =    0x57
+def key F12                            =    0x58
+
+def key \82Ð\82ç\82ª\82È Hiragana              =    0x70 # \82Ð\82ç\82ª\82È \83J\83^\83J\83\83\8d\81[\83}\8e\9a
+
+def key ReverseSolidus BackSlash       =    0x73 # \81__
+
+def key \95Ï\8a· Convert                   =    0x79 # \95Ï\8a·(\8e\9f\8có\95â) \91O\8có\95â \91S\8có\95â
+
+def key \96³\95Ï\8a· NonConvert              =    0x7b # \96³\95Ï\8a·
+
+def key YenSign Yen                    =    0x7d # \|
+
+def key MM/Messanger                   = E0-0x05 # (MultiMedia Keyboard) \83\81\83b\83Z\83\93\83W\83\83\81[
+
+def key MM/Undo        MM/F2                   = E0-0x08 # (MultiMedia Keyboard) F2 \8c³\82É\96ß\82·
+def key MM/Redo        MM/F3                   = E0-0x07 # (MultiMedia Keyboard) F3 \82â\82è\92¼\82µ
+
+def key MediaPrevTrack ScanPreviousTrack PreviousTrack \
+                                       = E0-0x10 # (MultiMedia Keyboard) |<<
+def key VAIO/TV/VIDEO                  = E0-0x11 # (Vaio) TV/VIDEO
+def key VAIO/TIMER-REC                 = E0-0x12 # (Vaio) TIMER REC
+def key VAIO/DV-CAPTURE                        = E0-0x13 # (Vaio) DV CAPTURE
+def key VAIO/VIDEO-EDIT                        = E0-0x14 # (Vaio) VIDEO EDIT
+def key VAIO/MAIL                      = E0-0x15 # (Vaio) MAIL
+def key VAIO/INTERNET                  = E0-0x16 # (Vaio) INTERNET
+def key MediaNextTrack ScanNextTrack NextTrack \
+                                       = E0-0x19 # (MultiMedia Keyboard) >>|
+
+def key NumEnter NumReturn             = E0-0x1c
+def key RightControl RControl RCtrl    = E0-0x1d
+
+def key VolumeMute Mute                        = E0-0x20 # (MultiMedia Keyboard)
+def key MM/Calculator ALCalculator     = E0-0x21 # (MultiMedia Keyboard) \93d\91ì
+
+def key MediaPlayPause Play/Pause      = E0-0x22 # (MultiMedia Keyboard) > / ||
+def key MM/SpellCheck  MM/F10          = E0-0x23 # (MultiMedia Keyboard) F10 \83X\83y\83\8b\83`\83F\83b\83N
+def key MediaStop Stop                 = E0-0x24 # (MultiMedia Keyboard) \81¡
+
+# def ignore                           = E0-0x2a # \82È\82É\82±\82ê (\96³\8e\8b)
+
+def key VolumeDown VolumeDecrement     = E0-0x2e # (MultiMedia Keyboard) -
+
+def key VolumeUp VolumeIncrement       = E0-0x30 # (MultiMedia Keyboard) +
+
+def key BrowserHome ACHome Internet    = E0-0x32 # (MultiMedia Keyboard) \83z\81[\83\80
+
+def key NumSolidus NumSlash            = E0-0x35 # \83e\83\93\83L\81[ /
+
+def key PrintScreen Snapshot           = E0-0x37
+def key RightAlt RAlt RMenu            = E0-0x38
+
+def key MM/Help                MM/F1           = E0-0x3b # (MultiMedia Keyboard) F1 \83w\83\8b\83v
+def key MM/MyMusic                     = E0-0x3c # (MultiMedia Keyboard) \83}\83C\83~\83\85\81[\83W\83b\83N
+
+def key MM/New         MM/F4           = E0-0x3e # (MultiMedia Keyboard) F4 \90V\8bK\8dì\90¬
+def key MM/Open                MM/F5           = E0-0x3f # (MultiMedia Keyboard) F5 \8aJ\82­
+def key MM/Close       MM/F6           = E0-0x40 # (MultiMedia Keyboard) F6 \95Â\82\82é
+def key MM/Reply       MM/F7           = E0-0x41 # (MultiMedia Keyboard) F7 \95Ô\90M
+def key MM/Forward     MM/F8           = E0-0x42 # (MultiMedia Keyboard) F8 \93]\91\97
+def key MM/Send                MM/F9           = E0-0x43 # (MultiMedia Keyboard) F9 \91\97\90M
+
+def key Break                          = E0-0x46 # Break
+def key Home                           = E0-0x47
+def key \81ª Up                          = E0-0x48
+def key PageUp Prior                   = E0-0x49
+
+def key \81© Left                                = E0-0x4b
+def key MM/MyDocument                  = E0-0x4c # (MultiMedia Keyboard) \83}\83C\83h\83L\83\85\83\81\83\93\83g
+def key \81¨ Right                       = E0-0x4d
+
+def key End                            = E0-0x4f
+def key \81« Down                                = E0-0x50
+def key PageDown Next                  = E0-0x51
+def key Insert                         = E0-0x52
+def key Delete Del                     = E0-0x53
+
+def key MM/Save                MM/F11          = E0-0x57 # (MultiMedia Keyboard) F11 \8fã\8f\91\82«\95Û\91
+def key MM/Print       MM/F12          = E0-0x58 # (MultiMedia Keyboard) F12 \88ó\8dü
+# def ignore                           = E0-0x59 # (Wireless Keyboard) Unknown
+
+def key LeftWindows LWindows LWin      = E0-0x5b
+def key RightWindows RWindows RWin     = E0-0x5c
+def key Applications Apps              = E0-0x5d
+def key PowerOff                       = E0-0x5e # Power off  (112 \83L\81[\83{\81[\83h)
+def key Sleep                          = E0-0x5f # Sleep      (112 \83L\81[\83{\81[\83h)
+
+def key WakeUp                         = E0-0x63 # Wake up    (112 \83L\81[\83{\81[\83h)
+def key MM/MyPicture                   = E0-0x64 # (MultiMedia Keyboard) \83}\83C\83s\83N\83`\83\83
+def key BrowserSearch ACSearch         = E0-0x65 # (Internet Explorer)
+def key BrowserFavorites ACBookmarks   = E0-0x66 # (Internet Explorer)
+def key BrowserRefresh ACRefresh       = E0-0x67 # (Internet Explorer)
+def key BrowserStop ACStop             = E0-0x68 # (Internet Explorer)
+def key BrowserForward ACForward       = E0-0x69 # (Internet Explorer)
+def key BrowserBack ACBack             = E0-0x6a # (Internet Explorer)
+def key ALLocalBrowser                 = E0-0x6b # (N/A) My Computer 
+def key LaunchMail ALEmailReader Email = E0-0x6c # (MultiMedia Keyboard) \83\81\81[\83\8b
+def key LaunchMediaSelect ALConsumerControlConfiguration \
+                                       = E0-0x6d # (MultiMedia Keyboard) \83\81\83f\83B\83A
+
+def key Pause                          = E1-0x1d 0x45 # Pause
+
+# def overflow                         =    0xff # \83I\81[\83o\81[\83t\83\8d\81[ (\96³\8e\8b)
+def sync                               =    0x7e # &Sync \82Å\8eg\82¤\83X\83L\83\83\83\93\83R\81[\83h
+
+def mod Shift  = LShift RShift
+def mod Alt    = LAlt RAlt
+def mod Control        = LControl RControl
+def mod Windows        = LWindows RWindows
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \83L\81[\83V\81[\83P\83\93\83X\92è\8b`
+#
+
+keyseq $ToggleIME              = A-\94¼\8ap/\91S\8ap
+keyseq $CapsLock               = S-\89p\90\94
+
+keyseq $SPACE                  = ~S-*Space                     #  
+keyseq $EXCLAMATION_MARK       =  S-*_1                        # !
+keyseq $QUOTATION_MARK         =  S-*_2                        # "
+keyseq $NUMBER_SIGN            =  S-*_3                        # #
+keyseq $DOLLAR_SIGN            =  S-*_4                        # $
+keyseq $PERCENT_SIGN           =  S-*_5                        # %
+keyseq $AMPERSAND              =  S-*_6                        # &
+keyseq $APOSTROPHE             =  S-*_7                        # '
+keyseq $LEFT_PARENTHESIS       =  S-*_8                        # (
+keyseq $RIGHT_PARENTHESIS      =  S-*_9                        # )
+keyseq $ASTERISK               =  S-*Colon                     # *
+keyseq $PLUS_SIGN              =  S-*Semicolon                 # +
+keyseq $COMMA                  = ~S-*Comma                     # ,
+keyseq $HYPHEN-MINUS           = ~S-*HyphenMinus               # -
+keyseq $FULL_STOP              = ~S-*FullStop                  # .
+keyseq $SOLIDUS                        = ~S-*Solidus                   # /
+keyseq $DIGIT_ZERO             = ~S-*_0                        # 0
+keyseq $DIGIT_ONE              = ~S-*_1                        # 1
+keyseq $DIGIT_TWO              = ~S-*_2                        # 2
+keyseq $DIGIT_THREE            = ~S-*_3                        # 3
+keyseq $DIGIT_FOUR             = ~S-*_4                        # 4
+keyseq $DIGIT_FIVE             = ~S-*_5                        # 5
+keyseq $DIGIT_SIX              = ~S-*_6                        # 6
+keyseq $DIGIT_SEVEN            = ~S-*_7                        # 7
+keyseq $DIGIT_EIGHT            = ~S-*_8                        # 8
+keyseq $DIGIT_NINE             = ~S-*_9                        # 9
+keyseq $COLON                  = ~S-*Colon                     # :
+keyseq $SEMICOLON              = ~S-*Semicolon                 # ;
+keyseq $LESS-THAN_SIGN         =  S-*Comma                     # <
+keyseq $EQUALS_SIGN            =  S-*HyphenMinus               # =
+keyseq $GREATER-THAN_SIGN      =  S-*FullStop                  # >
+keyseq $QUESTION_MARK          =  S-*Solidus                   # ?
+keyseq $COMMERCIAL_AT          = ~S-*CommercialAt              # @
+keyseq $LATIN_CAPITAL_LETTER_A =  S-*A                         # A
+keyseq $LATIN_CAPITAL_LETTER_B =  S-*B                         # B
+keyseq $LATIN_CAPITAL_LETTER_C =  S-*C                         # C
+keyseq $LATIN_CAPITAL_LETTER_D =  S-*D                         # D
+keyseq $LATIN_CAPITAL_LETTER_E =  S-*E                         # E
+keyseq $LATIN_CAPITAL_LETTER_F =  S-*F                         # F
+keyseq $LATIN_CAPITAL_LETTER_G =  S-*G                         # G
+keyseq $LATIN_CAPITAL_LETTER_H =  S-*H                         # H
+keyseq $LATIN_CAPITAL_LETTER_I =  S-*I                         # I
+keyseq $LATIN_CAPITAL_LETTER_J =  S-*J                         # J
+keyseq $LATIN_CAPITAL_LETTER_K =  S-*K                         # K
+keyseq $LATIN_CAPITAL_LETTER_L =  S-*L                         # L
+keyseq $LATIN_CAPITAL_LETTER_M =  S-*M                         # M
+keyseq $LATIN_CAPITAL_LETTER_N =  S-*N                         # N
+keyseq $LATIN_CAPITAL_LETTER_O =  S-*O                         # O
+keyseq $LATIN_CAPITAL_LETTER_P =  S-*P                         # P
+keyseq $LATIN_CAPITAL_LETTER_Q =  S-*Q                         # Q
+keyseq $LATIN_CAPITAL_LETTER_R =  S-*R                         # R
+keyseq $LATIN_CAPITAL_LETTER_S =  S-*S                         # S
+keyseq $LATIN_CAPITAL_LETTER_T =  S-*T                         # T
+keyseq $LATIN_CAPITAL_LETTER_U =  S-*U                         # U
+keyseq $LATIN_CAPITAL_LETTER_V =  S-*V                         # V
+keyseq $LATIN_CAPITAL_LETTER_W =  S-*W                         # W
+keyseq $LATIN_CAPITAL_LETTER_X =  S-*X                         # X
+keyseq $LATIN_CAPITAL_LETTER_Y =  S-*Y                         # Y
+keyseq $LATIN_CAPITAL_LETTER_Z =  S-*Z                         # Z
+keyseq $LEFT_SQUARE_BRACKET    = ~S-*LeftSquareBracket         # [
+keyseq $REVERSE_SOLIDUS                = ~S-*ReverseSolidus            # \
+keyseq $RIGHT_SQUARE_BRACKET   = ~S-*RightSquareBracket        # ]
+keyseq $CIRCUMFLEX_ACCENT      = ~S-*CircumflexAccent          # ^
+keyseq $LOW_LINE               =  S-*ReverseSolidus            # _
+keyseq $GRAVE_ACCENT           =  S-*CommercialAt              # `
+keyseq $LATIN_SMALL_LETTER_A   = ~S-*A                         # a
+keyseq $LATIN_SMALL_LETTER_B   = ~S-*B                         # b
+keyseq $LATIN_SMALL_LETTER_C   = ~S-*C                         # c
+keyseq $LATIN_SMALL_LETTER_D   = ~S-*D                         # d
+keyseq $LATIN_SMALL_LETTER_E   = ~S-*E                         # e
+keyseq $LATIN_SMALL_LETTER_F   = ~S-*F                         # f
+keyseq $LATIN_SMALL_LETTER_G   = ~S-*G                         # g
+keyseq $LATIN_SMALL_LETTER_H   = ~S-*H                         # h
+keyseq $LATIN_SMALL_LETTER_I   = ~S-*I                         # i
+keyseq $LATIN_SMALL_LETTER_J   = ~S-*J                         # j
+keyseq $LATIN_SMALL_LETTER_K   = ~S-*K                         # k
+keyseq $LATIN_SMALL_LETTER_L   = ~S-*L                         # l
+keyseq $LATIN_SMALL_LETTER_M   = ~S-*M                         # m
+keyseq $LATIN_SMALL_LETTER_N   = ~S-*N                         # n
+keyseq $LATIN_SMALL_LETTER_O   = ~S-*O                         # o
+keyseq $LATIN_SMALL_LETTER_P   = ~S-*P                         # p
+keyseq $LATIN_SMALL_LETTER_Q   = ~S-*Q                         # q
+keyseq $LATIN_SMALL_LETTER_R   = ~S-*R                         # r
+keyseq $LATIN_SMALL_LETTER_S   = ~S-*S                         # s
+keyseq $LATIN_SMALL_LETTER_T   = ~S-*T                         # t
+keyseq $LATIN_SMALL_LETTER_U   = ~S-*U                         # u
+keyseq $LATIN_SMALL_LETTER_V   = ~S-*V                         # v
+keyseq $LATIN_SMALL_LETTER_W   = ~S-*W                         # w
+keyseq $LATIN_SMALL_LETTER_X   = ~S-*X                         # x
+keyseq $LATIN_SMALL_LETTER_Y   = ~S-*Y                         # y
+keyseq $LATIN_SMALL_LETTER_Z   = ~S-*Z                         # z
+keyseq $LEFT_CURLY_BRACKET     =  S-*LeftSquareBracket         # {
+keyseq $VERTICAL_LINE          =  S-*YenSign                   # |
+keyseq $RIGHT_CURLY_BRACKET    =  S-*RightSquareBracket        # }
+keyseq $TILDE                  =  S-*CircumflexAccent          # ~
diff --git a/109on104.mayu b/109on104.mayu
new file mode 100644 (file)
index 0000000..1a0ac95
--- /dev/null
@@ -0,0 +1,24 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# MADO TSUKAI NO YUUTSU - 109on104.mayu
+# Copyright (C) 1999-2005, TAGA Nayuta <nayuta@users.sourceforge.net>
+#
+
+define KBD109on104
+
+def subst  S-*_2               = $QUOTATION_MARK
+def subst  S-*_6               = $AMPERSAND
+def subst  S-*_7               = $APOSTROPHE
+def subst  S-*_8               = $LEFT_PARENTHESIS
+def subst  S-*_9               = $RIGHT_PARENTHESIS
+def subst  S-*_0               = $LOW_LINE             # for lack of key
+def subst  S-*Hyphen           = $EQUALS_SIGN
+def subst ~S-*Equal            = $CIRCUMFLEX_ACCENT
+def subst  S-*Equal            = $TILDE
+def subst ~S-*OpenBracket      = $COMMERCIAL_AT
+def subst  S-*OpenBracket      = $GRAVE_ACCENT
+def subst    *CloseBracket     = $LEFT_SQUARE_BRACKET
+def subst  S-*Semicolon                = $PLUS_SIGN
+def subst ~S-*Quote            = $COLON
+def subst  S-*Quote            = $ASTERISK
+# def subst ~S-*               = $RIGHT_SQUARE_BRACKET # for lack of key
+# def subst  S-*               = $RIGHT_CURLY_BRACKET   # for lack of key
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..8677308
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,44 @@
+############################################################## -*- Makefile -*-
+#
+# Makefile for mayu
+#
+###############################################################################
+
+F      =       mayu-vc.mak
+
+all:
+       @echo "============================================================================="
+       @echo "Visual C++ 6.0:"
+       @echo "        nmake MAYU_VC=vc6"
+       @echo "        nmake MAYU_VC=vc6 clean"
+       @echo "        nmake MAYU_VC=vc6 distrib"
+       @echo "        nmake MAYU_VC=vc6 depend"
+       @echo "Visual C++ 7.0:"
+       @echo "        nmake MAYU_VC=vc7"
+       @echo "        nmake MAYU_VC=vc7 clean"
+       @echo "        nmake MAYU_VC=vc7 distrib"
+       @echo "        nmake MAYU_VC=vc7 depend"
+       @echo "Visual C++ 7.1:"
+       @echo "        nmake MAYU_VC=vc71"
+       @echo "        nmake MAYU_VC=vc71 clean"
+       @echo "        nmake MAYU_VC=vc71 distrib"
+       @echo "        nmake MAYU_VC=vc71 depend"
+       @echo "Visual C++ Toolkit 2003:"
+       @echo "        nmake MAYU_VC=vct"
+       @echo "        nmake MAYU_VC=vct clean"
+       @echo "        nmake MAYU_VC=vct distrib"
+       @echo "        nmake MAYU_VC=vct depend"
+       @echo "============================================================================="
+       $(MAKE) -f $(F) $(MAKEFLAGS) batch
+
+clean:
+       $(MAKE) -f $(F) $(MAKEFLAGS) batch_clean
+
+distclean:
+       $(MAKE) -f $(F) $(MAKEFLAGS) batch_distclean
+
+distrib:
+       $(MAKE) -f $(F) $(MAKEFLAGS) batch_distrib
+
+depend:
+       $(MAKE) -f $(F) $(MAKEFLAGS) TARGETOS=WINNT depend
diff --git a/array.h b/array.h
new file mode 100644 (file)
index 0000000..6e840a4
--- /dev/null
+++ b/array.h
@@ -0,0 +1,186 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// array.h
+
+
+#ifndef _ARRAY_H
+#  define _ARRAY_H
+
+#  include <memory>
+
+
+///
+template <class T, class Allocator = std::allocator<T> >
+class Array
+{
+public:
+  typedef typename Allocator::reference         reference; ///
+  typedef typename Allocator::const_reference   const_reference; ///
+  typedef typename Allocator::pointer           iterator; ///
+  typedef typename Allocator::const_pointer     const_iterator;        ///
+  typedef typename Allocator::size_type         size_type; ///
+  typedef typename Allocator::difference_type   difference_type; ///
+  typedef T                                     value_type;    ///
+  typedef Allocator                             allocator_type;        ///
+  typedef typename Allocator::pointer           pointer; ///
+  typedef typename Allocator::const_pointer     const_pointer; ///
+#if 0
+  typedef std::reverse_iterator<iterator>       reverse_iterator; ///
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;        ///
+#endif   
+private:
+  Allocator m_allocator;                       /// 
+  size_type m_size;                            /// 
+  pointer m_buf;                               /// array buffer
+
+public:
+  /// constructor
+  explicit Array(const Allocator& i_allocator = Allocator())
+    : m_allocator(i_allocator), m_size(0), m_buf(NULL)  { }
+         
+  /// constructor
+  explicit Array(size_type i_size, const T& i_value = T(),
+                const Allocator& i_allocator = Allocator())
+    : m_allocator(i_allocator), m_size(i_size),
+      m_buf(m_allocator.allocate(m_size, 0))
+  {
+    std::uninitialized_fill_n(m_buf, i_size, i_value);
+  }
+         
+  /// constructor
+  template <class InputIterator>
+  Array(InputIterator i_begin, InputIterator i_end,
+       const Allocator& i_allocator = Allocator())
+    : m_allocator(i_allocator), m_size(distance(i_begin, i_end)),
+      m_buf(Allocator::allocate(m_size, 0))
+  {
+    std::uninitialized_copy(i_begin, i_end, m_buf);
+  }
+         
+  /// copy constructor
+  Array(const Array& i_o) : m_size(0), m_buf(NULL) { operator=(i_o); }
+
+  /// destractor
+  ~Array() { clear(); }
+
+  ///
+  Array& operator=(const Array& i_o)
+  {
+    if (&i_o != this)
+    {
+      clear();
+      m_size = i_o.m_size;
+      m_buf = m_allocator.allocate(m_size, 0);
+      std::uninitialized_copy(i_o.m_buf, i_o.m_buf + m_size, m_buf);
+    }
+    return *this;
+  }
+  ///
+  allocator_type get_allocator() const { return Allocator(); }
+  /// return pointer to the array buffer
+  typename allocator_type::pointer get() { return m_buf; }
+  /// return pointer to the array buffer
+  typename allocator_type::const_pointer get() const { return m_buf; }
+  ///
+  iterator begin() { return m_buf; }
+  ///
+  const_iterator begin() const { return m_buf; }
+  ///
+  iterator end() { return m_buf + m_size; }
+  ///
+  const_iterator end() const { return m_buf + m_size; }
+#if 0
+  ///
+  reverse_iterator rbegin() { reverse_iterator(end()); }
+  ///
+  const_reverse_iterator rbegin() const { const_reverse_iterator(end()); }
+  ///
+  reverse_iterator rend() { reverse_iterator(begin()); }
+  ///
+  const_reverse_iterator rend() const { const_reverse_iterator(begin()); }
+#endif
+  ///
+  size_type size() const { return m_size; }
+  ///
+  size_type max_size() const { return -1; }
+  /// resize the array buffer.  NOTE: the original contents are cleared.
+  void resize(size_type i_size, const T& i_value = T())
+  {
+    clear();
+    m_size = i_size;
+    m_buf = m_allocator.allocate(m_size, 0);
+    std::uninitialized_fill_n(m_buf, i_size, i_value);
+  }
+  /// resize the array buffer.  
+  template <class InputIterator>
+  void resize(InputIterator i_begin, InputIterator i_end)
+  {
+    clear();
+    m_size = distance(i_begin, i_end);
+    m_buf = m_allocator.allocate(m_size, 0);
+    std::uninitialized_copy(i_begin, i_end, m_buf);
+  }
+  /// expand the array buffer. the contents of it are copied to the new one
+  void expand(size_type i_size, const T& i_value = T())
+  {
+    ASSERT( m_size <= i_size );
+    if (!m_buf)
+      resize(i_size, i_value);
+    else
+    {
+      pointer buf = m_allocator.allocate(i_size, 0);
+      std::uninitialized_copy(m_buf, m_buf + m_size, buf);
+      std::uninitialized_fill_n(buf + m_size, i_size - m_size, i_value);
+      clear();
+      m_size = i_size;
+      m_buf = buf;
+    }
+  }
+  ///
+  bool empty() const { return !m_buf; }
+  ///
+  reference operator[](size_type i_n) { return *(m_buf + i_n); }
+  ///
+  const_reference operator[](size_type i_n) const
+  { return *(m_buf + i_n); }
+  ///
+  const_reference at(size_type i_n) const
+  { return *(m_buf + i_n); }
+  ///
+  reference at(size_type i_n)
+  { return *(m_buf + i_n); }
+  ///
+  reference front() { return *m_buf; }
+  ///
+  const_reference front() const { return *m_buf; }
+  ///
+  reference back() { return *(m_buf + m_size - 1); }
+  ///
+  const_reference back() const { return *(m_buf + m_size - 1); }
+  ///
+  void swap(Array &i_o)
+  {
+    if (&i_o != this)
+    {
+      pointer buf = m_buf;
+      size_type size = m_size;
+      m_buf = i_o.m_buf;
+      m_size = i_o.m_size;
+      i_o.m_buf = buf;
+      i_o.m_size = size;
+    }
+  }
+  ///
+  void clear()
+  {
+    if (m_buf)
+    {
+      for (size_type i = 0; i < m_size; i ++)
+       m_allocator.destroy(&m_buf[i]);
+      m_allocator.deallocate(m_buf, m_size);
+      m_buf = 0;
+      m_size = 0;
+    }
+  }
+};
+
+#endif // _ARRAY_H
diff --git a/compiler_specific.h b/compiler_specific.h
new file mode 100644 (file)
index 0000000..b6253c1
--- /dev/null
@@ -0,0 +1,93 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// compiler_specific.h
+
+
+#ifndef _COMPILER_SPECIFIC_H
+#  define _COMPILER_SPECIFIC_H
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Microsoft Visual C++ 6.0
+
+#  if defined(_MSC_VER)
+
+// C4061 enum 'identifier' is not handled by case label
+// C4100 argument 'identifier' is not used
+// C4132 const 'object' must be initialized
+// C4552 'operator' : operator has no effect
+// C4701 local variable 'name' may be uninitialized
+// C4706 condition is a result of a assign
+// C4786 identifier is truncated into 255 chars (in debug information)
+#    pragma warning(disable : 4061 4100 4132 4552 4701 4706 4786)
+
+#    define setmode _setmode
+#    define for if (false) ; else for
+
+#    define stati64_t _stati64
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Borland C++ 5.5.1
+
+#  elif defined(__BORLANDC__)
+
+// W8004 'identifier' is assigned a value that is never used in function
+// W8022 'identifier' hides virtual function 'function'
+// W8027 Functions containing ... are not expanded inline
+// W8030 Temporary used for parameter 'identifier'
+//       in call to 'function' in function
+// W8060 Possibly incorrect assignment in function
+// W8070 Function should return a value in function
+// W8084 Suggest parentheses to clarify precedence in function
+#    pragma warn -8004
+#    pragma warn -8022
+#    pragma warn -8027
+#    pragma warn -8030
+#    pragma warn -8060
+#    pragma warn -8070
+#    pragma warn -8084
+
+#    ifdef _UNICODE
+extern wchar_t **_wargv;
+#    endif
+
+#    ifdef _MBCS
+#      define _istcntrl iscntrl
+#    endif
+
+#    include <windows.h>
+#    include <tchar.h>
+
+extern "C"
+{
+  int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE i_hPrevInstance,
+                      LPTSTR i_lpszCmdLine, int i_nCmdShow);
+}
+
+#    define stati64_t stati64
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Cygwin 1.1 (gcc 2.95.2)
+
+#  elif defined(__CYGWIN__)
+#    error "I don't know the details of this compiler... Plz hack."
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Watcom C++
+
+#  elif defined(__WATCOMC__)
+#    error "I don't know the details of this compiler... Plz hack."
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// unknown
+
+#  else
+#    error "I don't know the details of this compiler... Plz hack."
+
+#  endif
+
+
+#endif // _COMPILER_SPECIFIC_H
diff --git a/compiler_specific_func.cpp b/compiler_specific_func.cpp
new file mode 100644 (file)
index 0000000..7370ce2
--- /dev/null
@@ -0,0 +1,48 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// compiler_specific_func.cpp
+
+
+#include "compiler_specific_func.h"
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Microsoft Visual C++ 6.0
+
+#if defined(_MSC_VER)
+
+// get compiler version string
+tstring getCompilerVersionString()
+{
+  TCHAR buf[200];
+  _sntprintf(buf, NUMBER_OF(buf),
+            _T("Microsoft (R) 32-bit C/C++ Optimizing Compiler Version %d.%02d"),
+            _MSC_VER / 100,
+            _MSC_VER % 100);
+  return tstring(buf);
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Borland C++ 5.5.1
+
+#elif defined(__BORLANDC__)
+
+// get compiler version string
+tstring getCompilerVersionString()
+{
+  TCHAR buf[100];
+  _sntprintf(buf, NUMBER_OF(buf), _T("Borland C++ %d.%d.%d"),
+            __BORLANDC__ / 0x100,
+            __BORLANDC__ / 0x10 % 0x10,
+            __BORLANDC__ % 0x10);
+  return tstring(buf);
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// unknown
+
+#else
+#  error "I don't know the details of this compiler... Plz hack."
+
+#endif
diff --git a/compiler_specific_func.h b/compiler_specific_func.h
new file mode 100644 (file)
index 0000000..7919866
--- /dev/null
@@ -0,0 +1,16 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// compiler_specific_func.h
+
+
+#ifndef _COMPILER_SPECIFIC_FUNC_H
+#  define _COMPILER_SPECIFIC_FUNC_H
+
+#include "misc.h"
+#include "stringtool.h"
+
+
+/// get compiler version string
+tstring getCompilerVersionString();
+
+
+#endif // !_COMPILER_SPECIFIC_FUNC_H
diff --git a/contrib/109onAX.mayu b/contrib/109onAX.mayu
new file mode 100644 (file)
index 0000000..ccd5829
--- /dev/null
@@ -0,0 +1,31 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - AX.mayu
+# Copyright (C) 2002, \8f¼\96\94\8e\8bI <matsumoto678@oki.com>
+#
+
+define KBD109onAX
+
+def subst  S-*_2               = $QUOTATION_MARK
+def subst  S-*_6               = $AMPERSAND
+def subst  S-*_7               = $APOSTROPHE
+def subst  S-*_8               = $LEFT_PARENTHESIS
+def subst  S-*_9               = $RIGHT_PARENTHESIS
+
+def subst  S-*BackSlash                = $LOW_LINE
+def subst  S-*_0               = $TILDE # \82±\82ê\82Í\82È\82­\82Ä\82à\82¢\82¢
+
+def subst  S-*Hyphen           = $EQUALS_SIGN
+def subst ~S-*Equal            = $CIRCUMFLEX_ACCENT
+def subst  S-*Equal            = $TILDE
+def subst ~S-*OpenBracket      = $COMMERCIAL_AT
+def subst  S-*OpenBracket      = $GRAVE_ACCENT
+
+def subst ~S-*CloseBracket     = $LEFT_SQUARE_BRACKET
+def subst  S-*CloseBracket     = $LEFT_CURLY_BRACKET
+
+def subst  S-*Semicolon                = $PLUS_SIGN
+def subst ~S-*Quote            = $COLON
+def subst  S-*Quote            = $ASTERISK
+
+def subst ~S-*GraveAccent      = $RIGHT_SQUARE_BRACKET
+def subst  S-*GraveAccent      = $RIGHT_CURLY_BRACKET
diff --git a/contrib/98x1.mayu b/contrib/98x1.mayu
new file mode 100644 (file)
index 0000000..f56b0a0
--- /dev/null
@@ -0,0 +1,239 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - 98x1.mayu
+#
+# derived from 104.mayu, 109.mayu and AX.mayu
+# Copyright (C) 2001, HAJANO Nao`qui <Tory@sneering.104.net>
+#
+
+
+define KBD9801
+define KBD9821
+define KBDRBoard98
+
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# PC-98x1 \97p\95W\8f\80\83L\81[\83{\81[\83h\81i\81\95\8cÝ\8a·\83L\81[\83{\81[\83h\81j\92è\8b`
+#
+
+def key Esc Escape                     =    0x00
+def key _1                             =    0x01 # 1!
+def key _2                             =    0x02 # 2"
+def key _3                             =    0x03 # 3#
+def key _4                             =    0x04 # 4$
+def key _5                             =    0x05 # 5%
+def key _6                             =    0x06 # 6&
+def key _7                             =    0x07 # 7'
+def key _8                             =    0x08 # 8(
+def key _9                             =    0x09 # 9)
+def key _0                             =    0x0a # 0
+def key HyphenMinus Hyphen Minus       =    0x0b # -=
+def key Caret CircumflexAccent                 =    0x0c # ^`
+def key YenSign Yen                    =    0x0d # \|
+def key BS BackSpace Back              =    0x0e
+def key Tab                            =    0x0f
+def key Q                              =    0x10
+def key W                              =    0x11
+def key E                              =    0x12
+def key R                              =    0x13
+def key T                              =    0x14
+def key Y                              =    0x15
+def key U                              =    0x16
+def key I                              =    0x17
+def key O                              =    0x18
+def key P                              =    0x19
+def key Atmark CommercialAt            =    0x1a # @~
+def key LeftSquareBracket OpenBracket  =    0x1b # [{
+def key Enter Return                   =    0x1c
+def key A                              =    0x1d
+def key S                              =    0x1e
+def key D                              =    0x1f
+def key F                              =    0x20
+def key G                              =    0x21
+def key H                              =    0x22
+def key J                              =    0x23
+def key K                              =    0x24
+def key L                              =    0x25
+def key Semicolon                      =    0x26 # ;+
+def key Colon                          =    0x27 # :*
+def key RightSquareBracket CloseBracket =    0x28 # ]}
+def key Z                              =    0x29
+def key X                              =    0x2a
+def key C                              =    0x2b
+def key V                              =    0x2c
+def key B                              =    0x2d
+def key N                              =    0x2e
+def key M                              =    0x2f
+def key Comma                          =    0x30 # ,<
+def key FullStop Period                =    0x31 # .>
+def key Solidus Slash                  =    0x32 # /?
+def key _0xdf UNDERBAR                         =    0x33 #  _
+def key Space \83X\83y\81[\83X                 =    0x34
+def key XFER Kanji                     =    0x35
+def key ROLLUP PageDown Next           =    0x36
+def key ROLLDOWN PageUp Prior          =    0x37
+def key INS Insert                     =    0x38
+def key DEL Delete                     =    0x39
+def key \81ª Up                          =    0x3a
+def key \81© Left                                =    0x3b
+def key \81¨ Right                       =    0x3c
+def key \81« Down                                =    0x3d
+def key CLR Home Clear                 =    0x3e
+def key HELP End                       =    0x3f
+def key Subtract NumHyphenMinus NumMinus       =    0x40 # \83e\83\93\83L\81[ -
+def key Divide NumSolidus NumSlash     =    0x41 # \83e\83\93\83L\81[ /
+def key Numpad7 Num7                   =    0x42 # \83e\83\93\83L\81[ 7
+def key Numpad8 Num8                   =    0x43 # \83e\83\93\83L\81[ 8
+def key Numpad9 Num9                   =    0x44 # \83e\83\93\83L\81[ 9
+def key Multiply NumAsterisk NumMultiply       =    0x45 # \83e\83\93\83L\81[ *
+def key Numpad4 Num4                   =    0x46 # \83e\83\93\83L\81[ 4
+def key Numpad5 Num5                   =    0x47 # \83e\83\93\83L\81[ 5
+def key Numpad6 Num6                   =    0x48 # \83e\83\93\83L\81[ 6
+def key Add NumPlusSign NumPlus                =    0x49 # \83e\83\93\83L\81[ +
+def key Numpad1 Num1                   =    0x4a # \83e\83\93\83L\81[ 1
+def key Numpad2 Num2                   =    0x4b # \83e\83\93\83L\81[ 2
+def key Numpad3 Num3                   =    0x4c # \83e\83\93\83L\81[ 3
+def key TYLOR NumEqualsSign NumEquals  =    0x4d # \83e\83\93\83L\81[ =
+def key Numpad0 Num0                   =    0x4e # \83e\83\93\83L\81[ 0
+def key Separator NumComma             =    0x4f # \83e\83\93\83L\81[ ,
+def key Decimal NumFullStop NumPeriod  =    0x50 # \83e\83\93\83L\81[ .
+def key NFER NonConvert                        =    0x51
+def key vf1 F11                                =    0x52
+def key vf2 F12                                =    0x53
+def key vf3 F13                                =    0x54
+def key vf4 F14                                =    0x55
+def key vf5 F15                                =    0x56
+
+def key STOP Pause                     =    0x60
+def key COPY Snapshot PrintScreen      =    0x61
+def key F1                             =    0x62
+def key F2                             =    0x63
+def key F3                             =    0x64
+def key F4                             =    0x65
+def key F5                             =    0x66
+def key F6                             =    0x67
+def key F7                             =    0x68
+def key F8                             =    0x69
+def key F9                             =    0x6a
+def key F10                            =    0x6b
+
+def key SHIFT                          =    0x70
+def key CAPS Capital CapsLock          =    0x71
+def key \82©\82È \83J\83i Kana                 =    0x72
+def key GRPH Menu Alt Meta             =    0x73
+def key CTRL Control                   =    0x74
+
+def key LWin LWindows LeftWindows      =    0x77
+def key RWin RWindows RightWindows     =    0x78
+def key Apps Applications              =    0x79
+
+def sync                               =    0x7a # &Sync \82Å\8eg\82¤\83X\83L\83\83\83\93\83R\81[\83h
+
+def mod Shift  = SHIFT
+def mod Alt    = GRPH
+def mod Control        = CTRL
+def mod Windows        = LWindows RWindows
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \83L\81[\83V\81[\83P\83\93\83X\92è\8b`
+#
+
+keyseq $ToggleIME              = C-XFER
+keyseq $CapsLock               = CAPS
+
+keyseq $SPACE                  = ~S-*Space                     #  
+keyseq $EXCLAMATION_MARK       =  S-*_1                        # !
+keyseq $QUOTATION_MARK         =  S-*_2                        # "
+keyseq $NUMBER_SIGN            =  S-*_3                        # #
+keyseq $DOLLAR_SIGN            =  S-*_4                        # $
+keyseq $PERCENT_SIGN           =  S-*_5                        # %
+keyseq $AMPERSAND              =  S-*_6                        # &
+keyseq $APOSTROPHE             =  S-*_7                        # '
+keyseq $LEFT_PARENTHESIS       =  S-*_8                        # (
+keyseq $RIGHT_PARENTHESIS      =  S-*_9                        # )
+keyseq $ASTERISK               =  S-*Colon                     # *
+keyseq $PLUS_SIGN              =  S-*Semicolon                 # +
+keyseq $COMMA                  = ~S-*Comma                     # ,
+keyseq $HYPHEN-MINUS           = ~S-*HyphenMinus               # -
+keyseq $FULL_STOP              = ~S-*FullStop                  # .
+keyseq $SOLIDUS                        = ~S-*Solidus                   # /
+keyseq $DIGIT_ZERO             = ~S-*_0                        # 0
+keyseq $DIGIT_ONE              = ~S-*_1                        # 1
+keyseq $DIGIT_TWO              = ~S-*_2                        # 2
+keyseq $DIGIT_THREE            = ~S-*_3                        # 3
+keyseq $DIGIT_FOUR             = ~S-*_4                        # 4
+keyseq $DIGIT_FIVE             = ~S-*_5                        # 5
+keyseq $DIGIT_SIX              = ~S-*_6                        # 6
+keyseq $DIGIT_SEVEN            = ~S-*_7                        # 7
+keyseq $DIGIT_EIGHT            = ~S-*_8                        # 8
+keyseq $DIGIT_NINE             = ~S-*_9                        # 9
+keyseq $COLON                  = ~S-*Colon                     # :
+keyseq $SEMICOLON              = ~S-*Semicolon                 # ;
+keyseq $LESS-THAN_SIGN         =  S-*Comma                     # <
+keyseq $EQUALS_SIGN            =  S-*HyphenMinus               # =
+keyseq $GREATER-THAN_SIGN      =  S-*FullStop                  # >
+keyseq $QUESTION_MARK          =  S-*Solidus                   # ?
+keyseq $COMMERCIAL_AT          = ~S-*CommercialAt              # @
+keyseq $LATIN_CAPITAL_LETTER_A =  S-*A                         # A
+keyseq $LATIN_CAPITAL_LETTER_B =  S-*B                         # B
+keyseq $LATIN_CAPITAL_LETTER_C =  S-*C                         # C
+keyseq $LATIN_CAPITAL_LETTER_D =  S-*D                         # D
+keyseq $LATIN_CAPITAL_LETTER_E =  S-*E                         # E
+keyseq $LATIN_CAPITAL_LETTER_F =  S-*F                         # F
+keyseq $LATIN_CAPITAL_LETTER_G =  S-*G                         # G
+keyseq $LATIN_CAPITAL_LETTER_H =  S-*H                         # H
+keyseq $LATIN_CAPITAL_LETTER_I =  S-*I                         # I
+keyseq $LATIN_CAPITAL_LETTER_J =  S-*J                         # J
+keyseq $LATIN_CAPITAL_LETTER_K =  S-*K                         # K
+keyseq $LATIN_CAPITAL_LETTER_L =  S-*L                         # L
+keyseq $LATIN_CAPITAL_LETTER_M =  S-*M                         # M
+keyseq $LATIN_CAPITAL_LETTER_N =  S-*N                         # N
+keyseq $LATIN_CAPITAL_LETTER_O =  S-*O                         # O
+keyseq $LATIN_CAPITAL_LETTER_P =  S-*P                         # P
+keyseq $LATIN_CAPITAL_LETTER_Q =  S-*Q                         # Q
+keyseq $LATIN_CAPITAL_LETTER_R =  S-*R                         # R
+keyseq $LATIN_CAPITAL_LETTER_S =  S-*S                         # S
+keyseq $LATIN_CAPITAL_LETTER_T =  S-*T                         # T
+keyseq $LATIN_CAPITAL_LETTER_U =  S-*U                         # U
+keyseq $LATIN_CAPITAL_LETTER_V =  S-*V                         # V
+keyseq $LATIN_CAPITAL_LETTER_W =  S-*W                         # W
+keyseq $LATIN_CAPITAL_LETTER_X =  S-*X                         # X
+keyseq $LATIN_CAPITAL_LETTER_Y =  S-*Y                         # Y
+keyseq $LATIN_CAPITAL_LETTER_Z =  S-*Z                         # Z
+keyseq $LEFT_SQUARE_BRACKET    = ~S-*LeftSquareBracket         # [
+keyseq $REVERSE_SOLIDUS                = ~S-*YenSign                   # \
+keyseq $RIGHT_SQUARE_BRACKET   = ~S-*RightSquareBracket        # ]
+keyseq $CIRCUMFLEX_ACCENT      = ~S-*CircumflexAccent          # ^
+keyseq $LOW_LINE               =  S-*_0xdf                     # _
+keyseq $GRAVE_ACCENT           =  S-*CircumflexAccent          # `
+keyseq $LATIN_SMALL_LETTER_A   = ~S-*A                         # a
+keyseq $LATIN_SMALL_LETTER_B   = ~S-*B                         # b
+keyseq $LATIN_SMALL_LETTER_C   = ~S-*C                         # c
+keyseq $LATIN_SMALL_LETTER_D   = ~S-*D                         # d
+keyseq $LATIN_SMALL_LETTER_E   = ~S-*E                         # e
+keyseq $LATIN_SMALL_LETTER_F   = ~S-*F                         # f
+keyseq $LATIN_SMALL_LETTER_G   = ~S-*G                         # g
+keyseq $LATIN_SMALL_LETTER_H   = ~S-*H                         # h
+keyseq $LATIN_SMALL_LETTER_I   = ~S-*I                         # i
+keyseq $LATIN_SMALL_LETTER_J   = ~S-*J                         # j
+keyseq $LATIN_SMALL_LETTER_K   = ~S-*K                         # k
+keyseq $LATIN_SMALL_LETTER_L   = ~S-*L                         # l
+keyseq $LATIN_SMALL_LETTER_M   = ~S-*M                         # m
+keyseq $LATIN_SMALL_LETTER_N   = ~S-*N                         # n
+keyseq $LATIN_SMALL_LETTER_O   = ~S-*O                         # o
+keyseq $LATIN_SMALL_LETTER_P   = ~S-*P                         # p
+keyseq $LATIN_SMALL_LETTER_Q   = ~S-*Q                         # q
+keyseq $LATIN_SMALL_LETTER_R   = ~S-*R                         # r
+keyseq $LATIN_SMALL_LETTER_S   = ~S-*S                         # s
+keyseq $LATIN_SMALL_LETTER_T   = ~S-*T                         # t
+keyseq $LATIN_SMALL_LETTER_U   = ~S-*U                         # u
+keyseq $LATIN_SMALL_LETTER_V   = ~S-*V                         # v
+keyseq $LATIN_SMALL_LETTER_W   = ~S-*W                         # w
+keyseq $LATIN_SMALL_LETTER_X   = ~S-*X                         # x
+keyseq $LATIN_SMALL_LETTER_Y   = ~S-*Y                         # y
+keyseq $LATIN_SMALL_LETTER_Z   = ~S-*Z                         # z
+keyseq $LEFT_CURLY_BRACKET     =  S-*LeftSquareBracket         # {
+keyseq $VERTICAL_LINE          =  S-*YenSign                   # |
+keyseq $RIGHT_CURLY_BRACKET    =  S-*RightSquareBracket        # }
+keyseq $TILDE                  =  S-*CommercialAt              # ~
diff --git a/contrib/DVORAKon109.mayu b/contrib/DVORAKon109.mayu
new file mode 100644 (file)
index 0000000..2cd6c08
--- /dev/null
@@ -0,0 +1,79 @@
+#
+# DVORAKon109.mayu - dvorak layout on 109 layout for \91\8b\8eg\82¢\82Ì\97J\9fT
+#
+#
+# dvorak\83L\81[\94z\97ñ\82ð109\83L\81[\8fã\82É\8eÀ\8c»\82·\82é\81B
+# \83L\81[\94z\97ñ\82Í\81A\88È\89º\82Ì\82æ\82¤\82É\82È\82é\81B\8bó\94\92\82Ì\95\94\95ª\82Í\95Ï\8dX\82µ\82È\82¢\81B
+# S-0 \82ª ~ \82É\82È\82é\82±\82Æ\82Æ\81AS-^ \82ª _ \82É\82È\82é\82±\82Æ\82ð\8f\9c\82¯\82Î\81A\83L\81[\88Ê\92u\82ð\8cð\8a·\82µ\81A
+# ]} \82Å\82 \82Á\82½\88Ê\92u\82É Contol \82ð\92u\82¢\82½\82¾\82¯\81B(\_ \82Í\95s\97v\82É\82È\82é\82½\82ß\81B)
+#
+# ----------------------------------------------------------------------------
+# |    |  ! |  " |  # |  $ |  % |  & |  ' |  ( |  ) |  ~ |  { |  } |  ` |    |
+# |    | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  | 9  | 0  | [  | ]  | @  |    |
+# ----------------------------------------------------------------------------
+# |       |  * |  < |  > |  P |  Y |  F |  G |  C |  R |  L |  ? |  _ |      |
+# |       | :  | ,  | .  |    |    |    |    |    |    |    | /  | ^  |      |
+# ----------------------------------------------------------------------     |
+# |        |  A |  O |  E |  U |  I |  D |  H |  T |  N |  S |  = |    |     |
+# |        |    |    |    |    |    |    |    |    |    |    | -  |Ctrl|     |
+# ----------------------------------------------------------------------------
+# |          |  + |  Q |  J |  K |  X |  B |  M |  W |  V |  Z |  | |        |
+# |          | ;  |    |    |    |    |    |    |    |    |    | \  |        |
+# ----------------------------------------------------------------------------
+#
+
+define KBDDVORAKon109
+
+
+# \88ê\92i\96Ú
+def subst S-*_0                                = $TILDE
+def subst *Minus                       = *LeftSquareBracket
+def subst *CircumflexAccent            = *RightSquareBracket
+def subst *YenSign                     = *Atmark
+
+# \93ñ\92i\96Ú
+def subst *Q                           = *Colon
+def subst *W                           = *Comma
+def subst *E                           = *Period
+def subst *R                           = *P
+def subst *T                           = *Y
+def subst *Y                           = *F
+def subst *U                           = *G
+def subst *I                           = *C
+def subst *O                           = *R
+def subst *P                           = *L
+def subst *Atmark                      = *Slash
+def subst ~S-*LeftSquareBracket                = $CIRCUMFLEX_ACCENT
+def subst  S-*LeftSquareBracket        = $LOW_LINE
+
+# \8eO\92i\96Ú
+def subst *A                           = *A
+def subst *S                           = *O
+def subst *D                           = *E
+def subst *F                           = *U
+def subst *G                           = *I
+def subst *H                           = *D
+def subst *J                           = *H
+def subst *K                           = *T
+def subst *L                           = *N
+def subst *Semicolon                   = *S
+def subst *Colon                       = *Minus
+def subst *RightSquareBracket          = ~S-*ReverseSolidus    # temporary
+
+# \8el\92i\96Ú
+def subst *Z                           = *Semicolon
+def subst *X                           = *Q
+def subst *C                           = *J
+def subst *V                           = *K
+def subst *B                           = *X
+def subst *N                           = *B
+def subst *M                           = *M
+def subst *Comma                       = *W
+def subst *Period                      = *V
+def subst *Slash                       = *Z
+def subst *BackSlash                   = *YenSign
+
+
+keymap Global
+ mod control += RightSquareBracket
+ key ~S-*ReverseSolidus                        = *RControl
diff --git a/contrib/ax.mayu b/contrib/ax.mayu
new file mode 100644 (file)
index 0000000..471a16d
--- /dev/null
@@ -0,0 +1,257 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - AX.mayu
+#
+# derived from 104.mayu, and 109.mayu
+# Copyright (C) 1999-2000, TAGA Nayuta <nayuta@users.sourceforge.net>
+# 
+# AX.mayu
+# Copyright (C) 2000, KAWABE Nobukazu <nbk@imasy.or.jp>
+#
+
+define KBDAX
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# AX \93ú\96{\8cê\83L\81[\83{\81[\83h\92è\8b`
+#
+
+def key Esc Escape                     =    0x01
+def key _1                             =    0x02 # 1!
+def key _2                             =    0x03 # 2@
+def key _3                             =    0x04 # 3#
+def key _4                             =    0x05 # 4$
+def key _5                             =    0x06 # 5%
+def key _6                             =    0x07 # 6^
+def key _7                             =    0x08 # 7&
+def key _8                             =    0x09 # 8*
+def key _9                             =    0x0a # 9(
+def key _0                             =    0x0b # 0)
+def key HyphenMinus Hyphen Minus       =    0x0c # -_
+def key EqualsSign Equal               =    0x0d # =+
+def key BackSpace BS Back              =    0x0e
+def key Tab                            =    0x0f
+def key Q                              =    0x10
+def key W                              =    0x11
+def key E                              =    0x12
+def key R                              =    0x13
+def key T                              =    0x14
+def key Y                              =    0x15
+def key U                              =    0x16
+def key I                              =    0x17
+def key O                              =    0x18
+def key P                              =    0x19
+def key LeftSquareBracket OpenBracket  =    0x1a # [{
+def key RightSquareBracket CloseBracket        =    0x1b # ]}
+def key Enter Return                   =    0x1c
+def key NumEnter NumReturn             = E0-0x1c
+def key LeftControl LControl LCtrl     =    0x1d
+def key \89p\90\94/\83J\83i Eisuu                        = E0-0x1d # \89p\90\94 \83J\83i
+def key Pause                          = E1-0x1d 0x45 # Pause
+def key A                              =    0x1e
+def key S                              =    0x1f
+def key D                              =    0x20
+def key F                              =    0x21
+def key G                              =    0x22
+def key H                              =    0x23
+def key J                              =    0x24
+def key K                              =    0x25
+def key L                              =    0x26
+def key Semicolon                      =    0x27 # ;:
+def key Apostrophe Quote               =    0x28 # '"
+def key GraveAccent BackQuote          =    0x29 # `~
+def key LeftShift LShift               =    0x2a
+# def ignore                           = E0-0x2a # what is this? (ignore)
+def key YenSign Yen                    =    0x2b # \|
+def key Z                              =    0x2c
+def key X                              =    0x2d
+def key C                              =    0x2e
+def key V                              =    0x2f
+def key B                              =    0x30
+def key N                              =    0x31
+def key M                              =    0x32
+def key Comma                          =    0x33 # ,<
+def key FullStop Period                        =    0x34 # .>
+def key Solidus Slash                  =    0x35 # /?
+def key NumSolidus NumSlash            = E0-0x35 # Numpad /
+def key RightShift RShift              =    0x36
+def key NumAsterisk NumMultiply                =    0x37 # Numpad *
+def key PrintScreen Snapshot           = E0-0x37
+def key LeftAlt LAlt LMenu             =    0x38
+def key \8a¿\8e\9a Kanji                     = E0-0x38 # \8a¿\8e\9a
+def key Space                          =    0x39
+def key CapsLock Capital Caps          =    0x3a # CapsLock
+def key F1                             =    0x3b
+def key F2                             =    0x3c
+def key F3                             =    0x3d
+def key F4                             =    0x3e
+def key F5                             =    0x3f
+def key F6                             =    0x40
+def key F7                             =    0x41
+def key F8                             =    0x42
+def key F9                             =    0x43
+def key F10                            =    0x44
+def key NumLock                                =    0x45
+def key ScrollLock Scroll              =    0x46
+def key Break                          = E0-0x46 # Break
+def key Num7                           =    0x47 # Numpad 7
+def key Home                           = E0-0x47
+def key Num8                           =    0x48 # Numpad 8
+def key \81ª Up                          = E0-0x48
+def key Num9                           =    0x49 # Numpad 9
+def key PageUp Prior                   = E0-0x49
+def key NumHyphenMinus NumMinus                =    0x4a # Numpad -
+def key Num4                           =    0x4b # Numpad 4
+def key \81© Left                                = E0-0x4b
+def key Num5                           =    0x4c # Numpad 5
+def key Num6                           =    0x4d # Numpad 6
+def key \81¨ Right                       = E0-0x4d
+def key NumPlusSign NumPlus            =    0x4e # Numpad +
+def key Num1                           =    0x4f # Numpad 1
+def key End                            = E0-0x4f
+def key Num2                           =    0x50
+def key \81« Down                                = E0-0x50
+def key Num3                           =    0x51
+def key PageDown Next                  = E0-0x51
+def key Num0                           =    0x52
+def key Insert                         = E0-0x52
+def key NumFullStop NumPeriod          =    0x53 # Numpad .
+def key Delete Del                     = E0-0x53
+def key SysRq                          =    0x54
+def key ReverseSolidus BackSlash       =    0x56 # \|
+def key F11                            =    0x57
+def key F12                            =    0x58
+def key \96³\95Ï\8a· NonConvert              =    0x5a # \96³\95Ï\8a·
+def key \95Ï\8a· Convert                   =    0x5b # \95Ï\8a·
+def key AX                             =    0x5c # AX\83L\81[
+def key RightWindows RWindows RWin     = E0-0x5c # (\83L\81[\83{\81[\83h\8fã\82É\82Í\82È\82¢)
+def key Applications Apps              = E0-0x5d # (\83L\81[\83{\81[\83h\8fã\82É\82Í\82È\82¢)
+# def overflow                         =    0xff # overflow (ignore)
+
+def sync                               =    0x7e # scan code used by &Sync
+
+def mod Shift  = LShift RShift
+def mod Alt    = LAlt
+def mod Control        = LControl
+def mod Windows = RWindows
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# global keymap
+#
+
+keymap Global
+ mod Windows += AX
+ key *AX                       => *RWindows
+
+# \81EAX \83L\81[\83{\81[\83h\8fã\82É\82Í Windows \83L\81[\82Í\91\8dÝ\82µ\82È\82¢\81B
+# \81EWindows95 \82Å\82Í [AX] \83L\81[\82ª [Windows] \83L\81[\82Ì\96ð\96Ú\82ð\89Ê\82½\82µ\82Ä\82¢\82½\82ª\81A
+#   NT/2000 \82Å\82Í\96³\8e\8b\82³\82ê\82é\81B
+# \81EAX \83L\81[\83{\81[\83h\82Í RWindows \82â Applications \82Ì\83L\81[\83R\81[\83h\82ð\94­\90\82³\82¹\82é
+#   \82±\82Æ\82Í\82È\82¢\82ª\81ANT/2000 \82Ì\83h\83\89\83C\83o\82Í\82±\82ê\82ç\82Ì\83L\81[\83R\81[\83h\82ð\94F\8e¯\82·\82é\81B
+# \81E\82æ\82Á\82Ä\8fã\8bL\82Ì\82æ\82¤\82È\92è\8b`\82ð\82·\82é\82±\82Æ\82Å [AX] \83L\81[\82ð [Windows] \83L\81[\82Æ\82µ
+#   \82Ä\8eg\97p\82·\82é\82±\82Æ\82ª\82Å\82«\82é\81B
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# define some key sequence
+#
+
+keyseq $ToggleIME              = \8a¿\8e\9a
+keyseq $CapsLock               = CapsLock
+
+keyseq $SPACE                  = ~S-*Space                     #  
+keyseq $EXCLAMATION_MARK       =  S-*_1                        # !
+keyseq $QUOTATION_MARK         =  S-*Apostrophe                # "
+keyseq $NUMBER_SIGN            =  S-*_3                        # #
+keyseq $DOLLAR_SIGN            =  S-*_4                        # $
+keyseq $PERCENT_SIGN           =  S-*_5                        # %
+keyseq $AMPERSAND              =  S-*_7                        # &
+keyseq $APOSTROPHE             = ~S-*Apostrophe                # '
+keyseq $LEFT_PARENTHESIS       =  S-*_9                        # (
+keyseq $RIGHT_PARENTHESIS      =  S-*_0                        # )
+keyseq $ASTERISK               =  S-*_8                        # *
+keyseq $PLUS_SIGN              =  S-*EqualsSign                # +
+keyseq $COMMA                  = ~S-*Comma                     # ,
+keyseq $HYPHEN-MINUS           = ~S-*HyphenMinus               # -
+keyseq $FULL_STOP              = ~S-*FullStop                  # .
+keyseq $SOLIDUS                        = ~S-*Solidus                   # /
+keyseq $DIGIT_ZERO             = ~S-*_0                        # 0
+keyseq $DIGIT_ONE              = ~S-*_1                        # 1
+keyseq $DIGIT_TWO              = ~S-*_2                        # 2
+keyseq $DIGIT_THREE            = ~S-*_3                        # 3
+keyseq $DIGIT_FOUR             = ~S-*_4                        # 4
+keyseq $DIGIT_FIVE             = ~S-*_5                        # 5
+keyseq $DIGIT_SIX              = ~S-*_6                        # 6
+keyseq $DIGIT_SEVEN            = ~S-*_7                        # 7
+keyseq $DIGIT_EIGHT            = ~S-*_8                        # 8
+keyseq $DIGIT_NINE             = ~S-*_9                        # 9
+keyseq $COLON                  =  S-*Semicolon                 # :
+keyseq $SEMICOLON              = ~S-*Semicolon                 # ;
+keyseq $LESS-THAN_SIGN         =  S-*Comma                     # <
+keyseq $EQUALS_SIGN            = ~S-*EqualsSign                # =
+keyseq $GREATER-THAN_SIGN      =  S-*FullStop                  # >
+keyseq $QUESTION_MARK          =  S-*Solidus                   # ?
+keyseq $COMMERCIAL_AT          =  S-*_2                        # @
+keyseq $LATIN_CAPITAL_LETTER_A =  S-*A                         # A
+keyseq $LATIN_CAPITAL_LETTER_B =  S-*B                         # B
+keyseq $LATIN_CAPITAL_LETTER_C =  S-*C                         # C
+keyseq $LATIN_CAPITAL_LETTER_D =  S-*D                         # D
+keyseq $LATIN_CAPITAL_LETTER_E =  S-*E                         # E
+keyseq $LATIN_CAPITAL_LETTER_F =  S-*F                         # F
+keyseq $LATIN_CAPITAL_LETTER_G =  S-*G                         # G
+keyseq $LATIN_CAPITAL_LETTER_H =  S-*H                         # H
+keyseq $LATIN_CAPITAL_LETTER_I =  S-*I                         # I
+keyseq $LATIN_CAPITAL_LETTER_J =  S-*J                         # J
+keyseq $LATIN_CAPITAL_LETTER_K =  S-*K                         # K
+keyseq $LATIN_CAPITAL_LETTER_L =  S-*L                         # L
+keyseq $LATIN_CAPITAL_LETTER_M =  S-*M                         # M
+keyseq $LATIN_CAPITAL_LETTER_N =  S-*N                         # N
+keyseq $LATIN_CAPITAL_LETTER_O =  S-*O                         # O
+keyseq $LATIN_CAPITAL_LETTER_P =  S-*P                         # P
+keyseq $LATIN_CAPITAL_LETTER_Q =  S-*Q                         # Q
+keyseq $LATIN_CAPITAL_LETTER_R =  S-*R                         # R
+keyseq $LATIN_CAPITAL_LETTER_S =  S-*S                         # S
+keyseq $LATIN_CAPITAL_LETTER_T =  S-*T                         # T
+keyseq $LATIN_CAPITAL_LETTER_U =  S-*U                         # U
+keyseq $LATIN_CAPITAL_LETTER_V =  S-*V                         # V
+keyseq $LATIN_CAPITAL_LETTER_W =  S-*W                         # W
+keyseq $LATIN_CAPITAL_LETTER_X =  S-*X                         # X
+keyseq $LATIN_CAPITAL_LETTER_Y =  S-*Y                         # Y
+keyseq $LATIN_CAPITAL_LETTER_Z =  S-*Z                         # Z
+keyseq $LEFT_SQUARE_BRACKET    = ~S-*LeftSquareBracket         # [
+keyseq $REVERSE_SOLIDUS                = ~S-*ReverseSolidus            # \
+keyseq $RIGHT_SQUARE_BRACKET   = ~S-*RightSquareBracket        # ]
+keyseq $CIRCUMFLEX_ACCENT      =  S-*_6                        # ^
+keyseq $LOW_LINE               =  S-*HyphenMinus               # _
+keyseq $GRAVE_ACCENT           = ~S-*GraveAccent               # `
+keyseq $LATIN_SMALL_LETTER_A   = ~S-*A                         # a
+keyseq $LATIN_SMALL_LETTER_B   = ~S-*B                         # b
+keyseq $LATIN_SMALL_LETTER_C   = ~S-*C                         # c
+keyseq $LATIN_SMALL_LETTER_D   = ~S-*D                         # d
+keyseq $LATIN_SMALL_LETTER_E   = ~S-*E                         # e
+keyseq $LATIN_SMALL_LETTER_F   = ~S-*F                         # f
+keyseq $LATIN_SMALL_LETTER_G   = ~S-*G                         # g
+keyseq $LATIN_SMALL_LETTER_H   = ~S-*H                         # h
+keyseq $LATIN_SMALL_LETTER_I   = ~S-*I                         # i
+keyseq $LATIN_SMALL_LETTER_J   = ~S-*J                         # j
+keyseq $LATIN_SMALL_LETTER_K   = ~S-*K                         # k
+keyseq $LATIN_SMALL_LETTER_L   = ~S-*L                         # l
+keyseq $LATIN_SMALL_LETTER_M   = ~S-*M                         # m
+keyseq $LATIN_SMALL_LETTER_N   = ~S-*N                         # n
+keyseq $LATIN_SMALL_LETTER_O   = ~S-*O                         # o
+keyseq $LATIN_SMALL_LETTER_P   = ~S-*P                         # p
+keyseq $LATIN_SMALL_LETTER_Q   = ~S-*Q                         # q
+keyseq $LATIN_SMALL_LETTER_R   = ~S-*R                         # r
+keyseq $LATIN_SMALL_LETTER_S   = ~S-*S                         # s
+keyseq $LATIN_SMALL_LETTER_T   = ~S-*T                         # t
+keyseq $LATIN_SMALL_LETTER_U   = ~S-*U                         # u
+keyseq $LATIN_SMALL_LETTER_V   = ~S-*V                         # v
+keyseq $LATIN_SMALL_LETTER_W   = ~S-*W                         # w
+keyseq $LATIN_SMALL_LETTER_X   = ~S-*X                         # x
+keyseq $LATIN_SMALL_LETTER_Y   = ~S-*Y                         # y
+keyseq $LATIN_SMALL_LETTER_Z   = ~S-*Z                         # z
+keyseq $LEFT_CURLY_BRACKET     =  S-*LeftSquareBracket         # {
+keyseq $VERTICAL_LINE          =  S-*ReverseSolidus            # |
+keyseq $RIGHT_CURLY_BRACKET    =  S-*RightSquareBracket        # }
+keyseq $TILDE                  =  S-*GraveAccent               # ~
+keyseq $VERTICAL_LINE          =  S-*YenSign                   # |
diff --git a/contrib/dvorak.mayu b/contrib/dvorak.mayu
new file mode 100644 (file)
index 0000000..1a8b6e1
--- /dev/null
@@ -0,0 +1,98 @@
+#
+# Dvorak layout for \91\8b\8eg\82¢\82Ì\97J\9fT
+#
+# Written by KANAI Makoto <kanai@nadmin.org>
+#         on May. 2, 2000
+#
+# [\8eg\82¢\95û]
+# .mayu\82Ì\92\86\82Å
+#     include "104.mayu"
+# \82É\91±\82¢\82Ä
+#     include "dvorak.mayu"
+# \82Æ\82µ\82Ä\93Ç\82Ý\8d\9e\82Ü\82¹\82é¡
+# \82»\82Ì\8cã\82Í\81A\83A\83\93\83_\81[\83X\83R\83A\95t\82Ì\83L\81[\95Ê\96¼\82ð\8eg\82Á\82½\8ew\92è\82ª\89Â\94\\81B
+# \97á: window EditControl /:Edit$/ : Global
+#     key C-_H => BackSpace
+#
+
+def alias  _A                  = A
+def alias  _B                  = N
+def alias  _C                  = I
+def alias  _D                  = H
+def alias  _E                  = D
+def alias  _F                  = Y
+def alias  _G                  = U
+def alias  _H                  = J
+def alias  _I                  = G
+def alias  _J                  = C
+def alias  _K                  = V
+def alias  _L                  = P
+def alias  _M                  = M
+def alias  _N                  = L
+def alias  _O                  = S
+def alias  _P                  = R
+def alias  _Q                  = X
+def alias  _R                  = O
+def alias  _S                  = Semicolon
+def alias  _T                  = K
+def alias  _U                  = F
+def alias  _V                  = Period
+def alias  _W                  = Comma
+def alias  _X                  = B
+def alias  _Y                  = T
+def alias  _Z                  = Slash
+def alias  _CloseBracket       = Equal
+def alias  _Comma              = W
+def alias  _Equal              = CloseBracket
+def alias  _Minus              = Quote
+def alias  _OpenBracket                = Minus
+def alias  _Period             = E
+def alias  _Quote              = Q
+def alias  _Semicolon          = Z
+def alias  _Slash              = OpenBracket
+#def alias  _BackQuote         = BackQuote
+#def alias  _BackSlash         = BackSlash
+#def alias  _BackSpace         = BackSpace
+#def alias  _Caps              = Caps
+#def alias  _Enter             = Enter
+#def alias  _Escape            = Escape
+#def alias  _Space             = Space
+#def alias  _Tab               = Tab
+
+key *_A                        => *A
+key *_B                        => *B
+key *_C                        => *C
+key *_D                        => *D
+key *_E                        => *E
+key *_F                        => *F
+key *_G                        => *G
+key *_H                        => *H
+key *_I                        => *I
+key *_J                        => *J
+key *_K                        => *K
+key *_L                        => *L
+key *_M                        => *M
+key *_N                        => *N
+key *_O                        => *O
+key *_P                        => *P
+key *_Q                        => *Q
+key *_R                        => *R
+key *_S                        => *S
+key *_T                        => *T
+key *_U                        => *U
+key *_V                        => *V
+key *_W                        => *W
+key *_X                        => *X
+key *_Y                        => *Y
+key *_Z                        => *Z
+key *_CloseBracket     => *CloseBracket
+key *_Comma            => *Comma
+key *_Equal            => *Equal
+key *_Minus            => *Minus
+key *_OpenBracket      => *OpenBracket
+key *_Period           => *Period
+key *_Quote            => *Quote
+key *_Semicolon                => *Semicolon
+key *_Slash            => *Slash
+
+#--
diff --git a/contrib/dvorak109.mayu b/contrib/dvorak109.mayu
new file mode 100644 (file)
index 0000000..290822a
--- /dev/null
@@ -0,0 +1,111 @@
+#
+# Dvorak layout for \91\8b\8eg\82¢\82Ì\97J\9fT
+#
+# Written by KANAI Makoto <kanai@nadmin.org>
+#         on May. 2, 2000
+# Modified by Oota Toshiya <oota@mspd.mt.nec.co.jp>
+#      ver 1.1 2001/11/1
+#
+# [\8eg\82¢\95û]
+# .mayu\82Ì\92\86\82Å
+#     include "109.mayu"
+# \82É\91±\82¢\82Ä
+#     include "dvorak109.mayu"
+# \82Æ\82µ\82Ä\93Ç\82Ý\8d\9e\82Ü\82¹\82é¡
+
+def key EqualsSign Equal               =    0x0d # =+
+#key ~S-*\94¼\8ap/\91S\8ap             = $GRAVE_ACCENT
+#key  S-*\94¼\8ap/\91S\8ap             = $TILDE
+#key  A-\94¼\8ap/\91S\8ap              = $ToggleIME
+#key    *\96³\95Ï\8a·                = *Space
+#key    *\95Ï\8a·          = *Space
+#key    *\82Ð\82ç\82ª\82È              = *Space
+#key    *\89p\90\94          = S-*\89p\90\94
+#key *ReverseSolidus   = *RightShift
+
+
+def alias  _A                  = A
+def alias  _B                  = N
+def alias  _C                  = I
+def alias  _D                  = H
+def alias  _E                  = D
+def alias  _F                  = Y
+def alias  _G                  = U
+def alias  _H                  = J
+def alias  _I                  = G
+def alias  _J                  = C
+def alias  _K                  = V
+def alias  _L                  = P
+def alias  _M                  = M
+def alias  _N                  = L
+def alias  _O                  = S
+def alias  _P                  = R
+def alias  _Q                  = X
+def alias  _R                  = O
+def alias  _S                  = Semicolon
+def alias  _T                  = K
+def alias  _U                  = F
+def alias  _V                  = Period
+def alias  _W                  = Comma
+def alias  _X                  = B
+def alias  _Y                  = T
+def alias  _Z                  = Slash
+def alias  _Comma              = W
+def alias  _Period             = E
+
+key S-*_2              => Atmark
+def subst S-*_6                => $CIRCUMFLEX_ACCENT
+def subst S-*_7                => $AMPERSAND
+key S-*_8              => $ASTERISK
+key S-*_9              => $LEFT_PARENTHESIS
+key S-*_0              => $RIGHT_PARENTHESIS
+key *Minus             => $LEFT_SQUARE_BRACKET
+key S-*Minus           => $LEFT_CURLY_BRACKET
+key *EqualsSign                => $RIGHT_SQUARE_BRACKET
+key S-*EqualsSign      => $RIGHT_CURLY_BRACKET
+key S-*Q               => $QUOTATION_MARK
+key ~S-*Q              => $APOSTROPHE
+key S-*Atmark          => $QUESTION_MARK
+key ~S-*Atmark         => $SOLIDUS
+key S-*OpenBracket     => $PLUS_SIGN
+key ~S-*OpenBracket    => $EQUALS_SIGN
+
+key S-*Colon           => $LOW_LINE
+key ~S-*Colon          => $HYPHEN-MINUS
+key *X                 => *Q
+key S-*CloseBracket    => $TILDE
+key ~S-*CloseBracket   => $GRAVE_ACCENT
+
+key  S-*Z              => $COLON
+key  ~S-*Z             => $SEMICOLON
+
+
+key *_A                        => *A
+key *_B                        => *B
+key *_C                        => *C
+key *_D                        => *D
+key *_E                        => *E
+key *_F                        => *F
+key *_G                        => *G
+key *_H                        => *H
+key *_I                        => *I
+key *_J                        => *J
+key *_K                        => *K
+key *_L                        => *L
+key *_M                        => *M
+key *_N                        => *N
+key *_O                        => *O
+key *_P                        => *P
+key *_R                        => *R
+key *_S                        => *S
+key *_T                        => *T
+key *_U                        => *U
+key *_V                        => *V
+key *_W                        => *W
+key *_X                        => *X
+key *_Y                        => *Y
+key *_Z                        => *Z
+key *_Comma            => *Comma
+key *_Period           => *Period
+
+#--
diff --git a/contrib/keitai.mayu b/contrib/keitai.mayu
new file mode 100644 (file)
index 0000000..52cdea3
--- /dev/null
@@ -0,0 +1,555 @@
+keymap2 \8cg\91Ñ_0 : Global
+keymap2 \8cg\91Ñ_1 : Global
+keymap2 \8cg\91Ñ_2 : Global
+keymap2 \8cg\91Ñ_3 : Global
+keymap2 \8cg\91Ñ_4 : Global
+keymap2 \8cg\91Ñ_5 : Global
+keymap2 \8cg\91Ñ_6 : Global
+keymap2 \8cg\91Ñ_7 : Global
+keymap2 \8cg\91Ñ_8 : Global
+keymap2 \8cg\91Ñ_9 : Global
+keymap2 \8cg\91Ñ_ : Global
+
+keymap2 \8cg\91Ñ____ : Global
+ key *IC-IL-Num0 => BS &Prefix(\8cg\91Ñ_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_ : Global
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_9_9_9_9_9 : Global
+ key *IC-IL-Num3 => BS R A &Prefix(\8cg\91Ñ_9)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_9_9_9_9 : Global
+ key *IC-IL-Num3 => BS R O &Prefix(\8cg\91Ñ_9_9_9_9_9)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_9_9_9 : Global
+ key *IC-IL-Num3 => BS R E &Prefix(\8cg\91Ñ_9_9_9_9)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_9_9 : Global
+ key *IC-IL-Num3 => BS R U &Prefix(\8cg\91Ñ_9_9_9)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_9 : Global
+ key *IC-IL-Num3 => BS R I &Prefix(\8cg\91Ñ_9_9)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_8_8_8_8_8_8 : Global
+ key *IC-IL-Num2 => BS Y A &Prefix(\8cg\91Ñ_8)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_8_8_8_8_8 : Global
+ key *IC-IL-Num2 => BS X Y O &Prefix(\8cg\91Ñ_8_8_8_8_8_8)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_8_8_8_8 : Global
+ key *IC-IL-Num2 => BS X Y U &Prefix(\8cg\91Ñ_8_8_8_8_8)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_8_8_8 : Global
+ key *IC-IL-Num2 => BS X Y A &Prefix(\8cg\91Ñ_8_8_8_8)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_8_8 : Global
+ key *IC-IL-Num2 => BS Y O &Prefix(\8cg\91Ñ_8_8_8)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_8 : Global
+ key *IC-IL-Num2 => BS Y U &Prefix(\8cg\91Ñ_8_8)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_7_7_7_7_7 : Global
+ key *IC-IL-Num1 => BS M A &Prefix(\8cg\91Ñ_7)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_7_7_7_7 : Global
+ key *IC-IL-Num1 => BS M O &Prefix(\8cg\91Ñ_7_7_7_7_7)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_7_7_7 : Global
+ key *IC-IL-Num1 => BS M E &Prefix(\8cg\91Ñ_7_7_7_7)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_7_7 : Global
+ key *IC-IL-Num1 => BS M U &Prefix(\8cg\91Ñ_7_7_7)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_7 : Global
+ key *IC-IL-Num1 => BS M I &Prefix(\8cg\91Ñ_7_7)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+
+keymap2 \8cg\91Ñ_6_6_6_6_6_ : Global
+
+keymap2 \8cg\91Ñ_6_6_6_6_6____ : Global
+ key *IC-IL-Num0 => BS BS B O &Prefix(\8cg\91Ñ_6_6_6_6_6_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6_6___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_6_6_6_6_6____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6_6__ : Global
+ key *IC-IL-Num0 => BS H O Comma &Prefix(\8cg\91Ñ_6_6_6_6_6___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6_6_ : Global
+ key *IC-IL-Num0 => BS P O &Prefix(\8cg\91Ñ_6_6_6_6_6__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6_6 : Global
+ key *IC-IL-Num6 => BS H A &Prefix(\8cg\91Ñ_6)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS B O &Prefix(\8cg\91Ñ_6_6_6_6_6_)
+
+keymap2 \8cg\91Ñ_6_6_6_6_ : Global
+
+keymap2 \8cg\91Ñ_6_6_6_6____ : Global
+ key *IC-IL-Num0 => BS BS B E &Prefix(\8cg\91Ñ_6_6_6_6_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_6_6_6_6____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6__ : Global
+ key *IC-IL-Num0 => BS H E Comma &Prefix(\8cg\91Ñ_6_6_6_6___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6_ : Global
+ key *IC-IL-Num0 => BS P E &Prefix(\8cg\91Ñ_6_6_6_6__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_6 : Global
+ key *IC-IL-Num6 => BS H O &Prefix(\8cg\91Ñ_6_6_6_6_6)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS B E &Prefix(\8cg\91Ñ_6_6_6_6_)
+
+keymap2 \8cg\91Ñ_6_6_6_ : Global
+
+keymap2 \8cg\91Ñ_6_6_6____ : Global
+ key *IC-IL-Num0 => BS BS B U &Prefix(\8cg\91Ñ_6_6_6_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_6_6_6____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6__ : Global
+ key *IC-IL-Num0 => BS F U Comma &Prefix(\8cg\91Ñ_6_6_6___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6_ : Global
+ key *IC-IL-Num0 => BS P U &Prefix(\8cg\91Ñ_6_6_6__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_6 : Global
+ key *IC-IL-Num6 => BS H E &Prefix(\8cg\91Ñ_6_6_6_6)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS B U &Prefix(\8cg\91Ñ_6_6_6_)
+
+keymap2 \8cg\91Ñ_6_6_ : Global
+
+keymap2 \8cg\91Ñ_6_6____ : Global
+ key *IC-IL-Num0 => BS BS B I &Prefix(\8cg\91Ñ_6_6_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_6_6____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6__ : Global
+ key *IC-IL-Num0 => BS H I Comma &Prefix(\8cg\91Ñ_6_6___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6_ : Global
+ key *IC-IL-Num0 => BS P I &Prefix(\8cg\91Ñ_6_6__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_6 : Global
+ key *IC-IL-Num6 => BS F U &Prefix(\8cg\91Ñ_6_6_6)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS B I &Prefix(\8cg\91Ñ_6_6_)
+
+keymap2 \8cg\91Ñ_6_ : Global
+
+keymap2 \8cg\91Ñ_6____ : Global
+ key *IC-IL-Num0 => BS BS B A &Prefix(\8cg\91Ñ_6_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_6____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6__ : Global
+ key *IC-IL-Num0 => BS H A Comma &Prefix(\8cg\91Ñ_6___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6_ : Global
+ key *IC-IL-Num0 => BS P A &Prefix(\8cg\91Ñ_6__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_6 : Global
+ key *IC-IL-Num6 => BS H I &Prefix(\8cg\91Ñ_6_6)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS B A &Prefix(\8cg\91Ñ_6_)
+keymap2 \8cg\91Ñ_5_5_5_5_5 : Global
+ key *IC-IL-Num5 => BS N A &Prefix(\8cg\91Ñ_5)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_5_5_5_5 : Global
+ key *IC-IL-Num5 => BS N O &Prefix(\8cg\91Ñ_5_5_5_5_5)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_5_5_5 : Global
+ key *IC-IL-Num5 => BS N E &Prefix(\8cg\91Ñ_5_5_5_5)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_5_5 : Global
+ key *IC-IL-Num5 => BS N U &Prefix(\8cg\91Ñ_5_5_5)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_5 : Global
+ key *IC-IL-Num5 => BS N I &Prefix(\8cg\91Ñ_5_5)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_4_4_4_4_4_4 : Global
+ key *IC-IL-Num4 => BS T A &Prefix(\8cg\91Ñ_4)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+
+keymap2 \8cg\91Ñ_4_4_4_4_4_ : Global
+
+keymap2 \8cg\91Ñ_4_4_4_4_4____ : Global
+ key *IC-IL-Num0 => BS BS D O &Prefix(\8cg\91Ñ_4_4_4_4_4_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4_4___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_4_4_4_4_4____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4_4__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_4_4_4_4_4___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4_4_ : Global
+ key *IC-IL-Num0 => BS T O &Prefix(\8cg\91Ñ_4_4_4_4_4__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4_4 : Global
+ key *IC-IL-Num4 => BS X T U &Prefix(\8cg\91Ñ_4_4_4_4_4_4)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS D O &Prefix(\8cg\91Ñ_4_4_4_4_4_)
+
+keymap2 \8cg\91Ñ_4_4_4_4_ : Global
+
+keymap2 \8cg\91Ñ_4_4_4_4____ : Global
+ key *IC-IL-Num0 => BS BS D E &Prefix(\8cg\91Ñ_4_4_4_4_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_4_4_4_4____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_4_4_4_4___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4_ : Global
+ key *IC-IL-Num0 => BS T E &Prefix(\8cg\91Ñ_4_4_4_4__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_4 : Global
+ key *IC-IL-Num4 => BS T O &Prefix(\8cg\91Ñ_4_4_4_4_4)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS D E &Prefix(\8cg\91Ñ_4_4_4_4_)
+
+keymap2 \8cg\91Ñ_4_4_4_ : Global
+
+keymap2 \8cg\91Ñ_4_4_4____ : Global
+ key *IC-IL-Num0 => BS BS D U &Prefix(\8cg\91Ñ_4_4_4_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_4_4_4____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_4_4_4___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4_ : Global
+ key *IC-IL-Num0 => BS T U &Prefix(\8cg\91Ñ_4_4_4__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_4 : Global
+ key *IC-IL-Num4 => BS T E &Prefix(\8cg\91Ñ_4_4_4_4)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS D U &Prefix(\8cg\91Ñ_4_4_4_)
+
+keymap2 \8cg\91Ñ_4_4_ : Global
+
+keymap2 \8cg\91Ñ_4_4____ : Global
+ key *IC-IL-Num0 => BS BS D I &Prefix(\8cg\91Ñ_4_4_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_4_4____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_4_4___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4_ : Global
+ key *IC-IL-Num0 => BS T I &Prefix(\8cg\91Ñ_4_4__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_4 : Global
+ key *IC-IL-Num4 => BS T U &Prefix(\8cg\91Ñ_4_4_4)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS D I &Prefix(\8cg\91Ñ_4_4_)
+
+keymap2 \8cg\91Ñ_4_ : Global
+
+keymap2 \8cg\91Ñ_4____ : Global
+ key *IC-IL-Num0 => BS BS D A &Prefix(\8cg\91Ñ_4_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_4____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_4___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4_ : Global
+ key *IC-IL-Num0 => BS T A &Prefix(\8cg\91Ñ_4__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_4 : Global
+ key *IC-IL-Num4 => BS T I &Prefix(\8cg\91Ñ_4_4)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS D A &Prefix(\8cg\91Ñ_4_)
+
+keymap2 \8cg\91Ñ_3_3_3_3_3_ : Global
+
+keymap2 \8cg\91Ñ_3_3_3_3_3____ : Global
+ key *IC-IL-Num0 => BS BS Z O &Prefix(\8cg\91Ñ_3_3_3_3_3_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3_3___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_3_3_3_3_3____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3_3__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_3_3_3_3_3___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3_3_ : Global
+ key *IC-IL-Num0 => BS S O &Prefix(\8cg\91Ñ_3_3_3_3_3__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3_3 : Global
+ key *IC-IL-Num9 => BS S A &Prefix(\8cg\91Ñ_3)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS Z O &Prefix(\8cg\91Ñ_3_3_3_3_3_)
+
+keymap2 \8cg\91Ñ_3_3_3_3_ : Global
+
+keymap2 \8cg\91Ñ_3_3_3_3____ : Global
+ key *IC-IL-Num0 => BS BS Z E &Prefix(\8cg\91Ñ_3_3_3_3_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_3_3_3_3____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_3_3_3_3___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3_ : Global
+ key *IC-IL-Num0 => BS S E &Prefix(\8cg\91Ñ_3_3_3_3__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_3 : Global
+ key *IC-IL-Num9 => BS S O &Prefix(\8cg\91Ñ_3_3_3_3_3)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS Z E &Prefix(\8cg\91Ñ_3_3_3_3_)
+
+keymap2 \8cg\91Ñ_3_3_3_ : Global
+
+keymap2 \8cg\91Ñ_3_3_3____ : Global
+ key *IC-IL-Num0 => BS BS Z U &Prefix(\8cg\91Ñ_3_3_3_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_3_3_3____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_3_3_3___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3_ : Global
+ key *IC-IL-Num0 => BS S U &Prefix(\8cg\91Ñ_3_3_3__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_3 : Global
+ key *IC-IL-Num9 => BS S E &Prefix(\8cg\91Ñ_3_3_3_3)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS Z U &Prefix(\8cg\91Ñ_3_3_3_)
+
+keymap2 \8cg\91Ñ_3_3_ : Global
+
+keymap2 \8cg\91Ñ_3_3____ : Global
+ key *IC-IL-Num0 => BS BS J I &Prefix(\8cg\91Ñ_3_3_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_3_3____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_3_3___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3_ : Global
+ key *IC-IL-Num0 => BS S I &Prefix(\8cg\91Ñ_3_3__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_3 : Global
+ key *IC-IL-Num9 => BS S U &Prefix(\8cg\91Ñ_3_3_3)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS J I &Prefix(\8cg\91Ñ_3_3_)
+
+keymap2 \8cg\91Ñ_3_ : Global
+
+keymap2 \8cg\91Ñ_3____ : Global
+ key *IC-IL-Num0 => BS BS Z A &Prefix(\8cg\91Ñ_3_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_3____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_3___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3_ : Global
+ key *IC-IL-Num0 => BS S A &Prefix(\8cg\91Ñ_3__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_3 : Global
+ key *IC-IL-Num9 => BS S I &Prefix(\8cg\91Ñ_3_3)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS Z A &Prefix(\8cg\91Ñ_3_)
+
+keymap2 \8cg\91Ñ_2_2_2_2_2_ : Global
+
+keymap2 \8cg\91Ñ_2_2_2_2_2____ : Global
+ key *IC-IL-Num0 => BS BS G O &Prefix(\8cg\91Ñ_2_2_2_2_2_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2_2___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_2_2_2_2_2____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2_2__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_2_2_2_2_2___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2_2_ : Global
+ key *IC-IL-Num0 => BS K O &Prefix(\8cg\91Ñ_2_2_2_2_2__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2_2 : Global
+ key *IC-IL-Num8 => BS K A &Prefix(\8cg\91Ñ_2)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS G O &Prefix(\8cg\91Ñ_2_2_2_2_2_)
+
+keymap2 \8cg\91Ñ_2_2_2_2_ : Global
+
+keymap2 \8cg\91Ñ_2_2_2_2____ : Global
+ key *IC-IL-Num0 => BS BS G E &Prefix(\8cg\91Ñ_2_2_2_2_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_2_2_2_2____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_2_2_2_2___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2_ : Global
+ key *IC-IL-Num0 => BS K E &Prefix(\8cg\91Ñ_2_2_2_2__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_2 : Global
+ key *IC-IL-Num8 => BS K O &Prefix(\8cg\91Ñ_2_2_2_2_2)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS G E &Prefix(\8cg\91Ñ_2_2_2_2_)
+
+keymap2 \8cg\91Ñ_2_2_2_ : Global
+
+keymap2 \8cg\91Ñ_2_2_2____ : Global
+ key *IC-IL-Num0 => BS BS G U &Prefix(\8cg\91Ñ_2_2_2_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_2_2_2____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_2_2_2___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2_ : Global
+ key *IC-IL-Num0 => BS K U &Prefix(\8cg\91Ñ_2_2_2__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_2 : Global
+ key *IC-IL-Num8 => BS K E &Prefix(\8cg\91Ñ_2_2_2_2)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS G U &Prefix(\8cg\91Ñ_2_2_2_)
+
+keymap2 \8cg\91Ñ_2_2_ : Global
+
+keymap2 \8cg\91Ñ_2_2____ : Global
+ key *IC-IL-Num0 => BS BS G I &Prefix(\8cg\91Ñ_2_2_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_2_2____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_2_2___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2_ : Global
+ key *IC-IL-Num0 => BS K I &Prefix(\8cg\91Ñ_2_2__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_2 : Global
+ key *IC-IL-Num8 => BS K U &Prefix(\8cg\91Ñ_2_2_2)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS G I &Prefix(\8cg\91Ñ_2_2_)
+
+keymap2 \8cg\91Ñ_2_ : Global
+
+keymap2 \8cg\91Ñ_2____ : Global
+ key *IC-IL-Num0 => BS BS G A &Prefix(\8cg\91Ñ_2_)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2___ : Global
+ key *IC-IL-Num0 => BS FullStop &Prefix(\8cg\91Ñ_2____)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2__ : Global
+ key *IC-IL-Num0 => Comma &Prefix(\8cg\91Ñ_2___)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2_ : Global
+ key *IC-IL-Num0 => BS K A &Prefix(\8cg\91Ñ_2__)
+ key *IC-IL-\81¨ => &Ignore
+keymap2 \8cg\91Ñ_2 : Global
+ key *IC-IL-Num8 => BS K I &Prefix(\8cg\91Ñ_2_2)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => BS G A &Prefix(\8cg\91Ñ_2_)
+keymap2 \8cg\91Ñ_1_1_1_1_1_1_1_1_1_1 : Global
+ key *IC-IL-Num7 => BS A &Prefix(\8cg\91Ñ_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1_1_1_1_1_1_1_1 : Global
+ key *IC-IL-Num7 => BS X O &Prefix(\8cg\91Ñ_1_1_1_1_1_1_1_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1_1_1_1_1_1_1 : Global
+ key *IC-IL-Num7 => BS X E &Prefix(\8cg\91Ñ_1_1_1_1_1_1_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1_1_1_1_1_1 : Global
+ key *IC-IL-Num7 => BS X U &Prefix(\8cg\91Ñ_1_1_1_1_1_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1_1_1_1_1 : Global
+ key *IC-IL-Num7 => BS X I &Prefix(\8cg\91Ñ_1_1_1_1_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1_1_1_1 : Global
+ key *IC-IL-Num7 => BS X A &Prefix(\8cg\91Ñ_1_1_1_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1_1_1 : Global
+ key *IC-IL-Num7 => BS O &Prefix(\8cg\91Ñ_1_1_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1_1 : Global
+ key *IC-IL-Num7 => BS E &Prefix(\8cg\91Ñ_1_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1_1 : Global
+ key *IC-IL-Num7 => BS U &Prefix(\8cg\91Ñ_1_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_1 : Global
+ key *IC-IL-Num7 => BS I &Prefix(\8cg\91Ñ_1_1)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_0_0_0 : Global
+ key *IC-IL-NumFullStop => BS W A &Prefix(\8cg\91Ñ_0)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_0_0 : Global
+ key *IC-IL-NumFullStop => BS N N &Prefix(\8cg\91Ñ_0_0_0)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap2 \8cg\91Ñ_0 : Global
+ key *IC-IL-NumFullStop => BS W O &Prefix(\8cg\91Ñ_0_0)
+ key *IC-IL-\81¨ => &Ignore
+ key *IC-IL-Num0 => &Prefix(\8cg\91Ñ_)
+keymap Global
+ key *IC-IL-NumFullStop => W A &Prefix(\8cg\91Ñ_0)
+ key *IC-IL-Num7 => A &Prefix(\8cg\91Ñ_1)
+ key *IC-IL-Num8 => K A &Prefix(\8cg\91Ñ_2)
+ key *IC-IL-Num9 => S A &Prefix(\8cg\91Ñ_3)
+ key *IC-IL-Num4 => T A &Prefix(\8cg\91Ñ_4)
+ key *IC-IL-Num5 => N A &Prefix(\8cg\91Ñ_5)
+ key *IC-IL-Num6 => H A &Prefix(\8cg\91Ñ_6)
+ key *IC-IL-Num1 => M A &Prefix(\8cg\91Ñ_7)
+ key *IC-IL-Num2 => Y A &Prefix(\8cg\91Ñ_8)
+ key *IC-IL-Num3 => R A &Prefix(\8cg\91Ñ_9)
diff --git a/contrib/mayu-settings.txt b/contrib/mayu-settings.txt
new file mode 100644 (file)
index 0000000..0069fab
--- /dev/null
@@ -0,0 +1,200 @@
+\83p\83b\83P\81[\83W\82É\8aÜ\82Ü\82ê\82é\90Ý\92è\83t\83@\83C\83\8b\82É\82Â\82¢\82Ä  by HANAWA Yoshio\81i\92P\82È\82é\88ê\83\86\81[\83U\81[\81j
+
+.mayu\82ð\8f\91\82­\8dÛ\82É\81A\8dÅ\8f\89\82©\82ç\82 \82é\83t\83@\83C\83\8b\82ª\89½\82È\82Ì\82©\82í\82©\82ç\82È\82¢\82Æ
+\8bê\82µ\82¢\82Æ\8ev\82¢\82Ü\82µ\82½\82Ì\82Å\81A\83}\83j\83\85\83A\83\8b\82É\92Ç\89Á\82µ\82Ä\82­\82ê\81A\82Æ\82¢\82¤\88Ó\96¡\82Å
+\88ê\83\86\81[\83U\81[\82Å\82 \82é\8e\84\81i\88È\89º\81A\95M\8eÒ\81j\82ª\82±\82Ì\83t\83@\83C\83\8b\82ð\8dì\8eÒ\82É\83v\83\8c\83[\83\93\83g\82µ\82½\82Æ\82±\82ë\81A
+\82±\82Ì\83t\83@\83C\83\8b\82à\83p\83b\83P\81[\83W\82É\8aÜ\82Ü\82ê\82é\82±\82Æ\82É\82È\82è\82Ü\82µ\82½\81B
+\82±\82ê\82©\82ç\90Ý\92è\82ð\92²\90®\82·\82é\95û\82Ì\8eQ\8dl\82É\82È\82ê\82Î\8dK\82¢\82Å\82·\81B
+
+
+104.mayu        \89p\8cê\83L\81[\83{\81[\83h\97p\92è\8b`\83t\83@\83C\83\8b
+104on109.mayu   \89p\8cê\83L\81[\83{\81[\83h\82ð\93ú\96{\8cê\83L\81[\83{\81[\83h\95\97\82É\8eg\82¤\90Ý\92è
+109.mayu        \93ú\96{\8cê\83L\81[\83{\81[\83h\97p\92è\8b`\83t\83@\83C\83\8b
+109on104.mayu   \93ú\96{\8cê\83L\81[\83{\81[\83h\82ð\89p\8cê\83L\81[\83{\81[\83h\95\97\82É\8eg\82¤\90Ý\92è
+default.mayu    \81i\8dì\8eÒ\8dD\82Ý\82Ì\81j\95Ö\97\98\82È\90Ý\92è\82Ì\93ü\82Á\82½\83t\83@\83C\83\8b
+dot.mayu        \83f\83t\83H\83\8b\83g\82Ì\90Ý\92è\83t\83@\83C\83\8b
+emacsedit.mayu  emacs\82É\8e\97\82¹\82½\83L\81[\83}\83b\83v\82Ì\92è\8b`
+
+contrib/98x1.mayu          NEC PC-98x1\97p\82Ì\90Ý\92è
+contrib/ax.mayu            AX\83L\81[\83{\81[\83h\97p\82Ì\90Ý\92è
+contrib/dvorak.mayu        \95\81\92Ê\82Ì\83L\81[\83{\81[\83h\82Ådvorak\95\97\82É\8eg\82¤\90Ý\92è
+contrib/keitai.mayu        IME\93ü\97Í\8e\9e\82É\83e\83\93\83L\81[\82Å\8cg\91Ñ\93d\98b\95\97\82É\8eg\82¤\90Ý\92è
+contrib/mayu-settings.txt  \82±\82Ì\83t\83@\83C\83\8b
+
+
+\82±\82ê\82ç\82É\82Â\82¢\82Ä\8f\87\82É\90à\96¾\82µ\82Ä\82¢\82­\82Æ\81A
+
+104.mayu
+\89p\8cê\83L\81[\83{\81[\83h\82Å\82Ì\83L\81[\96¼\82Ì\92è\8b`\82ð\82µ\82Ä\82¢\82é\82¾\82¯\82Å\81A
+\82±\82ê\82¾\82¯\82Å\82Í\83L\81[\94z\92u\82É\8aÖ\82µ\82Ä\82Í\89½\82à\95Ï\82í\82è\82Ü\82¹\82ñ\82ª\81A
+\82±\82ê\82ª\82È\82¢\82Æ\89½\82à\93®\82«\82Ü\82¹\82ñ\82Ì\82Å\81A
+\81i\89p\8cê\83L\81[\83{\81[\83h\82È\82ç\82Î\81j\95K\82¸\8dÅ\8f\89\82É\93Ç\82Ý\8d\9e\82ñ\82Å\82­\82¾\82³\82¢\81B
+
+
+104on109.mayu
+\93ú\96{\8cê\83L\81[\83{\81[\83h\82ð\8eg\82í\82´\82é\82ð\93¾\82È\82¢\82à\82Ì\82Ì\81A
+\89p\8cê\83L\81[\83{\81[\83h\82É\97]\82è\82É\8aµ\82ê\82Ä\82¢\82é\82½\82ß\81A
+\83L\81[\83g\83b\83v\82Ì\95\8e\9a\82Æ\82Í\88Ù\82È\82Á\82Ä\82µ\82Ü\82¤\82É\82à\8aÖ\82í\82ç\82¸
+\89p\8cê\83L\81[\83{\81[\83h\82Æ\93¯\82\94z\92u\82É\82µ\82½\82¢\90l\82Ì\82½\82ß\82Ì\90Ý\92è\83t\83@\83C\83\8b\82Å\82·\81B
+\81i\95M\8eÒ\82Í\8fí\97p\82µ\82Ä\82¨\82è\82Ü\82·\81j
+\8bï\91Ì\93I\82É\82Í\81A
+  [\94¼\8ap/\91S\8ap]         => [`]
+  [Shift]+[\94¼\8ap/\91S\8ap] => [~]
+  [Alt]+[\94¼\8ap/\91S\8ap]   => IME on/off
+  [Shift]+[2]         => [@]
+  [Shift]+[6]         => [^]
+  [Shift]+[7]         => [&]
+  [Shift]+[8]         => [*]
+  [Shift]+[9]         => [(]
+  [Shift]+[0]         => [)]
+  [Shift]+[-]         => [_]
+  [^]                 => [=]
+  [Shift]+[^]         => [+]
+  [@]                 => [[]
+  [Shift]+[@]         => [{]
+  [[]                 => []]
+  [Shift]+[[]         => [}]
+  []]                 => [\]
+  [Shift]+[]]         => [|]
+  [Shift]+[;]         => [:]
+  [:]                 => [']
+  [Shift]+[:]         => ["]
+  [\96³\95Ï\8a·]            => [Space]
+  [\95Ï\8a·]              => [Space]
+  [\82Ð\82ç\82ª\82È]          => [Space]
+  [\89p\90\94]              => [Shift]+[\89p\90\94]
+  \81w\81__\82ë\81x           => [Shift]
+\82Æ\82È\82Á\82Ä\82¢\82Ü\82·\81B
+\81w]}\82Þ\81v\81x\82Ì\83L\81[\82É\88á\98a\8a´\82ð\8ao\82¦\82Ü\82·\82ª\81A
+Enter \82É\82µ\82Ä\82µ\82Ü\82¤\82Ì\82à\8eè\82©\82Æ\8ev\82¢\82Ü\82·\81B
+\81i\95M\8eÒ\82Í\82Ç\82¤\82Å\82à\82æ\82¢\82Ì\82Å\82·\82ª\81B
+  \82Æ\82¢\82¤\82Ì\82à\81A Enter \82Í C-m \82Ì\82Ý\82Æ\82¢\82¤\83|\83\8a\83V\81[\82È\82Ì\82Å\81j
+\91å\92ï\82Ì\90l\82Í\82±\82ê\82Å\96\9e\91«\82È\82Ì\82Å\82Í\82È\82¢\82Å\82µ\82å\82¤\82©\81B
+109\82ð\8eg\82Á\82Ä\82¢\82Ä\82à\81A\83h\83\89\83C\83o\82¾\82¯104\82É\82µ\82Ä\82µ\82Ü\82¦\82Î
+\93¯\82\82æ\82¤\82È\82±\82Æ\82ª\8eÀ\8c»\82Å\82«\82Ü\82·\82ª\81A
+\91¼\90l\82à\8eg\82¤\82æ\82¤\82È\83}\83V\83\93\82Å\82 \82ê\82Î\81A
+mayu\82ð\83C\83\93\83X\83g\81[\83\8b\82µ\82Ä104on109\82Å\8eg\82¤\95û\82ª\82¨\91E\82ß\82Å\82·\81B
+
+
+109.mayu
+\93ú\96{\8cê\83L\81[\83{\81[\83h\82Å\82Ì\83L\81[\96¼\82Ì\92è\8b`\82ð\82µ\82Ä\82¢\82é\82¾\82¯\82Å\81A
+\82±\82ê\82¾\82¯\82Å\82Í\83L\81[\94z\92u\82É\8aÖ\82µ\82Ä\82Í\89½\82à\95Ï\82í\82è\82Ü\82¹\82ñ\82ª\81A
+\82±\82ê\82ª\82È\82¢\82Æ\89½\82à\93®\82«\82Ü\82¹\82ñ\82Ì\82Å\81A
+\81i\93ú\96{\8cê\83L\81[\83{\81[\83h\82È\82ç\82Î\81j\95K\82¸\8dÅ\8f\89\82É\93Ç\82Ý\8d\9e\82ñ\82Å\82­\82¾\82³\82¢\81B
+
+
+109on104.mayu
+\89p\8cê\83L\81[\83{\81[\83h\82ð\8eg\82í\82´\82é\82ð\93¾\82È\82¢\82à\82Ì\82Ì\81A
+\93ú\96{\8cê\83L\81[\83{\81[\83h\82É\97]\82è\82É\8aµ\82ê\82Ä\82¢\82é\82½\82ß\81A
+\83L\81[\83g\83b\83v\82Ì\95\8e\9a\82Æ\82Í\88Ù\82È\82Á\82Ä\82µ\82Ü\82¤\82É\82à\8aÖ\82í\82ç\82¸
+\93ú\96{\8cê\83L\81[\83{\81[\83h\82Æ\93¯\82\94z\92u\82É\82µ\82½\82¢\90l\82Ì\82½\82ß\82Ì\90Ý\92è\83t\83@\83C\83\8b\82Å\82·\81B
+\82±\82ê\82ð\8fí\97p\82µ\82Ä\82¢\82é\90l\82Í\90¢\8aE\92\86\92T\82µ\82Ä\82à\82¢\82È\82¢\82Æ\8ev\82í\82ê\82Ü\82·\82Ì\82Å\81A
+\8d¡\82Ð\82Æ\82Â\97û\82ê\82Ä\82¢\82È\82¢\82Í\82¸\82Å\82·\81B\81i\8dì\8eÒ\82Í\8bH\82É\8eg\82¤\82»\82¤\82Å\82·\82ª\81j
+\8eg\82¢\82±\82ñ\82Å\82Ý\82Ä\81A\8a´\91z\82â\97v\96]\82ð\8dì\8eÒ\82É\91\97\82é\82Æ\8aì\82Î\82ê\82Ü\82·\81B
+
+
+default.mayu
+\8dì\8eÒ\82Ì\8eï\96¡\82É\8f]\82Á\82Ä\8dì\82ç\82ê\82½\81A\95Î\82Á\82½\83f\83t\83H\83\8b\83g\90Ý\92è\83t\83@\83C\83\8b\82Å\82·\81B
+\82±\82ê\82ð$HOME/.mayu\82Å\93Ç\82Ý\8d\9e\82ß\82Î\81AUN*X\8eg\82¢\82Í\8dK\82¹\82É\82È\82ê\82é\82Í\82¸\82Å\82·\81B
+\82¨\82¨\82Ü\82©\82É\8c¾\82¤\82Æ\81AUN*X\82âemacs\82ð\8fí\97p\82µ\82Ä\82¢\82é\90l\8cü\82¯\82Ì\90Ý\92è\82Å\82·\81B
+\83o\81[\83W\83\87\83\93\83A\83b\83v\82Ì\82½\82Ñ\82É\96³\8bO\93¹\82É\91\9d\82¦\82Ä\82¢\82­\82Ì\82Å\81A
+\91S\82Ä\82ð\90à\96¾\82·\82é\82Ì\82Í\95s\89Â\94\\82¾\82Æ\8ev\82¢\82Ü\82·\82ª\81A
+\89Â\94\\82È\94Í\88Í\82Å\97ñ\8b\93\82µ\82Ä\82¢\82«\82Ü\82·\81B
+1. Caps\82Ü\82½\82Í\89p\90\94\83L\81[\82ðCtrl\83L\81[\82É\82µ\82Ü\82·\81B\81i\93ü\82ê\91Ö\82¦\82Å\82Í\82 \82è\82Ü\82¹\82ñ\81j
+2. 109\83L\81[\83{\81[\83h\82Å\82©\82Â104on109\82ð\8eg\82Á\82Ä\82¢\82È\82¢\8fê\8d\87\81A
+   ESC\83L\81[\82Æ\94¼\8ap/\91S\8ap\83L\81[\82ð\93ü\82ê\91Ö\82¦\82Ü\82·\81B
+   \81i104on109\82ª\97L\8cø\82È\8fê\8d\87\82Í\81A\94¼\8ap/\91S\8ap\83L\81[\82Í\81u~\81v\82É\82È\82è\82Ü\82·\81j
+3. [Ctrl]+[Shift]+[\89½\82©\82Ì\83L\81[]\82Å\8c»\8dÝ\82Ì\83E\83C\83\93\83h\83E\82É\91Î\82·\82é\91\80\8dì\82ª\82Å\82«\82Ü\82·\81B
+     \92N\82ª\8dl\88Ä\8eÒ\82È\82Ì\82©\8dì\8eÒ\82ç\82à\92m\82è\82Ü\82¹\82ñ\82ª\81A\96^\8f\8a\82Å\82Ìtwm\82Ì\93®\8dì\82ð\93¥\8fP\82µ\82Ä\82¢\82Ü\82·\81B
+       C-S-[\96î\88ó\83L\81[]  \82Å\83E\83C\83\93\83h\83E\82ð\88Ú\93®
+       C-S-A-[\96î\88ó\83L\81[]\82Å\83E\83C\83\93\83h\83E\82ð\8f¬\82³\82­\88Ú\93®
+       C-S-z \82Å\8dÅ\91å\89»(zoom)
+       C-S-x \82Å\8fc\95û\8cü\82Ì\82Ý\8dÅ\91å\89»
+       C-S-c \82Å\89¡\95û\8cü\82Ì\82Ý\8dÅ\91å\89»
+       C-S-i \82Å\8dÅ\8f¬\89»(iconify)
+       C-S-k \82Å\95Â\82\82é(kill)
+       C-S-[a/e/p/n] \82Å\82»\82Ì\83E\83C\83\93\83h\83E\82ð\8d¶/\89E/\8fã/\89º\92[\82É\8d\87\82í\82¹\82é(emacs\95\97?)
+       C-S-l \82Å\82»\82Ì\83E\83C\83\93\83h\83E\82ª\83t\83H\81[\83J\83X\82ð\8e\9d\82Á\82½\82Ü\82Ü\88ê\94Ô\89º\82É(lower)
+       C-S-r \82Å\82»\82Ì\83E\83C\83\93\83h\83E\82ª\83t\83H\81[\83J\83X\82ð\8e\9d\82Á\82½\82Ü\82Ü\88ê\94Ô\8fã\82É(raise)
+       C-S-v \82Å\82»\82Ì\83E\83C\83\93\83h\83E\82ð\8c©\82¦\82é\88Ê\92u\82É\8e\9d\82Á\82Ä\82­\82é(visible?)
+     \82È\82Ç\82È\82Ç\81B
+     \8dÅ\8cã\82Ì\82à\82Ì\82Í\81A\82»\82Ì\91\8b\82ª\83}\83E\83X\82Å\82Ç\82¤\82â\82Á\82Ä\82à\82Â\82©\82ß\82È\82¢\8fê\8f\8a\82É\8ds\82Á\82½\82Æ\82«\82É
+     \82±\82ê\88È\8aO\82É\89ð\8c\88\95û\96@\82ª\82È\82¢\82Ù\82Ç\95Ö\97\98\82Å\82·\81B\81iWindows\95W\8f\80\82Å\82à\89Â\94\\82Å\82·\82¯\82Ç\81j
+     \82Ü\82½\81A\83t\83H\81[\83J\83X\82ð\8aO\82³\82È\82¢\82Å\8e©\95ª\8e©\90g\82Ì\8cã\82ë\82Ì\91\8b\82ð\8c©\82½\82¢\82Æ\82«\82É
+     lower&raise \82Í\95Ö\97\98\82Å\82·\81B\81iWindows\95W\8f\80\82Å\82Í\95s\89Â\94\\82È\93®\8dì\82Å\82·\81j
+     \83L\81[\88ê\94­\82Å\8dÅ\91å\89»\82à\95È\82É\82È\82è\82Ü\82·\81B
+4. C-\ \82ÅIME\82Ì\83I\83\93/\83I\83t\82ð\82Å\82«\82é\82æ\82¤\82É\82µ\82Ü\82·\81B
+     \88ê\95\94\82ÌUN*X\82Å\8dL\82­\8eg\82í\82ê\82Ä\82¢\82é\81Aegg\82Ì\83L\81[\83o\83C\83\93\83f\83B\83\93\83O\82Å\82·\81B
+5. \91½\82­\82Ì\83A\83v\83\8a\83P\81[\83V\83\87\83\93\82Åemacs\95\97\82È\83L\81[\93ü\97Í\82ð\8eó\82¯\95t\82¯\82Ü\82·\81B
+     \83\81\83\82\92 \82âInternetExplorer\81ANetScape\82È\82Ç\82ªemacs\95\97\82É\82È\82è\82Ü\82·\81B
+     \95M\8eÒ\82Í\82Ù\82Æ\82ñ\82Ç\8eg\82í\82È\82¢\82Ì\82Å\82·\82ª\81AWord\82âPowerPoint\82È\82Ç\82ÌOffice\90»\95i\81A
+     Becky!\82âEdmax\82È\82Ç\82Ì\83\81\81[\83\89\81[\82Å\82àemacs\95\97\82É\93®\82­\82æ\82¤\82Å\82·\81B
+     \83\81\83\82\92 \82È\82Ç\82ÅC-a\82Å\8ds\93ª\82É\8ds\82±\82¤\82Æ\82µ\82Ä\91S\95\94\91I\91ð\82µ\82Ä\82µ\82Ü\82¤\90l\81A
+     IE\82ânetscape\82ÅC-h\82Å\88ê\95\8e\9a\8fÁ\82»\82¤\82Æ\82µ\82Ä\83q\83X\83g\83\8a\82ð\8fo\82µ\82Ä\82µ\82Ü\82¤\90l\81A
+     \82Ü\82½\81A\83\81\83\82\92 \82ÅC-x C-s\82Å\83Z\81[\83u\82µ\82»\82¤\82É\82È\82é\90l\82É\82¨\91E\82ß\82Å\82·\81B
+6. NT\83R\83\93\83\\81[\83\8b\82ÆTeraTerm\82Å\81Akterm\95\97\82Ì\91\80\8dì\82ð\89Â\94\\82É\82µ\82Ü\82·\81B
+     UN*X\82ð\95\81\92i\8eg\82Á\82Ä\82¢\82é\90l\82Å\82à\81A\88Ó\8aO\82É\92m\82ç\82È\82¢\90l\82ª\91½\82¢\82Ì\82Å\82·\82ª\81A
+     xterm/kterm(UN*X\82Ì\95W\8f\80\93I\83R\83\93\83\\81[\83\8b)\82Å\82Í\81A
+       Shift+Insert\82Å\83y\81[\83X\83g\81A
+       Shift+PageUp/Down\82Å\8fã\89º\83X\83N\83\8d\81[\83\8b
+     \82ª\82Å\82«\82Ü\82·\81B\82±\82ê\82ðNT\83R\83\93\83\\81[\83\8b\82ÆTeraTerm\82Å\82à\82Å\82«\82é\82æ\82¤\82É\82µ\82Ü\82·\81B
+7. \83}\83C\83\93\83X\83C\81[\83p\82ª\83L\81[\83{\81[\83h\82¾\82¯\82Å\91\80\8dì\82Å\82«\82Ü\82·\81B
+     \83e\83\93\83L\81[\82Å\83}\83E\83X\83J\81[\83\\83\8b\88Ú\93®
+     z,x,c\83L\81[\82ª\82»\82ê\82¼\82ê\89E\83{\83^\83\93\81A\8d\89E\93¯\8e\9e\89\9f\82µ\81A\8d\83{\83^\83\93
+     \81i\8d\8eè\82Å\88µ\82¤\82½\82ß\81A\83}\83E\83X\82Æ\82Í\94z\92u\82ª\8bt\82Å\82·\81j
+8. \82»\82Ì\91¼\81A\83A\83v\83\8a\82²\82Æ\82Ì\90Ý\92è\81B
+     \97á\82¦\82Î\81ATeraTerm \82Å\82Í C-/ \82Ì\83L\81[\93ü\97Í\81iemacs\82Ìundo\81j\82ð
+     \93`\82¦\82Ä\82­\82ê\82È\82¢\82Æ\82¢\82¤\96â\91è\93_\82ª\82 \82è\82Ü\82·\82ª\81A
+     TeraTerm \8fã\82Å C-/ \82ª\89\9f\82³\82ê\82½\82ç C-_ \82ª\89\9f\82³\82ê\82½\82æ\82¤\82É\90U\95\91\82¤\82±\82Æ\82Å
+     \82±\82ê\82ð\89ð\8c\88\82µ\82Ä\82¢\82Ü\82·\81B\81i\82±\82ê\82Å\82Í\89ð\8c\88\82É\82È\82ç\82È\82¢\90l\82¢\82Ü\82·\82©\81H\81j
+
+
+\91¼\82É\82à\81A\96\9c\90l\82ª\8aì\82Ô\82Æ\8dì\8eÒ\82ª\8ev\82Á\82½\82ç\82Ç\82ñ\82Ç\82ñ\92Ç\89Á\82³\82ê\82Ä\82¢\82­\82Í\82¸\82Å\82·\81B
+\82Ü\82½\82Í\81A7\82Ì\83}\83C\83\93\83X\83C\81[\83p\82Ì\82æ\82¤\82É\81A\92N\82à\96À\98f\82ð\94í\82ç\82È\82¢\82Æ\8ev\82í\82ê\81A
+\82©\82Â\96Ê\94\92\82¯\82ê\82Î\8dÌ\97p\82³\82ê\82é\82©\82à\82µ\82ê\82Ü\82¹\82ñ\81B
+\95Ö\97\98\82È\81A\82Ü\82½\82Í\96Ê\94\92\82¢\90Ý\92è\82ª\82 \82è\82Ü\82µ\82½\82çML\82É\93\8a\8de\82µ\82Ä\82Ý\82Ä\89º\82³\82¢\81B
+
+emacs\95\97\83L\81[\83o\83C\83\93\83f\83B\83\93\83O\82É\82µ\82È\82¢\95û\82Í\82±\82Ì\83t\83@\83C\83\8b\82ð\93Ç\82Ý\8d\9e\82Ü\82¸\81A
+\82à\82µ\82±\82Ì\83t\83@\83C\83\8b\92\86\82Ì\95Ö\97\98\82È\95\94\95ª\82ª\82 \82é\82Ì\82È\82ç\82Î\81A\82»\82Ì\95\94\95ª\82ð
+$HOME/.mayu\82É\92Ç\8bL\82·\82é\82Ì\82ª\82¢\82¢\82©\82Æ\8ev\82¢\82Ü\82·\81B
+emacs\82É\8aµ\82ê\82½\95û\82Í$HOME/.mayu\82Å\82±\82Ì\83t\83@\83C\83\8b\82ðinclude\82µ\81A
+\95s\96\9e\82È\93_\82ð$HOME/.mayu\93à\82Å\83I\81[\83o\81[\83\89\83C\83h\82·\82ê\82Î\82æ\82¢\82©\82Æ\8ev\82¢\82Ü\82·\81B
+
+
+dot.mayu
+.mayu\82Ì\83T\83\93\83v\83\8b\82Å\82·\81B
+\83f\83t\83H\83\8b\83g\82Å\81u\91I\91ð\81v\82Ì\91Î\8fÛ\82É\82È\82Á\82Ä\82¢\82Ü\82·\81B
+define\82É\82æ\82è\81A\89p\8cê104\83L\81[\83{\81[\83h\82©\93ú\96{\8cê109\83L\81[\83{\81[\83h\82©(USE104)\81A
+\89p\8cê\83L\81[\83{\81[\83h\82È\82ç\82Î109\95\97\83L\81[\83o\83C\83\93\83f\83B\83\93\83O\82É\82·\82é\82©\82Ç\82¤\82©(USE109on104)\81A
+\93ú\96{\8cê\83L\81[\83{\81[\83h\82È\82ç\82Î104\95\97\83L\81[\83o\83C\83\93\83f\83B\83\93\83O\82É\82·\82é\82©\82Ç\82¤\82©(USE104on109)\81A
+\82»\82ê\82¼\82ê\82Ì\8fê\8d\87\82Édefault.mayu\82ð\93Ç\82Ý\82±\82Þ\82©\82Ç\82¤\82©(USEdefault)\82ð\91I\91ð\82Å\82«\82Ü\82·\81B
+
+
+emacsedit.mayu
+UN*X\82Å\95W\8f\80\93I\82È\81A\83L\81[\83o\83C\83\93\83f\83B\83\93\83O\82ª\93Æ\93Á\82È\83G\83f\83B\83^\82Å\82 \82é\81A
+emacs\82É\8e\97\82½\93®\8dì\82ð\8eÀ\8c»\82³\82¹\82é\82½\82ß\82Ì\90Ý\92è\83t\83@\83C\83\8b\82Å\82·\81B
+default.mayu\82Å\93Ç\82Ý\82±\82Ü\82ê\82Ä\82¢\82Ü\82·\81B
+
+
+contrib/98x1.mayu
+contrib/ax.mayu
+contrib/dvorak.mayu
+\82±\82ê\82ç\82Ì\83t\83@\83C\83\8b\82Í\81Amayu\82Ì\83\86\81[\83U\81[\82©\82ç\92ñ\8b\9f\82³\82ê\82½\83t\83@\83C\83\8b\82Å\82·\81B
+PC-98x1\97p\82Ì\90Ý\92è\83t\83@\83C\83\8b\82Æ\81A
+AX\83L\81[\83{\81[\83h\97p\82Ì\90Ý\92è\83t\83@\83C\83\8b\82Æ\81A
+\95\81\92Ê\82Ì\83L\81[\83{\81[\83h\82Ådvorak\95\97\82É\8eg\82¤\90Ý\92è\82Ì\82æ\82¤\82Å\82·\81B
+\8ec\94O\82È\82ª\82ç\95M\8eÒ\82Í\8eg\82Á\82½\82±\82Æ\82ª\82 \82è\82Ü\82¹\82ñ\82ª\81A
+ML\82Ì\89ß\8b\8e\83\8d\83O\82ª\8eQ\8dl\82É\82È\82é\82©\82à\82µ\82ê\82Ü\82¹\82ñ\81B
+
+
+contrib/keitai.mayu
+\95M\8eÒ\82ª\83V\83\83\83\8c\82Å\8dì\82Á\82½\83t\83@\83C\83\8b\82Å\82·\81B\83L\81[\83{\81[\83h\82Ì\94z\92u\82Í\8ao\82¦\82Ä\82¢\82È\82¢\82¯\82ê\82Ç\82à\81A
+\8cg\91Ñ\93d\98b\82Å\83\81\81[\83\8b\82ð\8f\91\82­\82Ì\82Í\88Ù\8fí\82É\91¬\82¢\81A\82Æ\82¢\82¤\90l\8cü\82¯\82Å\82· :-)
+IME\83I\83\93\82Ì\8fó\91Ô\82Å\81A\82©\82È\93ü\97Í\82ª\83e\83\93\83L\81[\82¾\82¯\82Å\8ds\82¦\82Ü\82·\81B
+\8eÀ\97p\82É\82È\82é\82Æ\82Í\8ev\82¦\82Ü\82¹\82ñ\82ª\81A\8eQ\8dl\82Æ\82¢\82¤\82±\82Æ\82Å\81B
+
+
+2000/03/02  written by HANAWA Yoshio <hanawa@is.s.u-tokyo.ac.jp>
+2000/04/06  rewritten by HANAWA Yoshio
+2000/04/24  fixed small bug by TAGA Nayuta <nayuta@i.am>
+2000/05/06  fixed obsolete articles for mayu-3.11 by HANAWA Yoshio
diff --git a/d/.cvsignore b/d/.cvsignore
new file mode 100755 (executable)
index 0000000..e526118
--- /dev/null
@@ -0,0 +1,7 @@
+*.log\r
+*.err\r
+obj\r
+objfre\r
+objchk\r
+objfre_wxp_x86\r
+objchk_wxp_x86\r
diff --git a/d/Makefile b/d/Makefile
new file mode 100644 (file)
index 0000000..45387cc
--- /dev/null
@@ -0,0 +1,17 @@
+!include $(NTMAKEENV)\makefile.def
+
+clean:
+       -del buildfre.log
+       -del i386\mayud.sys
+       -del i386\mayud.pdb
+       -del obj\_objects.mac
+       -del objfre\i386\*.obj
+       -del objfre\i386\*.mac
+       -del objfre_wxp_x86\i386\*.obj
+       -del objfre_wxp_x86\*.mac
+       -del *~
+       -rd obj
+       -rd objfre\i386
+       -rd objfre
+       -rd objfre_wxp_x86\i386
+       -rd objfre_wxp_x86
diff --git a/d/README.txt b/d/README.txt
new file mode 100644 (file)
index 0000000..9ab9cda
--- /dev/null
@@ -0,0 +1,75 @@
+
+
+                       \91\8b\8eg\82¢\82Ì\97J\9fT\83h\83\89\83C\83o
+
+
+1. \83R\83\93\83p\83C\83\8b\95û\96@
+
+       Windows 200 DDK \82Æ Visual C++ 6.0 \82Å build \83\86\81[\83e\83B\83\8a\83e\83B\82ð\97\98
+       \97p\82µ\82Ä\83R\83\93\83p\83C\83\8b\82µ\82Ü\82·\81B
+
+       > cd mayu\d
+       > build
+       > cd nt4
+       > build
+
+       mayud.sys \82ð %windir%\system32\drivers\ \82Ö\83R\83s\81[\82µ test.reg \82ð
+       \93ü\97Í\82·\82ê\82Î\81A\8eè\93®\82Å\83f\83o\83C\83X\82ð on/off \82Å\82«\82Ü\82·\81B(\96\94\82Í Windows
+       NT4.0 \82Ì\8fê\8d\87\82Í mayudnt4.sys \82ð mayud.sys \82Æ\82¢\82¤\96¼\91O\82Å\83R\83s\81[)
+
+
+2. \8eg\82¢\95û
+
+       mayud \82ð\93®\8dì\82³\82¹\82é\82Æ
+
+             \\.\MayuDetour1
+
+       \82Æ\82¢\82¤\83f\83o\83C\83X\82ª\82Å\82«\82Ü\82·\81B\82±\82Ì\83f\83o\83C\83X\82ð GENERIC_READ |
+       GENERIC_WRITE \82Å\8aJ\82«\82Ü\82·\81B
+
+       ReadFile / WriteFile \82Å\82Í\81A\88È\89º\82Ì\8d\\91¢\91Ì\82ð\8eg\82¢\82Ü\82·\81B\83f\83o\83C\83X\82ð
+       \8aJ\82¢\82½\82 \82Æ\82É\81AReadFile \82·\82é\82Æ\83\86\81[\83U\81[\82ª\93ü\97Í\82µ\82½\83L\81[\82ð\8eæ\93¾\82Å\82«
+       \82Ü\82·\81BWriteFile \82·\82é\82Æ\83\86\81[\83U\82ª\82 \82½\82©\82à\83L\81[\82ð\93ü\97Í\82µ\82½\82©\82Ì\82æ\82¤\82É 
+       Windows \82ð\91\80\8dì\82·\82é\82±\82Æ\82ª\82Å\82«\82Ü\82·\81B
+
+       struct KEYBOARD_INPUT_DATA
+       {
+         enum { BREAK = 1,
+                E0 = 2, E1 = 4,
+                TERMSRV_SET_LED = 8 };
+         enum { KEYBOARD_OVERRUN_MAKE_CODE = 0xFF };
+         
+         USHORT UnitId;
+         USHORT MakeCode;
+         USHORT Flags; 
+         USHORT Reserved;
+         ULONG ExtraInformation;
+       };
+
+       UnitId \82Æ Reserved \82Í\8fí\82É 0 \82Å\82·\81BExtraInformation \82É\92l\82ð\90Ý\92è
+       \82·\82é\82Æ\81AWM_KEYDOWN \82È\82Ç\82Ì\83\81\83b\83Z\81[\83W\82ª\97\88\82½\8e\9e\82É 
+       GetMessageExtraInfo() API \82Å\82»\82Ì\92l\82ð\8eæ\93¾\82·\82é\82±\82Æ\82ª\82Å\82«\82Ü\82·\81B
+       MakeCode \82Í\83L\81[\83{\81[\83h\82Ì\83X\83L\83\83\83\93\83R\81[\83h\82Å\82·\81BFlags \82Í BREAK, E0,
+       E1, TERMSRV_SET_LED \82ª\91g\82Ý\8d\87\82í\82³\82Á\82Ä\82¢\82Ü\82·\81BBREAK \82Í\83L\81[\82ð\97£\82µ
+       \82½\82Æ\82«\81AE0 \82Æ E1 \82Í\8ag\92£\83L\81[\82ð\89\9f\82µ\82½\82Æ\82«\82É\90Ý\92è\82³\82ê\82Ü\82·\81B
+
+
+3. \83o\83O
+
+       * ReadFile \82ª ERROR_OPERATION_ABORTED \82Å\8e¸\94s\82µ\82½\8fê\8d\87\82à\82¤\88ê\93
+         ReadFile \82·\82é\95K\97v\82ª\82 \82è\82Ü\82·\81B
+
+       * \95¡\90\94\82Ì\83X\83\8c\83b\83h\82©\82ç mayud \83f\83o\83C\83X\82ð read \82·\82é\82Æ
+         MULTIPLE_IRP_COMPLETE_REQUESTS (0x44) \82Å\97\8e\82¿\82é\82±\82Æ\82ª\82 \82é\82æ\82¤
+         \82Å\82·\81B\8dÄ\8c»\90«\82Í\95s\96¾\81B
+
+       * ReadFile \82·\82é\82Æ\83\86\81[\83U\81[\82ª\93ü\97Í\82·\82é\82Ü\82Å\89i\89\93\82É\8bA\82Á\82Ä\82«\82Ü\82¹\82ñ\81B
+         NT4.0 \82È\82ç\82Î\95Ê\83X\83\8c\83b\83h\82Å CancelIo \82·\82é\82±\82Æ\82Å ReadFile \82ð\83L\83\83
+         \83\93\83Z\83\8b\82·\82é\82±\82Æ\82ª\82Å\82«\82Ü\82·\82ª\81AWindows 2000 \82Å\82Í\95û\96@\82ª\82 \82è\82Ü\82¹
+         \82ñ\81B
+
+       * PnP \82Í\8dl\97\82µ\82Ä\82¢\82Ü\82¹\82ñ\81B\82Â\82Ü\82è\81A\83L\81[\83{\81[\83h\82ð\82Â\82¯\82½\82è\97£\82µ\82½\82è
+         \82·\82é\82Æ\82Ç\82¤\82È\82é\82©\82í\82©\82è\82Ü\82¹\82ñ\81B
+
+       * \83L\81[\83{\81[\83h\82ª\93ñ\82Â\88È\8fã\82 \82é\82Æ\82«\82Å\82à\81A\83f\83o\83C\83X\82Í\88ê\82Â\82µ\82©\82Å\82«\82Ü\82¹
+         \82ñ\81B
diff --git a/d/SOURCES b/d/SOURCES
new file mode 100644 (file)
index 0000000..87a13e5
--- /dev/null
+++ b/d/SOURCES
@@ -0,0 +1,8 @@
+TARGETNAME=    mayud
+TARGETTYPE=    DRIVER
+TARGETPATH=    .
+USE_MAPSYM=    1
+
+INCLUDES=      $(BASEDIR)\inc;.
+
+SOURCES=       mayud.c log.c
diff --git a/d/i386/.cvsignore b/d/i386/.cvsignore
new file mode 100755 (executable)
index 0000000..0150ff7
--- /dev/null
@@ -0,0 +1 @@
+*.pdb\r
diff --git a/d/i386/mayud.sys b/d/i386/mayud.sys
new file mode 100755 (executable)
index 0000000..88a1650
Binary files /dev/null and b/d/i386/mayud.sys differ
diff --git a/d/ioctl.h b/d/ioctl.h
new file mode 100755 (executable)
index 0000000..f5ed828
--- /dev/null
+++ b/d/ioctl.h
@@ -0,0 +1,19 @@
+#ifndef _IOCTL_H\r
+#define _IOCTL_H\r
+\r
+#define TOUCHPAD_SCANCODE 0xfe\r
+\r
+// Ioctl value\r
+#define IOCTL_MAYU_DETOUR_CANCEL                                        \\r
+CTL_CODE(FILE_DEVICE_KEYBOARD, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)\r
+\r
+#define IOCTL_MAYU_GET_VERSION                                  \\r
+CTL_CODE(FILE_DEVICE_KEYBOARD, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)\r
+\r
+#define IOCTL_MAYU_GET_LOG                                      \\r
+CTL_CODE(FILE_DEVICE_KEYBOARD, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)\r
+\r
+#define IOCTL_MAYU_FORCE_KEYBOARD_INPUT                                 \\r
+CTL_CODE(FILE_DEVICE_KEYBOARD, 0x804, METHOD_BUFFERED, FILE_WRITE_ACCESS)\r
+\r
+#endif // !_IOCTL_H\r
diff --git a/d/keyque.c b/d/keyque.c
new file mode 100644 (file)
index 0000000..0ae9453
--- /dev/null
@@ -0,0 +1,152 @@
+///////////////////////////////////////////////////////////////////////////////
+// keyque.c
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Definitions
+
+
+typedef struct KeyQue
+{
+  ULONG count;                 // Number of keys in the que
+  ULONG lengthof_que;          // Length of que
+  KEYBOARD_INPUT_DATA *insert; // Insertion pointer for que
+  KEYBOARD_INPUT_DATA *remove; // Removal pointer for que
+  KEYBOARD_INPUT_DATA *que;
+} KeyQue;
+
+
+#define KeyQueSize 100
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Prototypes
+
+
+NTSTATUS KqInitialize(KeyQue *kq);
+void KqClear(KeyQue *kq);
+NTSTATUS KqFinalize(KeyQue *kq);
+BOOLEAN KqIsEmpty(KeyQue *kq);
+ULONG KqEnque(KeyQue *kq, IN  KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf);
+ULONG KqDeque(KeyQue *kq, OUT KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf);
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text( init, KqInitialize )
+#pragma alloc_text( page, KqFinalize )
+#endif // ALLOC_PRAGMA
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Functions
+
+
+NTSTATUS KqInitialize(KeyQue *kq)
+{
+  kq->count = 0;
+  kq->lengthof_que = KeyQueSize;
+  kq->que = ExAllocatePool(NonPagedPool,
+                          kq->lengthof_que * sizeof(KEYBOARD_INPUT_DATA));
+  kq->insert = kq->que;
+  kq->remove = kq->que;
+  if (kq->que == NULL)
+    return STATUS_INSUFFICIENT_RESOURCES;
+  else
+    return STATUS_SUCCESS;
+}
+
+
+void KqClear(KeyQue *kq)
+{
+  kq->count = 0;
+  kq->insert = kq->que;
+  kq->remove = kq->que;
+}
+
+
+NTSTATUS KqFinalize(KeyQue *kq)
+{
+  if (kq->que)
+    ExFreePool(kq->que);
+  return STATUS_SUCCESS;
+}
+
+
+BOOLEAN KqIsEmpty(KeyQue *kq)
+{
+  return 0 == kq->count;
+}
+
+
+// return: lengthof copied data
+ULONG KqEnque(KeyQue *kq, IN KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf)
+{
+  ULONG rest;
+  
+  if (kq->lengthof_que - kq->count < lengthof_buf) // overflow
+    lengthof_buf = kq->lengthof_que - kq->count; // chop overflowed datum
+  if (lengthof_buf <= 0)
+    return 0;
+
+  rest = kq->lengthof_que - (kq->insert - kq->que);
+  if (rest < lengthof_buf)
+  {
+    ULONG copy = rest;
+    if (0 < copy)
+    {
+      RtlMoveMemory((PCHAR)kq->insert, (PCHAR)buf,
+                   sizeof(KEYBOARD_INPUT_DATA) * copy);
+      buf += copy;
+    }
+    copy = lengthof_buf - copy;
+    if (0 < copy)
+      RtlMoveMemory((PCHAR)kq->que, (PCHAR)buf,
+                   sizeof(KEYBOARD_INPUT_DATA) * copy);
+    kq->insert = kq->que + copy;
+  }
+  else
+  {
+    RtlMoveMemory((PCHAR)kq->insert, (PCHAR)buf,
+                 sizeof(KEYBOARD_INPUT_DATA) * lengthof_buf);
+    kq->insert += lengthof_buf;
+  }
+  kq->count += lengthof_buf;
+  return lengthof_buf;
+}
+
+
+// return: lengthof copied data
+ULONG KqDeque(KeyQue *kq, OUT KEYBOARD_INPUT_DATA *buf, IN ULONG lengthof_buf)
+{
+  ULONG rest;
+  
+  if (kq->count < lengthof_buf)
+    lengthof_buf = kq->count;
+  if (lengthof_buf <= 0)
+    return 0;
+
+  rest = kq->lengthof_que - (kq->remove - kq->que);
+  if (rest < lengthof_buf)
+  {
+    ULONG copy = rest;
+    if (0 < copy)
+    {
+      RtlMoveMemory((PCHAR)buf, (PCHAR)kq->remove,
+                   sizeof(KEYBOARD_INPUT_DATA) * copy);
+      buf += copy;
+    }
+    copy = lengthof_buf - copy;
+    if (0 < copy)
+      RtlMoveMemory((PCHAR)buf, (PCHAR)kq->que,
+                   sizeof(KEYBOARD_INPUT_DATA) * copy);
+    kq->remove = kq->que + copy;
+  }
+  else
+  {
+    RtlMoveMemory((PCHAR)buf, (PCHAR)kq->remove,
+                 sizeof(KEYBOARD_INPUT_DATA) * lengthof_buf);
+    kq->remove += lengthof_buf;
+  }
+  kq->count -= lengthof_buf;
+  return lengthof_buf;
+}
diff --git a/d/log.c b/d/log.c
new file mode 100755 (executable)
index 0000000..9ba964b
--- /dev/null
+++ b/d/log.c
@@ -0,0 +1,164 @@
+#if DBG\r
+\r
+#include <ntddk.h>\r
+#include <stdarg.h>\r
+\r
+#include "log.h"\r
+\r
+#define BUF_MAX_SIZE 128\r
+\r
+typedef struct _logEntry {\r
+  LIST_ENTRY listEntry;\r
+  UNICODE_STRING log;\r
+} logEntry;\r
+\r
+static LIST_ENTRY s_logList;\r
+static KSPIN_LOCK s_logListLock;\r
+static PIRP s_irp;\r
+\r
+void mayuLogInit(const char *message)\r
+{\r
+  InitializeListHead(&s_logList);\r
+  KeInitializeSpinLock(&s_logListLock);\r
+  s_irp = NULL;\r
+  mayuLogEnque(message);\r
+}\r
+\r
+void mayuLogTerm()\r
+{\r
+  if (s_irp)\r
+  {\r
+    IoReleaseCancelSpinLock(s_irp->CancelIrql);\r
+    s_irp->IoStatus.Status = STATUS_CANCELLED;\r
+    s_irp->IoStatus.Information = 0;\r
+    IoCompleteRequest(s_irp, IO_NO_INCREMENT);\r
+    s_irp = NULL;\r
+  }\r
+}\r
+\r
+void mayuLogEnque(const char *fmt, ...)\r
+{\r
+  va_list argp;\r
+  logEntry *entry;\r
+  ANSI_STRING ansiBuf;\r
+  UNICODE_STRING unicodeBuf;\r
+  CHAR buf[BUF_MAX_SIZE] = "";\r
+  WCHAR wbuf[BUF_MAX_SIZE] = L"";\r
+  USHORT i, j;\r
+  ULONG ul;\r
+  PUNICODE_STRING punicode;\r
+\r
+  entry = (logEntry*)ExAllocatePool(NonPagedPool, sizeof(logEntry));\r
+  if (!entry)\r
+    return;\r
+  entry->log.Length = 0;\r
+  entry->log.MaximumLength = BUF_MAX_SIZE;\r
+  entry->log.Buffer = (PWSTR)ExAllocatePool(NonPagedPool, BUF_MAX_SIZE);\r
+\r
+  unicodeBuf.Length = 0;\r
+  unicodeBuf.MaximumLength = BUF_MAX_SIZE;\r
+  unicodeBuf.Buffer = wbuf;\r
+\r
+  ansiBuf.Length = 0;\r
+  ansiBuf.MaximumLength = BUF_MAX_SIZE;\r
+  ansiBuf.Buffer = buf;\r
+\r
+  va_start(argp, fmt);\r
+  for (i = j = 0; i < BUF_MAX_SIZE; ++i)\r
+  {\r
+    ansiBuf.Buffer[i - j] = fmt[i];\r
+    if (fmt[i] == '\0')\r
+    {\r
+      ansiBuf.Length = i - j;\r
+      RtlAnsiStringToUnicodeString(&unicodeBuf, &ansiBuf, FALSE);\r
+      RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);\r
+      break;\r
+    }\r
+    if (fmt[i] == '%')\r
+    {\r
+      ansiBuf.Length = i - j;\r
+      RtlAnsiStringToUnicodeString(&unicodeBuf, &ansiBuf, FALSE);\r
+      RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);\r
+      switch(fmt[++i])\r
+      {\r
+      case 'x':\r
+        ul = va_arg(argp, ULONG);\r
+        RtlIntegerToUnicodeString(ul, 16, &unicodeBuf);\r
+        RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);\r
+        break;\r
+      case 'd':\r
+        ul = va_arg(argp, ULONG);\r
+        RtlIntegerToUnicodeString(ul, 10, &unicodeBuf);\r
+        RtlAppendUnicodeStringToString(&entry->log, &unicodeBuf);\r
+        break;\r
+      case 'T':\r
+        punicode = va_arg(argp, PUNICODE_STRING);\r
+        RtlAppendUnicodeStringToString(&entry->log, punicode);\r
+      }      \r
+      j = i + 1;\r
+    }\r
+  }\r
+  va_end(argp);\r
+\r
+  ExInterlockedInsertTailList(&s_logList, &entry->listEntry, &s_logListLock);\r
+\r
+  if (s_irp)\r
+  {\r
+    KIRQL cancelIrql;\r
+\r
+    mayuLogDeque(s_irp);\r
+    IoAcquireCancelSpinLock(&cancelIrql);\r
+    IoSetCancelRoutine(s_irp, NULL);\r
+    IoReleaseCancelSpinLock(cancelIrql);\r
+    IoCompleteRequest(s_irp, IO_NO_INCREMENT);\r
+    s_irp = NULL;\r
+  }\r
+}\r
+\r
+VOID mayuLogCancel(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)\r
+{\r
+  s_irp = NULL;\r
+  IoReleaseCancelSpinLock(irp->CancelIrql);\r
+  irp->IoStatus.Status = STATUS_CANCELLED;\r
+  irp->IoStatus.Information = 0;\r
+  IoCompleteRequest(irp, IO_NO_INCREMENT);\r
+}\r
+\r
+NTSTATUS mayuLogDeque(PIRP irp)\r
+{\r
+  KIRQL currentIrql;\r
+\r
+  KeAcquireSpinLock(&s_logListLock, &currentIrql);\r
+  if (IsListEmpty(&s_logList) == TRUE)\r
+  {\r
+    KIRQL cancelIrql;\r
+\r
+    IoAcquireCancelSpinLock(&cancelIrql);\r
+    IoMarkIrpPending(irp);\r
+    s_irp = irp;\r
+    IoSetCancelRoutine(irp, mayuLogCancel);\r
+    IoReleaseCancelSpinLock(cancelIrql);\r
+    KeReleaseSpinLock(&s_logListLock, currentIrql);\r
+    irp->IoStatus.Information = 0;\r
+    irp->IoStatus.Status = STATUS_PENDING;\r
+  }\r
+  else\r
+  {\r
+    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);\r
+    PLIST_ENTRY pListEntry;\r
+    logEntry *pEntry;\r
+\r
+    KeReleaseSpinLock(&s_logListLock, currentIrql);\r
+    pListEntry = ExInterlockedRemoveHeadList(&s_logList, &s_logListLock);\r
+    pEntry = CONTAINING_RECORD(pListEntry, logEntry, listEntry);\r
+    RtlCopyMemory(irp->AssociatedIrp.SystemBuffer,\r
+                  pEntry->log.Buffer, pEntry->log.Length);\r
+    irp->IoStatus.Information = pEntry->log.Length;\r
+    irp->IoStatus.Status = STATUS_SUCCESS;\r
+    ExFreePool(pEntry->log.Buffer);\r
+    ExFreePool(pEntry);\r
+  }\r
+  return irp->IoStatus.Status;\r
+}\r
+\r
+#endif // DBG\r
diff --git a/d/log.h b/d/log.h
new file mode 100755 (executable)
index 0000000..5a139cb
--- /dev/null
+++ b/d/log.h
@@ -0,0 +1,28 @@
+#ifndef _LOG_H\r
+#define _LOG_H\r
+\r
+#if DBG\r
+\r
+// Initiallize logging queue and enqueue "message" as\r
+// first log.\r
+void mayuLogInit(const char *message);\r
+\r
+// Finalize logging queue.\r
+void mayuLogTerm(void);\r
+\r
+// Enqueue one message to loggin queue.\r
+// Use printf like format to enqueue,\r
+// following types are available.\r
+// %x: (ULONG)unsigned long in hexadecimal\r
+// %d: (ULONG)unsigned long in decimal\r
+// %T: (PUNICODE)pointer to unicode string\r
+// Notice: specifing minimal width such as "%2d"\r
+//         is unavailable yet.\r
+void mayuLogEnque(const char *fmt, ...);\r
+\r
+// Dequeue one message from logging queue to "irp".\r
+NTSTATUS mayuLogDeque(PIRP irp);\r
+\r
+#endif // DBG\r
+\r
+#endif // !_LOG_H\r
diff --git a/d/mayud.c b/d/mayud.c
new file mode 100644 (file)
index 0000000..e8d20e9
--- /dev/null
+++ b/d/mayud.c
@@ -0,0 +1,1242 @@
+///////////////////////////////////////////////////////////////////////////////
+// Driver for Madotsukai no Yu^utsu for Windows2000
+
+
+#include <ntddk.h>
+#include <ntddkbd.h>
+#include <devioctl.h>
+
+#pragma warning(3 : 4061 4100 4132 4701 4706)
+
+#include "ioctl.h"
+#include "keyque.c"
+
+//#define USE_TOUCHPAD // very experimental!
+
+#if DBG
+// Enable debug logging only on checked build:
+// We use macro to avoid function call overhead
+// in non-logging case, and use double paren such
+// as DEBUG_LOG((...)) because of va_list in macro.
+#include "log.h"
+#define DEBUG_LOG_INIT(x) mayuLogInit x
+#define DEBUG_LOG_TERM(x) mayuLogTerm x
+#define DEBUG_LOG(x) mayuLogEnque x
+#define DEBUG_LOG_RETRIEVE(x) mayuLogDeque x
+#else
+#define DEBUG_LOG_INIT(x)
+#define DEBUG_LOG_TERM(x)
+#define DEBUG_LOG(x)
+#define DEBUG_LOG_RETRIEVE(x) STATUS_INVALID_DEVICE_REQUEST
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Device Extensions
+
+struct _DetourDeviceExtension;
+struct _FilterDeviceExtension;
+
+typedef struct _DetourDeviceExtension
+{
+  PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
+
+  KSPIN_LOCK lock; // lock below datum
+  PDEVICE_OBJECT filterDevObj;
+  LONG isOpen;
+  BOOLEAN wasCleanupInitiated; //
+  PIRP irpq;
+  KeyQue readQue; // when IRP_MJ_READ, the contents of readQue are returned
+} DetourDeviceExtension;
+
+typedef struct _FilterDeviceExtension
+{
+  PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
+  
+  PDEVICE_OBJECT detourDevObj;
+  PDEVICE_OBJECT kbdClassDevObj; // keyboard class device object
+  
+#ifdef USE_TOUCHPAD
+  BOOLEAN isKeyboard;
+#endif
+  KSPIN_LOCK lock; // lock below datum
+  PIRP irpq;
+  KeyQue readQue; // when IRP_MJ_READ, the contents of readQue are returned
+#ifdef USE_TOUCHPAD
+  BOOLEAN isTouched;
+#endif
+} FilterDeviceExtension;
+
+///////////////////////////////////////////////////////////////////////////////
+// Protorypes (TODO)
+
+
+NTSTATUS DriverEntry       (IN PDRIVER_OBJECT, IN PUNICODE_STRING);
+NTSTATUS mayuAddDevice     (IN PDRIVER_OBJECT, IN PDEVICE_OBJECT);
+VOID mayuUnloadDriver      (IN PDRIVER_OBJECT);
+VOID mayuDetourReadCancel (IN PDEVICE_OBJECT, IN PIRP);
+
+NTSTATUS filterGenericCompletion (IN PDEVICE_OBJECT, IN PIRP, IN PVOID);
+NTSTATUS filterReadCompletion    (IN PDEVICE_OBJECT, IN PIRP, IN PVOID);
+
+NTSTATUS mayuGenericDispatch (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS detourCreate        (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS detourClose         (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS detourRead          (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS detourWrite         (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS detourCleanup       (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS detourDeviceControl (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS filterRead          (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS filterPassThrough   (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS detourPnP           (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS filterPnP           (IN PDEVICE_OBJECT, IN PIRP);
+#ifndef MAYUD_NT4
+NTSTATUS detourPower         (IN PDEVICE_OBJECT, IN PIRP);
+NTSTATUS filterPower         (IN PDEVICE_OBJECT, IN PIRP);
+#endif // !MAYUD_NT4
+
+BOOLEAN CancelKeyboardClassRead(IN PIRP, IN PDEVICE_OBJECT);
+NTSTATUS readq(KeyQue*, PIRP);
+
+#ifdef USE_TOUCHPAD
+NTSTATUS filterTouchpadCompletion (IN PDEVICE_OBJECT, IN PIRP, IN PVOID);
+NTSTATUS filterTouchpad      (IN PDEVICE_OBJECT, IN PIRP);
+#endif
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text( init, DriverEntry )
+#endif // ALLOC_PRAGMA
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Global Constants / Variables
+
+BOOLEAN g_isPnP;
+BOOLEAN g_isXp;
+ULONG g_SpinLock_offset;
+ULONG g_RequestIsPending_offset;
+
+// Device names
+#define UnicodeString(str) { sizeof(str) - sizeof(UNICODE_NULL),       \
+                            sizeof(str) - sizeof(UNICODE_NULL), str }
+
+static UNICODE_STRING MayuDetourDeviceName =
+UnicodeString(L"\\Device\\MayuDetour0");
+
+static UNICODE_STRING MayuDetourWin32DeviceName =
+UnicodeString(L"\\DosDevices\\MayuDetour1");
+
+static UNICODE_STRING KeyboardClassDeviceName =
+UnicodeString(DD_KEYBOARD_DEVICE_NAME_U L"0");
+
+static UNICODE_STRING KeyboardClassDriverName =
+UnicodeString(L"\\Driver\\kbdclass");
+
+#ifdef USE_TOUCHPAD
+#define TOUCHPAD_PRESSURE_OFFSET 7
+#endif
+
+// Global Variables
+PDRIVER_DISPATCH _IopInvalidDeviceRequest; // Default dispatch function
+
+
+#define MAYUD_MODE L""
+static UNICODE_STRING MayuDriverVersion =
+UnicodeString(L"$Revision: 1.27 $" MAYUD_MODE);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Entry / Unload
+
+void DEBUG_LOGChain(PDRIVER_OBJECT driverObject)
+{
+  PDEVICE_OBJECT deviceObject = driverObject->DeviceObject;
+
+  if (deviceObject)
+  {
+    while (deviceObject->NextDevice)
+    {
+      DEBUG_LOG(("%x->", deviceObject));
+      deviceObject = deviceObject->NextDevice;
+    }
+    DEBUG_LOG(("%x", deviceObject));
+  }
+  return;
+}
+
+// initialize driver
+NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject,
+                    IN PUNICODE_STRING registryPath)
+{
+  NTSTATUS status;
+  BOOLEAN is_symbolicLinkCreated = FALSE;
+  ULONG i;
+  PDEVICE_OBJECT detourDevObj = NULL;
+  DetourDeviceExtension *detourDevExt = NULL;
+  ULONG start = 0;
+  RTL_QUERY_REGISTRY_TABLE query[2];
+  
+  UNREFERENCED_PARAMETER(registryPath);
+
+  DEBUG_LOG_INIT(("mayud: start logging"));
+
+  // Environment specific initialize
+  RtlZeroMemory(query, sizeof(query));
+  query[0].Name = L"Start";
+  query[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+  query[0].EntryContext = &start;
+  RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, L"mayud", query, NULL, NULL);
+  if (start == 0x03) {
+    g_isPnP = TRUE;
+    DEBUG_LOG(("is PnP"));
+  } else {
+    g_isPnP = FALSE;
+    DEBUG_LOG(("is not PnP"));
+  }
+#ifdef MAYUD_NT4
+  g_isXp = FALSE;
+  g_SpinLock_offset = 48;
+  g_RequestIsPending_offset = 0;
+#else /* !MAYUD_NT4 */
+  if (IoIsWdmVersionAvailable(1, 0x20)) { // is WindowsXP
+    DEBUG_LOG(("is WindowsXp"));
+    g_isXp = TRUE;
+    g_SpinLock_offset = 108;
+    g_RequestIsPending_offset = 0;
+  } else if (IoIsWdmVersionAvailable(1, 0x10)) { // is Windows2000
+    DEBUG_LOG(("is Windows2000"));
+    g_isXp =FALSE;
+    g_SpinLock_offset = 116;
+    g_RequestIsPending_offset = 48;
+  } else { // Unknown version
+    DEBUG_LOG(("unknown Windows"));
+    status = STATUS_UNKNOWN_REVISION;
+    goto error;
+  }
+#endif /* MAYUD_NT4 */
+
+  // initialize global variables
+  _IopInvalidDeviceRequest = driverObject->MajorFunction[IRP_MJ_CREATE];
+  
+  // set major functions
+  driverObject->DriverUnload = mayuUnloadDriver;
+  if (g_isPnP == TRUE) {
+    driverObject->DriverExtension->AddDevice = mayuAddDevice;
+  }
+  for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+#ifdef MAYUD_NT4
+    if (i != IRP_MJ_POWER)
+#endif // MAYUD_NT4
+      driverObject->MajorFunction[i] = mayuGenericDispatch;
+  if (g_isPnP == TRUE) {
+    driverObject->MajorFunction[IRP_MJ_PNP] = mayuGenericDispatch;
+  }
+  
+  // create a device
+  {
+    // create detour device
+    status = IoCreateDevice(driverObject, sizeof(DetourDeviceExtension),
+                           &MayuDetourDeviceName, FILE_DEVICE_KEYBOARD,
+                           0, FALSE, &detourDevObj);
+    
+    if (!NT_SUCCESS(status)) goto error;
+    DEBUG_LOG(("create detour device: %x", detourDevObj));
+    DEBUG_LOGChain(driverObject);
+    detourDevObj->Flags |= DO_BUFFERED_IO;
+#ifndef MAYUD_NT4
+    detourDevObj->Flags |= DO_POWER_PAGABLE;
+#endif // !MAYUD_NT4
+
+    // initialize detour device extension
+    detourDevExt = (DetourDeviceExtension*)detourDevObj->DeviceExtension;
+    RtlZeroMemory(detourDevExt, sizeof(DetourDeviceExtension));
+    detourDevExt->filterDevObj = NULL;
+
+    KeInitializeSpinLock(&detourDevExt->lock);
+    detourDevExt->isOpen = FALSE;
+    detourDevExt->wasCleanupInitiated = FALSE;
+    detourDevExt->irpq = NULL;
+    status = KqInitialize(&detourDevExt->readQue);
+    if (!NT_SUCCESS(status)) goto error;
+    
+    // create symbolic link for detour
+    status =
+      IoCreateSymbolicLink(&MayuDetourWin32DeviceName, &MayuDetourDeviceName);
+    if (!NT_SUCCESS(status)) goto error;
+    is_symbolicLinkCreated = TRUE;
+    
+    if (g_isPnP == FALSE)
+    // attach filter device to keyboard class device
+    {
+      PFILE_OBJECT f;
+      PDEVICE_OBJECT kbdClassDevObj;
+      
+      status = IoGetDeviceObjectPointer(&KeyboardClassDeviceName,
+                                       FILE_ALL_ACCESS, &f,
+                                       &kbdClassDevObj);
+      if (!NT_SUCCESS(status)) goto error;
+      ObDereferenceObject(f);
+      status = mayuAddDevice(driverObject, kbdClassDevObj);
+      
+      // why cannot I do below ?
+//      status = IoAttachDevice(filterDevObj, &KeyboardClassDeviceName,
+//                           &filterDevExt->kbdClassDevObj);
+      if (!NT_SUCCESS(status)) goto error;
+    }
+    
+    // initialize Major Functions
+    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+    {
+      detourDevExt->MajorFunction[i] = _IopInvalidDeviceRequest;
+    }
+
+    detourDevExt->MajorFunction[IRP_MJ_READ] = detourRead;
+    detourDevExt->MajorFunction[IRP_MJ_WRITE] = detourWrite;
+    detourDevExt->MajorFunction[IRP_MJ_CREATE] = detourCreate;
+    detourDevExt->MajorFunction[IRP_MJ_CLOSE] = detourClose;
+    detourDevExt->MajorFunction[IRP_MJ_CLEANUP] = detourCleanup;
+    detourDevExt->MajorFunction[IRP_MJ_DEVICE_CONTROL] = detourDeviceControl;
+
+#ifndef MAYUD_NT4
+    detourDevExt->MajorFunction[IRP_MJ_POWER] = detourPower;
+#endif // !MAYUD_NT4
+    if (g_isPnP == TRUE) {
+      detourDevExt->MajorFunction[IRP_MJ_PNP] = detourPnP;
+    }
+  }
+  detourDevObj->Flags &= ~DO_DEVICE_INITIALIZING;  
+  
+  return STATUS_SUCCESS;
+  
+  error:
+  {
+    if (is_symbolicLinkCreated)
+      IoDeleteSymbolicLink(&MayuDetourWin32DeviceName);
+    if (detourDevObj)
+    {
+      KqFinalize(&detourDevExt->readQue);
+      IoDeleteDevice(detourDevObj);
+    }
+  }
+  return status;
+}
+
+NTSTATUS mayuAddDevice(IN PDRIVER_OBJECT driverObject,
+                      IN PDEVICE_OBJECT kbdClassDevObj)
+{
+  NTSTATUS status;
+  PDEVICE_OBJECT devObj;
+  PDEVICE_OBJECT filterDevObj;
+  PDEVICE_OBJECT attachedDevObj;
+  DetourDeviceExtension *detourDevExt;
+  FilterDeviceExtension *filterDevExt;
+  ULONG i;
+
+  DEBUG_LOG(("attach to device: %x", kbdClassDevObj));
+  DEBUG_LOG(("type of device: %x", kbdClassDevObj->DeviceType));
+  DEBUG_LOG(("name of driver: %T", &(kbdClassDevObj->DriverObject->DriverName)));
+
+  // create filter device
+  status = IoCreateDevice(driverObject, sizeof(FilterDeviceExtension),
+                         NULL, FILE_DEVICE_KEYBOARD,
+                         0, FALSE, &filterDevObj);
+  DEBUG_LOG(("add filter device: %x", filterDevObj));
+  DEBUG_LOGChain(driverObject);
+  if (!NT_SUCCESS(status)) return status;
+  filterDevObj->Flags |= DO_BUFFERED_IO;
+#ifndef MAYUD_NT4
+  filterDevObj->Flags |= DO_POWER_PAGABLE;
+#endif // !MAYUD_NT4
+
+  // initialize filter device extension
+  filterDevExt = (FilterDeviceExtension*)filterDevObj->DeviceExtension;
+  RtlZeroMemory(filterDevExt, sizeof(FilterDeviceExtension));
+
+  KeInitializeSpinLock(&filterDevExt->lock);
+  filterDevExt->irpq = NULL;
+  status = KqInitialize(&filterDevExt->readQue);
+  if (!NT_SUCCESS(status)) goto error;
+#ifdef USE_TOUCHPAD
+  filterDevExt->isKeyboard = FALSE;
+  filterDevExt->isTouched = FALSE;
+#endif
+
+  attachedDevObj = kbdClassDevObj->AttachedDevice;
+  while (attachedDevObj)
+  {
+    DEBUG_LOG(("attached to %T", &(attachedDevObj->DriverObject->DriverName)));
+    DEBUG_LOG(("type of attched device: %x", attachedDevObj->DeviceType));
+#ifdef USE_TOUCHPAD
+    if (RtlCompareUnicodeString(&KeyboardClassDriverName, &attachedDevObj->DriverObject->DriverName, TRUE) == 0)
+      filterDevExt->isKeyboard = TRUE;
+#endif
+    attachedDevObj = attachedDevObj->AttachedDevice;
+  }
+
+  devObj = filterDevObj->NextDevice;
+  while (devObj->NextDevice) {
+    devObj = devObj->NextDevice;
+  }
+  filterDevExt->detourDevObj = devObj;
+  detourDevExt = (DetourDeviceExtension*)devObj->DeviceExtension;
+  if (!detourDevExt->filterDevObj) {
+    detourDevExt->filterDevObj = filterDevObj;
+  }
+
+  filterDevExt->kbdClassDevObj =
+    IoAttachDeviceToDeviceStack(filterDevObj, kbdClassDevObj);
+  if (!filterDevExt->kbdClassDevObj) goto error;
+
+  for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {
+    filterDevExt->MajorFunction[i] =
+      (filterDevExt->kbdClassDevObj->DriverObject->MajorFunction[i]
+       == _IopInvalidDeviceRequest) ?
+      _IopInvalidDeviceRequest : filterPassThrough;
+  }
+#ifdef USE_TOUCHPAD
+  if (filterDevExt->isKeyboard == FALSE)
+  {
+    DEBUG_LOG(("filter read: GlidePoint"));
+    filterDevObj->DeviceType = FILE_DEVICE_MOUSE;
+    filterDevExt->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = filterTouchpad;
+  }
+  else
+#endif
+  {
+    DEBUG_LOG(("filter read: Keyboard"));
+    filterDevExt->MajorFunction[IRP_MJ_READ] = filterRead;
+  }
+#ifndef MAYUD_NT4
+  filterDevExt->MajorFunction[IRP_MJ_POWER] = filterPower;
+#endif // !MAYUD_NT4
+  if (g_isPnP == TRUE) {
+    filterDevExt->MajorFunction[IRP_MJ_PNP] = filterPnP;
+  }
+  filterDevObj->Flags &= ~DO_DEVICE_INITIALIZING;  
+
+  return STATUS_SUCCESS;
+
+ error:
+  DEBUG_LOG(("mayuAddDevice: error"));
+  if (filterDevObj) {
+      KqFinalize(&filterDevExt->readQue);
+      IoDeleteDevice(filterDevObj);
+  }
+  return status;
+}
+
+BOOLEAN CancelKeyboardClassRead(PIRP cancelIrp, PDEVICE_OBJECT kbdClassDevObj)
+{
+  PVOID kbdClassDevExt;
+  BOOLEAN isSafe;
+  PKSPIN_LOCK SpinLock;
+  KIRQL currentIrql;
+
+  kbdClassDevExt = kbdClassDevObj->DeviceExtension;
+  SpinLock = (PKSPIN_LOCK)((ULONG)kbdClassDevExt + g_SpinLock_offset);
+  KeAcquireSpinLock(SpinLock, &currentIrql);
+  if (g_isXp == TRUE) {
+    isSafe = cancelIrp->CancelRoutine ? TRUE : FALSE;
+  } else {
+    isSafe = *(BOOLEAN*)((ULONG)kbdClassDevExt + g_RequestIsPending_offset);
+  }
+  if (isSafe == TRUE) {
+    KeReleaseSpinLock(SpinLock, currentIrql);
+    IoCancelIrp(cancelIrp);
+  } else {
+    DEBUG_LOG(("cancel irp not pending"));
+    KeReleaseSpinLock(SpinLock, currentIrql);
+  }
+  return isSafe;
+}
+
+// unload driver
+VOID mayuUnloadDriver(IN PDRIVER_OBJECT driverObject)
+{
+  KIRQL currentIrql;
+  PIRP cancelIrp;
+  PDEVICE_OBJECT devObj;
+  DetourDeviceExtension *detourDevExt;
+
+  // walk on device chain(the last one is detour device?)
+  devObj = driverObject->DeviceObject;
+  while (devObj->NextDevice) {
+    FilterDeviceExtension *filterDevExt
+      = (FilterDeviceExtension*)devObj->DeviceExtension;
+    PDEVICE_OBJECT delObj;
+    PDEVICE_OBJECT kbdClassDevObj;
+
+    // detach
+    IoDetachDevice(filterDevExt->kbdClassDevObj);
+    // cancel filter IRP_MJ_READ
+    KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+    // TODO: at this point, the irp may be completed (but what can I do for it ?)
+    // finalize read que
+    KqFinalize(&filterDevExt->readQue);
+    cancelIrp = filterDevExt->irpq;
+    filterDevExt->irpq = NULL;
+    kbdClassDevObj = filterDevExt->kbdClassDevObj;
+    KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+    if (cancelIrp) {
+      while (CancelKeyboardClassRead(cancelIrp, kbdClassDevObj) != TRUE);
+    }
+    // delete device objects
+    delObj= devObj;
+    devObj = devObj->NextDevice;
+    IoDeleteDevice(delObj);
+  }
+
+  detourDevExt = (DetourDeviceExtension*)devObj->DeviceExtension;
+  // cancel filter IRP_MJ_READ
+  KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+  // TODO: at this point, the irp may be completed (but what can I do for it ?)
+  cancelIrp = detourDevExt->irpq;
+  // finalize read que
+  KqFinalize(&detourDevExt->readQue);
+  KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+  if (cancelIrp)
+    IoCancelIrp(cancelIrp);
+  // delete device objects
+  IoDeleteDevice(devObj);
+
+  // delete symbolic link
+  IoDeleteSymbolicLink(&MayuDetourWin32DeviceName);
+  DEBUG_LOG_TERM(());
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Cancel Functionss
+
+
+// detour read cancel
+VOID mayuDetourReadCancel(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  DetourDeviceExtension *devExt =
+    (DetourDeviceExtension *)deviceObject->DeviceExtension;
+  KIRQL currentIrql;
+
+  KeAcquireSpinLock(&devExt->lock, &currentIrql);
+  devExt->irpq = NULL;
+  KeReleaseSpinLock(&devExt->lock, currentIrql);
+  IoReleaseCancelSpinLock(irp->CancelIrql);
+  DEBUG_LOG(("detourReadCancel:"));
+#if 0
+  KeAcquireSpinLock(&devExt->lock, &currentIrql);
+  if (devExt->irpq && irp == deviceObject->CurrentIrp)
+    // the current request is being cancelled
+  {
+    deviceObject->CurrentIrp = NULL;
+    devExt->irpq = NULL;
+    KeReleaseSpinLock(&devExt->lock, currentIrql);
+    IoStartNextPacket(deviceObject, TRUE);
+  }
+  else
+  {
+    // Cancel a request in the device queue
+    KIRQL cancelIrql;
+    
+    IoAcquireCancelSpinLock(&cancelIrql);
+    KeRemoveEntryDeviceQueue(&deviceObject->DeviceQueue,
+                            &irp->Tail.Overlay.DeviceQueueEntry);
+    IoReleaseCancelSpinLock(cancelIrql);
+    KeReleaseSpinLock(&devExt->lock, currentIrql);
+  }
+#endif
+  
+  irp->IoStatus.Status = STATUS_CANCELLED;
+  irp->IoStatus.Information = 0;
+  IoCompleteRequest(irp, IO_KEYBOARD_INCREMENT);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Complete Functions
+
+
+// 
+NTSTATUS filterGenericCompletion(IN PDEVICE_OBJECT deviceObject,
+                                IN PIRP irp, IN PVOID context)
+{
+  UNREFERENCED_PARAMETER(deviceObject);
+  UNREFERENCED_PARAMETER(context);
+  
+  if (irp->PendingReturned)
+    IoMarkIrpPending(irp);
+  return STATUS_SUCCESS;
+}
+
+
+// 
+NTSTATUS filterReadCompletion(IN PDEVICE_OBJECT deviceObject,
+                             IN PIRP irp, IN PVOID context)
+{
+  NTSTATUS status;
+  KIRQL currentIrql, cancelIrql;
+  PIRP irpCancel = NULL;
+  FilterDeviceExtension *filterDevExt =
+    (FilterDeviceExtension*)deviceObject->DeviceExtension;
+  PDEVICE_OBJECT detourDevObj = filterDevExt->detourDevObj;
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)detourDevObj->DeviceExtension;
+
+  UNREFERENCED_PARAMETER(context);
+  
+  KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+  filterDevExt->irpq = NULL;
+  KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+  if (irp->PendingReturned) {
+    status = STATUS_PENDING;
+    IoMarkIrpPending(irp);
+  } else {
+    status = STATUS_SUCCESS;
+  }
+
+  KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+  if (detourDevExt->isOpen && !detourDevExt->wasCleanupInitiated)
+  {
+    // if detour is opened, key datum are forwarded to detour
+    if (irp->IoStatus.Status == STATUS_SUCCESS)
+    {
+      PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+      
+      KqEnque(&detourDevExt->readQue,
+             (KEYBOARD_INPUT_DATA *)irp->AssociatedIrp.SystemBuffer,
+             irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA));
+
+      irp->IoStatus.Status = STATUS_CANCELLED;
+      irp->IoStatus.Information = 0;
+      detourDevExt->filterDevObj = deviceObject;
+    }
+
+    IoAcquireCancelSpinLock(&cancelIrql);
+    if (detourDevExt->irpq) {
+      if (readq(&detourDevExt->readQue, detourDevExt->irpq) ==
+         STATUS_SUCCESS) {
+       IoSetCancelRoutine(detourDevExt->irpq, NULL);
+       IoCompleteRequest(detourDevExt->irpq, IO_KEYBOARD_INCREMENT);
+       detourDevExt->irpq = NULL;
+      }
+    }
+    IoReleaseCancelSpinLock(cancelIrql);
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+
+    KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+    status = readq(&filterDevExt->readQue, irp);
+    KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+  }
+  else
+  {
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+  }
+
+  if (status == STATUS_SUCCESS)
+    irp->IoStatus.Status = STATUS_SUCCESS;
+  return irp->IoStatus.Status;
+}
+
+NTSTATUS readq(KeyQue *readQue, PIRP irp)
+{
+  if (!KqIsEmpty(readQue)) {
+    PIO_STACK_LOCATION irpSp;
+    ULONG len;
+
+    irpSp = IoGetCurrentIrpStackLocation(irp);
+    len = KqDeque(readQue,
+                 (KEYBOARD_INPUT_DATA *)irp->AssociatedIrp.SystemBuffer,
+                 irpSp->Parameters.Read.Length / sizeof(KEYBOARD_INPUT_DATA));
+    irp->IoStatus.Status = STATUS_SUCCESS;
+    irp->IoStatus.Information = len * sizeof(KEYBOARD_INPUT_DATA);
+    irpSp->Parameters.Read.Length = irp->IoStatus.Information;
+    return STATUS_SUCCESS;
+  } else {
+    irp->IoStatus.Status = STATUS_PENDING;
+    irp->IoStatus.Information = 0;
+    return STATUS_PENDING;
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Dispatch Functions
+
+
+// Generic Dispatcher
+NTSTATUS mayuGenericDispatch(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+
+  if (deviceObject->NextDevice) {
+    FilterDeviceExtension *filterDevExt =
+      (FilterDeviceExtension *)deviceObject->DeviceExtension;
+
+#ifdef USE_TOUCHPAD
+    if (filterDevExt->isKeyboard == FALSE)
+    {
+      DEBUG_LOG(("MajorFunction: %x", irpSp->MajorFunction));
+    }
+#endif
+    return filterDevExt->MajorFunction[irpSp->MajorFunction](deviceObject, irp);
+  } else {
+    DetourDeviceExtension *detourDevExt = 
+      (DetourDeviceExtension *)deviceObject->DeviceExtension;
+
+    return detourDevExt->MajorFunction[irpSp->MajorFunction](deviceObject, irp);
+  }
+}
+
+
+// detour IRP_MJ_CREATE
+NTSTATUS detourCreate(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)deviceObject->DeviceExtension;
+
+  if (1 < InterlockedIncrement(&detourDevExt->isOpen))
+    // mayu detour device can be opend only once at a time
+  {
+    InterlockedDecrement(&detourDevExt->isOpen);
+    irp->IoStatus.Status = STATUS_INTERNAL_ERROR;
+  }
+  else
+  {
+    PIRP irpCancel;
+    KIRQL currentIrql;
+    PDEVICE_OBJECT filterDevObj;
+    
+    KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+    detourDevExt->wasCleanupInitiated = FALSE;
+    KqClear(&detourDevExt->readQue);
+    filterDevObj = detourDevExt->filterDevObj;
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+    if (filterDevObj) {
+      FilterDeviceExtension *filterDevExt =
+       (FilterDeviceExtension*)filterDevObj->DeviceExtension;
+      PDEVICE_OBJECT kbdClassDevObj;
+
+      KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+      irpCancel = filterDevExt->kbdClassDevObj->CurrentIrp;
+      kbdClassDevObj = filterDevExt->kbdClassDevObj;
+      KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+      if (irpCancel) {
+       CancelKeyboardClassRead(irpCancel, kbdClassDevObj);
+      }
+    }
+
+    irp->IoStatus.Status = STATUS_SUCCESS;
+  }
+  irp->IoStatus.Information = 0;
+  IoCompleteRequest(irp, IO_NO_INCREMENT);
+  return irp->IoStatus.Status;
+}
+
+
+// detour IRP_MJ_CLOSE
+NTSTATUS detourClose(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)deviceObject->DeviceExtension;
+  KIRQL currentIrql;
+
+  KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+  InterlockedDecrement(&detourDevExt->isOpen);
+  KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+  irp->IoStatus.Status = STATUS_SUCCESS;
+  irp->IoStatus.Information = 0;
+  IoCompleteRequest(irp, IO_NO_INCREMENT);
+  DEBUG_LOG_TERM(());
+  return STATUS_SUCCESS;
+}
+
+
+// detour IRP_MJ_READ
+NTSTATUS detourRead(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  NTSTATUS status;
+  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)deviceObject->DeviceExtension;
+  KIRQL currentIrql, cancelIrql;
+
+  KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+  if (irpSp->Parameters.Read.Length == 0)
+    status = STATUS_SUCCESS;
+  else if (irpSp->Parameters.Read.Length % sizeof(KEYBOARD_INPUT_DATA))
+    status = STATUS_BUFFER_TOO_SMALL;
+  else
+    status = readq(&detourDevExt->readQue, irp);
+  if (status == STATUS_PENDING) {
+    IoAcquireCancelSpinLock(&cancelIrql);
+    IoMarkIrpPending(irp);
+    detourDevExt->irpq = irp;
+    IoSetCancelRoutine(irp, mayuDetourReadCancel);
+    IoReleaseCancelSpinLock(cancelIrql);
+  }
+  else {
+    IoCompleteRequest(irp, IO_KEYBOARD_INCREMENT);
+  }
+  KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+  return status;
+}
+
+
+// detour IRP_MJ_WRITE
+NTSTATUS detourWrite(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  NTSTATUS status;
+  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+  ULONG len = irpSp->Parameters.Write.Length;
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)deviceObject->DeviceExtension;
+  
+  irp->IoStatus.Information = 0;
+  if (len == 0)
+    status = STATUS_SUCCESS;
+  else if (len % sizeof(KEYBOARD_INPUT_DATA))
+    status = STATUS_INVALID_PARAMETER;
+  else {
+    // write to filter que
+    KIRQL cancelIrql, currentIrql;
+    PIRP irpCancel;
+    PDEVICE_OBJECT filterDevObj;
+
+    KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+    filterDevObj = detourDevExt->filterDevObj;
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+    // enque filter que
+    if (filterDevObj) {
+      FilterDeviceExtension *filterDevExt =
+       (FilterDeviceExtension*)filterDevObj->DeviceExtension;
+      PDEVICE_OBJECT kbdClassDevObj;
+
+      KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+
+      len /= sizeof(KEYBOARD_INPUT_DATA);
+      len = KqEnque(&filterDevExt->readQue,
+                   (KEYBOARD_INPUT_DATA *)irp->AssociatedIrp.SystemBuffer,
+                   len);
+      irp->IoStatus.Information = len * sizeof(KEYBOARD_INPUT_DATA);
+      irpSp->Parameters.Write.Length = irp->IoStatus.Information;
+      // cancel filter irp
+      irpCancel = filterDevExt->irpq; 
+      filterDevExt->irpq = NULL;
+      kbdClassDevObj = filterDevExt->kbdClassDevObj;
+      KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+      if (irpCancel) {
+       CancelKeyboardClassRead(irpCancel, kbdClassDevObj);
+      }
+      status = STATUS_SUCCESS;
+    } else {
+      irp->IoStatus.Information = 0;
+      irpSp->Parameters.Write.Length = irp->IoStatus.Information;
+      status = STATUS_CANCELLED;
+    }
+  }
+  IoCompleteRequest(irp, IO_NO_INCREMENT);
+  return status;
+}
+
+
+// detour IRP_MJ_CLEANUP
+NTSTATUS detourCleanup(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  KIRQL currentIrql, cancelIrql;
+  PIO_STACK_LOCATION irpSp;
+  PIRP  currentIrp = NULL, irpCancel;
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)deviceObject->DeviceExtension;
+
+  KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+  IoAcquireCancelSpinLock(&cancelIrql);
+  irpSp = IoGetCurrentIrpStackLocation(irp);
+  detourDevExt->wasCleanupInitiated = TRUE;
+  
+  // Complete all requests queued by this thread with STATUS_CANCELLED
+  currentIrp = deviceObject->CurrentIrp;
+  deviceObject->CurrentIrp = NULL;
+  detourDevExt->irpq = NULL;
+  
+  while (currentIrp != NULL)
+  {
+    IoSetCancelRoutine(currentIrp, NULL);
+    currentIrp->IoStatus.Status = STATUS_CANCELLED;
+    currentIrp->IoStatus.Information = 0;
+    
+    IoReleaseCancelSpinLock(cancelIrql);
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+    IoCompleteRequest(currentIrp, IO_NO_INCREMENT);
+    KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+    IoAcquireCancelSpinLock(&cancelIrql);
+    
+    // Dequeue the next packet (IRP) from the device work queue.
+    {
+      PKDEVICE_QUEUE_ENTRY packet =
+       KeRemoveDeviceQueue(&deviceObject->DeviceQueue);
+      currentIrp = packet ?
+       CONTAINING_RECORD(packet, IRP, Tail.Overlay.DeviceQueueEntry) : NULL;
+    }
+  }
+  
+  IoReleaseCancelSpinLock(cancelIrql);
+  KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+  
+  // Complete the cleanup request with STATUS_SUCCESS.
+  irp->IoStatus.Status = STATUS_SUCCESS;
+  irp->IoStatus.Information = 0;
+  IoCompleteRequest(irp, IO_NO_INCREMENT);
+  
+  return STATUS_SUCCESS;
+}
+
+
+// detour IRP_MJ_DEVICE_CONTROL
+NTSTATUS detourDeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  NTSTATUS status;
+  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)deviceObject->DeviceExtension;
+  
+  irp->IoStatus.Information = 0;
+  if (irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_MAYU_GET_LOG) DEBUG_LOG(("DeviceIoControl: %x", irpSp->Parameters.DeviceIoControl.IoControlCode));
+  status = STATUS_INVALID_DEVICE_REQUEST;
+  switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
+  {
+    case IOCTL_MAYU_DETOUR_CANCEL:
+    {
+      KIRQL currentIrql;
+      PIRP irpCancel = NULL;
+      
+      KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+      if (detourDevExt->isOpen)
+       irpCancel = detourDevExt->irpq;
+      KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+      
+      if (irpCancel)
+       IoCancelIrp(irpCancel);// at this point, the irpCancel may be completed
+      status = STATUS_SUCCESS;
+      break;
+    }
+    case IOCTL_MAYU_GET_VERSION:
+    {
+      if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
+         MayuDriverVersion.Length)
+      {
+         status = STATUS_INVALID_PARAMETER;
+         break;
+      }
+      RtlCopyMemory(irp->AssociatedIrp.SystemBuffer,
+                   MayuDriverVersion.Buffer, MayuDriverVersion.Length);
+      irp->IoStatus.Information = MayuDriverVersion.Length;
+      DEBUG_LOG(("Version: %T", &MayuDriverVersion));
+      status = STATUS_SUCCESS;
+      break;
+    }
+    case IOCTL_MAYU_GET_LOG:
+      status = DEBUG_LOG_RETRIEVE((irp));
+      break;
+    case IOCTL_MAYU_FORCE_KEYBOARD_INPUT:
+    {
+      KIRQL currentIrql, cancelIrql;
+
+      // if detour is opened, key datum are forwarded to detour
+      if (irpSp->Parameters.DeviceIoControl.InputBufferLength %
+         sizeof(KEYBOARD_INPUT_DATA))
+      {
+       status = STATUS_INVALID_PARAMETER;
+       break;
+      }
+      KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+      KqEnque(&detourDevExt->readQue,
+             (KEYBOARD_INPUT_DATA *)irp->AssociatedIrp.SystemBuffer,
+             irpSp->Parameters.DeviceIoControl.InputBufferLength
+             / sizeof(KEYBOARD_INPUT_DATA));
+
+      if (detourDevExt->irpq) {
+       if (readq(&detourDevExt->readQue, detourDevExt->irpq) ==
+           STATUS_SUCCESS) {
+         IoAcquireCancelSpinLock(&cancelIrql);
+         IoSetCancelRoutine(detourDevExt->irpq, NULL);
+         IoReleaseCancelSpinLock(cancelIrql);
+         IoCompleteRequest(detourDevExt->irpq, IO_KEYBOARD_INCREMENT);
+         detourDevExt->irpq = NULL;
+       }
+      }
+      KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+      status = STATUS_SUCCESS;
+      break;
+    }
+    default:
+      status = STATUS_INVALID_DEVICE_REQUEST;
+      break;
+  }
+  irp->IoStatus.Status = status;
+  if (status != STATUS_PENDING)
+    IoCompleteRequest(irp, IO_NO_INCREMENT);
+  
+  return status;
+}
+
+
+#ifndef MAYUD_NT4
+// detour IRP_MJ_POWER
+NTSTATUS detourPower(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  UNREFERENCED_PARAMETER(deviceObject);
+  
+  PoStartNextPowerIrp(irp);
+  irp->IoStatus.Status = STATUS_SUCCESS;
+  irp->IoStatus.Information = 0;
+  IoCompleteRequest(irp, IO_NO_INCREMENT);
+  return STATUS_SUCCESS;
+}
+#endif // !MAYUD_NT4
+
+
+// filter IRP_MJ_READ
+NTSTATUS filterRead(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  NTSTATUS status;
+  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+  FilterDeviceExtension *filterDevExt =
+    (FilterDeviceExtension*)deviceObject->DeviceExtension;
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)filterDevExt->detourDevObj->DeviceExtension;
+  KIRQL currentIrql;
+  
+  KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+  if (detourDevExt->isOpen && !detourDevExt->wasCleanupInitiated)
+    // read from que
+  {
+    ULONG len = irpSp->Parameters.Read.Length;
+    
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+    irp->IoStatus.Information = 0;
+    KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+    if (len == 0)
+      status = STATUS_SUCCESS;
+    else if (len % sizeof(KEYBOARD_INPUT_DATA))
+      status = STATUS_BUFFER_TOO_SMALL;
+    else
+      status = readq(&filterDevExt->readQue, irp);
+    KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+    if (status != STATUS_PENDING) {
+      irp->IoStatus.Status = status;
+      IoCompleteRequest(irp, IO_NO_INCREMENT);
+      return status;
+    }
+  }
+  else
+  {
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+  }
+  KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+  filterDevExt->irpq = irp;
+  KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+  
+  *IoGetNextIrpStackLocation(irp) = *irpSp;
+  IoSetCompletionRoutine(irp, filterReadCompletion, NULL, TRUE, TRUE, TRUE);
+  return IoCallDriver(filterDevExt->kbdClassDevObj, irp);
+}
+
+
+// pass throught irp to keyboard class driver
+NTSTATUS filterPassThrough(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  FilterDeviceExtension *filterDevExt =
+    (FilterDeviceExtension*)deviceObject->DeviceExtension;
+
+  *IoGetNextIrpStackLocation(irp) = *IoGetCurrentIrpStackLocation(irp);
+  IoSetCompletionRoutine(irp, filterGenericCompletion,
+                        NULL, TRUE, TRUE, TRUE);
+  return IoCallDriver(filterDevExt->kbdClassDevObj, irp);
+}
+
+
+#ifndef MAYUD_NT4
+// filter IRP_MJ_POWER
+NTSTATUS filterPower(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  FilterDeviceExtension *filterDevExt =
+    (FilterDeviceExtension*)deviceObject->DeviceExtension;
+
+  PoStartNextPowerIrp(irp);
+  IoSkipCurrentIrpStackLocation(irp);
+  return PoCallDriver(filterDevExt->kbdClassDevObj, irp);
+}
+#endif // !MAYUD_NT4
+NTSTATUS filterPnP(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+  FilterDeviceExtension *filterDevExt =
+    (FilterDeviceExtension*)deviceObject->DeviceExtension;
+  DetourDeviceExtension *detourDevExt =
+    (DetourDeviceExtension*)filterDevExt->detourDevObj->DeviceExtension;
+  KIRQL currentIrql;
+  NTSTATUS status;
+  ULONG minor;
+  PIRP cancelIrp;
+  PDRIVER_OBJECT driverObject = deviceObject->DriverObject;
+
+  minor = irpSp->MinorFunction;
+  IoSkipCurrentIrpStackLocation(irp);
+  status = IoCallDriver(filterDevExt->kbdClassDevObj, irp);
+  DEBUG_LOG(("filterPnP: minor=%d(%x)", minor, minor));
+  switch (minor) {
+  case IRP_MN_SURPRISE_REMOVAL:
+  case IRP_MN_REMOVE_DEVICE:
+    KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+    if (detourDevExt->filterDevObj == deviceObject) {
+      PDEVICE_OBJECT devObj = deviceObject->DriverObject->DeviceObject;
+
+      DEBUG_LOG(("filterPnP: current filter(%x) was removed", deviceObject));
+      detourDevExt->filterDevObj = NULL;
+      while (devObj->NextDevice) {
+       if (devObj != deviceObject) {
+         detourDevExt->filterDevObj = devObj;
+         break;
+       }
+       devObj = devObj->NextDevice;
+      }
+      DEBUG_LOG(("filterPnP: current filter was changed to %x", detourDevExt->filterDevObj));
+    }
+    KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+    // detach
+    IoDetachDevice(filterDevExt->kbdClassDevObj);
+
+    KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+    // TODO: at this point, the irp may be completed (but what can I do for it ?)
+    cancelIrp = filterDevExt->irpq;
+    KqFinalize(&filterDevExt->readQue);
+
+    KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+    if (cancelIrp) {
+      IoCancelIrp(cancelIrp);
+    }
+    IoDeleteDevice(deviceObject);
+    DEBUG_LOG(("delete filter device: %x", deviceObject));
+    DEBUG_LOGChain(driverObject);
+    break;
+  default:
+    break;
+  }
+  return status;
+}
+
+
+#ifdef USE_TOUCHPAD
+// 
+NTSTATUS filterTouchpadCompletion(IN PDEVICE_OBJECT deviceObject,
+                                IN PIRP irp, IN PVOID context)
+{
+  KIRQL currentIrql;
+  FilterDeviceExtension *filterDevExt =
+    (FilterDeviceExtension*)deviceObject->DeviceExtension;
+  PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(irp);
+  //PIO_STACK_LOCATION irpSp = IoGetNextIrpStackLocation(irp);
+  UCHAR *data = irp->UserBuffer;
+  UCHAR pressure;
+
+  UNREFERENCED_PARAMETER(context);
+  
+  if (irp->PendingReturned)
+    IoMarkIrpPending(irp);
+
+  if (data)
+    pressure = data[TOUCHPAD_PRESSURE_OFFSET];
+  else
+    pressure = 0;
+
+  if (data)
+  {
+    ULONG *p = (ULONG*)data;
+    //DEBUG_LOG(("UserBuffer: %2x %2x %2x %2x", data[4], data[5], data[6], data[7]));
+    //DEBUG_LOG(("UserBuffer: %x %x %x %x %x %x %x %x", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]));
+  }
+  KeAcquireSpinLock(&filterDevExt->lock, &currentIrql);
+  if (filterDevExt->isTouched == FALSE && pressure)
+  {
+    KIRQL currentIrql, cancelIrql;
+    PDEVICE_OBJECT detourDevObj = filterDevExt->detourDevObj;
+    DetourDeviceExtension *detourDevExt =
+      (DetourDeviceExtension*)detourDevObj->DeviceExtension;
+    if (detourDevExt->isOpen)
+    {
+      KEYBOARD_INPUT_DATA PadKey = {0, TOUCHPAD_SCANCODE, 0, 0, 0};
+      KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+      // if detour is opened, key datum are forwarded to detour
+      KqEnque(&detourDevExt->readQue, &PadKey, 1);
+      detourDevExt->filterDevObj = deviceObject;
+
+      if (detourDevExt->irpq) {
+       if (readq(&detourDevExt->readQue, detourDevExt->irpq) ==
+           STATUS_SUCCESS) {
+         IoAcquireCancelSpinLock(&cancelIrql);
+         IoSetCancelRoutine(detourDevExt->irpq, NULL);
+         IoReleaseCancelSpinLock(cancelIrql);
+         IoCompleteRequest(detourDevExt->irpq, IO_KEYBOARD_INCREMENT);
+         detourDevExt->irpq = NULL;
+       }
+      }
+      KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+    }
+    filterDevExt->isTouched = TRUE;
+  }
+  else
+  {
+    if (filterDevExt->isTouched == TRUE && pressure == 0)
+    {
+      KIRQL currentIrql, cancelIrql;
+      PDEVICE_OBJECT detourDevObj = filterDevExt->detourDevObj;
+      DetourDeviceExtension *detourDevExt =
+       (DetourDeviceExtension*)detourDevObj->DeviceExtension;
+      if (detourDevExt->isOpen)
+      {
+       KEYBOARD_INPUT_DATA PadKey = {0, TOUCHPAD_SCANCODE, 1, 0, 0};
+       KeAcquireSpinLock(&detourDevExt->lock, &currentIrql);
+       // if detour is opened, key datum are forwarded to detour
+       KqEnque(&detourDevExt->readQue, &PadKey, 1);
+       detourDevExt->filterDevObj = deviceObject;
+
+       if (detourDevExt->irpq) {
+         if (readq(&detourDevExt->readQue, detourDevExt->irpq) ==
+             STATUS_SUCCESS) {
+           IoAcquireCancelSpinLock(&cancelIrql);
+           IoSetCancelRoutine(detourDevExt->irpq, NULL);
+           IoReleaseCancelSpinLock(cancelIrql);
+           IoCompleteRequest(detourDevExt->irpq, IO_KEYBOARD_INCREMENT);
+           detourDevExt->irpq = NULL;
+         }
+       }
+       KeReleaseSpinLock(&detourDevExt->lock, currentIrql);
+      }
+      filterDevExt->isTouched = FALSE;
+    }
+  }
+  //DEBUG_LOG(("touchpad pressed: out=%u in=%u code=%u status=%x SystemBuffer=%x UserBuffer=%x", irpSp->Parameters.DeviceIoControl.OutputBufferLength, irpSp->Parameters.DeviceIoControl.InputBufferLength, irpSp->Parameters.DeviceIoControl.IoControlCode, irp->IoStatus.Status, irp->AssociatedIrp.SystemBuffer, irp->UserBuffer));
+  KeReleaseSpinLock(&filterDevExt->lock, currentIrql);
+  return STATUS_SUCCESS;
+}
+
+
+// filter touchpad input
+NTSTATUS filterTouchpad(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  FilterDeviceExtension *filterDevExt =
+    (FilterDeviceExtension*)deviceObject->DeviceExtension;
+
+  *IoGetNextIrpStackLocation(irp) = *IoGetCurrentIrpStackLocation(irp);
+  IoSetCompletionRoutine(irp, filterTouchpadCompletion,
+                        NULL, TRUE, TRUE, TRUE);
+  return IoCallDriver(filterDevExt->kbdClassDevObj, irp);
+}
+#endif
+
+
+NTSTATUS detourPnP(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  UNREFERENCED_PARAMETER(deviceObject);
+
+  IoSkipCurrentIrpStackLocation(irp);
+  irp->IoStatus.Status = STATUS_SUCCESS;
+  irp->IoStatus.Information = 0;
+  IoCompleteRequest(irp, IO_NO_INCREMENT);
+  return STATUS_SUCCESS;
+}
diff --git a/d/nt4/.cvsignore b/d/nt4/.cvsignore
new file mode 100755 (executable)
index 0000000..e526118
--- /dev/null
@@ -0,0 +1,7 @@
+*.log\r
+*.err\r
+obj\r
+objfre\r
+objchk\r
+objfre_wxp_x86\r
+objchk_wxp_x86\r
diff --git a/d/nt4/Makefile b/d/nt4/Makefile
new file mode 100644 (file)
index 0000000..7c70641
--- /dev/null
@@ -0,0 +1,17 @@
+!include $(NTMAKEENV)\makefile.def
+
+clean:
+       -del buildfre.log
+       -del i386\mayudnt4.sys
+       -del i386\mayudnt4.pdb
+       -del obj\_objects.mac
+       -del objfre\i386\*.obj
+       -del objfre\i386\*.mac
+       -del objfre_wxp_x86\i386\*.obj
+       -del objfre_wxp_x86\*.mac
+       -del *~
+       -rd obj
+       -rd objfre\i386
+       -rd objfre
+       -rd objfre_wxp_x86\i386
+       -rd objfre_wxp_x86
diff --git a/d/nt4/SOURCES b/d/nt4/SOURCES
new file mode 100644 (file)
index 0000000..65de031
--- /dev/null
@@ -0,0 +1,7 @@
+TARGETNAME=    mayudnt4
+TARGETTYPE=    DRIVER
+TARGETPATH=    .
+
+INCLUDES=      $(BASEDIR)\inc;.
+
+SOURCES=       mayudnt4.c ../log.c
diff --git a/d/nt4/i386/.cvsignore b/d/nt4/i386/.cvsignore
new file mode 100755 (executable)
index 0000000..0150ff7
--- /dev/null
@@ -0,0 +1 @@
+*.pdb\r
diff --git a/d/nt4/i386/mayudnt4.sys b/d/nt4/i386/mayudnt4.sys
new file mode 100755 (executable)
index 0000000..0687ed7
Binary files /dev/null and b/d/nt4/i386/mayudnt4.sys differ
diff --git a/d/nt4/mayudnt4.c b/d/nt4/mayudnt4.c
new file mode 100644 (file)
index 0000000..62fab53
--- /dev/null
@@ -0,0 +1,7 @@
+///////////////////////////////////////////////////////////////////////////////
+// Driver for Madotsukai no Yu^utsu for WindowsNT4.0
+
+
+#define MAYUD_NT4
+#include "../mayud.c"
+
diff --git a/d/rescue/.cvsignore b/d/rescue/.cvsignore
new file mode 100755 (executable)
index 0000000..e526118
--- /dev/null
@@ -0,0 +1,7 @@
+*.log\r
+*.err\r
+obj\r
+objfre\r
+objchk\r
+objfre_wxp_x86\r
+objchk_wxp_x86\r
diff --git a/d/rescue/Makefile b/d/rescue/Makefile
new file mode 100755 (executable)
index 0000000..f94f4c0
--- /dev/null
@@ -0,0 +1,13 @@
+!include $(NTMAKEENV)\makefile.def
+
+clean:
+       -del buildfre.log
+       -del i386\mayudrsc.sys
+       -del i386\mayudrsc.pdb
+       -del obj\_objects.mac
+       -del objfre\i386\\mayudrsc.obj
+       -del *~
+       -rd i386
+       -rd obj
+       -rd objfre\i386
+       -rd objfre
diff --git a/d/rescue/SOURCES b/d/rescue/SOURCES
new file mode 100755 (executable)
index 0000000..809830b
--- /dev/null
@@ -0,0 +1,7 @@
+TARGETNAME=    mayudrsc
+TARGETTYPE=    DRIVER
+TARGETPATH=    .
+
+INCLUDES=      $(BASEDIR)\inc;.
+
+SOURCES=       mayudrsc.c
diff --git a/d/rescue/i386/.cvsignore b/d/rescue/i386/.cvsignore
new file mode 100755 (executable)
index 0000000..0150ff7
--- /dev/null
@@ -0,0 +1 @@
+*.pdb\r
diff --git a/d/rescue/i386/mayudrsc.sys b/d/rescue/i386/mayudrsc.sys
new file mode 100755 (executable)
index 0000000..8975f74
Binary files /dev/null and b/d/rescue/i386/mayudrsc.sys differ
diff --git a/d/rescue/mayudrsc.c b/d/rescue/mayudrsc.c
new file mode 100755 (executable)
index 0000000..61bdabd
--- /dev/null
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////////
+// Rescue driver for Madotsukai no Yu^utsu for Windows2000/XP
+
+
+#include <ntddk.h>
+
+#pragma warning(3 : 4061 4100 4132 4701 4706)
+
+///////////////////////////////////////////////////////////////////////////////
+// Protorypes
+
+
+NTSTATUS DriverEntry       (IN PDRIVER_OBJECT, IN PUNICODE_STRING);
+NTSTATUS mayuAddDevice     (IN PDRIVER_OBJECT, IN PDEVICE_OBJECT);
+VOID mayuUnloadDriver      (IN PDRIVER_OBJECT);
+NTSTATUS mayuGenericDispatch (IN PDEVICE_OBJECT, IN PIRP);
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text( init, DriverEntry )
+#endif // ALLOC_PRAGMA
+
+///////////////////////////////////////////////////////////////////////////////
+// Entry / Unload
+
+
+// initialize driver
+NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject,
+                    IN PUNICODE_STRING registryPath)
+{
+  ULONG i;
+  UNREFERENCED_PARAMETER(registryPath);
+
+  // set major functions
+  driverObject->DriverUnload = mayuUnloadDriver;
+  driverObject->DriverExtension->AddDevice = mayuAddDevice;
+  for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+    driverObject->MajorFunction[i] = mayuGenericDispatch;
+  driverObject->MajorFunction[IRP_MJ_PNP] = mayuGenericDispatch;
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS mayuAddDevice(IN PDRIVER_OBJECT driverObject,
+                      IN PDEVICE_OBJECT kbdClassDevObj)
+{
+  UNREFERENCED_PARAMETER(driverObject);
+  UNREFERENCED_PARAMETER(kbdClassDevObj);
+  return STATUS_SUCCESS;
+}
+
+// unload driver
+VOID mayuUnloadDriver(IN PDRIVER_OBJECT driverObject)
+{
+  UNREFERENCED_PARAMETER(driverObject);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Dispatch Functions
+
+
+// Generic Dispatcher
+NTSTATUS mayuGenericDispatch(IN PDEVICE_OBJECT deviceObject, IN PIRP irp)
+{
+  UNREFERENCED_PARAMETER(deviceObject);
+  UNREFERENCED_PARAMETER(irp);
+  return STATUS_SUCCESS;
+}
diff --git a/d/test.reg b/d/test.reg
new file mode 100644 (file)
index 0000000..efdfe6f
--- /dev/null
@@ -0,0 +1,6 @@
+REGEDIT4
+
+[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mayud]
+"Type"=dword:00000001
+"Start"=dword:00000003
+"ErrorControl"=dword:00000000
diff --git a/default.mayu b/default.mayu
new file mode 100644 (file)
index 0000000..69b6e52
--- /dev/null
@@ -0,0 +1,553 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - default.mayu
+# Copyright (C) 1999-2005, TAGA Nayuta <nayuta@users.sourceforge.net>
+#
+
+if ( !KBD109 ) and ( !KBD104 )
+  include "109.mayu"
+endif
+if ( KBD104 )
+  def alias \81ª = Up
+  def alias \81« = Down
+  def alias \81© = Left
+  def alias \81¨ = Right
+  def alias Yen        = BackSlash
+endif
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \83L\81[\83V\81[\83P\83\93\83X
+#
+
+keyseq $WindowClose = A-F4
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Global \83L\81[\83}\83b\83v
+#
+
+keymap Global
+ key *IC-C-Yen         = $ToggleIME            # IME ON/OFF \82ð\82·\82é\83L\81[\82Ì\8ew\92è
+ key C-S-M     C-A-M   = Applications          # \83A\83v\83\8a\83P\81[\83V\83\87\83\93\83L\81[
+ key C-S-L     C-A-L   = &WindowLower          # \83E\83B\83\93\83h\83E\82ð\88ê\94Ô\89º\82Ö
+ key C-S-R     C-A-R   = &WindowRaise          # \83E\83B\83\93\83h\83E\82ð\88ê\94Ô\8fã\82Ö
+# key C-S-R     C-A-R  = &WindowToggleTopMost &Wait(200) &WindowToggleTopMost
+ key C-S-Z     C-A-Z   = &WindowMaximize       # \83E\83B\83\93\83h\83E\82Ì\8dÅ\91å\89» (IE\91S\89æ\96Ê)
+ key C-S-I     C-A-I   = &WindowMinimize       # \83E\83B\83\93\83h\83E\82Ì\8dÅ\8f¬\89»
+ key C-S-X     C-A-X   = &WindowVMaximize      # \83E\83B\83\93\83h\83E\82Ì\8fc\8dÅ\91å\89»
+ key C-S-C     C-A-C   = &WindowHMaximize      # \83E\83B\83\93\83h\83E\82Ì\89¡\8dÅ\91å\89»
+ key C-S-Left  C-A-Left        = &WindowMove(-16, 0)   # \83E\83B\83\93\83h\83E\82Ì\88Ú\93®
+ key C-S-Right C-A-Right= &WindowMove(16, 0)   #       \81V
+ key C-S-Up    C-A-Up  = &WindowMove(0, -16)   #       \81V
+ key C-S-Down  C-A-Down        = &WindowMove(0, 16)    #       \81V
+ key C-S-A-Left                = &WindowMove(-1, 0)    #       \81V
+ key C-S-A-Right       = &WindowMove(1, 0)     #       \81V
+ key C-S-A-Up          = &WindowMove(0, -1)    #       \81V
+ key C-S-A-Down                = &WindowMove(0, 1)     #       \81V
+ key W-Left            = &MouseMove(-16, 0)    # \83}\83E\83X\82Ì\88Ú\93®
+ key W-Right           = &MouseMove(16, 0)     #       \81V
+ key W-Up              = &MouseMove(0, -16)    #       \81V
+ key W-Down            = &MouseMove(0, 16)     #       \81V
+ key W-A-C-Left                = &MouseMove(-1, 0)     #       \81V
+ key W-A-C-Right       = &MouseMove(1, 0)      #       \81V
+ key W-A-C-Up          = &MouseMove(0, -1)     #       \81V
+ key W-A-C-Down                = &MouseMove(0, 1)      #       \81V
+ key C-A-A             = &WindowClingToLeft    # \83E\83B\83\93\83h\83E\82ð\8d\82É\8añ\82¹\82é
+ key C-A-E             = &WindowClingToRight   # \83E\83B\83\93\83h\83E\82ð\89E\82É\8añ\82¹\82é
+ key C-A-P             = &WindowClingToTop     # \83E\83B\83\93\83h\83E\82ð\8fã\82É\8añ\82¹\82é
+ key C-A-N             = &WindowClingToBottom  # \83E\83B\83\93\83h\83E\82ð\89º\82É\8añ\82¹\82é
+ key C-A-V             = &WindowMoveVisibly    # \83E\83B\83\93\83h\83E\82ð\8c©\82¦\82é\88Ê\92u\82Ö\88Ú\93®
+ key C-S-K     C-A-K   = $WindowClose          # \83E\83B\83\93\83h\83E\82ð\95Â\82\82é
+ key C-S-T             = &WindowToggleTopMost  # \8dÅ\91O\96Ê\83g\83O\83\8b
+ key C-S-D             = &WindowIdentify &MayuDialog(Log, SHOW)
+                                               # \83E\83B\83\93\83h\83E\82Ì\91f\90«\82ð\92²\82×\82é
+ key C-S-H             = &WindowSetAlpha(70)   # \83E\83B\83\93\83h\83E\82Ì\94¼\93§\96¾\89»
+ key C-S-A-H           = &WindowSetAlpha(-1)   # \94¼\93§\96¾\89»\91S\82Ä\89ð\8f\9c
+ key C-S-U             = &WindowRedraw         # \83E\83B\83\93\83h\83E\82Ì\8dÄ\95`\89æ
+ key C-S-S             = &LoadSetting &HelpMessage(Mayu, "\8dÄ\93Ç\8d\9e\8a®\97¹") # \90Ý\92è\83t\83@\83C\83\8b\82Ì\93Ç\82Ý\8d\9e\82Ý
+ key C-S-F1            = &InvestigateCommand   # WM_COMMAND \82Ì\92²\8d¸
+ if ( ! EmacsMove/ShiftSelection )
+   key C-S-A   C-S-B   = &WindowClingToLeft    # \83E\83B\83\93\83h\83E\82ð\8d\82É\8añ\82¹\82é
+   key C-S-F   C-S-E   = &WindowClingToRight   # \83E\83B\83\93\83h\83E\82ð\89E\82É\8añ\82¹\82é
+   key C-S-P           = &WindowClingToTop     # \83E\83B\83\93\83h\83E\82ð\8fã\82É\8añ\82¹\82é
+   key C-S-N           = &WindowClingToBottom  # \83E\83B\83\93\83h\83E\82ð\89º\82É\8añ\82¹\82é
+   key C-S-V           = &WindowMoveVisibly    # \83E\83B\83\93\83h\83E\82ð\8c©\82¦\82é\88Ê\92u\82Ö\88Ú\93®
+ endif
+
+ if ( KBD109 ) and ( ! KBD104on109 )
+   key *\94¼\8ap/\91S\8ap      = *Esc                  # Esc \82Æ\94¼\8ap/\91S\8ap\82Ì\93ü\82ê\91Ö\82¦
+   key *Esc            = *\94¼\8ap/\91S\8ap            #       \81V
+ endif
+
+ if ( KBD109 )
+   mod control += \89p\90\94                         # \89p\90\94\82ð Control \82É
+   key *\89p\90\94           = *LControl             #       \81V
+ else
+   mod control += CapsLock                     # CapsLock \82ð Control \82É
+   key *CapsLock       = *LControl             #       \81V
+ endif
+
+ if ( GANA )
+   if ( KBD109 )
+     mod alt += !!\96³\95Ï\8a·                       # \96³\95Ï\8a·\82ð Alt \82É
+     key *\96³\95Ï\8a·       = *\96³\95Ï\8a·               #       \81V
+     key A-\96³\95Ï\8a·      = \96³\95Ï\8a·                #       \81V
+     key IC-A-K                = \96³\95Ï\8a·                # IME \82Å\95Ï\8a·\92\86\82Ì A-K \82Í\96³\95Ï\8a·
+     key *IC-\95Ï\8a·      = $ToggleIME            # IME ON/OFF \82ð\82·\82é\83L\81[\82Ì\8ew\92è
+   endif
+   key *ScrollLock     = $CapsLock             # ScrollLock \82ð CapsLock \82É
+   key C-\81ª            = W-\81ª                  # for VD
+   key C-\81«            = W-\81«                  #       \81V
+   key C-\81©            = W-\81©                  #       \81V
+   key C-\81¨            = W-\81¨                  #       \81V
+ endif
+
+keymap2 GlobalEscape : Global = &KeymapParent
+ event prefixed                = &HelpMessage("Global", "ESC-")
+ event before-key-down = &HelpMessage
+ key M-C-G             = &Ignore
+
+keymap Global
+ if ( MAP-ESCAPE-TO-META )
+   key Escape          = &Prefix(GlobalEscape) &EditNextModifier(M-)
+   if ( KBD109 ) and ( ! KBD104on109 )
+     key \94¼\8ap/\91S\8ap     = &Prefix(GlobalEscape) &EditNextModifier(M-)
+   endif
+ endif
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91S\82Ä(\82Å\82Í\82È\82¢\82ª\82¾\82¢\82½\82¢)\83f\83t\83H\83\8b\83g\82Ì\83L\81[\83}\83b\83v\82Ì\92è\8b`
+#
+
+keymap KeymapDefault = &Default
+ if ( KBD109 )
+   mod control += \89p\90\94                         # \89p\90\94\82ð Control \82É
+   key *\89p\90\94           = *LControl             #       \81V
+ else
+   mod control += CapsLock                     # CapsLock \82ð Control \82É
+   key *CapsLock       = *LControl             #       \81V
+ endif
+ if ( GANA )
+   if ( KBD109 )
+     mod alt += !!\96³\95Ï\8a·                       # \96³\95Ï\8a·\82ð Alt \82É
+     key *\96³\95Ï\8a·       = *\96³\95Ï\8a·               #       \81V
+     key A-\96³\95Ï\8a·      = \96³\95Ï\8a·                #       \81V
+     key IC-A-K                = \96³\95Ï\8a·                # IME \82Å\95Ï\8a·\92\86\82Ì A-K \82Í\96³\95Ï\8a·
+   endif
+ endif
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \83R\83\93\83g\83\8d\81[\83\8b\82Ì\90Ý\92è
+#
+
+include        "emacsedit.mayu"
+
+window EditControl     /:(Edit|TEdit|RichEdit(20[AW])?)$/ : EmacsEdit
+window SysListView32   /:SysListView32$/ : EmacsMove
+window SysTreeView32   /:SysTreeView32$/ : EmacsMove
+window ComboBox        /:ComboBox(:Edit)?$/ : EmacsEdit
+ key M-N M-P           = A-Down                # \83h\83\8d\83b\83v\83_\83E\83\93\83\81\83j\83\85\81[\82ð\8aJ\82­
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Windows \82Ì\88ê\94Ê\93I\90Ý\92è
+#
+
+ keyseq $WM_VSCROLL/SB_PAGEUP          = &PostMessage(ToItself, 277, 2, 0)
+ keyseq $WM_VSCROLL/SB_PAGEDOWN                = &PostMessage(ToItself, 277, 3, 0)
+
+keymap2        GeneralC-X : EmacsC-X
+ key C-S               = C-S                   # \8fã\8f\91\82«\95Û\91¶(S)
+ key C-W               = LAlt F A              # \96¼\91O\82ð\95t\82¯\82Ä\95Û\91¶(A)...
+ key C-F               = C-O                   # \8aJ\82­(O)...
+ key K                 = C-N                   # \90V\8bK\8dì\90¬(N)
+ key C-C               = LAlt F X              # \8fI\97¹(X)
+# key C-C              = A-Q                   # \8fI\97¹(X)
+# key C-C              = $WindowClose          # \8fI\97¹(X)
+
+
+## \83_\83C\83A\83\8d\83O\83{\83b\83N\83X .........................................................
+
+window DialogBox       /:#32770:/ : Global
+ key C-G               = Escape
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# MDI \8fã\82Ì\83E\83B\83\93\83h\83E\82Ì\90Ý\92è
+#
+
+keymap2 MDI-WindowOperation : Global
+ key C-S-L     C-A-L   = &WindowLower(MDI)             # \83E\83B\83\93\83h\83E\82ð\88ê\94Ô\89º\82Ö
+ key C-S-R     C-A-R   = &WindowRaise(MDI)             # \83E\83B\83\93\83h\83E\82ð\88ê\94Ô\8fã\82Ö
+ key C-S-Z     C-A-Z   = &WindowMaximize(MDI)          # \83E\83B\83\93\83h\83E\82Ì\8dÅ\91å\89»
+ key C-S-I     C-A-I   = &WindowMinimize(MDI)          # \83E\83B\83\93\83h\83E\82Ì\8dÅ\8f¬\89»
+ key C-S-X     C-A-X   = &WindowVMaximize(MDI)         # \83E\83B\83\93\83h\83E\82Ì\8fc\8dÅ\91å\89»
+ key C-S-C     C-A-C   = &WindowHMaximize(MDI)         # \83E\83B\83\93\83h\83E\82Ì\89¡\8dÅ\91å\89»
+ key C-S-Left  C-A-Left        = &WindowMove(-16, 0, MDI)      # \83E\83B\83\93\83h\83E\82Ì\88Ú\93®
+ key C-S-Right C-A-Right= &WindowMove(16, 0, MDI)      #       \81V
+ key C-S-Up    C-A-Up  = &WindowMove(0, -16, MDI)      #       \81V
+ key C-S-Down  C-A-Down        = &WindowMove(0, 16, MDI)       #       \81V
+ key C-S-A-Left                = &WindowMove(-1, 0, MDI)       #       \81V
+ key C-S-A-Right       = &WindowMove(1, 0, MDI)        #       \81V
+ key C-S-A-Up          = &WindowMove(0, -1, MDI)       #       \81V
+ key C-S-A-Down                = &WindowMove(0, 1, MDI)        #       \81V
+ key C-S-A C-S-B C-A-A = &WindowClingToLeft(MDI)       # \83E\83B\83\93\83h\83E\8d\82É\8añ\82¹\82é
+ key C-S-E C-S-F C-A-E = &WindowClingToRight(MDI)      # \83E\83B\83\93\83h\83E\89E\82É\8añ\82¹\82é
+ key C-S-P     C-A-P   = &WindowClingToTop(MDI)        # \83E\83B\83\93\83h\83E\8fã\82É\8añ\82¹\82é
+ key C-S-N     C-A-N   = &WindowClingToBottom(MDI)     # \83E\83B\83\93\83h\83E\89º\82É\8añ\82¹\82é
+ key C-S-V     C-A-V   = &WindowMoveVisibly(MDI)       # \83E\83B\83\93\83h\83E\8c©\82¦\82é\88Ê\92u
+ key C-S-K     C-A-K   = C-F4                          # \83E\83B\83\93\83h\83E\82ð\95Â\82\82é
+
+window MDI     /:MDIClient:/ : Global
+ key C-S-Q     C-A-Q   = &Prefix(MDI-WindowOperation)
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \8ae\83A\83v\83\8a\83P\81[\83V\83\87\83\93\82Ì\90Ý\92è
+#
+
+
+## \91\8b\8eg\82¢\82Ì\97J\9fT ...............................................................
+## http://mayu.sourceforge.net
+
+# \89¼\91z\83L\81[\92²\8d¸\83E\83B\83\93\83h\83E\82Å\82Í\91S\82Ä\83f\83t\83H\83\8b\83g
+window MayuInvestigate /mayu\.exe:#32770:mayuFocus$/ : KeymapDefault
+
+# \83\8d\83O\83E\83B\83\93\83h\83E Esc \82Å\95Â\82\82ç\82ê\82é\82æ\82¤\82É
+window MayuLog ( /mayu\.exe:#32770:Button/ \
+               && /\83\8d\83O - \91\8b\8eg\82¢\82Ì\97J\9fT/ ) : Global
+ key C-G               = $WindowClose
+ key Esc               = $WindowClose
+
+
+## Console ....................................................................
+
+ keyseq $ConsoleWindowClass/copy       = &PostMessage(ToItself, 274, 65520, 0)
+ keyseq $ConsoleWindowClass/paste      = &PostMessage(ToItself, 274, 65521, 0)
+ keyseq $ConsoleWindowClass/region     = &PostMessage(ToItself, 274, 65522, 0)
+ keyseq $ConsoleWindowClass/scroll     = &PostMessage(ToItself, 274, 65523, 0)
+ keyseq $ConsoleWindowClass/search     = &PostMessage(ToItself, 274, 65524, 0)
+ keyseq $ConsoleWindowClass/select-all = &PostMessage(ToItself, 274, 65525, 0)
+
+window  ConsoleWindowClass /^ConsoleWindowClass$/ : Global
+ key C-S-K     C-A-K   = A-Space C             # \83E\83B\83\93\83h\83E\82ð\95Â\82\82é
+ key S-Insert          = $ConsoleWindowClass/paste
+ key S-Prior           = $WM_VSCROLL/SB_PAGEUP
+ key S-Next            = $WM_VSCROLL/SB_PAGEDOWN
+ key S-~NL-Num9                = $WM_VSCROLL/SB_PAGEUP
+ key S-~NL-Num3                = $WM_VSCROLL/SB_PAGEDOWN
+
+
+## Explorer, Internet Explorer ................................................
+
+ keyseq $Explorer/show-folder-bar = &PostMessage(ToMainWindow, 273, 41525, 0)
+
+window ExplorerList /EXPLORER.*:SHELLDLL_DefView:.*SysListView32$/ \
+                       : SysListView32
+ key S-R               = F2                    # \96¼\91O\82Ì\95Ï\8dX
+ key C-S-Z             = &Sync&WindowMaximize  # \83E\83B\83\93\83h\83E\82Ì\8dÅ\91å\89»
+ key C-A-Z             = C-&WindowMaximize     # \83E\83B\83\93\83h\83E\82Ì\91S\89æ\96Ê\89»
+ key M-E               = $Explorer/show-folder-bar # \83t\83H\83\8b\83_\82ð\95\\8e¦
+
+window ExplorerTree /EXPLORER.*:BaseBar:.*SysTreeView32$/ : SysTreeView32
+ key S-R               = F2                    # \96¼\91O\82Ì\95Ï\8dX
+ key C-S-Z             = &Sync&WindowMaximize  # \83E\83B\83\93\83h\83E\82Ì\8dÅ\91å\89»
+ key C-A-Z             = C-&WindowMaximize     # \83E\83B\83\93\83h\83E\82Ì\91S\89æ\96Ê\89»
+ key M-E               = $Explorer/show-folder-bar # \83t\83H\83\8b\83_\82ð\95\\8e¦
+
+window InternetExplorer /:Internet Explorer_Server$/ : EmacsEdit
+ key C-S-Z             = &Sync&WindowMaximize  # \83E\83B\83\93\83h\83E\82Ì\8dÅ\91å\89»
+ key C-A-Z             = C-&WindowMaximize     # \83E\83B\83\93\83h\83E\82Ì\91S\89æ\96Ê\89»
+
+window MicrosoftJava   /:Microsoft VM For Java\(TM\) Host Window Class:/ \
+       : EmacsEdit
+
+
+## Emacs ......................................................................
+## http://www.gnu.org/software/emacs/windows/ntemacs.html
+
+keymap Emacsen : Global
+ key C-Yen             = &Default
+ if ( MAP-ESCAPE-TO-META )                     # ESC \82ª M- \82É\82È\82é\82Ì\82ð\91j\8e~\82·\82é
+   if ( KBD109 ) and ( ! KBD104on109 )
+     key *\94¼\8ap/\91S\8ap    = *Esc
+     key *Esc          = *\94¼\8ap/\91S\8ap
+   else
+     key Escape                = &Default
+   endif
+ endif
+
+window Meadow  /:Meadow$/ : Emacsen
+ key IC-M-X            = $ToggleIME M-X
+window MULE    /:MULE$/ : Emacsen
+window Emacs   /:Emacs$/ : Emacsen
+
+
+## Notepad ....................................................................
+
+ keyseq $Notepad/new           = &PostMessage(ToParentWindow, 273, 9, 0)
+ keyseq $Notepad/open          = &PostMessage(ToParentWindow, 273, 10, 0)
+ keyseq $Notepad/save-as       = &PostMessage(ToParentWindow, 273, 1, 0)
+
+keymap2        NotepadC-X : GeneralC-X
+ event prefixed                = &HelpMessage("\83\81\83\82\92  C-x-", \
+       "C-x C-s\t\8fã\8f\91\82«\95Û\91¶\r\n"       \
+       "C-x C-f\t\8aJ\82­\t\r\n"           \
+       "C-x k\t\t\90V\8bK\8dì\90¬\r\n"         \
+       "C-x C-c\t\8fI\97¹")
+ event before-key-down = &HelpMessage
+ key C-S               = $Notepad/save-as      # \8fã\8f\91\82«\95Û\91¶(S)
+ key C-F               = $Notepad/open         # \8aJ\82­(O)...
+ key K                 = $Notepad/new          # \90V\8bK\8dì\90¬(N)
+ key C-C               = $WindowClose          # \83\81\83\82\92 \82Ì\8fI\97¹(X)
+
+window Notepad /:Notepad:Edit$/ : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(NotepadC-X)
+ key C-S               = F3                    # \8c\9f\8dõ(F)...
+ key M-J               = C-G                   # \8ds\82Ö\88Ú\93®
+
+
+## ASTEC-X ....................................................................
+## http://www.astec.co.jp/
+
+ keyseq $ASTEC-X/copy-to-x     = &PostMessage(ToItself, 274, 16, 0)
+
+window ASTEC-X /:ASTEC-X$/ : Global
+ key C-Yen             = &Default
+ key *IC-IL-C-Yen      = $ToggleIME            # IME\82ª\83I\83\93\82È\82ç\82ÎIME\82ð\83I\83t
+
+
+## Becky! Internet Mail .......................................................
+## http://www.rimarts.co.jp/index-j.html
+
+window BeckyInternetMail /Rebecca\.exe:BeckyComposeFrameClass:/ : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(GeneralC-X)
+
+window BeckyInternetMail2 /B2\.exe:Becky2ComposeFrame:/ : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(GeneralC-X)
+
+
+## Microsoft Power Point ......................................................
+
+keymap2        PowerPointC-X : GeneralC-X
+ key C-C               = $WindowClose          # \8fI\97¹(X)
+
+window PowerPoint /POWERPNT\.EXE:.*:(paneClassDC|REComboBox20W|RichEdit20W)$/\
+                       : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(PowerPointC-X)
+
+window PowerPoint2 /POWERPNT\.EXE:PP9FrameClass.*/ : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(PowerPointC-X)
+
+## Microsoft Visual Basic 6.0 .................................................
+
+window VisualBasic /vb6\.exe:.*:VbaWindow$/ : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(GeneralC-X)
+
+
+## Microsoft Word .............................................................
+
+window MicrosoftWord /WINWORD\.EXE:.*:_WwG$/ : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(GeneralC-X)
+
+
+## Microsoft Excel ............................................................
+
+window MicrosoftExcel /EXCEL\.EXE:XLMAIN:/ : EmacsEdit
+ if ( !ZXCV ) key C-X  = &Prefix(GeneralC-X)
+
+
+## Microsoft Pinball ..........................................................
+
+window MSPinball /PINBALL\.EXE:1c7c22a0-9576-11ce-bf80-444553540000$/ : Global
+ key A-Enter           = F4
+
+
+## Netscape Navigator .........................................................
+## http://www.netscape.com/
+
+window NetscapeNavigator /Netscape\.exe:/ : Global
+ key C-H               = BackSpace             # BackSpace
+ key C-S               = C-F                   # \8c\9f\8dõ
+
+
+## Mozilla ....................................................................
+## http://www.mozilla.org/
+
+window Mozilla /:MozillaWindowClass$/ : EmacsEdit
+
+
+## Personal Dictionary ........................................................
+## http://member.nifty.ne.jp/TaN/
+
+window PersonalDictionary /PDICW32\.EXE:PDICW:ComboBox:Edit/ : EmacsEdit
+ key C-K               = S-End S-Delete        # \8ds\96\96\82Ü\82Å\8dí\8f\9c
+ key C-Y               = S-Insert              # PASTE
+
+
+## Real Player ................................................................
+## http://www.real.com/
+
+window RealPlayer /realplay.exe:PNGUIClass/ : Global
+ key A-Enter           = LAlt V Z F
+ key C-R               = C-P
+
+
+## TeraTerm ...................................................................
+## http://hp.vector.co.jp/authors/VA002416/
+
+window TeraTerm /TTermPRO\.exe:VTWin32$/ : Global
+ key C-Slash           = C-S-HyphenMinus       # C-_ \82ð\93ü\97Í
+ key S-Prior           = C-Prior               # \83X\83N\83\8d\81[\83\8b
+ key S-Next            = C-Next                # \83X\83N\83\8d\81[\83\8b
+ key IC-M-X    IL-M-X  = $ToggleIME M-X        # for emacs
+ if ( KBD109 )
+   key C-S-ReverseSolidus = C-S-HyphenMinus    # C-_ \82ð\93ü\97Í
+ endif
+
+
+## Waffle .....................................................................
+## http://sakura.tsg.ne.jp/~tjkawa/witalk2/
+## Emacs \95\97\83L\81[\83o\83C\83\93\83f\83B\83\93\83O\82É\82µ\82Ä\82¨\82­\82±\82Æ
+
+ keyseq        $WaffleMark/cancel              = Left Right
+
+window Waffle /WITALK2\.EXE:.*:RichEdit(20A)?$/ : Global
+keymap2        WaffleMark : Waffle = $WaffleMark/cancel &KeymapParent
+
+keymap Waffle
+ key Home              = &Default              # \95\93ª
+ key End               = &Default              # \95\96\96
+ key C-Space           = &Prefix(WaffleMark)   # Mark
+ key C-A               = &Default              # \8ds\93ª
+ key C-B               = &Default              # \81©
+ key C-C               = &Default              # (Waffle Prefix)
+ key M-B               = &Default              # \81©(\92P\8cê)
+ key C-D               = &Default              # \8dí\8f\9c
+ key M-D               = &Default              # \8dí\8f\9c(\92P\8cê)
+ key C-E               = &Default              # \8ds\96\96
+ key C-F               = &Default              # \81¨
+ key M-F               = &Default              # \81¨(\92P\8cê)
+ key C-G               = &Default              # CANCEL
+ key C-H               = &Default              # BS
+ key C-J               = &Default              # RETURN
+ key C-K               = &Default              # \8ds\96\96\82Ü\82Å\8dí\8f\9c
+ key M-L               = &Default              # \8f¬\95\8e\9a
+ key C-M               = &Default              # RETURN
+ key C-N               = &Default              # \81«
+ key C-O               = &Default              # \88ê\8ds\91\9d\82â\82·
+ key C-P               = &Default              # \81ª
+ key C-Q               = &Prefix(KeymapDefault) # mayu \82É\8d\89E\82³\82ê\82È\82¢\83L\81[\93ü\97Í
+ key C-S               = &Default              # \8c\9f\8dõ
+ key C-T               = &Default              # \95\8e\9a\93ü\82ê\91Ö\82¦
+ key C-V               = Next                  # \8e\9f\95Å (Waffle \82Ì\83o\83O?)
+ key M-V               = &Default              # \91O\95Å
+ key C-W               = &Default              # CUT
+ key M-W               = &Default              # COPY
+ key C-Y               = &Default              # PASTE
+ key M-U               = &Default              # \91å\95\8e\9a
+ key S-Home            = &Default              # \95\93ª(\91I\91ð)
+ key S-End             = &Default              # \95\96\96(\91I\91ð)
+ key S-M-Comma         = &Default              # \95\93ª
+ key S-M-Period                = &Default              # \95\96\96
+ key M-BackSpace       = &Default              # BS(\92P\8cê)
+ key C-Slash           = &Default              # UNDO
+
+keymap2        WaffleMark
+ key Home              = S-C-Home      &Prefix(WaffleMark)     # \95\93ª
+ key End               = S-C-End       &Prefix(WaffleMark)     # \95\96\96
+ key C-A               = S-Home        &Prefix(WaffleMark)     # \8ds\93ª
+ key C-B               = S-Left        &Prefix(WaffleMark)     # \81©
+ key M-B               = S-C-Left      &Prefix(WaffleMark)     # \81©(\92P\8cê)
+ key C-E               = S-End &Prefix(WaffleMark)             # \8ds\96\96
+ key C-F               = S-Right       &Prefix(WaffleMark)     # \81¨
+ key M-F               = S-C-Right     &Prefix(WaffleMark)     # \81¨(\92P\8cê)
+ key C-G               = $WaffleMark/cancel &Undefined         # \83L\83\83\83\93\83Z\83\8b
+ key C-N               = S-Down        &Prefix(WaffleMark)     # \81«
+ key C-P               = S-Up          &Prefix(WaffleMark)     # \81ª
+ key C-V               = S-Next        &Prefix(WaffleMark)     # \8e\9f\95Å
+ key M-V               = S-Prior       &Prefix(WaffleMark)     # \91O\95Å
+ key C-W               = C-W Left Right                        # CUT
+ key M-W               = M-W Left Right                        # COPY
+ key S-M-Comma         = S-C-Home      &Prefix(WaffleMark)     # \95\93ª
+ key S-M-Period                = S-C-End       &Prefix(WaffleMark)     # \95\96\96
+ key Left              = S-Left        &Prefix(WaffleMark)     # \81©
+ key Up                        = S-Up          &Prefix(WaffleMark)     # \81ª
+ key Right             = S-Right       &Prefix(WaffleMark)     # \81¨
+ key Down              = S-Down        &Prefix(WaffleMark)     # \81«
+
+
+## Xyzzy ......................................................................
+## http://www.jsdlab.co.jp/~kamei/
+
+window Xyzzy /xyzzy\.exe:/ : Global
+ key C-S-K     C-A-K   = C-X C-C               # \83E\83B\83\93\83h\83E\82ð\95Â\82\82é
+
+
+## Windows Media Player .......................................................
+
+window WindowsMediaPlayer /mplayer2.*:(Media Player 2|VideoRenderer)/ : Global
+ key C-A               = Space         # Play
+ key C-R               = Space         # Play
+ key C-P               = Space         # Pause
+ key C-S               = Period        # Stop
+
+
+## Windows Mine Sweeper .......................................................
+
+window WindowsMineSweeper /winmine.exe:\83}\83C\83\93\83X\83C\81[\83p$/ : Global
+ key D-Z               = &VK(RButton)
+ key U-Z               = &Ignore
+ key D-X               = &VK(MButton)
+ key U-X               = &Ignore
+ key D-C               = &VK(LButton)
+ key U-C               = &Ignore
+ key Q                 = F2
+ key Num1              = &MouseMove(-16,  16)
+ key Num2              = &MouseMove(  0,  16)
+ key Num3              = &MouseMove( 16,  16)
+ key Num4              = &MouseMove(-16,   0)
+ key Num6              = &MouseMove( 16,   0)
+ key Num7              = &MouseMove(-16, -16)
+ key Num8              = &MouseMove(  0, -16)
+ key Num9              = &MouseMove( 16, -16)
+
+
+## ICQ2000 ....................................................................
+## http://web.icq.com/
+
+if ( GANA )
+  window ICQMessageSession \
+       ( /ICQ\.exe:#32770:Edit$/ && /Message Session/ ) : EmacsEdit
+   key Enter           = M-S
+endif
+
+
+## Acrobat Reader .............................................................
+## http://www.adobe.co.jp/support/custsupport/library/acrwin.html
+
+window AcrobatReader /AcroRd32.exe:.*:MDIClient:/ : EmacsMove
+ key Space             = PageDown
+ key BS                        = PageUp
+
+
+## Edmax ......................................................................
+## http://www.bekkoame.ne.jp/~t.mzaki/
+
+window EdMax-edit /edmax\.exe:.*Afx:400000:b:0:1900010:0$/ : EmacsEdit
+
+
+## VisualBasic ................................................................
+
+window VBTextBox /:ThunderRT6FormDC:(ThunderRT6TextBox|RichTextWndClass)$/ \
+       : EmacsEdit
+
+## StarOffice/StarSuite/OpenOffice ............................................
+
+window StarOffice /soffice\.exe:SALFRAME$/ : EmacsEdit
+
+## Opera ......................................................................
+
+window Opera /Opera\.exe:/ : EmacsEdit
diff --git a/dlgeditsetting.cpp b/dlgeditsetting.cpp
new file mode 100644 (file)
index 0000000..81628b5
--- /dev/null
@@ -0,0 +1,182 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlgeditsetting.cpp
+
+
+#include "misc.h"
+#include "mayurc.h"
+#include "windowstool.h"
+#include "dlgeditsetting.h"
+#include "layoutmanager.h"
+#include <windowsx.h>
+
+
+///
+class DlgEditSetting : public LayoutManager
+{
+  HWND m_hwndMayuPathName;                     ///
+  HWND m_hwndMayuPath;                         ///
+  HWND m_hwndSymbols;                          ///
+
+  DlgEditSettingData *m_data;                  ///
+
+public:
+  ///
+  DlgEditSetting(HWND i_hwnd)
+    : LayoutManager(i_hwnd),
+      m_hwndMayuPathName(NULL),
+      m_hwndMayuPath(NULL),
+      m_hwndSymbols(NULL),
+      m_data(NULL)
+  {
+  }
+  
+  /// WM_INITDIALOG
+  BOOL wmInitDialog(HWND /* focus */, LPARAM i_lParam)
+  {
+    m_data = reinterpret_cast<DlgEditSettingData *>(i_lParam);
+    
+    setSmallIcon(m_hwnd, IDI_ICON_mayu);
+    setBigIcon(m_hwnd, IDI_ICON_mayu);
+    
+    CHECK_TRUE( m_hwndMayuPathName
+               = GetDlgItem(m_hwnd, IDC_EDIT_mayuPathName) );
+    CHECK_TRUE( m_hwndMayuPath = GetDlgItem(m_hwnd, IDC_EDIT_mayuPath) );
+    CHECK_TRUE( m_hwndSymbols = GetDlgItem(m_hwnd, IDC_EDIT_symbols) );
+
+    SetWindowText(m_hwndMayuPathName, m_data->m_name.c_str());
+    SetWindowText(m_hwndMayuPath, m_data->m_filename.c_str());
+    SetWindowText(m_hwndSymbols, m_data->m_symbols.c_str());
+    
+    restrictSmallestSize();
+    
+    // set layout manager
+    typedef LayoutManager LM;
+
+    addItem(GetDlgItem(m_hwnd, IDC_STATIC_mayuPathName));
+    addItem(GetDlgItem(m_hwnd, IDC_EDIT_mayuPathName),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_STATIC_mayuPathNameComment),
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE);
+
+    addItem(GetDlgItem(m_hwnd, IDC_STATIC_mayuPath));
+    addItem(GetDlgItem(m_hwnd, IDC_EDIT_mayuPath),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_browse),
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE);
+
+    addItem(GetDlgItem(m_hwnd, IDC_STATIC_symbols));
+    addItem(GetDlgItem(m_hwnd, IDC_EDIT_symbols),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_STATIC_symbolsComment),
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_TOP_EDGE);
+    
+    addItem(GetDlgItem(m_hwnd, IDOK),
+           LM::ORIGIN_CENTER, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_TOP_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDCANCEL),
+           LM::ORIGIN_CENTER, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_TOP_EDGE);
+
+    restrictSmallestSize(LM::RESTRICT_BOTH);
+    restrictLargestSize(LM::RESTRICT_VERTICALLY);
+    
+    return TRUE;
+  }
+  
+  /// WM_CLOSE
+  BOOL wmClose()
+  {
+    CHECK_TRUE( EndDialog(m_hwnd, 0) );
+    return TRUE;
+  }
+
+  /// WM_COMMAND
+  BOOL wmCommand(int /* i_notify_code */, int i_id, HWND /* i_hwnd_control */)
+  {
+    _TCHAR buf[GANA_MAX_PATH];
+    switch (i_id)
+    {
+      case IDC_BUTTON_browse:
+      {
+       tstring title = loadString(IDS_openMayu);
+       tstring filter = loadString(IDS_openMayuFilter);
+       for (size_t i = 0; i < filter.size(); ++ i)
+         if (filter[i] == _T('|'))
+           filter[i] = _T('\0');
+
+       _tcscpy(buf, _T(".mayu"));
+       OPENFILENAME of;
+       memset(&of, 0, sizeof(of));
+       of.lStructSize = sizeof(of);
+       of.hwndOwner = m_hwnd;
+       of.lpstrFilter = filter.c_str();
+       of.nFilterIndex = 1;
+       of.lpstrFile = buf;
+       of.nMaxFile = NUMBER_OF(buf);
+       of.lpstrTitle = title.c_str();
+       of.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST |
+         OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
+       if (GetOpenFileName(&of))
+         SetWindowText(m_hwndMayuPath, buf);
+       return TRUE;
+      }
+      
+      case IDOK:
+      {
+       GetWindowText(m_hwndMayuPathName, buf, NUMBER_OF(buf));
+       m_data->m_name = buf;
+       GetWindowText(m_hwndMayuPath, buf, NUMBER_OF(buf));
+       m_data->m_filename = buf;
+       GetWindowText(m_hwndSymbols, buf, NUMBER_OF(buf));
+       m_data->m_symbols = buf;
+       CHECK_TRUE( EndDialog(m_hwnd, 1) );
+       return TRUE;
+      }
+      
+      case IDCANCEL:
+      {
+       CHECK_TRUE( EndDialog(m_hwnd, 0) );
+       return TRUE;
+      }
+    }
+    return FALSE;
+  }
+};
+
+
+//
+BOOL CALLBACK dlgEditSetting_dlgProc(HWND i_hwnd, UINT i_message,
+                                    WPARAM i_wParam, LPARAM i_lParam)
+{
+  DlgEditSetting *wc;
+  getUserData(i_hwnd, &wc);
+  if (!wc)
+    switch (i_message)
+    {
+      case WM_INITDIALOG:
+       wc = setUserData(i_hwnd, new DlgEditSetting(i_hwnd));
+       return wc->wmInitDialog(
+         reinterpret_cast<HWND>(i_wParam), i_lParam);
+    }
+  else
+    switch (i_message)
+    {
+      case WM_COMMAND:
+       return wc->wmCommand(HIWORD(i_wParam), LOWORD(i_wParam),
+                            reinterpret_cast<HWND>(i_lParam));
+      case WM_CLOSE:
+       return wc->wmClose();
+      case WM_NCDESTROY:
+       delete wc;
+       return TRUE;
+      default:
+       return wc->defaultWMHandler(i_message, i_wParam, i_lParam);
+    }
+  return FALSE;
+}
diff --git a/dlgeditsetting.h b/dlgeditsetting.h
new file mode 100644 (file)
index 0000000..fa61db7
--- /dev/null
@@ -0,0 +1,25 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlgeditsetting.h
+
+
+#ifndef _DLGEDITSETTING_H
+#  define _DLGEDITSETTING_H
+
+#  include "stringtool.h"
+
+
+/// dialog procedure of "Edit Setting" dialog box
+BOOL CALLBACK dlgEditSetting_dlgProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
+
+/// parameters for "Edit Setting" dialog box
+class DlgEditSettingData
+{
+public:
+  tstringi m_name;                             /// setting name
+  tstringi m_filename;                         /// filename of setting
+  tstringi m_symbols;          /// symbol list (-Dsymbol1;-Dsymbol2;-D...)
+};
+
+
+#endif // !_DLGEDITSETTING_H
diff --git a/dlginvestigate.cpp b/dlginvestigate.cpp
new file mode 100644 (file)
index 0000000..8865b04
--- /dev/null
@@ -0,0 +1,197 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlginvestigate.cpp
+
+
+#include "misc.h"
+#include "engine.h"
+#include "focus.h"
+#include "hook.h"
+#include "mayurc.h"
+#include "stringtool.h"
+#include "target.h"
+#include "windowstool.h"
+#include "vkeytable.h"
+#include "dlginvestigate.h"
+#include <iomanip>
+
+
+///
+class DlgInvestigate
+{
+  HWND m_hwnd;                                 ///
+  UINT m_WM_MAYU_MESSAGE;                      ///
+  DlgInvestigateData m_data;                   /// 
+  
+public:
+  ///
+  DlgInvestigate(HWND i_hwnd)
+    : m_hwnd(i_hwnd),
+      m_WM_MAYU_MESSAGE(RegisterWindowMessage(
+                           addSessionId(WM_MAYU_MESSAGE_NAME).c_str()))
+  {
+    m_data.m_engine = NULL;
+    m_data.m_hwndLog = NULL;
+  }
+  
+  /// WM_INITDIALOG
+  BOOL wmInitDialog(HWND /* i_focus */, LPARAM i_lParam)
+  {
+    m_data = *reinterpret_cast<DlgInvestigateData *>(i_lParam);
+    setSmallIcon(m_hwnd, IDI_ICON_mayu);
+    setBigIcon(m_hwnd, IDI_ICON_mayu);
+    return TRUE;
+  }
+  
+  /// WM_DESTROY
+  BOOL wmDestroy()
+  {
+    unsetSmallIcon(m_hwnd);
+    unsetBigIcon(m_hwnd);
+    return TRUE;
+  }
+  
+  /// WM_CLOSE
+  BOOL wmClose()
+  {
+    ShowWindow(m_hwnd, SW_HIDE);
+    return TRUE;
+  }
+
+  /// WM_COMMAND
+  BOOL wmCommand(int /* i_notifyCode */, int i_id, HWND /* i_hwndControl */)
+  {
+    switch (i_id)
+    {
+      case IDOK:
+      {
+       ShowWindow(m_hwnd, SW_HIDE);
+       return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /// WM_focusNotify
+  BOOL wmFocusNotify(bool i_isFocused, HWND i_hwndFocus)
+  {
+    if (m_data.m_engine &&
+       i_hwndFocus == GetDlgItem(m_hwnd, IDC_CUSTOM_scancode))
+      m_data.m_engine->enableLogMode(i_isFocused);
+    return TRUE;
+  }
+  
+  /// WM_targetNotify
+  BOOL wmTargetNotify(HWND i_hwndTarget)
+  {
+    _TCHAR className[GANA_MAX_ATOM_LENGTH];
+    bool ok = false;
+    if (GetClassName(i_hwndTarget, className, NUMBER_OF(className)))
+    {
+      if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0)
+      {
+       _TCHAR titleName[1024];
+       if (GetWindowText(i_hwndTarget, titleName, NUMBER_OF(titleName)) == 0)
+         titleName[0] = _T('\0');
+       {
+         Acquire a(&m_data.m_engine->m_log, 1);
+         m_data.m_engine->m_log << _T("HWND:\t") << std::hex
+                                << reinterpret_cast<int>(i_hwndTarget)
+                                << std::dec << std::endl;
+       }
+       Acquire a(&m_data.m_engine->m_log, 0);
+       m_data.m_engine->m_log << _T("CLASS:\t") << className << std::endl;
+       m_data.m_engine->m_log << _T("TITLE:\t") << titleName << std::endl;
+       ok = true;
+      }
+    }
+    if (!ok)
+      CHECK_TRUE( PostMessage(i_hwndTarget, m_WM_MAYU_MESSAGE,
+                             MayuMessage_notifyName, 0) );
+    return TRUE;
+  }
+  
+  /// WM_vkeyNotify
+  BOOL wmVkeyNotify(int i_nVirtKey, int /* i_repeatCount */,
+                   BYTE /* i_scanCode */, bool i_isExtended,
+                   bool /* i_isAltDown */, bool i_isKeyup)
+  {
+    Acquire a(&m_data.m_engine->m_log, 0);
+    m_data.m_engine->m_log
+      << (i_isExtended ? _T(" E-") : _T("   "))
+      << _T("0x") << std::hex << std::setw(2) << std::setfill(_T('0'))
+      << i_nVirtKey << std::dec << _T("  &VK( ")
+      << (i_isExtended ? _T("E-") : _T("  "))
+      << (i_isKeyup ? _T("U-") : _T("D-"));
+    
+    for (const VKeyTable *vkt = g_vkeyTable; vkt->m_name; ++ vkt)
+    {
+      if (vkt->m_code == i_nVirtKey)
+      {
+       m_data.m_engine->m_log << vkt->m_name << _T(" )") << std::endl;
+       return TRUE;
+      }
+    }
+    m_data.m_engine->m_log << _T("0x") << std::hex << std::setw(2)
+                          << std::setfill(_T('0')) << i_nVirtKey << std::dec
+                          << _T(" )") << std::endl;
+    return TRUE;
+  }
+
+  BOOL wmMove(int /* i_x */, int /* i_y */)
+  {
+    RECT rc1, rc2;
+    GetWindowRect(m_hwnd, &rc1);
+    GetWindowRect(m_data.m_hwndLog, &rc2);
+    
+    MoveWindow(m_data.m_hwndLog, rc1.left, rc1.bottom,
+              rcWidth(&rc2), rcHeight(&rc2), TRUE);
+    
+    return TRUE;
+  }
+};
+
+
+//
+BOOL CALLBACK dlgInvestigate_dlgProc(HWND i_hwnd, UINT i_message,
+                                    WPARAM i_wParam, LPARAM i_lParam)
+{
+  DlgInvestigate *wc;
+  getUserData(i_hwnd, &wc);
+  if (!wc)
+    switch (i_message)
+    {
+      case WM_INITDIALOG:
+       wc = setUserData(i_hwnd, new DlgInvestigate(i_hwnd));
+       return wc->wmInitDialog(reinterpret_cast<HWND>(i_wParam), i_lParam);
+    }
+  else
+    switch (i_message)
+    {
+      case WM_MOVE:
+       return wc->wmMove(static_cast<short>(LOWORD(i_lParam)),
+                         static_cast<short>(HIWORD(i_lParam)));
+      case WM_COMMAND:
+       return wc->wmCommand(HIWORD(i_wParam), LOWORD(i_wParam),
+                            reinterpret_cast<HWND>(i_lParam));
+      case WM_CLOSE:
+       return wc->wmClose();
+      case WM_DESTROY:
+       return wc->wmDestroy();
+      case WM_APP_notifyFocus:
+       return wc->wmFocusNotify(!!i_wParam,
+                                reinterpret_cast<HWND>(i_lParam));
+      case WM_APP_targetNotify:
+       return wc->wmTargetNotify(reinterpret_cast<HWND>(i_lParam));
+      case WM_APP_notifyVKey:
+       return wc->wmVkeyNotify(
+         static_cast<int>(i_wParam), static_cast<int>(i_lParam & 0xffff),
+         static_cast<BYTE>((i_lParam >> 16) & 0xff),
+         !!(i_lParam & (1 << 24)),
+         !!(i_lParam & (1 << 29)),
+         !!(i_lParam & (1 << 31)));
+      case WM_NCDESTROY:
+       delete wc;
+       return TRUE;
+    }
+  return FALSE;
+}
diff --git a/dlginvestigate.h b/dlginvestigate.h
new file mode 100644 (file)
index 0000000..31ccf28
--- /dev/null
@@ -0,0 +1,26 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlginvestigate.h
+
+
+#ifndef _DLGINVESTIGATE_H
+#  define _DLGINVESTIGATE_H
+
+#  include <windows.h>
+
+
+/// dialog procedure of "Investigate" dialog box
+BOOL CALLBACK dlgInvestigate_dlgProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
+
+class Engine;
+
+/// parameters for "Investigate" dialog box
+class DlgInvestigateData
+{
+public:
+  Engine *m_engine;                            /// engine
+  HWND m_hwndLog;                              /// log
+};
+
+
+#endif // !_DLGINVESTIGATE_H
diff --git a/dlglog.cpp b/dlglog.cpp
new file mode 100644 (file)
index 0000000..50641c5
--- /dev/null
@@ -0,0 +1,193 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlglog.cpp
+
+
+#include "misc.h"
+#include "mayu.h"
+#include "mayurc.h"
+#include "registry.h"
+#include "windowstool.h"
+#include "msgstream.h"
+#include "layoutmanager.h"
+#include "dlglog.h"
+#include <windowsx.h>
+
+
+///
+class DlgLog : public LayoutManager
+{
+  HWND m_hwndEdit;                             ///
+  HWND m_hwndTaskTray;                         /// tasktray window
+  LOGFONT m_lf;                                        ///
+  HFONT m_hfontOriginal;                       ///
+  HFONT m_hfont;                               ///
+  tomsgstream *m_log;                          ///
+  
+public:
+  ///
+  DlgLog(HWND i_hwnd)
+    : LayoutManager(i_hwnd),
+      m_hwndEdit(GetDlgItem(m_hwnd, IDC_EDIT_log)),
+      m_hwndTaskTray(NULL),
+      m_hfontOriginal(GetWindowFont(m_hwnd)),
+      m_hfont(NULL)
+  {
+  }
+  
+  /// WM_INITDIALOG
+  BOOL wmInitDialog(HWND /* i_focus */, LPARAM i_lParam)
+  {
+    DlgLogData *dld = reinterpret_cast<DlgLogData *>(i_lParam);
+    m_log = dld->m_log;
+    m_hwndTaskTray = dld->m_hwndTaskTray;
+    
+    // set icons
+    setSmallIcon(m_hwnd, IDI_ICON_mayu);
+    setBigIcon(m_hwnd, IDI_ICON_mayu);
+    
+    // set font
+    Registry::read(MAYU_REGISTRY_ROOT, _T("logFont"), &m_lf,
+                  loadString(IDS_logFont));
+    m_hfont = CreateFontIndirect(&m_lf);
+    SetWindowFont(m_hwndEdit, m_hfont, false);
+    
+    // resize
+    RECT rc;
+    CHECK_TRUE( GetClientRect(m_hwnd, &rc) );
+    wmSize(0, (short)rc.right, (short)rc.bottom);
+
+    // debug level
+    bool isChecked =
+      (IsDlgButtonChecked(m_hwnd, IDC_CHECK_detail) == BST_CHECKED);
+    m_log->setDebugLevel(isChecked ? 1 : 0);
+
+    // set layout manager
+    typedef LayoutManager LM;
+    addItem(GetDlgItem(m_hwnd, IDOK),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_EDIT_log),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_clearLog),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_changeFont),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_CHECK_detail),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    restrictSmallestSize();
+
+    // enlarge window
+    GetWindowRect(m_hwnd, &rc);
+    rc.bottom += (rc.bottom - rc.top) * 3;
+    MoveWindow(m_hwnd, rc.left, rc.top,
+              rc.right - rc.left, rc.bottom - rc.top, true);
+    return TRUE;
+  }
+
+  /// WM_DESTROY
+  BOOL wmDestroy()
+  {
+    // unset font
+    SetWindowFont(m_hwndEdit, m_hfontOriginal, false);
+    DeleteObject(m_hfont);
+    
+    // unset icons
+    unsetBigIcon(m_hwnd);
+    unsetSmallIcon(m_hwnd);
+    return TRUE;
+  }
+  
+  /// WM_CLOSE
+  BOOL wmClose()
+  {
+    ShowWindow(m_hwnd, SW_HIDE);
+    return TRUE;
+  }
+
+  /// WM_COMMAND
+  BOOL wmCommand(int /* i_notifyCode */, int i_id, HWND /* i_hwndControl */)
+  {
+    switch (i_id)
+    {
+      case IDOK:
+      {
+       ShowWindow(m_hwnd, SW_HIDE);
+       return TRUE;
+      }
+      
+      case IDC_BUTTON_clearLog:
+      {
+       Edit_SetSel(m_hwndEdit, 0, Edit_GetTextLength(m_hwndEdit));
+       Edit_ReplaceSel(m_hwndEdit, _T(""));
+       SendMessage(m_hwndTaskTray, WM_APP_dlglogNotify,
+                   DlgLogNotify_logCleared, 0);
+       return TRUE;
+      }
+      
+      case IDC_BUTTON_changeFont:
+      {
+       CHOOSEFONT cf;
+       memset(&cf, 0, sizeof(cf));
+       cf.lStructSize = sizeof(cf);
+       cf.hwndOwner = m_hwnd;
+       cf.lpLogFont = &m_lf;
+       cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
+       if (ChooseFont(&cf))
+       {
+         HFONT hfontNew = CreateFontIndirect(&m_lf);
+         SetWindowFont(m_hwnd, hfontNew, true);
+         DeleteObject(m_hfont);
+         m_hfont = hfontNew;
+         Registry::write(MAYU_REGISTRY_ROOT, _T("logFont"), m_lf);
+       }
+       return TRUE;
+      }
+      
+      case IDC_CHECK_detail:
+      {
+       bool isChecked =
+         (IsDlgButtonChecked(m_hwnd, IDC_CHECK_detail) == BST_CHECKED);
+       m_log->setDebugLevel(isChecked ? 1 : 0);
+       return TRUE;
+      }
+    }
+    return FALSE;
+  }
+};
+
+
+//
+BOOL CALLBACK dlgLog_dlgProc(HWND i_hwnd, UINT i_message,
+                            WPARAM i_wParam, LPARAM i_lParam)
+{
+  DlgLog *wc;
+  getUserData(i_hwnd, &wc);
+  if (!wc)
+    switch (i_message)
+    {
+      case WM_INITDIALOG:
+       wc = setUserData(i_hwnd, new DlgLog(i_hwnd));
+       return wc->wmInitDialog(reinterpret_cast<HWND>(i_wParam), i_lParam);
+    }
+  else
+    switch (i_message)
+    {
+      case WM_COMMAND:
+       return wc->wmCommand(HIWORD(i_wParam), LOWORD(i_wParam),
+                            reinterpret_cast<HWND>(i_lParam));
+      case WM_CLOSE:
+       return wc->wmClose();
+      case WM_DESTROY:
+       return wc->wmDestroy();
+      case WM_NCDESTROY:
+       delete wc;
+       return TRUE;
+      default:
+       return wc->defaultWMHandler(i_message, i_wParam, i_lParam);
+    }
+  return FALSE;
+}
diff --git a/dlglog.h b/dlglog.h
new file mode 100644 (file)
index 0000000..b449957
--- /dev/null
+++ b/dlglog.h
@@ -0,0 +1,35 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlglog.h
+
+
+#ifndef _DLGLOG_H
+#  define _DLGLOG_H
+
+#  include <windows.h>
+#  include "msgstream.h"
+
+
+//
+BOOL CALLBACK dlgLog_dlgProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
+
+enum
+{
+  ///
+  WM_APP_dlglogNotify = WM_APP + 115,
+};
+
+enum DlgLogNotify
+{
+  DlgLogNotify_logCleared,                     ///
+};
+
+/// parameters for "Investigate" dialog box
+class DlgLogData
+{
+public:
+  tomsgstream *m_log;                          /// log stream
+  HWND m_hwndTaskTray;                         /// tasktray window
+};
+
+#endif // !_DLGLOG_H
diff --git a/dlgsetting.cpp b/dlgsetting.cpp
new file mode 100644 (file)
index 0000000..0b59ec6
--- /dev/null
@@ -0,0 +1,374 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlgsetting.cpp
+
+
+#include "misc.h"
+
+#include "mayu.h"
+#include "mayurc.h"
+#include "registry.h"
+#include "stringtool.h"
+#include "windowstool.h"
+#include "setting.h"
+#include "dlgeditsetting.h"
+#include "layoutmanager.h"
+
+#include <commctrl.h>
+#include <windowsx.h>
+
+
+///
+class DlgSetting : public LayoutManager
+{
+  HWND m_hwndMayuPaths;                                ///
+  
+  ///
+  Registry m_reg;
+
+  typedef DlgEditSettingData Data;             ///
+
+  ///
+  void insertItem(int i_index, const Data &i_data)
+  {
+    LVITEM item;
+    item.mask = LVIF_TEXT;
+    item.iItem = i_index;
+    
+    item.iSubItem = 0;
+    item.pszText = const_cast<_TCHAR *>(i_data.m_name.c_str());
+    CHECK_TRUE( ListView_InsertItem(m_hwndMayuPaths, &item) != -1 );
+
+    ListView_SetItemText(m_hwndMayuPaths, i_index, 1,
+                        const_cast<_TCHAR *>(i_data.m_filename.c_str()));
+    ListView_SetItemText(m_hwndMayuPaths, i_index, 2,
+                        const_cast<_TCHAR *>(i_data.m_symbols.c_str()));
+  }
+  
+  ///
+  void setItem(int i_index, const Data &i_data)
+  {
+    ListView_SetItemText(m_hwndMayuPaths, i_index, 0,
+                        const_cast<_TCHAR *>(i_data.m_name.c_str()));
+    ListView_SetItemText(m_hwndMayuPaths, i_index, 1,
+                        const_cast<_TCHAR *>(i_data.m_filename.c_str()));
+    ListView_SetItemText(m_hwndMayuPaths, i_index, 2,
+                        const_cast<_TCHAR *>(i_data.m_symbols.c_str()));
+  }
+
+  ///
+  void getItem(int i_index, Data *o_data)
+  {
+    _TCHAR buf[GANA_MAX_PATH];
+    LVITEM item;
+    item.mask = LVIF_TEXT;
+    item.iItem = i_index;
+    item.pszText = buf;
+    item.cchTextMax = NUMBER_OF(buf);
+    
+    item.iSubItem = 0;
+    CHECK_TRUE( ListView_GetItem(m_hwndMayuPaths, &item) );
+    o_data->m_name = item.pszText;
+    
+    item.iSubItem = 1;
+    CHECK_TRUE( ListView_GetItem(m_hwndMayuPaths, &item) );
+    o_data->m_filename = item.pszText;
+
+    item.iSubItem = 2;
+    CHECK_TRUE( ListView_GetItem(m_hwndMayuPaths, &item) );
+    o_data->m_symbols = item.pszText;
+  }
+
+  ///
+  void setSelectedItem(int i_index)
+  {
+    ListView_SetItemState(m_hwndMayuPaths, i_index,
+                         LVIS_SELECTED, LVIS_SELECTED);
+  }
+
+  ///
+  int getSelectedItem()
+  {
+    if (ListView_GetSelectedCount(m_hwndMayuPaths) == 0)
+      return -1;
+    for (int i = 0; ; ++ i)
+    {
+      if (ListView_GetItemState(m_hwndMayuPaths, i, LVIS_SELECTED))
+       return i;
+    }
+  }
+
+public:
+  ///
+  DlgSetting(HWND i_hwnd)
+    : LayoutManager(i_hwnd),
+      m_hwndMayuPaths(NULL),
+      m_reg(MAYU_REGISTRY_ROOT)
+  {
+  }
+  
+  /// WM_INITDIALOG
+  BOOL wmInitDialog(HWND /* i_focus */, LPARAM /* i_lParam */)
+  {
+    setSmallIcon(m_hwnd, IDI_ICON_mayu);
+    setBigIcon(m_hwnd, IDI_ICON_mayu);
+    
+    CHECK_TRUE( m_hwndMayuPaths = GetDlgItem(m_hwnd, IDC_LIST_mayuPaths) );
+
+    // create list view colmn
+    RECT rc;
+    GetClientRect(m_hwndMayuPaths, &rc);
+    
+    LVCOLUMN lvc; 
+    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; 
+    lvc.fmt = LVCFMT_LEFT; 
+    lvc.cx = (rc.right - rc.left) / 3;
+
+    tstringi str = loadString(IDS_mayuPathName);
+    lvc.pszText = const_cast<_TCHAR *>(str.c_str());
+    CHECK( 0 ==, ListView_InsertColumn(m_hwndMayuPaths, 0, &lvc) );
+    str = loadString(IDS_mayuPath);
+    lvc.pszText = const_cast<_TCHAR *>(str.c_str());
+    CHECK( 1 ==, ListView_InsertColumn(m_hwndMayuPaths, 1, &lvc) );
+    str = loadString(IDS_mayuSymbols);
+    lvc.pszText = const_cast<_TCHAR *>(str.c_str());
+    CHECK( 2 ==, ListView_InsertColumn(m_hwndMayuPaths, 2, &lvc) );
+
+    Data data;
+    insertItem(0, data);                               // TODO: why ?
+    
+    // set list view
+    tregex split(_T("^([^;]*);([^;]*);(.*)$"));
+    tstringi dot_mayu;
+    int i;
+    for (i = 0; i < MAX_MAYU_REGISTRY_ENTRIES; ++ i)
+    {
+      _TCHAR buf[100];
+      _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), i);
+      if (!m_reg.read(buf, &dot_mayu))
+       break;
+
+      tsmatch what;
+      if (boost::regex_match(dot_mayu, what, split))
+      {
+       data.m_name = what.str(1);
+       data.m_filename = what.str(2);
+       data.m_symbols = what.str(3);
+       insertItem(i, data);
+      }
+    }
+
+    CHECK_TRUE( ListView_DeleteItem(m_hwndMayuPaths, i) );     // TODO: why ?
+
+    // arrange list view size
+    ListView_SetColumnWidth(m_hwndMayuPaths, 0, LVSCW_AUTOSIZE);
+    ListView_SetColumnWidth(m_hwndMayuPaths, 1, LVSCW_AUTOSIZE);
+    ListView_SetColumnWidth(m_hwndMayuPaths, 2, LVSCW_AUTOSIZE);
+
+    ListView_SetExtendedListViewStyle(m_hwndMayuPaths, LVS_EX_FULLROWSELECT);
+
+    // set selection
+    int index;
+    m_reg.read(_T(".mayuIndex"), &index, 0);
+    setSelectedItem(index);
+
+    // set layout manager
+    typedef LayoutManager LM;
+    addItem(GetDlgItem(m_hwnd, IDC_STATIC_mayuPaths),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_LIST_mayuPaths),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_up),
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_CENTER,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_CENTER);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_down),
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_CENTER,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_CENTER);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_add),
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_edit),
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_delete),
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDCANCEL),
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDOK),
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE);
+    restrictSmallestSize();
+    return TRUE;
+  }
+
+  /// WM_CLOSE
+  BOOL wmClose()
+  {
+    EndDialog(m_hwnd, 0);
+    return TRUE;
+  }
+
+  /// WM_NOTIFY
+  BOOL wmNotify(int i_id, NMHDR *i_nmh)
+  {
+    switch (i_id)
+    {
+      case IDC_LIST_mayuPaths:
+       if (i_nmh->code == NM_DBLCLK)
+         FORWARD_WM_COMMAND(m_hwnd, IDC_BUTTON_edit, NULL, 0, SendMessage);
+       return TRUE;
+    }
+    return TRUE;
+  }
+  
+  /// WM_COMMAND
+  BOOL wmCommand(int /* i_notifyCode */, int i_id, HWND /* i_hwndControl */)
+  {
+    _TCHAR buf[GANA_MAX_PATH];
+    switch (i_id)
+    {
+      case IDC_BUTTON_up:
+      case IDC_BUTTON_down:
+      {
+       int count = ListView_GetItemCount(m_hwndMayuPaths);
+       if (count < 2)
+         return TRUE;
+       int index = getSelectedItem();
+       if (index < 0 ||
+           (i_id == IDC_BUTTON_up && index == 0) ||
+           (i_id == IDC_BUTTON_down && index == count - 1))
+         return TRUE;
+
+       int target = (i_id == IDC_BUTTON_up) ? index - 1 : index + 1;
+
+       Data dataIndex, dataTarget;
+       getItem(index, &dataIndex);
+       getItem(target, &dataTarget);
+       setItem(index, dataTarget);
+       setItem(target, dataIndex);
+       
+       setSelectedItem(target);
+       return TRUE;
+      }
+      
+      case IDC_BUTTON_add:
+      {
+       Data data;
+       int index = getSelectedItem();
+       if (0 <= index)
+         getItem(index, &data);
+       if (DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_editSetting),
+                          m_hwnd, dlgEditSetting_dlgProc, (LPARAM)&data))
+         if (!data.m_name.empty())
+         {
+           insertItem(0, data);
+           setSelectedItem(0);
+         }
+       return TRUE;
+      }
+      
+      case IDC_BUTTON_delete:
+      {
+       int index = getSelectedItem();
+       if (0 <= index)
+       {
+         CHECK_TRUE( ListView_DeleteItem(m_hwndMayuPaths, index) );
+         int count = ListView_GetItemCount(m_hwndMayuPaths);
+         if (count == 0)
+           ;
+         else if (count == index)
+           setSelectedItem(index - 1);
+         else
+           setSelectedItem(index);
+       }
+       return TRUE;
+      }
+      
+      case IDC_BUTTON_edit:
+      {
+       Data data;
+       int index = getSelectedItem();
+       if (index < 0)
+         return TRUE;
+       getItem(index, &data);
+       if (DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_editSetting),
+                          m_hwnd, dlgEditSetting_dlgProc, (LPARAM)&data))
+       {
+         setItem(index, data);
+         setSelectedItem(index);
+       }
+       return TRUE;
+      }
+      
+      case IDOK:
+      {
+       int count = ListView_GetItemCount(m_hwndMayuPaths);
+       int index;
+       for (index = 0; index < count; ++ index)
+       {
+         _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
+         Data data;
+         getItem(index, &data);
+         m_reg.write(buf, data.m_name + _T(";") +
+                     data.m_filename + _T(";") + data.m_symbols);
+       }
+       for (; ; ++ index)
+       {
+         _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
+         if (!m_reg.remove(buf))
+           break;
+       }
+       index = getSelectedItem();
+       if (index < 0)
+         index = 0;
+       m_reg.write(_T(".mayuIndex"), index);
+       EndDialog(m_hwnd, 1);
+       return TRUE;
+      }
+      
+      case IDCANCEL:
+      {
+       CHECK_TRUE( EndDialog(m_hwnd, 0) );
+       return TRUE;
+      }
+    }
+    return FALSE;
+  }
+};
+
+
+//
+BOOL CALLBACK dlgSetting_dlgProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
+{
+  DlgSetting *wc;
+  getUserData(i_hwnd, &wc);
+  if (!wc)
+    switch (i_message)
+    {
+      case WM_INITDIALOG:
+       wc = setUserData(i_hwnd, new DlgSetting(i_hwnd));
+       return wc->wmInitDialog(reinterpret_cast<HWND>(i_wParam), i_lParam);
+    }
+  else
+    switch (i_message)
+    {
+      case WM_COMMAND:
+       return wc->wmCommand(HIWORD(i_wParam), LOWORD(i_wParam),
+                            reinterpret_cast<HWND>(i_lParam));
+      case WM_CLOSE:
+       return wc->wmClose();
+      case WM_NCDESTROY:
+       delete wc;
+       return TRUE;
+      case WM_NOTIFY:
+       return wc->wmNotify(static_cast<int>(i_wParam),
+                           reinterpret_cast<NMHDR *>(i_lParam));
+      default:
+       return wc->defaultWMHandler(i_message, i_wParam, i_lParam);
+    }
+  return FALSE;
+}
diff --git a/dlgsetting.h b/dlgsetting.h
new file mode 100644 (file)
index 0000000..0f3d0d4
--- /dev/null
@@ -0,0 +1,16 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlgsetting.h
+
+
+#ifndef _DLGSETTING_H
+#  define _DLGSETTING_H
+
+#  include <windows.h>
+
+
+///
+BOOL CALLBACK dlgSetting_dlgProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
+
+
+#endif // !_DLGSETTING_H
diff --git a/dlgversion.cpp b/dlgversion.cpp
new file mode 100644 (file)
index 0000000..41cf77a
--- /dev/null
@@ -0,0 +1,139 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlgversion.cpp
+
+
+#include "misc.h"
+
+#include "mayu.h"
+#include "mayurc.h"
+#include "windowstool.h"
+#include "compiler_specific_func.h"
+#include "layoutmanager.h"
+
+#include <cstdio>
+#include <windowsx.h>
+
+
+///
+class DlgVersion : public LayoutManager
+{
+  HWND m_hwnd;         ///
+  
+public:
+  ///
+  DlgVersion(HWND i_hwnd)
+    : LayoutManager(i_hwnd),
+      m_hwnd(i_hwnd)
+  {
+  }
+  
+  /// WM_INITDIALOG
+  BOOL wmInitDialog(HWND /* i_focus */, LPARAM i_lParam)
+  {
+    TCHAR *mayudVersion = (TCHAR*)i_lParam;
+    setSmallIcon(m_hwnd, IDI_ICON_mayu);
+    setBigIcon(m_hwnd, IDI_ICON_mayu);
+    
+    _TCHAR modulebuf[1024];
+    CHECK_TRUE( GetModuleFileName(g_hInst, modulebuf,
+                                 NUMBER_OF(modulebuf)) );
+    
+    _TCHAR buf[1024];
+    _sntprintf(buf, NUMBER_OF(buf), loadString(IDS_version).c_str(),
+              _T(VERSION)
+#ifndef NDEBUG
+              _T(" (DEBUG)")
+#endif // !NDEBUG
+#ifdef _UNICODE
+              _T(" (UNICODE)")
+#endif // !_UNICODE
+              ,
+              mayudVersion,
+              loadString(IDS_homepage).c_str(),
+              (_T(LOGNAME) _T("@") + toLower(_T(COMPUTERNAME))).c_str(),
+              _T(__DATE__) _T(" ") _T(__TIME__),
+              getCompilerVersionString().c_str(),
+              modulebuf);
+    
+    
+    Edit_SetText(GetDlgItem(m_hwnd, IDC_EDIT_builtBy), buf);
+    
+    // set layout manager
+    typedef LayoutManager LM;
+
+    addItem(GetDlgItem(m_hwnd, IDC_STATIC_mayuIcon),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_EDIT_builtBy),
+           LM::ORIGIN_LEFT_EDGE, LM::ORIGIN_TOP_EDGE,
+           LM::ORIGIN_RIGHT_EDGE, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDC_BUTTON_download),
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE);
+    addItem(GetDlgItem(m_hwnd, IDOK),
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE,
+           LM::ORIGIN_CENTER, LM::ORIGIN_BOTTOM_EDGE);
+    restrictSmallestSize();
+    
+    return TRUE;
+  }
+  
+  /// WM_CLOSE
+  BOOL wmClose()
+  {
+    CHECK_TRUE( EndDialog(m_hwnd, 0) );
+    return TRUE;
+  }
+
+  /// WM_COMMAND
+  BOOL wmCommand(int /* i_notifyCode */, int i_id, HWND /* i_hwndControl */)
+  {
+    switch (i_id)
+    {
+      case IDOK:
+      {
+       CHECK_TRUE( EndDialog(m_hwnd, 0) );
+       return TRUE;
+      }
+      case IDC_BUTTON_download:
+      {
+       ShellExecute(NULL, NULL, loadString(IDS_homepage).c_str(),
+                    NULL, NULL, SW_SHOWNORMAL);
+       CHECK_TRUE( EndDialog(m_hwnd, 0) );
+       return TRUE;
+      }
+    }
+    return FALSE;
+  }
+};
+
+
+//
+BOOL CALLBACK dlgVersion_dlgProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
+{
+  DlgVersion *wc;
+  getUserData(i_hwnd, &wc);
+  if (!wc)
+    switch (i_message)
+    {
+      case WM_INITDIALOG:
+       wc = setUserData(i_hwnd, new DlgVersion(i_hwnd));
+       return wc->wmInitDialog(reinterpret_cast<HWND>(i_wParam), i_lParam);
+    }
+  else
+    switch (i_message)
+    {
+      case WM_COMMAND:
+       return wc->wmCommand(HIWORD(i_wParam), LOWORD(i_wParam),
+                            reinterpret_cast<HWND>(i_lParam));
+      case WM_CLOSE:
+       return wc->wmClose();
+      case WM_NCDESTROY:
+       delete wc;
+       return TRUE;
+      default:
+       return wc->defaultWMHandler(i_message, i_wParam, i_lParam);
+    }
+  return FALSE;
+}
diff --git a/dlgversion.h b/dlgversion.h
new file mode 100644 (file)
index 0000000..98d76f2
--- /dev/null
@@ -0,0 +1,16 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dlgversion.h
+
+
+#ifndef _DLGVERSION_H
+#  define _DLGVERSION_H
+
+#  include <windows.h>
+
+
+///
+BOOL CALLBACK dlgVersion_dlgProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
+
+
+#endif // !_DLGVERSION_H
diff --git a/doc++-header.html b/doc++-header.html
new file mode 100644 (file)
index 0000000..e9266b2
--- /dev/null
@@ -0,0 +1,85 @@
+<html lang="ja">
+<head>
+<meta http-equiv="Content-Type" content="text/html;charset=ascii">
+<style type="text/css">
+<!--
+body
+{
+       font-family:Arial;
+       font-size:10pt;
+       color:#000055;
+       background-color:#f7f7ff;
+       margin-bottom:100ex;
+}
+a:link         { color:#0000ff; }
+a:visited      { color:#000055; }
+a:active       { color:#ff0000; }
+a:hover                { color:#ff0000; }
+h2
+{
+       font-size:12pt;
+       color:#ffffff;
+       background-color:#000055;
+       padding:5pt;
+}
+h2 a:link      { color:#ffffff; }
+h2 a:visited   { color:#eeeeff; }
+h2 a:active    { color:#ffff00; }
+h2 a:hover     { color:#ffff00; }
+h3
+{
+       font-size:10pt;
+       color:#000055;
+       background-color:#ddddff;
+       padding:2pt;
+}
+blockquote
+{
+       border-style: solid solid solid solid;
+       border-width:1px;
+       padding:5pt;
+}
+blockquote dl
+{
+       margin-left:0pt;
+       margin-right:0pt;
+       margin-top:5pt;
+       margin-bottom:5pt;
+}
+blockquote dt
+{
+       font-weight:bold;
+}
+code, tt
+{
+       color:550055;
+       font-family:Courier New;
+}
+pre
+{
+       border-style: solid solid solid solid;
+       border-width:1px;
+       background-color:#ffffff;
+       color:550055;
+       font-family:Courier New;
+}
+i
+{
+       color:#550055;
+       font-style:normal;
+}
+p
+{
+       margin:0pt;
+       padding:0pt;
+}
+dl
+{
+       margin-left:30pt;
+}
+-->
+</style>
+
+</head>
+
+<body>
diff --git a/doc++.conf b/doc++.conf
new file mode 100644 (file)
index 0000000..afb5b01
--- /dev/null
@@ -0,0 +1,145 @@
+# Document all
+documentAll            false
+
+# Use C/C++ comments as doc++-comments
+useNormalComments      false
+
+# Parse HTML syntax, not only TeX
+HTMLSyntax             true
+
+# Read a list of input files from this file
+# fileList
+
+# Parse Java instead of C/C++
+parseJava              false
+
+# Ignore `#define' macros
+ignoreDefines          false
+
+# Document private members
+documentPrivateMembers true
+
+# Optimize for speed instead of size
+optimizeForSpeed       false
+
+# Activate Quantel extensions, folding & appended comments
+quantelExtensions      true
+
+# Generate internal documentation
+internalDoc            false
+
+# Generate TeX output instead of HTML
+doTeX                  false
+
+# Generate upwards arrows in class graphs
+upwardsArrows          true
+
+# Turn verbose mode on
+verboseOperation       false
+
+# Scan `#include'ed header files
+# scanIncludes         false
+
+# Generate DocBook SGML output instead of HTML
+doDocBook              false
+
+# List of input files
+# inputFiles
+
+#
+# Additional options for HTML output
+#
+
+# Use tables instead of descriptions lists
+useTables              false
+
+# Use tables with borders instead of descriptions lists
+useTablesWithBorders   false
+
+# Use this file as footer on HTML pages
+# footer
+
+# Set the output directory
+outputDir              srcdesc
+
+# Show filenames in manual pages
+showFilenames          true
+
+# Show filenames with path in manual pages
+showFilenamesWithPath  true
+
+# Do not generate GIFS for equations, etc.
+noGifs                 false
+
+# Force generation of GIFs
+forceGifs              false
+
+# Don't show inherited members
+noInheritedMembers     false
+
+# Do not generate Java graphs
+noJavaGraphs           false
+
+# Keep trivial class graphs
+trivialGraphs          false
+
+# Don't show members without documentation in DOC section
+noMembers              false
+
+# Show members in TOC
+showMembersInTOC       false
+
+# Discard general stuff
+discardGeneral         false
+
+# Sort entries alphabetically
+sortEntries            true
+
+# Use this file as header on HTML pages
+header                 doc++-header.html
+
+# Print group documentation before group
+groupBeforeGroup       false
+
+# Print class documentation before group
+classBeforeGroup       false
+
+# Use this suffix for HTML pages
+htmlSuffix             .html
+
+#
+# Additional options for TeX output
+#
+
+# Only generate class graph
+onlyClassGraph         false
+
+# Read TeX environment from this file
+# environment
+
+# Generate index
+generateIndex          false
+
+# Setup TeX style option
+# style
+
+# Use the following TeX packages
+# usePackage
+
+# Use the content of this file as TeX title page
+# title
+
+# Set minimum depth (number of levels) in TOC
+minimumDepth           1
+
+# Do not generate TeX environment
+noEnvironment          false
+
+# Do not generate the class graph
+noClassGraph           false
+
+# Set output file name
+# outputFilename
+
+# Generate source code listing
+generateSourceListing
diff --git a/doc/CONTENTS-ja.html b/doc/CONTENTS-ja.html
new file mode 100644 (file)
index 0000000..c7e7096
--- /dev/null
@@ -0,0 +1,236 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+<html lang="ja">
+<head>
+<meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp">
+<link rel="stylesheet" type="text/css" href="README.css">
+<link rel="prev" href="CUSTOMIZE-ja.html">
+<link rel="next" href="MANUAL-ja.html">
+<title>\e$BAk;H$$$NM+]5\e(B - CONTENTS</title>
+</head>
+<body class="contents">
+<div class="section">
+  <ol>
+    <li><a href="MANUAL-ja.html#ABSTRACT" target="MANUAL">abstract</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#INSTALL" target="MANUAL">install</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#UNINSTALL" target="MANUAL">uninstall</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#MENU" target="MANUAL">menu</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#TUTORIAL" target="MANUAL">tutorial</a>
+       <div class="subsection">
+         <ol>
+           <li><a href="MANUAL-ja.html#dotmayu" target="MANUAL">\e$B<+J,MQ$N@_Dj%U%!%$%k$r:n$k\e(B</a>
+           <li><a href="MANUAL-ja.html#minimum" target="MANUAL">\e$B:n$C$?@_Dj%U%!%$%k$K:GDc8B$N@_Dj$r=q$/\e(B</a>
+           <li><a href="MANUAL-ja.html#key" target="MANUAL">\e$BIaDL$N%-!<$rF~$lBX$($F$_$k\e(B</a>
+           <li><a href="MANUAL-ja.html#window" target="MANUAL">\e$BFCDj$N%&%$%s%I%&$N$_$G%-!<3d$jEv$F$rJQ99$7$F$_$k\e(B</a>
+           <li><a href="MANUAL-ja.html#modifier" target="MANUAL">\e$B%-!<$,%b%G%#%U%!%$%d%-!<$H6&$K2!$5$l$?>l9g$KCV$-49$($F$_$k\e(B</a>
+           <li><a href="MANUAL-ja.html#modifier2" target="MANUAL">\e$B%b%G%#%U%!%$%d%-!<$N>uBV$HL54X78$KCV$-49$($F$_$k\e(B</a>
+           <li><a href="MANUAL-ja.html#mod" target="MANUAL">\e$B%b%G%#%U%!%$%d$K$J$C$F$$$k%-!<$rCV$-49$($k\e(B</a>
+           <li><a href="MANUAL-ja.html#more" target="MANUAL">\e$B$h$j9bEY$J@_Dj\e(B</a>
+         </ol>
+       </div>
+    <li><a href="MANUAL-ja.html#FAQ" target="MANUAL">FAQ</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="CUSTOMIZE-ja.html#CUSTOMIZE" target="MANUAL">customize</a>
+       <div class="subsection">
+         <ol>
+           <li><a href="CUSTOMIZE-ja.html#key" target="MANUAL">\e$B%-!<3d$jEv$F$NJQ99\e(B</a>
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="CUSTOMIZE-ja.html#modifier" target="MANUAL">\e$B%b%G%#%U%!%$%d$N;XDj\e(B (<code>C-</code>, <code>M-</code>, <code>A-</code>, <code>S-</code>, <code>NL-</code>, <code>CL-</code>, <code>SL-</code>, <code>KL-</code>, <code>IL-</code>,<br><code>IC-</code>, <code>MAX-</code>, <code>MIN-</code>, <code>MMAX-</code>, <code>MMIN-</code>, <code>T-</code>, <code>TS-</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#ignoreModifier" target="MANUAL">\e$B%b%G%#%U%!%$%d%-!<$NL5;k\e(B (<code>*</code>, <code>~</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#inputModifier" target="MANUAL">\e$BF~NO$5$l$?%-!<$HF1$8%b%G%#%U%!%$%d$N;XDj\e(B (<code>*</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#keyUpDown" target="MANUAL">\e$B%-!<$r2!$9\e(B / \e$BN%$9\e(B (<code>D-</code>, <code>U-</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#keyRepeat" target="MANUAL">\e$B%-!<%j%T!<%H$7$?\e(B (<code>R-</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#defaultModifier" target="MANUAL">\e$B%G%U%)%k%H%b%G%#%U%!%$%d$NJQ99\e(B</a>
+                 </ul>
+               </div>
+               
+           <li><a href="CUSTOMIZE-ja.html#keymap" target="MANUAL">\e$B%-!<%^%C%WDj5A\e(B</a>
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="CUSTOMIZE-ja.html#windowClass" target="MANUAL">\e$B%&%#%s%I%&%/%i%9\e(B/\e$B%?%$%H%kL>\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#regexp" target="MANUAL">\e$B@55,I=8=$K$D$$$F\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#parentKeymap" target="MANUAL">\e$B?F%-!<%^%C%W\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#defaultKey" target="MANUAL">\e$B%G%U%)%k%H%-!<\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#keymap2" target="MANUAL">\e$BFsCJ3,%-!<%^%C%W\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#initialKeymap" target="MANUAL">\e$B=i4|%-!<%^%C%W\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#conflictKeymap" target="MANUAL">\e$BL7=b$7$?%-!<%^%C%W$N;XDj\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#matchManyClasses" target="MANUAL"><code>window</code> \e$B$KJ#?t3:Ev$9$k>l9g\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#perKeymapDefinition" target="MANUAL">\e$B%-!<%^%C%W$,1F6A$9$kDj5A\e(B</a>
+                 </ul>
+               </div>
+           <li><a href="CUSTOMIZE-ja.html#mod" target="MANUAL">\e$B%b%G%#%U%!%$%d%-!<3d$jEv$F$NJQ99\e(B</a>
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="CUSTOMIZE-ja.html#trueModifier" target="MANUAL">\e$B??$N%b%G%#%U%!%$%d\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#oneShotModifier" target="MANUAL">One Shot \e$B%b%G%#%U%!%$%d\e(B (SandS)</a>
+                   <li><a href="CUSTOMIZE-ja.html#oneShotRepeatableModifier" target="MANUAL">One Shot (\e$B%-!<%j%T!<%HM-\e(B)</a>
+                   <li><a href="CUSTOMIZE-ja.html#lock" target="MANUAL">\e$B%m%C%/%-!<\e(B (<code>L0-</code>\e$B!A\e(B<code>L9-</code>)</a>
+                 </ul>
+               </div>
+           <li><a href="CUSTOMIZE-ja.html#keyseq" target="MANUAL">\e$B%-!<%7!<%1%s%9Dj5A\e(B</a>
+           <li><a href="CUSTOMIZE-ja.html#event" target="MANUAL">\e$B%$%Y%s%HDj5A\e(B</a>
+           <li><a href="CUSTOMIZE-ja.html#keyboard" target="MANUAL">\e$B%-!<%\!<%IDj5A\e(B</a>
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="CUSTOMIZE-ja.html#def_key" target="MANUAL">\e$B%-!<Dj5A\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#def_mod" target="MANUAL">\e$B%b%G%#%U%!%$%dDj5A\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#def_sync" target="MANUAL">\e$BF14|Dj5A\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#def_alias" target="MANUAL">\e$BJLL>Dj5A\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#def_subst" target="MANUAL">\e$BBeMQDj5A\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#def_option_KL" target="MANUAL">\e$B%*%W%7%g%s\e(B (<code>KL-</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#def_option_delay_of_oneShotRepeatableModifier" target="MANUAL">\e$B%*%W%7%g%s\e(B (<code>delay-of !!!</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#def_option_ts4mayu" target="MANUAL">\e$B%*%W%7%g%s\e(B (<code>sts4mayu, cts4mayu</code>)</a>
+                 </ul>
+               </div>
+           <li><a href="CUSTOMIZE-ja.html#include" target="MANUAL">\e$B%U%!%$%kFI$_9~$_\e(B</a>
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="CUSTOMIZE-ja.html#HOME" target="MANUAL">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>
+                 </ul>
+               </div>
+           <li><a href="CUSTOMIZE-ja.html#cond" target="MANUAL">\e$B>r7oJ,4t\e(B</a>
+           <li><a href="CUSTOMIZE-ja.html#function" target="MANUAL"><code><em>FUNCTION</em></code> \e$B%j%U%!%l%s%9\e(B</a>
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="CUSTOMIZE-ja.html#function_ClipboardCopy" target="MANUAL"><code>&amp;ClipboardCopy</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_ClipboardUpcaseDowncaseWord" target="MANUAL"><code>&amp;ClipboardDowncaseWord</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_ClipboardUpcaseDowncaseWord" target="MANUAL"><code>&amp;ClipboardUpcaseWord</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Default" target="MANUAL"><code>&amp;Default</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_DescribeBindings" target="MANUAL"><code>&amp;DescribeBindings</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_DirectSSTP" target="MANUAL"><code>&amp;DirectSSTP</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_EditNextModifier" target="MANUAL"><code>&amp;EditNextModifier</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_EmacsEditKillLine" target="MANUAL"><code>&amp;EmacsEditKillLineFunc</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_EmacsEditKillLine" target="MANUAL"><code>&amp;EmacsEditKillLinePred</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_HelpMessage" target="MANUAL"><code>&amp;HelpMessage</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_HelpVariable" target="MANUAL"><code>&amp;HelpVariable</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Ignore" target="MANUAL"><code>&amp;Ignore</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_InvestigateCommand" target="MANUAL"><code>&amp;InvestigateCommand</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Keymap" target="MANUAL"><code>&amp;Keymap</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_KeymapParent" target="MANUAL"><code>&amp;KeymapParent</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_KeymapPrevPrefix" target="MANUAL"><code>&amp;KeymapPrevPrefix</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_KeymapWindow" target="MANUAL"><code>&amp;KeymapWindow</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_LoadSetting" target="MANUAL"><code>&amp;LoadSetting</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_MayuDialog" target="MANUAL"><code>&amp;MayuDialog</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_MouseHook" target="MANUAL"><code>&amp;MouseHook</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_MouseMove" target="MANUAL"><code>&amp;MouseMove</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_MouseWheel" target="MANUAL"><code>&amp;MouseWheel</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_OtherWindowClass" target="MANUAL"><code>&amp;OtherWindowClass</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_PlugIn" target="MANUAL"><code>&amp;PlugIn</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_PostMessage" target="MANUAL"><code>&amp;PostMessage</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Prefix" target="MANUAL"><code>&amp;Prefix</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Recenter" target="MANUAL"><code>&amp;Recenter</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Repeat" target="MANUAL"><code>&amp;Repeat</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_SetImeStatus" target="MANUAL"><code>&amp;SetImeStatus</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_SetImeString" target="MANUAL"><code>&amp;SetImeString</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_ShellExecute" target="MANUAL"><code>&amp;ShellExecute</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Sync" target="MANUAL"><code>&amp;Sync</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Toggle" target="MANUAL"><code>&amp;Toggle</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Undefined" target="MANUAL"><code>&amp;Undefined</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_VK" target="MANUAL"><code>&amp;VK</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Variable" target="MANUAL"><code>&amp;Variable</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_Wait" target="MANUAL"><code>&amp;Wait</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowCling" target="MANUAL"><code>&amp;WindowClingToBottom</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowCling" target="MANUAL"><code>&amp;WindowClingToLeft</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowCling" target="MANUAL"><code>&amp;WindowClingToRight</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowCling" target="MANUAL"><code>&amp;WindowClingToTop</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowClose" target="MANUAL"><code>&amp;WindowClose</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax" target="MANUAL"><code>&amp;WindowHMaximize</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowIdentify" target="MANUAL"><code>&amp;WindowIdentify</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowRiseLower" target="MANUAL"><code>&amp;WindowLower</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax" target="MANUAL"><code>&amp;WindowMaximize</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax" target="MANUAL"><code>&amp;WindowMinimize</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMonitor" target="MANUAL"><code>&amp;WindowMonitor</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMonitorTo" target="MANUAL"><code>&amp;WindowMonitorTo</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMove" target="MANUAL"><code>&amp;WindowMove</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMoveTo" target="MANUAL"><code>&amp;WindowMoveTo</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMoveVisibly" target="MANUAL"><code>&amp;WindowMoveVisibly</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowRedraw" target="MANUAL"><code>&amp;WindowRedraw</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowResizeTo" target="MANUAL"><code>&amp;WindowResizeTo</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowRiseLower" target="MANUAL"><code>&amp;WindowRaise</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowSetAlpha" target="MANUAL"><code>&amp;WindowSetAlpha</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowToggleTopMost" target="MANUAL"><code>&amp;WindowToggleTopMost</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax" target="MANUAL"><code>&amp;WindowVMaximize</code></a>
+                   <li><a href="CUSTOMIZE-ja.html#arg_subst" target="MANUAL">\e$B0z?tCV49\e(B (<code>$Clipboard</code>, <code>$WindowClassName</code>, <code>$WindowTitleName</code>)</a>
+                   <li><a href="CUSTOMIZE-ja.html#string" target="MANUAL">\e$BJ8;zNs\e(B</a>
+                 </ul>
+               </div>
+           <li><a href="CUSTOMIZE-ja.html#compile" target="MANUAL">\e$B%S%k%I\e(B</a>
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="CUSTOMIZE-ja.html#compile_tool" target="MANUAL">\e$BI,MW$J$b$N\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#compile_source" target="MANUAL">\e$B%=!<%9$NE83+\e(B</a>
+                   <li><a href="CUSTOMIZE-ja.html#compile_build" target="MANUAL">\e$B%S%k%I\e(B</a>
+                 </ul>
+               </div>
+         </ol>
+       </div>
+    <li><a href="MANUAL-ja.html#SECURITY" target="MANUAL">security</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#BUGS" target="MANUAL">bugs</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#RELATEDWORK" target="MANUAL">related work</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#REFERENCES" target="MANUAL">references</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#COPYRIGHT" target="MANUAL">copyright</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#SUPPORT" target="MANUAL">support</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#ACKNOWLEDGEMENT" target="MANUAL">acknowledgements</a>
+       <div class="subsection"><ol></ol></div>
+    <li><a href="MANUAL-ja.html#HISTORY" target="MANUAL">history</a>
+       <div class="subsection"><ol></ol></div>
+  </ol>
+</div>
+<div class="appendix">
+  <ol>
+    <li>appendix
+       <div class="subsection">
+         <ol>
+           <li>sample settings
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="../dot.mayu" target="MANUAL"><code>dot.mayu</code></a>
+                   <li><a href="../default.mayu" target="MANUAL"><code>default.mayu</code></a>
+                   <li><a href="../emacsedit.mayu" target="MANUAL"><code>emacsedit.mayu</code></a>
+                   <li><a href="../104.mayu" target="MANUAL"><code>104.mayu</code></a>
+                   <li><a href="../109.mayu" target="MANUAL"><code>109.mayu</code></a>
+                   <li><a href="../109on104.mayu" target="MANUAL"><code>109on104.mayu</code></a>
+                   <li><a href="../104on109.mayu" target="MANUAL"><code>104on109.mayu</code></a>
+                 </ul>
+               </div>
+           <li>syntax
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="syntax.txt" target="MANUAL"><code>syntax.txt</code></a>
+                 </ul>
+               </div>
+           <li>emacs mode
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="../mayu-mode.el" target="MANUAL"><code>mayu-mode.el</code></a>
+                 </ul>
+               </div>
+           <li>user contributions
+               <div class="subsubsection">
+                 <ul>
+                   <li><a href="../contrib/109onAX.mayu" target="MANUAL"><code>contrib/109onAX.mayu</code></a>
+                   <li><a href="../contrib/98x1.mayu" target="MANUAL"><code>contrib/98x1.mayu</code></a>
+                   <li><a href="../contrib/ax.mayu" target="MANUAL"><code>contrib/ax.mayu</code></a>
+                   <li><a href="../contrib/dvorak.mayu" target="MANUAL"><code>contrib/dvorak.mayu</code></a>
+                   <li><a href="../contrib/DVORAKon109.mayu" target="MANUAL"><code>contrib/DVORAKon109.mayu</code></a>
+                   <li><a href="../contrib/keitai.mayu" target="MANUAL"><code>contrib/keitai.mayu</code></a>
+                   <li><a href="../contrib/mayu-settings.txt" target="MANUAL"><code>contrib/mayu-settings.txt</code></a>
+                 </ul>
+               </div>
+         </ol>
+       </div>
+  </ol>
+</div>
+
+</body>
+</html>
diff --git a/doc/CUSTOMIZE-ja.html b/doc/CUSTOMIZE-ja.html
new file mode 100644 (file)
index 0000000..f2c98e8
--- /dev/null
@@ -0,0 +1,1694 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+<html lang="ja">
+<head>
+<meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp">
+<link rel="stylesheet" type="text/css" href="README.css">
+<link rel="prev" href="MANUAL-ja.html">
+<link rel="next" href="CONTENTS-ja.html">
+<title>mayu - MANUAL - CUSTOMIZE</title>
+</head>
+
+<body class="manual">
+
+<div class="main">
+  <dl>
+    <dt class="h1"><a name="CUSTOMIZE" href="MANUAL-ja.html#CUSTOMIZE">7. customize</a>
+       
+    <dd class="d1">
+       <div>
+         <p>\e$BIUB0$N\e(B <code>.mayu</code> (<a href="../dot.mayu"><code>dot.mayu</code></a>) \e$B$rMxMQ$9$l$P!"%(%G%#%C%H%3%s%H%m!<%k$G\e(B Emacs \e$BIw$NA`:n$,$G$-$k$h$&$K$J$j$^$9$,!"\e(B<code>.mayu</code> \e$B$r%+%9%?%^%$%:$9$k$3$H$K$h$C$F!"\e(BWindows \e$B$r<+J,$N9%$-$J%-!<%P%$%s%G%#%s%0$GMxMQ$9$k$3$H$,$G$-$k$h$&$K$J$j$^$9!#\e(B</p>
+         
+         <p><code>.mayu</code> \e$B$O\e(B<a href="#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>\e$B$+$i8!:w$5$l$^$9!#\e(B</p>
+
+         <p><code>.mayu</code> \e$B$O>e$+$i2<$XFI$^$l$F$$$-!"=EJ#$9$k5-=R$,$"$l$P!"$h$j2<$K=q$+$l$F$$$k$b$N$,M-8z$K$J$j$^$9!#%3%a%s%H$O\e(B <code>#</code> \e$B$G$O$8$a$^$9!#%"%k%U%!%Y%C%H$NBgJ8;z$H>.J8;z$O6hJL$5$l$^$;$s!#>\$7$$J8K!$O\e(B <a href="syntax.txt"><code>syntax.txt</code></a> \e$B$r;2>H$7$F$/$@$5$$!#\e(B</p>
+
+         <p>\e$B$3$N>O$rFI$`A0$K!"\e(B<a href="../contrib/mayu-settings.txt"><code>contrib/mayu-settings.txt</code></a> \e$B$rFI$s$GIUB0$N@_Dj%U%!%$%k$K$D$$$FM}2r$r?<$a$F$*$/$3$H$r$*4+$a$7$^$9!#\e(B</p>
+         
+         <dl>
+           <dt class="h2"><a name="key">i. \e$B%-!<3d$jEv$F$NJQ99\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p>\e$B%-!<3d$jEv$F$rJQ99$9$k$K$O!"0J2<$N$h$&$K5-=R$r$7$^$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 &nbsp;key <em>KEY</em> = <em>KEY</em> \e$B$d\e(B <em>FUNCTION</em> \e$B!D\e(B
+                 </p>
+                 
+                 <p><code>=</code> \e$B$h$j:8$N\e(B <code><em>KEY</em></code> \e$B$r%-!<%\!<%I$G2!$9$H!"\e(BWindows \e$B$X$O\e(B <code>=</code> \e$B$h$j1&$N\e(B <code><em>KEY</em></code> \e$B$,=gHV$KF~NO$5$l$^$9!#$^$?!"1&$K\e(B <code><em>FUNCTION</em></code> \e$B$,=q$+$l$F$$$k>l9g$O%&%#%s%I%&$N:GBg2=$d0\F0$J$I$N5!G=$,<B9T$5$l$^$9!#\e(B</p>
+                 
+                 <p><code><em>KEY</em></code> \e$B$O\e(B<a href="#keyboard">\e$B%-!<%\!<%IDj5A\e(B</a>\e$B$GDj5A$5$l$k$b$N$G!"%G%U%)%k%H$G$O\e(B <a href="../109.mayu"><code>109.mayu</code></a> \e$BKt$O\e(B <a href="../104.mayu"><code>104.mayu</code></a> \e$B$GDj5A$5$l$F$$$k\e(B <code><em>KEY</em></code> \e$B$,;HMQ$G$-$^$9!#\e(B</p>
+                 
+                 <dl>
+                   <dt class="h3"><a name="modifier">\e$B%b%G%#%U%!%$%d$N;XDj\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p><code><em>KEY</em></code> \e$B$NA0$K0J2<$N$h$&$J5-9f$rIU$1$k$3$H$K$h$C$F!"%3%s%H%m!<%k%-!<$J$I$N>uBV$rI=8=$G$-$^$9!#$^$?!"$3$l$i$r%b%G%#%U%!%$%d$H8F$V$3$H$K$7$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li><code>C-</code> \e$B$O!"\e(B<kbd>Control</kbd> \e$B$,2!$5$l$F$$$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>M-</code> \e$B$+\e(B <code>A-</code> \e$B$O!"\e(B<kbd>Alt</kbd> \e$B$,2!$5$l$F$$$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>S-</code> \e$B$O!"\e(B<kbd>Shift</kbd> \e$B$,2!$5$l$F$$$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>NL-</code> \e$B$O!"\e(B<kbd>NumLock</kbd> \e$B$,%m%C%/>uBV$G$"$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>CL-</code> \e$B$O!"\e(B<kbd>CapsLock</kbd> \e$B$,%m%C%/>uBV$G$"$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>SL-</code> \e$B$O!"\e(B<kbd>ScrollLock</kbd> \e$B$,%m%C%/>uBV$G$"$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>KL-</code> \e$B$O!"\e(B<kbd>\e$B%+%J\e(B</kbd> \e$B$,%m%C%/>uBV$G$"$k$3$H$rI=$7$^$9!#\e(B<br>
+                               (<a href="CUSTOMIZE-ja.html#def_option_KL" target="MANUAL">\e$B%*%W%7%g%s\e(B (<code>KL-</code>)</a>\e$B$r$h$/FI$s$G$/$@$5$$\e(B)<br>
+                               109 \e$B%-!<%\!<%I$J$i!"\e(B<kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>\e$B$R$i$,$J\e(B</kbd>\e$B!#\e(B<br>
+                               104 \e$B%-!<%\!<%I$J$i!"\e(B<kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>CapsLock</kbd>\e$B!#\e(B
+                           <li><code>IL-</code> \e$B$O!"\e(BIME \e$B$,\e(B on \e$B$K$J$C$F$$$k$3$H$rI=$7$^$9\e(B
+                           <li><code>IC-</code> \e$B$O!"\e(BIME \e$B$GJQ49Cf$G$"$k$3$H$rI=$7$^$9\e(B
+                           <li><code>MAX-</code> \e$B$O!"%&%#%s%I%&$,:GBg2=$5$l$F$$$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>MIN-</code> \e$B$O!"%&%#%s%I%&$,:G>.2=$5$l$F$$$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>MMAX-</code> \e$B$O!"\e(BMDI \e$B;R%&%#%s%I%&$,:GBg2=$5$l$F$$$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>MMIN-</code> \e$B$O!"\e(BMDI \e$B;R%&%#%s%I%&$,:G>.2=$5$l$F$$$k$3$H$rI=$7$^$9!#\e(B
+                           <li><code>T-</code> \e$B$O!"%?%C%A%Q%C%I$K;X$,?($l$F$$$k$3$H$rI=$7$^$9!#M-8z$K$9$k$?$a$K$O\e(B<a href="#def_option_ts4mayu" target="MANUAL">\e$B%*%W%7%g%s\e(B</a>\e$B$r@_Dj$9$kI,MW$,$"$j$^$9!#\e(B
+                           <li><code>TS-</code> \e$B$O!"A4$F$N%-!<$,N%$5$l$k$^$G%*%U$K$J$i$J$$$3$H$r=|$1$P\e(B <code>T-</code> \e$B$HF1$8$G$9!#\e(B
+                         </ul>
+                         
+                         <p>\e$B0J2<$N$h$&$K5-=R$9$k$H!"\e(B<kbd>Control</kbd> + <kbd>A</kbd> \e$B$r2!$7$?;~$K!"\e(BWindows \e$B$X$O\e(B <kbd>HOME</kbd> \e$B%-!<$,F~NO$5$l$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key C-A = HOME
+                         </p>
+                       </div>
+                       
+                   <dt class="h3"><a name="ignoreModifier">\e$B%b%G%#%U%!%$%d%-!<$NL5;k\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B>e5-$NNc$G$O:8B&$K\e(B <code>C-A</code> \e$B$H5-=R$7$F$$$^$9$,!"$3$N5-=R$G$O!"%m%C%/%-!<$J$I$O2!$5$l$F$$$F$b2!$5$l$F$J$/$F$bNI$$$H5-=R$7$F$$$k$3$H$K$J$j$^$9!#$?$H$($P!"\e(B<kbd>CapsLock</kbd> \e$B$r2!$7$?$"$H$G\e(B <kbd>Control</kbd> + <kbd>A</kbd> \e$B$r2!$7$F$b!"2!$5$:$K\e(B <kbd>Control</kbd> + <kbd>A</kbd> \e$B$r2!$7$F$b!"\e(BWindows \e$B$X$O\e(B <kbd>Home</kbd> \e$B$,F~NO$5$l$^$9!#\e(B</p>
+                         
+                         <p>\e$BFCDj$N%b%G%#%U%!%$%d$N>uBV$rL5;k$7$?$$>l9g$O!"%b%G%#%U%!%$%d$K\e(B "<code>*</code>" \e$B$r$D$1$^$9!#5U$K%b%G%#%U%!%$%d$,I,$:2!$5$l$F$$$J$1$l$P$J$i$J$$>l9g$OIU$1$^$;$s!#$^$?%b%G%#%U%!%$%d$,I,$:N%$5$l$F$$$J$1$l$P$J$i$J$$>l9g$O\e(B "<code>~</code>" \e$B$rIU$1$^$9!#$?$H$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key *S-F9 = &amp;WindowMinimize
+                         </p>
+                         
+                         <p class="continue">\e$B$3$N$h$&$K5-=R$9$k$H!"\e(B<kbd>F9</kbd> \e$BKt$O\e(B <kbd>Shift</kbd> + <kbd>F9</kbd> \e$B$G%&%#%s%I%&$r:G>.2=$9$k$3$H$,$G$-$^$9$,!"Nc$($P!"\e(B<kbd>Control</kbd> + <kbd>F9</kbd> \e$B$G$O$G$-$^$;$s!#\e(B</p>
+                         
+                         <p>\e$B%G%U%)%k%H$G$O!"0EL[$K\e(B <code>~C-~M-~S-*NL-*CL-*SL-*KL-*IL-~IC-*MAX-*MIN-*MMAX-*MMIN-*T-*TS-</code> \e$B$,;XDj$5$l$F$$$k$3$H$K$J$C$F$$$^$9$,!"\e(B<a href="#defaultModifier">\e$BJQ99\e(B</a>\e$B$G$-$^$9!#\e(B</p>
+                         
+                         <p>\e$B$^$?!"\e(B<kbd>Shift</kbd> \e$B$OI,$:2!$5$l$F$$$F$[$7$$$,$[$+$N%b%G%#%U%!%$%d$O$I$&$G$b$$$$$H$$$&>l9g$O!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key S-*F9 = &amp;WindowMinimize
+                         </p>
+
+                         <p class="continue">\e$B$H$$$&$h$&$K\e(B "<code>*</code>" \e$B$r%-!<$ND>A0$K5-=R$7$^$9!#\e(B"<code>~</code>" \e$B$K$D$$$F$bF1MM$G$9!#\e(B</p>
+                       </div>
+
+                   <dt class="h3"><a name="inputModifier">\e$BF~NO$5$l$?%-!<$HF1$8%b%G%#%U%!%$%d$N;XDj\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p><code>=</code> \e$B$h$j1&B&$G$N%b%G%#%U%!%$%d$N;XDj$NJ}K!$G$9!#\e(B</p>
+
+                         <p class="sample">
+                         &nbsp;key *S-A = C-*S-B
+                         </p>
+                         
+                         <p>\e$BNc$($P$3$N$h$&$K5-=R$7$?>l9g!"\e(B<kbd>Shift</kbd> + <kbd>A</kbd> \e$B$r2!$9$H!"\e(BWindows \e$B$X$O\e(B <kbd>Shift</kbd> + <kbd>Control</kbd> + <kbd>B</kbd> \e$B$,F~NO$5$l$^$9!#\e(B<kbd>A</kbd> \e$B$r2!$9$H!"\e(BWindows \e$B$X$O\e(B <kbd>Control</kbd> + <kbd>B</kbd> \e$B$,F~NO$5$l$^$9!#\e(B</p>
+                         
+                         <p>\e$B$D$^$j!"\e(B<code>=</code> \e$B$N1&B&$G\e(B <code>*</code> \e$B$G;XDj$5$l$?%b%G%#%U%!%$%d$O!"%-!<%\!<%I$G<B:]$KF~NO$7$?%b%G%#%U%!%$%d$HF1$8$K$J$k$h$&$K@_Dj$5$l$^$9!#\e(B</p>
+                         
+                         <p>\e$B$7$?$,$C$F!"\e(B<kbd>A</kbd> \e$B$r\e(B <kbd>B</kbd> \e$B$HF~$lBX$($?$$>l9g$O!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key *A = *B<br>
+                         &nbsp;key *B = *A
+                         </p>
+
+                         <p class="continue">\e$B$H$J$j$^$9!#\e(B</p>
+                       </div>
+
+                   <dt class="h3"><a name="keyUpDown">\e$B%-!<$r2!$9\e(B/\e$BN%$9\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p><code><em>KEY</em></code> \e$B$NA0$K%b%G%#%U%!%$%d$HF1$8$h$&$K\e(B <code>D-</code> \e$B$H\e(B <code>U-</code> \e$B$rIU$1$k$3$H$,$G$-$^$9!#$3$l$O!"$=$l$>$l%-!<$N2!$9$3$H$HN%$9$3$H$KBP1~$7$F$$$^$9!#%G%U%)%k%H$G$O\e(B <code>*D-*U-</code> \e$B$,;XDj$5$l$F$$$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key A = B C
+                         </p>
+                         
+                         <p class="continue">\e$B$H$$$&5-=R$O!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key *U-*D-A = D-B U-B D-C U-C
+                         </p>
+
+                         <p class="continue">\e$B$HF1$8$G$"$j!"$5$i$K<!$N$b$N$H$bF1$8$K$J$j$^$9!#%-!<%j%T!<%H$,5/$3$C$?>l9g$O!"\e(B<code>~U-D-A</code> \e$B$,2?EY$b<B9T$5$l!"%-!<$rN%$7$?$H$-$K\e(B <code>U-~D-A</code> \e$B$,<B9T$5$l$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key ~U-D-A = D-B U-B D-C<br>
+                         &nbsp;key U-~D-A = U-C
+                         </p>
+                       </div>
+
+                   <dt class="h3"><a name="keyRepeat">\e$B%-!<%j%T!<%H$7$?\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p><code>=</code> \e$B$h$j:8$N\e(B <code><em>KEY</em></code> \e$B$NA0$K%b%G%#%U%!%$%d$HF1$8$h$&$K\e(B <code>R-</code> \e$B$rIU$1$k$3$H$,$G$-$^$9!#$3$l$O!"%-!<%j%T!<%H$,H/@8$7$?$3$H$rI=$7$^$9!#%G%U%)%k%H$G$O\e(B <code>*R-</code> \e$B$,;XDj$5$l$F$$$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key A = B<br>
+                         &nbsp;key R-A = C
+                         </p>
+                         
+                         <p class="continue">\e$B$H$$$&5-=R$r$9$k$H!"\e(B<kbd>A</kbd> \e$B$r2!$7$D$E$1$k$H!"\e(B</p>
+                         
+                         <p class="sample">
+                         BCCCCCCCCCCCCCCCCCCCCC
+                         </p>
+
+                         \e$B$HF~NO$5$l$^$9!#$H$F$b$d$d$3$7$$$N$G$"$^$j;H$o$J$$$h$&$K$7$^$7$g$&!#\e(B
+                       </div>
+                       
+                   <dt class="h3"><a name="defaultModifier">\e$B%G%U%)%k%H%b%G%#%U%!%$%d$NJQ99\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%G%U%)%k%H$G$O!":8B&$N%-!<$K$O\e(B <code>~C-~M-~S-*NL-*CL-*SL-*KL-*IL-~IC-*MAX-*MIN-*MMAX-*MMIN-*T-*TS-</code> \e$B$,;XDj$5$l$F$$$^$9$,!"$3$l$rJQ99$9$k$3$H$,$G$-$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key *IC- =
+                         </p>
+                         
+                         <p class="continue">\e$B$H5-=R$9$k$H!"$3$NJ80J9_$N%G%U%)%k%H%b%G%#%U%!%$%d$O\e(B <code>~C-~M-~S-*NL-*CL-*SL-*KL-*IL-*IC-*MAX-*MIN-*MMAX-*MMIN-*T-*TS-</code> \e$B$H$J$j$^$9!#\e(B</p>
+                         
+                         <p>\e$B%G%U%)%k%H%b%G%#%U%!%$%d$NJQ99$rJ#?t9T$&$H$-$K$O!"Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key L0-*IC-~C- =
+                         </p>
+                         
+                         <p class="continue">\e$B$N$h$&$K$7$J$1$l$P$J$j$^$;$s!#0J2<$N$h$&$K;XDj$9$k$N$O4V0c$$$G$9!#:G8e$N$b$N$7$+M-8z$K$J$j$^$;$s!#\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key L0- =<br>
+                         &nbsp;key *IC- =<br>
+                         &nbsp;key ~C- = # \e$B$3$N9T$7$+M-8z$K$J$i$J$$\e(B<br>
+                         </p>
+                       </div>
+                 </dl>
+               </div>
+               
+           <dt class="h2"><a name="keymap">ii. \e$B%-!<%^%C%WDj5A\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p>\e$B!VAk;H$$$NM+]5!W$K$O!"%-!<%^%C%W$H$$$&35G0$,$"$j$^$9!#%-!<%^%C%W$K%+%9%?%^%$%:$7$?$$%-!<>pJs$r=q$-9~$s$G$f$-!"%&%#%s%I%&$4$H$K%-!<%^%C%W$r;H$$J,$1$^$9!#%-!<%^%C%W$rDj5A$9$k$K$O!"0J2<$N$I$l$+$NJ8$r=q$$$F$+$i%-!<$r@_Dj$7$^$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 keymap <em>\e$B%-!<%^%C%WL>\e(B</em><br>
+                 keymap2 <em>\e$B%-!<%^%C%WL>\e(B</em><br>
+                 window <em>\e$B%-!<%^%C%WL>\e(B</em> <em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em><br>
+                 window <em>\e$B%-!<%^%C%WL>\e(B</em> ( <em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em> &amp;&amp; <em>\e$B%&%#%s%I%&%?%$%H%kL>\e(B</em> )<br>
+                 window <em>\e$B%-!<%^%C%WL>\e(B</em> ( <em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em> || <em>\e$B%&%#%s%I%&%?%$%H%kL>\e(B</em> )<br>
+                 </p>
+                 
+                 <p>\e$BNc$($P!"%a%bD"$G\e(B <kbd>Control</kbd> + <kbd>Z</kbd> \e$B$r2!$9$H:G>.2=$5$l$k$,!"%a%bD"0J30$N%(%G%#%C%H%3%s%H%m!<%k$G\e(B <kbd>Control</kbd> + <kbd>Z</kbd> \e$B$r2!$9$HC1$J$k\e(B <kbd>Z</kbd> \e$B%-!<$HF1$8$K$J$k$H$$$&;XDj$,$7$?$$>l9g$O!"\e(B</p>
+                 
+                 <p class="sample">
+                 window EditControl /:Edit$/ : Global<br>
+                 &nbsp;key C-Z = Z<br>
+                 window Notpad /Notepad:Edit$/ : Global<br>
+                 &nbsp;key C-Z = &amp;WindowMinimize
+                 </p>
+                 
+                 <p class="continue">\e$B$H5-=R$7$^$9!#$3$3$G\e(B <code>/Notepad:Edit$/</code> \e$B$O%a%bD"$N>e$K$"$k%(%G%#%C%H%3%s%H%m!<%k$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$rI=$7$F$$$^$9!#\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$O@55,I=8=$G5-=R$7$^$9!#\e(B<code>: Global</code> \e$B$O\e(B<code><em>\e$B?F%-!<%^%C%W\e(B</em></code>\e$B$r;XDj$7$F$$$^$9!#\e(B</p>
+                 
+                 <dl>
+                   <dt class="h3"><a name="windowClass">\e$B%&%#%s%I%&%/%i%9\e(B/\e$B%?%$%H%kL>\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>Windows \e$B$NA4$F$N%&%#%s%I%&$O!"2?$i$+$N%&%#%s%I%&%/%i%9$KB0$7$F$$$^$9!#Nc$($P!"%a%bD"$N%&%#%s%I%&%/%i%9L>$O\e(B <code>Notepad</code> \e$B$G!"%(%G%#%C%H%3%s%H%m!<%k$N%&%#%s%I%&%/%i%9L>$O\e(B <code>Edit</code> \e$B$G$9!#\e(B</p>
+                         
+                         <p>\e$B!VAk;H$$$NM+]5!W$O!"$I$N%&%#%s%I%&$G$I$N%-!<$r2!$7$?$i$I$s$JF0:n$r$9$k$+!"$H$$$&$3$H$r6hJL$9$k$?$a$K\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$H\e(B<code><em>\e$B%&%#%s%I%&%?%$%H%kL>\e(B</em></code>\e$B$rMQ$$$F$$$^$9!#$=$N$?$a$K!"!VAk;H$$$NM+]5!W$G$O%&%#%s%I%&$N=E$J$j$N>uBV$r\e(B "<code>:</code>" \e$B$G7R$2$FI=8=$7$^$9!#Nc$($P!"%a%bD"$N>e$N%(%G%#%C%H%3%s%H%m!<%k$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$J$i$P!"\e(B</p>
+                         
+                         <p class="sample">
+                         C:\WINDOWS\system32\notepad.exe:Notepad:Edit
+                         </p>
+                         
+                         <p class="continue">\e$B$HI=8=$7$^$9!#$?$@$7!"\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$N0lHV:G=i$K$O$=$N%"%W%j%1!<%7%g%s$N%Q%9L>$rIU$1$F$$$^$9!#\e(B</p>
+                         
+                         <p><code>window</code> \e$BJ8$K$O!"$3$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$H\e(B<code><em>\e$B%&%#%s%I%&%?%$%H%kL>\e(B</em></code>\e$B$r5-=R$9$k$3$H$,$G$-$^$9$,!"\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$BA4$F$r=q$/I,MW$O$J$/!"@55,I=8=$G>JN,$9$k$3$H$,$G$-$^$9!#\e(B</p>
+                         
+                         <p>\e$BNc$($P!"\e(B<code>/:Edit$/</code> \e$B$OA4$F$N%(%G%#%C%H%3%s%H%m!<%k$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$rI=$7$^$9$7!"\e(B<code>/:#32770.*:Edit$/</code> \e$B$J$i$P!"%@%$%"%m%0%\%C%/%9>e$K$"$kA4$F$N%(%G%#%C%H%3%s%H%m!<%k$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$rI=$7$^$9\e(B (<code>#32770</code> \e$B$O%@%$%"%m%0%\%C%/%9$N%&%#%s%I%&%/%i%9L>\e(B)\e$B!#\e(B</p>
+                         
+                         <p>\e$B8D!9$N%&%#%s%I%&$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$H\e(B<code><em>\e$B%&%#%s%I%&%?%$%H%kL>\e(B</em></code>\e$B$rD4$Y$k$K$O!"%?%9%/%H%l%$%a%K%e!<\e(B<a href="MANUAL-ja.html#menu-i" class="menu-item">\e$BD4::\e(B(I)...</a>\e$B$N!V%&%#%s%I%&$ND4::!W!"$^$?$O\e(B<code><em>FUNCTION</em></code> <a href="#function_WindowIdentify"><code>&amp;WindowIdentify</code></a> \e$B$rMxMQ$7$F$/$@$5$$!#\e(B</p>
+                         
+                         <p><code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$H\e(B<code><em>\e$B%&%#%s%I%&%?%$%H%kL>\e(B</em></code>\e$B$NN>J}$r5-=R$9$k>l9g$O!"3g8L$G0O$_$=$N4V$r\e(B <code>&amp;&amp;</code> \e$B$+\e(B <code>||</code> \e$B$G6h@Z$j$^$9!#\e(B<code>&amp;&amp;</code> \e$B$N>l9g$O!"N>J}$K%^%C%A$9$k$h$&$J%&%#%s%I%&$rI=$7!"\e(B<code>||</code> \e$B$N>l9g$O$I$A$i$+0lJ}$K%^%C%A$9$k$h$&$J%&%#%s%I%&$rI=$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="regexp">\e$B@55,I=8=$K$D$$$F\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$H\e(B<code><em>\e$B%&%#%s%I%&%?%$%H%kL>\e(B</em></code>\e$B$K$O@55,I=8=$,;HMQ$G$-$^$9!#@55,I=8=$O\e(B <code>/.../</code> \e$B$G0O$`$+!"\e(B<code>\m@...@</code>\e$B$G0O$_$^$9\e(B (\e$B$?$@$7\e(B<code>@</code>\e$B$O$I$s$JJ8;z$G$bNI$$$G$9\e(B)\e$B!#\e(B</p>
+                         
+                         <p>\e$B@55,I=8=%(%s%8%s$K$O\e(B <a href="http://www.boost.org/libs/regex/doc/index.html" target="_top">Boost.Regex</a> \e$B$r;HMQ$7$F$$$^$9!#$3$N%(%s%8%s$G$O\e(B <a href="http://www.kt.rim.or.jp/~kbk/perl5.005/perlre.html" target="_top">Perl \e$B$G;HMQ$G$-$k@55,I=8=\e(B</a>\e$B$,$[$\%+%P!<$5$l$F$$$^$9!#$h$/;H$$$=$&$J$b$N$r5s$2$F$*$-$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li>"<code>|</code>" Alternation
+                           <li>"<code>*</code>" Match 0 or more times
+                           <li>"<code>+</code>" Match 1 or more times
+                           <li>"<code>?</code>" Match 1 or 0 times
+                           <li>"<code>.</code>" Match any character
+                           <li>"<code>^</code>" Match the beginning of the string
+                           <li>"<code>$</code>" Match the end of the string
+                           <li>"<code>\b</code>" Match a word boundary
+                           <li>"<code>\B</code>" Match a non word boundary
+                           <li>"<code>\w</code>" Match a word character (<code>[0-9a-z_]</code>)
+                           <li>"<code>\W</code>" Match a non word character
+                           <li>"<code>\s</code>" Match a whitespace character
+                           <li>"<code>\S</code>" Match a non-whitespace character
+                           <li>"<code>\d</code>" Match a digit character
+                           <li>"<code>\D</code>" Match a non-digit character
+                           <li>"<code>(</code>" "<code>)</code>" Grouping
+                           <li>"<code>[</code>" "<code>]</code>" Character class
+                           <li>\e$B$h$j>\$7$/$O\e(B <a href="http://www.boost.org/libs/regex/doc/syntax.html" target="_top">Boost.Regex: Regular Expression Syntax</a>\e$B$r8+$F$/$@$5$$!#\e(B
+                         </ul>
+                       </div>
+                       
+                   <dt class="h3"><a name="parentKeymap">\e$B?F%-!<%^%C%W\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B?F%-!<%^%C%W$H$O!"8=:_$N%-!<%^%C%W$KE,@Z$J%-!<3d$jEv$F$,Dj5A$5$l$F$$$J$$>l9g$K!"%-!<$rA\$7$K9T$/%-!<%^%C%W$G$9!#\e(B"<code>:</code>" \e$B$N8e$m$K\e(B<em>\e$B?F%-!<%^%C%WL>\e(B</em>\e$B$r=q$-$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         keymap sub : Global<br>
+                         &nbsp;key     C-A = &amp;WindowMinimize<br>
+                         window EditControl /:Edit$/ : sub<br>
+                         &nbsp;key     C-A = &amp;KeymapParent
+                         </p>
+                         
+                         <p class="continue">\e$B$H5-=R$7$?>l9g!"%(%G%#%C%H%3%s%H%m!<%k$G\e(B <kbd>Control</kbd> + <kbd>A</kbd> \e$B$rF~NO$9$k$H!"%&%#%s%I%&$O:G>.2=$5$l$^$9!#$D$^$j!"\e(B<a href="#function_KeymapParent"><code>&amp;KeymapParent</code></a> \e$B$r5-=R$9$k$3$H$G?F%-!<%^%C%W$GDj5A$5$l$?%-!<$rMxMQ$9$k$3$H$,$G$-$k$N$G$9!#$b$7!"\e(B<em>\e$B?F%-!<%^%C%WL>\e(B</em>\e$B$,;XDj$5$l$F$$$J$1$l$P\e(B <a href="#function_Default"><code>&amp;Default</code></a> \e$B07$$$H$J$j!"%&%#%s%I%&$X%-!<$,$=$N$^$^F~NO$5$l$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="defaultKey">\e$B%G%U%)%k%H%-!<\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code>keymap</code>\e$B!"\e(B<code>window</code>\e$B!"\e(B<code>keymap2</code> \e$B$K$O!":G8e$K%-!<$rMeNs$9$k$3$H$K$h$C$F%G%U%)%k%H%-!<$rDj5A$9$k$3$H$,$G$-$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         window EditControl /:Edit$/ : Global = A<br>
+                         &nbsp;key *B = *C
+                         </p>
+                         
+                         <p class="continue">\e$B$H5-=R$9$k$H!"\e(B<kbd>B</kbd> \e$B$rF~NO$9$k$H\e(B <kbd>C</kbd> \e$B$rF~NO$7$?$3$H$K$J$k$,!"\e(B<kbd>B</kbd> \e$B0J30$N%-!<$rF~NO$9$k$H!"\e(B<kbd>A</kbd> \e$B$rF~NO$7$?$3$H$K$J$j$^$9!#$^$?!"%G%U%)%k%H%-!<$r;XDj$7$J$+$C$?>l9g$N%G%U%)%k%H%-!<$O!"\e(B<code>keymap</code> \e$B$H\e(B <code>window</code> \e$B$N>l9g$O\e(B <a href="#function_KeymapParent"><code>&amp;KeymapParent</code></a> \e$B$G!"\e(B<code>keymap2</code> \e$B$N>l9g$O\e(B <a href="#function_Undefined"><code>&amp;Undefined</code></a> \e$B$K$J$j$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="keymap2">\e$BFsCJ3,%-!<%^%C%W\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code>keymap2</code> \e$B$O%G%U%)%k%H%-!<$,\e(B <a href="#function_Undefined"><code>&amp;Undefined</code></a> \e$B$K$J$C$F$k$h$&$J%-!<%^%C%W$G!"<g$K\e(B <a href="#function_Prefix"><code>&amp;Prefix</code></a> \e$B$rMxMQ$7$F\e(B 2 \e$B%9%H%m!<%/%-!<$r5-=R$9$k;~$K;HMQ$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="initialKeymap">\e$B=i4|%-!<%^%C%W\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code>.mayu</code> \e$B$N0lHV:G=i$N9T$K$O!"\e(B</p>
+                         
+                         <p class="sample">
+                         window Global ( // || // ) = &amp;OtherWindowClass
+                         </p>
+                         
+                         <p class="continue">\e$B$H$$$&9T$,1#$l$F$$$k$H9M$($F2<$5$$!#$D$^$j!"\e(B<code>.mayu</code> \e$B$G2?$b%-!<%^%C%W$r;XDj$;$:$K=q$-;O$a$k$H!"\e(B<em>\e$B%-!<%^%C%WL>\e(B</em> <code>Global</code> \e$B$N%-!<%^%C%W$KBP$9$k%-!<Dj5A$K$J$k$H$$$&$3$H$G$9!#$=$7$F!"\e(B<code>Global</code> \e$B%-!<%^%C%W$N%G%U%)%k%H%-!<$O\e(B <a href="#function_OtherWindowClass"><code>&amp;OtherWindowClass</code></a> \e$B$,@_Dj$5$l$F$$$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="conflictKeymap">\e$BL7=b$7$?%-!<%^%C%W$N;XDj\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$BF1$8%-!<%^%C%W$KBP$9$k\e(B <code>keymap</code> \e$B$d\e(B <code>window</code> \e$B$d\e(B <code>keymap2</code> \e$B$O2?EY$G$b;XDj$G$-$^$9$,!"L7=b$9$k;XDj$r$7$F$O$$$1$^$;$s!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         keymap Amap : Global<br>
+                         ...<br>
+                         keymap Bmap : Amap<br>
+                         ...<br>
+                         keymap Amap : Global<br>
+                         ...
+                         </p>
+                         
+                         \e$B$H$$$&;XDj$OLdBj$"$j$^$;$s$,!"\e(B
+                         
+                         <p class="sample">
+                         keymap Amap : Global<br>
+                         ...<br>
+                         keymap Bmap : Amap<br>
+                         ...<br>
+                         keymap Amap : Bmap    # \e$BL7=b\e(B<br>
+                         ...
+                         </p>
+                         
+                         <p class="continue">\e$B$H$$$&;XDj$O$7$F$O$$$1$^$;$s!#$3$N>l9g!"\e(B<code>keymap Amap : Bmap</code> \e$B$N$+$o$j$K\e(B <code>keymap Amap : Global</code> \e$B$,;XDj$5$l$?$b$N$H$_$J$5$l$^$9!#%(%i!<$O=P$^$;$s!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="matchManyClasses"><code>window</code> \e$B$KJ#?t3:Ev$9$k>l9g\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$BNc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         window EditControl /:Edit$/ : Global<br>
+                         &nbsp;key A = A space E D I T enter<br>
+                         &nbsp;key B = B space E D I T enter<br>
+                         window Notepad /:Notepad/ : Global<br>
+                         &nbsp;key A = A space N O T E P A D enter<br>
+                         &nbsp;key C = C space N O T E P A D enter
+                         </p>
+                         
+                         <p class="continue">\e$B$H$$$&5-=R$r$7$?$H$7$^$9!#$3$3$G!"!V%a%bD"!W$rN)$A>e$2$k$H!"%a%bD"$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$O\e(B</p>
+                         
+                         <p class="sample">
+                         C:\WINDOWS\system32\notepad.exe:Notepad:Edit
+                         </p>
+                         
+                         <p class="continue">\e$B$H$J$C$F$$$k$N$G!"\e(B<code>/:Edit$/</code> \e$B$H\e(B <code>/:Notepad/</code> \e$B$ON>J}6&$b%a%bD"$N\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$K3:Ev$7$^$9!#$3$N;~!"\e(B<kbd>A</kbd> \e$B$rF~NO$9$k$H!"%a%bD"$K$O!V\e(B<code>a notepad</code>\e$B!W$HI=<($5$l$^$9!#$3$l$O!"=EJ#$9$k5-=R$,$"$l$P!"$h$j2<$K=q$+$l$F$$$k$b$N$,M-8z$K$J$k$+$i$G$9!#$7$+$7!"\e(B<kbd>B</kbd> \e$B$rF~NO$7$?>l9g$O!"=EJ#$7$F$$$J$$$N$G!"%a%bD"$K$O!V\e(B<code>b edit</code>\e$B!W$HI=<($5$l$k$3$H$K$J$j$^$9!#\e(B</p>
+                         
+                         <p><kbd>B</kbd> \e$B$rF~NO$7$?>l9g$K!"FbIt$G9T$o$l$k=hM}$O0J2<$N$h$&$K$J$j$^$9!#\e(B</p>
+                         
+                         <ol>
+                           <li>\e$B$^$:\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$O\e(B <code>/:Notepad/</code> \e$B$K3:Ev$7$^$9$,!"%-!<3d$jEv$F$,$J$$$N$G!"\e(B<code>window</code> \e$B$N%G%U%)%k%H%-!<$G$"$k\e(B <code>&amp;KeymapParent</code> \e$B$,:NMQ$5$l$^$9!#\e(B
+                           <li><code>&amp;KeymapParent</code> \e$B$O\e(B<em>\e$B?F%-!<%^%C%W\e(B</em>\e$B$N;2>H$J$N$G!"\e(B<code>Global</code> \e$B%-!<%^%C%W$r;2>H$7$^$9!#\e(B
+                           <li>\e$B$=$&$9$k$H!"\e(B<code>Global</code> \e$B%-!<%^%C%W$G$b\e(B <kbd>B</kbd> \e$B$N3d$jEv$F$,$J$$$N$G!"\e(B<code>Global</code> \e$B%-!<%^%C%W$N%G%U%)%k%H%-!<$G$"$k!"\e(B<code>&amp;OtherWindowClass</code> \e$B$,:NMQ$5$l$^$9!#\e(B
+                           <li><code>&amp;OtherWindowClass</code> \e$B$,:NMQ$5$l$k$H!"$^$:!"B>$K3:Ev$9$k\e(B<code><em>\e$B%&%#%s%I%&%/%i%9L>\e(B</em></code>\e$B$,$J$$$+$I$&$+C5$7$^$9!#$b$7$J$1$l$P!"\e(B<code>&amp;Default</code> \e$B07$$$H$J$j$^$9!#$3$N>l9g$O\e(B <code>/:Edit$/</code> \e$B$K3:Ev$7$^$9!#\e(B
+                           <li><code>/:Edit$/</code> \e$B$K3:Ev$7$?$N$G!"\e(B<code>/:Edit$/</code> \e$B$N\e(B <kbd>B</kbd> \e$B$,:NMQ$5$l$^$9!#$7$?$,$C$F!"!V\e(Bb edit\e$B!W$HI=<($5$l$k$3$H$H$J$j$^$9!#\e(B
+                         </ol>
+                       </div>
+                       
+                   <dt class="h3"><a name="perKeymapDefinition">\e$B%-!<%^%C%W$,1F6A$9$kDj5A\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         \e$B0J2<$NC18l$G;O$^$kDj5A$O!"%-!<%^%C%WKh$KDj5A$G$-$^$9!#\e(B
+                         <ul>
+                           <li><code>key ...</code> <a href="#key">\e$B%-!<3d$jEv$F$NJQ99\e(B</a>
+                           <li><code>event ...</code> <a href="#event">\e$B%$%Y%s%HDj5A\e(B</a>
+                           <li><code>mod ...</code> <a href="#mod">\e$B%b%G%#%U%!%$%d%-!<3d$jEv$F$NJQ99\e(B</a>
+                         </ul>
+                         \e$B0J2<$NC18l$G;O$^$kDj5A$O!"%-!<%^%C%WKh$KDj5A$9$k$3$H$O$G$-$^$;$s!#\e(B
+                         <ul>
+                           <li><code>def ...</code> <a href="#keyboard">\e$B%-!<%\!<%IDj5A\e(B</a>
+                           <li><code>keyseq ...</code> <a href="#keyseq">\e$B%-!<%7!<%1%s%9Dj5A\e(B</a>
+                         </ul>
+                       </div>
+                 </dl>
+               </div>
+               
+           <dt class="h2"><a name="mod">iii. \e$B%b%G%#%U%!%$%d%-!<3d$jEv$F$NJQ99\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p class="sample">
+                 &nbsp;mod <em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em> = <em>\e$B%-!<L>\e(B</em> \e$B!D\e(B<br>
+                 &nbsp;mod <em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em> += <em>\e$B%-!<L>\e(B</em> \e$B!D\e(B<br>
+                 &nbsp;mod <em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em> -= <em>\e$B%-!<L>\e(B</em> \e$B!D\e(B<br>
+                 </p>
+                 
+                 <p>\e$B:G=i$N\e(B 3 \e$B$D$O!"\e(B<em>\e$B%-!<L>\e(B</em>\e$B$G;XDj$7$?%-!<$r%b%G%#%U%!%$%d%-!<$K$7$?$j\e(B (<code>=</code>) \e$BDI2C$7$?$j\e(B (<code>+=</code>) \e$B:o=|$7$?$j\e(B (<code>-=</code>) \e$B$7$^$9!#3F%-!<%^%C%WKh$K3d$jEv$F$^$9!#L@<(E*$K3d$jEv$F$J$$>l9g$O!"?F%-!<%^%C%W$+$i0z$-7Q$,$l$^$9!#Nc$($P!"\e(B</p>
+                 
+                 <p class="sample">
+                 &nbsp;mod shift += \e$BL5JQ49\e(B
+                 </p>
+                 
+                 <p class="continue">\e$B$O!"\e(B<kbd>\e$BL5JQ49\e(B</kbd> \e$B%-!<$r\e(B shift \e$B%b%G%#%U%!%$%d%-!<$K$7$^$9!#=>$C$F!"\e(B</p>
+                 
+                 <p class="sample">
+                 &nbsp;key S-A = X
+                 </p>
+                 
+                 <p class="continue">\e$B$H$$$&5-=R$,$"$C$?>l9g$K!"\e(B<kbd>\e$BL5JQ49\e(B</kbd> + <kbd>A</kbd> \e$B$r2!$9$H\e(B <kbd>X</kbd> \e$B$rF~NO$7$?$3$H$K$J$j$^$9!#@53N$K$O!"\e(B<kbd>\e$BL5JQ492!$9\e(B</kbd> <kbd>X\e$B2!$9\e(B</kbd> <kbd>X\e$BN%$9\e(B</kbd> <kbd>\e$BL5JQ49N%$9\e(B</kbd> \e$B$H$$$&%-!<$,\e(B Windows \e$B$XF~NO$5$l$^$9!#$3$l$G$OET9g$,0-$$$H$$$&$3$H$OB?$$$H;W$o$l$k$N$G!"\e(B</p>
+                 
+                 <p class="sample">
+                 &nbsp;key *\e$BL5JQ49\e(B = *LShift
+                 </p>
+                 
+                 <p class="continue">\e$B$H$7$F\e(B <kbd>\e$BL5JQ49\e(B</kbd> \e$B%-!<$r2!$9$H\e(B <kbd>LShift</kbd> \e$B$,F~NO$5$l$k$h$&$K3d$jEv$F$^$9!#$=$&$9$l$P!"\e(BWindows \e$B$X$O\e(B <kbd>LShift\e$B2!$9\e(B</kbd> <kbd>LShift\e$BN%$9\e(B</kbd> <kbd>X\e$B2!$9\e(B</kbd> <kbd>X\e$BN%$9\e(B</kbd> \e$B$H$$$&%-!<$,F~NO$5$l$^$9!#\e(B</p>
+                 
+                 <p><em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em>\e$B$K$O!"\e(B<code>shift</code>, <code>alt</code> (<code>meta</code>, <code>menu</code>), <code>control</code> (<code>ctrl</code>), <code>windows</code> (<code>win</code>), <code>mod0</code>\e$B!A\e(B<code>mod9</code> \e$B$,5-=R$G$-$^$9!#3g8L$NCf$NL>A0$b;HMQ$G$-$^$9!#\e(B</p>
+                 
+                 <p><code>mod0</code>\e$B!A\e(B<code>mod9</code> \e$B$O!VAk;H$$$NM+]5!W$NCf$G$N$_M-8z$J%b%G%#%U%!%$%d$G!"Nc$($P0J2<$N$h$&$K;HMQ$7$^$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 &nbsp;mod mod0 = Up<br>
+                 &nbsp;key M0-Left = Left Up
+                 </p>
+                 
+                 <p class="continue">\e$B$3$N$h$&$K3d$jEv$F$k$H!"\e(B<kbd>\e$B",\e(B</kbd> \e$B$r2!$7$J$,$i\e(B <kbd>\e$B"+\e(B</kbd> \e$B$r2!$9$H%+!<%=%k$,:8<P$a>e$X0\F0$9$k$3$H$K$J$j$^$9!#\e(B</p>
+                 
+                 <dl>
+                   <dt class="h3"><a name="trueModifier">\e$B??$N%b%G%#%U%!%$%d\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%b%G%#%U%!%$%d$K$7$?$$%-!<$NA0$K\e(B "<code>!</code>" \e$B$rIU$1$k$H!"\e(B<em>\e$B??$N%b%G%#%U%!%$%d\e(B</em>\e$B$K$J$j$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;mod shift += !\e$BL5JQ49\e(B<br>
+                         &nbsp;key \e$BL5JQ49\e(B = Y<br>
+                         &nbsp;key S-A = X
+                         </p>
+                         
+                         <p class="continue">\e$B$H5-=R$7$?>l9g!"\e(B<kbd>\e$BL5JQ49\e(B</kbd> + <kbd>A</kbd> \e$B$r2!$9$H\e(B <kbd>X\e$B2!$9\e(B</kbd> <kbd>X\e$BN%$9\e(B</kbd> \e$B$H$$$&%-!<$,\e(B Windows \e$B$XF~NO$5$l$^$9!#\e(BWindows \e$B$+$i$O!"\e(B<kbd>\e$BL5JQ49\e(B</kbd> \e$B%-!<$,2!$5$l$?$H$$$&$3$H$OJ,$+$j$^$;$s$7!"\e(B<kbd>Y</kbd> \e$B$b\e(B Windows \e$B$XF~NO$5$l$k$3$H$O$"$j$^$;$s!#$D$^$j!"??$N%b%G%#%U%!%$%d$KDj5A$5$l$F$$$k%-!<$d\e(B <code><em>FUNCTION</em></code> \e$B$J$I$O<B9T$5$l$^$;$s!#\e(B</p>
+                         
+                         <p>\e$B0J2<$N$h$&$J9T$r5-=R$9$k$H!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;mod !<em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em>
+                         </p>
+                         
+                         <p class="continue">\e$B$=$N\e(B<em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em>\e$B$K3d$jEv$F$i$l$F$$$k%b%G%#%U%!%$%d$rA4$F\e(B<em>\e$B??$N%b%G%#%U%!%$%d\e(B</em>\e$B$KJQ99$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="oneShotModifier">One Shot \e$B%b%G%#%U%!%$%d\e(B (SandS)</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>(\e$B0lHLE*$K$O\e(B SandS \e$B$H8F$P$l$F$$$k5!G=$G$9!#\e(BSpace and Shift \e$B$NN,$G$9!#\e(B)</p>
+                         
+                         <p>\e$B%b%G%#%U%!%$%d$K$7$?$$%-!<$NA0$K\e(B "<code>!!</code>" \e$B$rIU$1$k$H!"\e(B<em>One Shot \e$B%b%G%#%U%!%$%d\e(B</em>\e$B$K$J$j$^$9!#$?$H$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;mod shift = !!LShift<br>
+                         &nbsp;key S-A = X<br>
+                         &nbsp;key S-LShift = Y
+                         </p>
+                         
+                         <p class="continue">\e$B$H5-=R$7$?>l9g!"\e(B<kbd>LShift</kbd> \e$B$r2!$7$F$9$0N%$7$?>l9g$O!"\e(BWindows \e$B$X$O!"\e(B<kbd>Y</kbd> \e$B$,F~NO$5$l$^$9$,!"\e(B<kbd>LShift</kbd> + <kbd>A</kbd> \e$B$rF~NO$7$?>l9g$O!"\e(B<kbd>X</kbd> \e$B$N$_$,\e(B Windows \e$B$XF~NO$5$l$^$9!#\e(B</p>
+                         
+                         <p>\e$B0J2<$N$h$&$J9T$r5-=R$9$k$H!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;mod !!<em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em>
+                         </p>
+                         
+                         <p class="continue">\e$B$=$N\e(B<em>\e$B%b%G%#%U%!%$%d%-!<L>\e(B</em>\e$B$K3d$jEv$F$i$l$F$$$k%b%G%#%U%!%$%d$rA4$F\e(B<em>One Shot \e$B%b%G%#%U%!%$%d\e(B</em>\e$B$KJQ99$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="oneShotRepeatableModifier">One Shot (\e$B%-!<%j%T!<%HM-\e(B)</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><em>One Shot \e$B%b%G%#%U%!%$%d\e(B</em>\e$B$ODL>o%-!<%j%T!<%H$7$^$;$s$,!"\e(B"<code>!!!</code>" \e$B$rIU$1$k$H!"%-!<%j%T!<%H$r$9$k$h$&$K$J$j$^$9!#$?$H$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;mod shift = !!!Up<br>
+                         </p>
+                         
+                         <p>\e$B$H$9$k$H!"\e(B<kbd>\e$B",\e(B</kbd> \e$B$r2!$7$J$,$i2?$+JL$N%-!<\e(B (\e$BNc$($P\e(B <kbd>A</kbd>) \e$B$r2!$9$H\e(B <kbd>Shift</kbd> + <kbd>A</kbd> \e$B$HF1$8$3$H$K$J$j$^$9$,!"\e(B<kbd>\e$B",\e(B</kbd> \e$B$r2!$7$C$Q$J$7$K$9$k$H\e(B <kbd>\e$B",\e(B</kbd> \e$B$,%-!<%j%T!<%H$7$F!"%+!<%=%k$,>e$XF0$/$H$$$&$3$H$K$J$j$^$9!#\e(B</p>
+
+                         <p>\e$B%-!<%j%T!<%H$,3+;O$9$k$^$G$N;~4V$r\e(B<a href="#def_option_delay_of_oneShotRepeatableModifier">\e$B%*%W%7%g%s\e(B (<code>delay-of !!!</code>)</a> \e$B$G@_Dj$G$-$^$9!#\e(B</p>
+                         
+                       </div>
+                       
+                   <dt class="h3"><a name="lock">\e$B%m%C%/%-!<\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B!VAk;H$$$NM+]5!W$K$O!"!VAk;H$$$NM+]5!W$NCf$G$N$_M-8z$J%m%C%/%-!<$,B8:_$7$^$9!#$3$l$i$O%-!<$N%b%G%#%U%!%$%d$H$7$F\e(B <code>L0-</code>\e$B!A\e(B<code>L9-</code> \e$B$r=q$/$3$H$,$G$-!"\e(B<a href="#function_Toggle"><code>&amp;Toggle</code></a> \e$B$r;H$&$3$H$K$h$j%H%0%k$5$;$k$3$H$,$G$-$^$9!#Nc$($P!"\e(B
+                         
+                         <p class="sample">
+                         &nbsp;key \e$B$R$i$,$J\e(B = &amp;Toggle(Lock0)<br>
+                         &nbsp;key L0-A = B
+                         </p>
+                         
+                         <p class="continue">\e$B$H5-=R$9$k$H!"\e(B<kbd>\e$B$R$i$,$J\e(B</kbd> \e$B%-!<$,%H%0%k>uBV$K$J$C$F$$$k$H$-$K\e(B <kbd>A</kbd> \e$B$r2!$9$H\e(B Windows \e$B$X$O\e(B <kbd>B</kbd> \e$B$,F~NO$5$l$^$9!#\e(B</p>
+                       </div>
+                 </dl>
+               </div>
+               
+           <dt class="h2"><a name="keyseq" class="a2">iv. \e$B%-!<%7!<%1%s%9Dj5A\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p class="sample">
+                 keyseq $<em>\e$B%-!<%7!<%1%s%9L>\e(B</em> = <em>KEY</em> \e$B$d\e(B <em>FUNCTION</em> \e$B!D\e(B
+                 </p>
+                 
+                 <p><code>keyseq</code> \e$B$r;H$&$3$H$G!"0lO"$N%-!<F~NO$KBP$7$FL>A0$rIU$1$k$3$H$,$G$-$^$9!#Nc$($P!"\e(B</p>
+                 
+                 <p class="sample">
+                 keyseq $Right2Times = Right Right<br>
+                 &nbsp;key C-F = $Right2Times
+                 </p>
+                 
+                 <p class="continue">\e$B$H$9$k$H!"\e(B<kbd>Control</kbd> + <kbd>F</kbd> \e$B$G1&$KFs$D%+!<%=%k$r?J$a$k$3$H$,$G$-$^$9!#Kt!"\e(B</p>
+                 
+                 <p class="sample">
+                 &nbsp;key C-F = Right Right
+                 </p>
+                 
+                 <p class="continue">\e$B$O!"\e(B<code>$Right2Times</code> \e$B$H$$$&L>A0$,Dj5A$5$l$J$$$3$H0J30$O!"@h$NNc$HF1$8$K$J$j$^$9!#\e(B</p>
+               </div>
+               
+           <dt class="h2"><a name="event" class="a2">v. \e$B%$%Y%s%HDj5A\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p class="sample">
+                 &nbsp;event <em>EVENT</em> = <em>KEY</em> \e$B$d\e(B <em>FUNCTION</em> \e$B!D\e(B
+                 </p>
+                 
+                 <p>\e$B$"$k%$%Y%s%H$,5/$3$C$?$H$-$K\e(B <code><em>KEY</em></code> \e$B$d\e(B <code><em>FUNCTION</em></code> \e$B$r<B9T$7$^$9!#%$%Y%s%H$O%-!<%^%C%WKh$KDj5A$5$l!"?F%-!<%^%C%W$K%$%Y%s%H$,Dj5A$5$l$F$$$F$b$=$l$OL5;k$5$l$^$9!#\e(B</p>
+                 
+                 <p><code><em>EVENT</em></code> \e$B$K$O0J2<$N$b$N$,;XDj$G$-$^$9!#\e(B</p>
+                 
+                 <ul>
+                   <li><code>prefixed</code>: <a href="#function_Prefix"><code>&amp;Prefix</code></a> \e$B$K$h$C$F%-!<%^%C%W$,;XDj$5$l$?;~!#\e(B
+                   <li><code>before-key-down</code>: \e$B%-!<$,2!$5$?;~!#\e(B
+                   <li><code>after-key-up</code>: \e$B%-!<$,N%$5$l$?8e!#\e(B
+                 </ul>
+               </div>
+               
+           <dt class="h2"><a name="keyboard">vi. \e$B%-!<%\!<%IDj5A\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p>\e$B%G%U%)%k%H$N%-!<%\!<%IDj5A$O\e(B <a href="../109.mayu"><code>109.mayu</code></a> \e$BKt$O\e(B <a href="../104.mayu"><code>104.mayu</code></a> \e$B$K=q$+$l$F$$$^$9!#\e(B</p>
+                 
+                 <dl>
+                   <dt class="h3"><a name="def_key">\e$B%-!<Dj5A\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%-!<%\!<%I$NJ*M}E*$J%-!<$rDj5A$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def key <em>\e$B%-!<L>\e(B</em>\e$B!D\e(B = <em>\e$B%9%-%c%s%3!<%I\e(B</em>\e$B!D\e(B
+                         </p>
+                         
+                         <p>\e$B%-!<$,H/@8$9$k\e(B<code><em>\e$B%9%-%c%s%3!<%I\e(B</em></code>\e$B$r5-=R$7$F$$$-$^$9!#\e(B<code><em>\e$B%9%-%c%s%3!<%I\e(B</em></code>\e$B$O?t;z$G=q$-!"\e(B<code>E0-</code> \e$B$d\e(B <code>E1-</code> \e$B$H$$$&3HD%%-!<%U%i%0$r$D$1$k$3$H$,$G$-$^$9!#Kt!"\e(B</p>
+                         
+                         <p class="sample">
+                         def key Pause = E1-0x1d 0x45
+                         </p>
+                         
+                         <p>\e$B$3$N$h$&$K0lO"$N\e(B<em>\e$B%9%-%c%s%3!<%I\e(B</em>\e$B$rH/@8$5$;$k%-!<$K$O%9%-%c%s%3!<%I$r=q$-JB$Y$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="def_mod">\e$B%b%G%#%U%!%$%dDj5A\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%-!<%\!<%I$NJ*M}E*$J%b%G%#%U%!%$%d%-!<$rDj5A$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def mod <em>\e$B%b%G%#%U%!%$%dL>\e(B</em> = <em>\e$B%-!<L>\e(B</em>\e$B!D\e(B
+                         </p>
+                         
+                         <p><code><em>\e$B%b%G%#%U%!%$%dL>\e(B</em></code>\e$B$K$O!"\e(B<code>shift</code>, <code>alt</code> (<code>meta</code>, <code>menu</code>), <code>control</code> (<code>ctrl</code>), <code>windows</code> (<code>win</code>) \e$B$,5-=R$G$-$^$9!#3g8L$NCf$NL>A0$b;HMQ$G$-$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="def_sync">\e$BF14|Dj5A\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code>&amp;Sync</code> \e$B$K;HMQ$9$k\e(B<code><em>\e$B%9%-%c%s%3!<%I\e(B</em></code>\e$B$rDj5A$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def sync = <em>\e$B%9%-%c%s%3!<%I\e(B</em>\e$B!D\e(B
+                         </p>
+                         
+                         <p><code>&amp;Sync</code> \e$B$,<B9T$5$l$k$H$-!"!VAk;H$$$NM+]5!W$O$3$N\e(B<code><em>\e$B%9%-%c%s%3!<%I\e(B</em></code>\e$B$r\e(B Windows \e$B$KAw$j$^$9!#$=$7$F!"3F%&%#%s%I%&$,$3$N%-!<$,F~NO$5$l$?$3$H$r!VAk;H$$$NM+]5!W$XO"Mm$7$F$/$k$^$G=hM}$rCfCG$7$^$9!#$3$N$h$&$K$7$FF14|$r$H$k$N$G!"$3$N\e(B<code><em>\e$B%9%-%c%s%3!<%I\e(B</em></code>\e$B$,IT@5$K@_Dj$5$l$F$$$k$H!"F14|$,$H$l$:!VAk;H$$$NM+]5!W$,\e(B 5 \e$BIC$[$I8G$^$j$^$9\e(B (\e$B$D$^$j\e(B 5 \e$BIC$[$I2?$bF~NO$G$-$J$/$J$j$^$9\e(B)\e$B!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="def_alias">\e$BJLL>Dj5A\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%-!<$NJLL>$rDj5A$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def alias <em>\e$BJLL>\e(B</em> = <em>\e$B%-!<L>\e(B</em>
+                         </p>
+                         
+                         <p>\e$BJLL>$,4{B8$N%-!<L>$HF1$8$@$C$?>l9g$O!"JLL>$N$[$&$,M%@h$5$l$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="def_subst">\e$BBeMQDj5A\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B$"$k%-!<$rJL$N%-!<$H$7$FBeMQ$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def subst <em>KEY</em> = <em>KEY</em> \e$B$d\e(B <em>\e$B%-!<%7!<%1%s%9\e(B</em> \e$B!D\e(B
+                         </p>
+                         
+                         <p>\e$B%-!<$,F~NO$5$l$k$H!"$^$:$3$NBeMQDj5A$K$h$C$FF~NO$5$l$?%-!<$,CV$-49$($i$l$^$9!#$=$N8e!"\e(B<a href="#key">\e$B%-!<3d$jEv$F$NJQ99\e(B</a>\e$B$K=>$C$FJQ49$5$l$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def subst A = B<br>
+                         &nbsp;key B = C<br>
+                         </p>
+                         
+                         <p>\e$B>e5-$NNc$G$O!"\e(B<kbd>A</kbd> \e$B$rF~NO$9$k$H!"$^$:BeMQDj5A$G\e(B <kbd>B</kbd> \e$B$,2!$5$l$?$3$H$K$J$C$F!"\e(B<kbd>B</kbd> \e$B$,F~NO$5$l$?>l9g$O\e(B <kbd>C</kbd> \e$B$,:G=*E*$K\e(B Windows \e$B$XF~NO$5$l$k$N$G!"7k6I\e(B <kbd>A</kbd> \e$B$r2!$9$H\e(B <kbd>C</kbd> \e$B$,2!$5$l$?$3$H$K$J$j$^$9!#\e(B</p>
+                         
+                         <p>\e$BBeMQDj5A$O!"%-!<%^%C%W$G%-!<$,JQ99$5$l$k$h$jA0$K<B9T$5$l$^$9!#Nc$($P!"\e(B109 \e$B%-!<%\!<%I>e$G\e(B 104 \e$B%-!<%\!<%I$d\e(B Dvorak \e$B$N%(%_%e%l!<%H$r$7$?$$$H$-$K;HMQ$7$^$9!#\e(B</p>
+                         
+                         <p><code>=</code> \e$B$N:81&$O\e(B<a href="#key">\e$B%-!<3d$jEv$F$NJQ99\e(B</a>\e$B$N$b$N$HF1$8$b$N$,;XDj$G$-0UL#$bF1$8$K$J$j$^$9$,!"1&B&$O@hF,$,\e(B <code><em>FUNCTION</em></code> \e$B$G$O$J$/\e(B <code><em>KEY</em></code> \e$B$G$J$1$l$P$J$i$:!"@hF,$N\e(B <code><em>KEY</em></code> \e$B$7$+0UL#$r;}$A$^$;$s!#\e(B</p>
+                         
+                         <p>\e$B0J2<?'!9$JNc!#\e(B</p>
+                         
+                         <p class="sample">
+                         def subst A = C-B<br>
+                         &nbsp;key *B = S-*C<br>
+                         </p>
+                         
+                         <p>\e$B>e5-$NNc$G$O\e(B <kbd>A</kbd> \e$B$rF~NO$9$k$H!":G=*E*$K\e(B <kbd>Shift</kbd> + <kbd>C</kbd> \e$B$,\e(B Windows \e$B$X=PNO$5$l$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def subst A = B C D $Hoge &amp;Toggle(Lock0)<br>
+                         </p>
+                         
+                         <p>\e$B>e5-$NNc$G$O\e(B <kbd>A</kbd> \e$B$rF~NO$9$k$H!"\e(B<kbd>B</kbd> \e$B$,\e(B Windows \e$B$X=PNO$5$l$^$9!#\e(B<code>C D $Hoge &amp;Toggle(Lock0)</code> \e$B$OL5;k$5$l$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         keyseq $COLON = ~S-*Colon<br>
+                         def subst S-*Semicolon = $COLON<br>
+                         </p>
+                         
+                         <p>\e$B>e5-$NNc$G$O\e(B <kbd>Shift</kbd> + <kbd>;</kbd> \e$B$rF~NO$9$k$H!"\e(B<kbd>:</kbd> \e$B$K$J$j!"\e(B<kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>;</kbd> \e$B$rF~NO$9$k$H!"\e(B<kbd>Control</kbd> + <kbd>:</kbd> \e$B$K$J$j$^$9!#\e(B</p>
+                       </div>
+
+                   <dt class="h3"><a name="def_option_KL">\e$B%*%W%7%g%s\e(B (<code>KL-</code>)</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%+%J%m%C%/\e(B <code>KL-</code> \e$B$r@5$7$/@_Dj$9$k$h$&$K$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def option KL- = enable
+                         </p>
+
+                         <p>\e$B$3$N%*%W%7%g%s$r@_Dj$7$J$$>l9g!"FCDj$N>l9g$K%+%J%m%C%/$N>uBV$,@5$7$/<hF@$G$-$^$;$s!#\e(B</p>
+
+                         <p>\e$B$3$N%*%W%7%g%s$r@_Dj$9$l$P!"%+%J%m%C%/$N>uBV$O@5$7$/<hF@$G$-$^$9$,!"\e(BIME \e$B$GJ8;zNs$rF~NOCfL$3NDj$N$^$^JL$N%&%#%s%I%&$X%U%)!<%+%9$r@Z$jBX$(!"85$N%&%#%s%I%&$X%U%)!<%+%9$rLa$7$?;~$K!"\e(BIME \e$B$KF~NOCf$@$C$?J8;zNs$O<:$o$l$^$9!#\e(B</p>
+
+                         <p>109 \e$B%-!<%\!<%I$G\e(B <kbd>Alt</kbd> + <kbd>\e$B$R$i$,$J\e(B</kbd> \e$B$r;HMQ$9$k%+%J%m%C%/$K$O$&$^$/BP1~$G$-$^$;$s$G$7$?!#IaCJ\e(B <kbd>Alt</kbd> + <kbd>\e$B$R$i$,$J\e(B</kbd> \e$B$r;HMQ$7$F$$$k?M$O!"\e(B</p>
+                         
+                         <p class="sample">
+                         keymap Global<br>
+                         &nbsp;key *IC-*IL-A-\e$B$R$i$,$J\e(B = C-S-\e$B$R$i$,$J\e(B<br>
+                         </p>
+
+                         <p class="continue">\e$B$H$$$&@_Dj$r$7$FBe$o$j$K\e(B<kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>\e$B$R$i$,$J\e(B</kbd> \e$B$,;HMQ$5$l$k$h$&$K$7$F$/$@$5$$!#\e(B</p>
+
+                         <p>\e$B$^$?!"\e(BIME \e$B$N5!G=$N!VF|K\8lF~NO$HO"F0$7$F%+%J%m%C%/$r\e(Bon/off\e$B$9$k!W$H$$$&@_Dj$K$7$F$$$k>l9g$b%+%J%m%C%/$N>uBV$r@5$7$/<hF@$H$$$&Js9p$,$"$j$^$9!#$=$N>l9g$O\e(B IME \e$B$r\e(B on/off \e$B$K$9$k%-!<$K!"F1;~$K%+%J%m%C%/$b$7$F$/$l$k$h$&$K@_Dj$9$k$HNI$$$G$7$g$&!#\e(B</p>
+
+                         <p>\e$B;29M\e(B: <a href="http://support.microsoft.com/default.aspx?scid=kb;ja;415068" target="_top">IME2000:\e$B$+$J\e(B/\e$B%m!<%^;zF~NO$r@Z$jBX$($kJ}K!\e(B</a></p>
+
+                         <blockquote>
+                         <ol>
+                           <li><a href="MANUAL-ja.html#menu-l">\e$B%m%0%&%$%s%I%&\e(B</a>\e$B$rI=<($7$F!"!V"">\:Y\e(B(<u>D</u>)\e$B!W$r%A%'%C%/$7$F$*$-$^$9!#\e(B
+                           <li>\e$B!V%a%bD"!W$r\e(B 2 \e$B$D5/F0$7:81&$KJB$Y$^$9!#\e(B
+                           <li>\e$B:8$N%a%bD"$G%+%J$r%m%C%/$7$F2?J8;z$+F~NO$7$F$/$@$5$$!#\e(B<br>
+                               109 \e$B%-!<%\!<%I$J$i!"\e(B<kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>\e$B$R$i$,$J\e(B</kbd>\e$B!#\e(B<br>
+                               104 \e$B%-!<%\!<%I$J$i!"\e(B<kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>CapsLock</kbd>\e$B!#\e(B<br>
+                               (\e$B:8$N%a%bD"$K$OH>3Q%+%?%+%J$,I=<($5$l$^$9\e(B)
+                           <li>\e$B1&$N%a%bD"$K2?J8;z$,F~NO$7$F$/$@$5$$!#\e(B<br>
+                               (\e$B1&$N%a%bD"$K$OH>3Q%+%?%+%J$,I=<($5$l$^$9\e(B)
+                           <li>IME \e$B$r%*%s$K$7$F%m!<%^;zF~NO$K$7$F1&$N%a%bD"$K2?J8;z$+F~NO$7$F$/$@$5$$!#\e(B
+                           <li>\e$B:8$N%a%bD"$K2?J8;z$+F~NO$7$F$/$@$5$$!#\e(B<br>
+                               (\e$B:8$N%a%bD"$K$OH>3Q%+%?%+%J$,I=<($5$l$^$9\e(B)
+                           <li>\e$B$3$3$G!"\e(B<a href="MANUAL-ja.html#menu-l">\e$B%m%0%&%$%s%I%&\e(B</a>\e$B$r8+$k$H\e(B <code>KL-</code> \e$B$,IU$$$F$$$^$;$s!#\e(B
+                         </ol>
+                         <p>\e$B%+%J%m%C%/$N>uBV$O!"\e(BIME \e$B$,%*%s$N;~$H%*%U$N;~$G!"$Y$D$Y$D$K5-21$5$l$F$$$k$h$&$G$9!#\e(B</p>
+                         <p>\e$B$7$+$7!"\e(BIME \e$B$,%*%s$N%&%#%s%I%&$+$i\e(B IME \e$B$,%*%U$N%&%#%s%I%&$X%U%)!<%+%9$,0\$C$?$H$-$K!"%+%J%m%C%/$N>uBV$O@5$7$/H?1G$5$l$J$$$h$&$G$9!#\e(B</p>
+                         <p>\e$B$=$N8e\e(B IME \e$B$r%*%s%*%U$9$k%?%$%_%s%0$G!"%+%J%m%C%/$N>uBV$,@5$7$/H?1G$5$l$^$9!#\e(B</p>
+                         <p>\e$B$=$3$G!"$3$N%*%W%7%g%s$r@_Dj$9$k$H!"%U%)!<%+%9$,JQ2=$7$?;~$K\e(B IME \e$B%*%s%*%U$r<+F0E*$K9T$$!"%+%J%m%C%/>uBV$rH?1G$7$^$9!#\e(B</p>
+                         </blockquote>
+                         
+                       </div>
+                   </dd>
+
+                   <dt class="h3"><a name="def_option_delay_of_oneShotRepeatableModifier">\e$B%*%W%7%g%s\e(B (<code>delay-of !!!</code>)</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><a href="#oneShotRepeatableModifier">\e$B%-!<%j%T!<%HM-\e(B One Shot (<code>!!!</code>)</a> \e$B$N%-!<%j%T!<%H$,;O$^$k$^$G$N;~4V$r;XDj$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         def option delay-of !!! = <em>DELAY</em>
+                         </p>
+
+                         <p>\e$B:G=i$N\e(B <code><em>DELAY</em></code> \e$B2s$N%-!<%j%T!<%H$rL5;k$9$k$h$&$K$7$^$9!#\e(B</p>
+
+                         <p>\e$B%G%U%)%k%H$G$O\e(B <code><em>DELAY</em></code> \e$B$O\e(B 0 \e$B$G$9!#\e(B</p>
+                       </div>
+                   </dd>
+
+                   <dt class="h3"><a name="def_option_ts4mayu">\e$B%*%W%7%g%s\e(B (<code>sts4mayu, cts4mayu</code>)</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%b%G%#%U%!%$%d\e(B <code>T-, TS-</code> \e$B$N%5%]!<%H$rM-8z$K$7$^$9!#JLES\e(B DLL(<code>sts4mayu.dll</code> \e$B$^$?$O\e(B <code>cts4mayu.dll</code>)\e$B$,I,MW$G$9!#%$%s%9%H!<%k%Q%C%1!<%8$K$OF1:-$7$F$*$j$^$;$s$N$G!"\e(B<a href="http://mayu.sourceforge.net/test/ts4mayu/">\e$B$3$3\e(B</a>\e$B$+$i<hF@$7!"\e(B<code>mayu.exe</code> \e$B$HF1$8%G%#%l%/%H%j$KCV$$$F2<$5$$!#\e(B</p>
+                         
+                         <p>Synaptics \e$B$N%?%C%A%Q%C%I$r;HMQ$9$k!#\e(B <code>sts4mayu.dll</code> \e$B$,I,MW$G$9!#\e(B</p>
+                         <p class="sample">
+                         def option sts4mayu = enable
+                         </p>
+                         
+                         <p>Cirque GlidePoint \e$B$N%?%C%A%Q%C%I$r;HMQ$9$k!#\e(B <code>cts4mayu.dll </code>\e$B$,I,MW$G$9!#\e(B</p>
+                         <p class="sample">
+                         def option cts4mayu = enable
+                         </p>
+                       </div>
+                   </dd>
+                 </dl>
+               </div>
+               
+           <dt class="h2"><a name="include">vii. \e$B%U%!%$%kFI$_9~$_\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p class="sample">
+                 include <em>\e$B%U%!%$%kL>\e(B</em>
+                 </p>
+                 
+                 <p>\e$B$H=q$/$3$H$K$h$C$F!"$=$N9T$K\e(B<em>\e$B%U%!%$%kL>\e(B</em> <a href="#string">\e$BJ8;zNs\e(B</a>\e$B$G<($5$l$k%U%!%$%k$rA^F~$9$k$3$H$,$G$-$^$9!#\e(B<em>\e$B%U%!%$%kL>\e(B</em>\e$B$O\e(B<a href="#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>\e$B$+$i8!:w$5$l$^$9!#\e(B</p>
+                 
+                 <dl>
+                   <dt class="h3"><a name="HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%[!<%`%G%#%l%/%H%j$O!"\e(B</p>
+                         
+                         <ul>
+                           <li>\e$B@_Dj\e(B(S)... \e$B$G;XDj$7$?%U%!%$%k$N$"$k%G%#%l%/%H%j\e(B
+                           <li><code>%HOME%</code>
+                           <li><code>%HOMEDRIVE%%HOMEPATH%</code>
+                           <li><code>%USERPROFILE%</code>
+                           <li><code>mayu.exe</code> \e$B$N%+%l%s%H%G%#%l%/%H%j\e(B
+                           <li><code>mayu.exe</code> \e$B$N$"$k>l=j\e(B
+                         </ul>
+                         
+                         <p class="continue">\e$B$N$I$l$+$K$J$j$^$9!#>e$+$i=gHV$K8!:w$5$l$^$9!#\e(B</p>
+                       </div>
+                 </dl>
+               </div>
+               
+           <dt class="h2"><a name="cond">viii. \e$B>r7oJ,4t\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p>\e$B%7%s%\%k$rDj5A$7$F!"$=$N%7%s%\%k$K$h$C$F>r7oJ,4t$5$;$k$3$H$,$G$-$^$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 define <em>\e$B%7%s%\%k\e(B</em><br>
+                 if ( <em>\e$B%7%s%\%k\e(B</em> )<br>
+                 \e$B!A\e(B<br>
+                 else<br>
+                 \e$B!A\e(B<br>
+                 endif
+                 </p>
+                 
+                 \e$BNc$($P<!$N$h$&$K5-=R$9$k$H!"\e(B
+                 
+                 <p class="sample">
+                 if ( SwapAB )<br>
+                 &nbsp;key *A = *B<br>
+                 &nbsp;key *B = *A<br>
+                 endif
+                 </p>
+                 
+                 <p class="continue"><code>SwapAB</code> \e$B$H$$$&%7%s%\%k$,\e(B <code>define</code> \e$B$5$l$F$$$k>l9g$K!"\e(B<kbd>A</kbd> \e$B$H\e(B <kbd>B</kbd> \e$B$rF~$lBX$($^$9!#\e(B</p>
+                 
+                 <p>\e$B!V\e(B<a href="MANUAL-ja.html#menu-s">\e$B@_Dj\e(B(<u>S</u>)...</a>\e$B!W$G\e(B <code>-D\e$B%7%s%\%kL>\e(B</code> \e$B$r=q$/$3$H$G%7%s%\%k$rDj5A$9$k$3$H$,$G$-$^$9!#\e(B</p>
+               </div>
+               
+           <dt class="h2"><a name="function">ix. <code><em>FUNCTION</em></code> \e$B%j%U%!%l%s%9\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <dl class="function">
+                   <dt class="h3"><a name="function_ClipboardCopy"><code>&amp;ClipboardCopy(<em>text</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code><em>text</em></code> <a href="#string">\e$BJ8;zNs\e(B</a>\e$B$r%/%j%C%W%\!<%I$X%3%T!<$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_ClipboardUpcaseDowncaseWord"><code>&amp;ClipboardUpcaseWord</code>, <code>&amp;ClipboardDowncaseWord</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B$=$l$>$l!"%/%j%C%W%\!<%I$NCf?H$NJ8;z$rBgJ8;z2=Kt$O>.J8;z2=$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Default"><code>&amp;Default</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$BF~NO$5$l$?%-!<$r$=$N$^$^\e(B Windows \e$B$XF~NO$7$^$9!#$=$N$?$a!"!VAk;H$$$NM+]5!W$r5/F0$7$F$J$$;~$HF1$8F0:n$,4|BT$G$-$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_DescribeBindings"><code>&amp;DescribeBindings</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code>&amp;DescribeBindings</code> \e$B$O!"8=:_$N%-!<%^%C%W$G$I$N$h$&$J%-!<A`:n$r$9$k$H$I$N$h$&$JF0:n$,5/$3$k$+$rI=<($7$^$9!#$,!"I=<(7A<0$,$$$^$$$AJ,$+$j$K$/$$$N$G$I$&$7$h$&$+;W0FCf!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_DirectSSTP"><code>&amp;DirectSSTP(/<em>name</em>/, <em>protocol</em> <em>[</em>, <em>header ...]</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><a href="http://sakura.mikage.to/directsstp.html" target="_top">Direct</a> <a href="http://sakura.mikage.to/sstp.html" target="_top">SSTP</a> \e$B%W%m%H%3%k$r$7$c$Y$j$^$9!#\e(B</p>
+                         
+                         <p><code><em>/name/</em></code> \e$B$K%^%C%A$9$kL>A0$N%4!<%9%H$X%j%/%(%9%H$r\e(B Direct SSTP \e$B$r;HMQ$7$FAw$j$^$9!#\e(B</p>
+                         
+                         <p><code><em>protocol</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$r>JN,$9$k$H\e(B <code>NOTIFY SSTP/1.1</code> \e$B$K$J$j$^$9!#\e(B</p>
+                         
+                         <p><code><em>header</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$K%+%s%^$G6h@Z$C$F%X%C%@$r=q$-JB$Y$^$9!#\e(B<code>Sender</code> \e$B%X%C%@$r>JN,$9$k$H!VAk;H$$$NM+]5!W$NL>A0$,A^F~$5$l$^$9!#\e(B<code>HWnd</code> \e$B%X%C%@$H\e(B <code>Charset</code> \e$B%X%C%@$O!VAk;H$$$NM+]5!W$,E,@Z$K;XDj$9$k$N$G0z?t$H$7$F;XDj$7$F$O$$$1$^$;$s!#\e(B</p>
+                         
+                         <p>\e$BA*Br;h$J$I$rI=<($7$F$bEz$($r<u$1<h$k$3$H$O$G$-$^$;$s$,!"!VAk;H$$$NM+]5!W$O%4!<%9%H$+$iJV;v$r\e(B 5 \e$BIC4VBT$A$^$9!#\e(B</p>
+                         
+                         <p>\e$BNc\e(B:</p>
+                         
+                         <p class="sample">
+                         &nbsp;key F12 = \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&amp;DirectSSTP(/\e$B%+%l%s\e(B/, \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"SEND SSTP/1.2", \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Script: " \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\1\e$B$3$s$K$A$o\e(B" \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\_w[1000]\\0\\s3\e$B%+%l%s$N$3$H8F$s$@!)\e(B" \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\_w[1000]\\1\e$B!d$_$s$J\e(B" \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\_w[1000]\\0\\s4\\n\\n\e$B!D!D!#\e(B" \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\e" ) \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&amp;DirectSSTP(/\e$BAPMU\e(B/, \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"SEND SSTP/1.2", \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Sender: \e$B$^$f\e(B", \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Script: " \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\_w[1000]\\0\e$B$h$P$l$F$^$9$h$?$@$-$A$5$s!#\e(B" \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\_w[1000]\\1\e$B$-$K$9$k$J!#\e(B" \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\\e" )<br>
+                         </p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_EditNextModifier"><code>&amp;EditNextModifier(<em>\e$B%b%G%#%U%!%$%d\e(B</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B<!$K%f!<%6!<$,%-!<$rF~NO$7$?;~$K!"\e(B<code><em>\e$B%b%G%#%U%!%$%d\e(B</em></code> \e$B$,2!$5$l$F$$$k$3$H$K$7$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key ESC = &amp;EditNextModifier(M-)
+                         </p>
+                       </div>
+                       
+                       <p class="continue">\e$B$H$9$k$H!"\e(B<kbd>Alt</kbd> + <kbd>X</kbd> \e$B$J$I$r\e(B <kbd>ESCAPE</kbd> <kbd>X</kbd> \e$B$J$I$GBeMQ$9$k$3$H$,2DG=$K$J$j$^$9!#\e(B</p>
+                       
+                   <dt class="h3"><a name="function_EmacsEditKillLine"><code>&amp;EmacsEditKillLinePred</code>, <code>&amp;EmacsEditKillLineFunc</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%(%G%#%C%H%3%s%H%m!<%k$G\e(B emacs \e$B$N\e(B kill-line \e$B$N$h$&$J5!G=$r<B8=$7$^$9!#;H$$J}$O\e(B <a href="../emacsedit.mayu"><code>emacsedit.mayu</code></a> \e$B$r;2>H$N$3$H!#\e(B</p>
+                         <p>kill-line \e$B$OHs>o$K$d$d$3$7$$=hM}$r$7$F$$$^$9!#\e(B</p>
+                         
+                         <p>\e$B$^$:!"\e(B<code>C-k</code> \e$B$N4|BT$5$l$kF0:n$O!"\e(B</p>
+                         
+                         <p><strong>(C-k-1)</strong> \e$B%+!<%=%k$,9TKv$K$"$k>l9g!"%/%j%C%W%\!<%I$K2~9T$rDI2C$7$F%F%-%9%H$+$i$O2~9T$r:o=|$9$k!#\e(B</p>
+                         
+                         <p><strong>(C-k-2)</strong> \e$B%+!<%=%k$,9TKv0J30$N>l9g!"9TKv$^$G$r%/%j%C%W%\!<%I$KDI2C$7$F9TKv$^$G$N%F%-%9%H$r:o=|!#\e(B</p>
+                         
+                         <p>\e$B$G$9!#!VAk;H$$$NM+]5!W$G$NDj5A$O!"\e(B<a href="../emacsedit.mayu"><code>emacsedit.mayu</code></a> \e$B$G$O!"\e(B</p>
+                         
+                         <p class="sample">
+                         keyseq $EmacsEdit/kill-line = \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&amp;EmacsEditKillLineFunc S-End C-X &amp;Sync \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&amp;EmacsEditKillLinePred((Delete), (Return Left))
+                         </p>
+                         
+                         <p>\e$B$3$&$J$C$F$k$O$:$G$9!#\e(B<p>
+                         
+                         <p><a href="#function_EmacsEditKillLine"><code>&amp;EmacsEditKillLineFunc</code></a> \e$B$O=i2s$@$1!"%/%j%C%W%\!<%I$NCf?H$r%/%j%"$7$^$9!#=i2s$G$J$$>l9g$O!"%/%j%C%W%\!<%I$NCf?H$r!VAk;H$$$NM+]5!WFbIt$KJ]B8\e(B <strong>(\e$B"(\e(B)</strong> \e$B$7$^$9!#\e(B</p>
+                         
+                         <p>\e$B$=$N8e\e(B <code>S-End C-X</code> \e$B$G9TKv$^$G$rA*Br$7!V@Z$j<h$j!W$^$9!#$3$3$G!"%/%j%C%W%\!<%I$K9TKv$^$G$,%3%T!<$5$l$?$o$1$G$9$,!"%/%j%C%W%\!<%I$NCf?H$K$O4v$D$+2DG=@-$,$"$j$^$9!#\e(B</p>
+                         
+                         <p>EDIT \e$B%3%s%H%m!<%k$N>l9g\e(B</p>
+                         
+                         <p><strong>(EDIT-1)</strong> \e$B%+!<%=%k$,9TKv$K$"$k$H!"!V!W\e(B(\e$B$+$i$C$]\e(B)</p>
+                         <p><strong>(EDIT-2)</strong> \e$B%+!<%=%k$,9TKv0J30$@$H!"!V9TKv$^$G$NJ8;zNs!W\e(B</p>
+                         
+                         <p>\e$B$G$9!#\e(BIE \e$B$NCf$N%(%G%#%C%H%\%C%/%9$N>l9g!"\e(B</p>
+                         
+                         <p><strong>(IE-1)</strong> \e$B%+!<%=%k$,9TKv$K$"$k$H!"!V2~9T!W\e(B</p>
+                         <p><strong>(IE-2)</strong> \e$B%+!<%=%k$,9TKv0J30$@$H!"!V9TKv$^$G$NJ8;zNs!\2~9T!W\e(B</p>
+                         
+                         <p>\e$B$G$9!#\e(B</p>
+                         
+                         <p><a href="#function_EmacsEditKillLine"><code>&amp;EmacsEditKillLinePred</code></a> \e$B$O!"%/%j%C%W%\!<%I$NCf?H$rD4$Y$F!"\e(B</p>
+                         
+                         <p><strong>(EDIT-1)</strong> \e$B$N>l9g$O!"\e(B<strong>\e$B"(\e(B</strong>\e$B$GJ]B8$7$?%G!<%?$K!V2~9T!W$rDI2C$7$F%/%j%C%W%\!<%I$X=q$-La$7$^$9!#$=$N8e!"Bh0l0z?t!"$D$^$j\e(B <code>Delete</code> \e$B$r<B9T$7$^$9!#\e(B</p>
+                         
+                         <p><strong>(EDIT-2)</strong> \e$B$N>l9g$O!"\e(B<strong>\e$B"(\e(B</strong>\e$B$GJ]B8$7$?%G!<%?$K!V9TKv$^$G$NJ8;zNs!W$rDI2C$7$F%/%j%C%W%\!<%I$X=q$-La$7$^$9!#\e(B</p>
+                         
+                         <p><strong>(IE-1)</strong> \e$B$N>l9g$O!"\e(B<strong>\e$B"(\e(B</strong>\e$B$GJ]B8$7$?%G!<%?$K!V2~9T!W$rDI2C$7$F%/%j%C%W%\!<%I$X=q$-La$7$^$9!#\e(B</p>
+                         
+                         <p><strong>(IE-2)</strong> \e$B$N>l9g$O!"\e(B<strong>\e$B"(\e(B</strong>\e$B$GJ]B8$7$?%G!<%?$K!V9TKv$^$G$NJ8;zNs\e(B(\e$B2~9T$O=|$/\e(B)\e$B!W$rDI2C$7$F%/%j%C%W%\!<%I$X=q$-La$7$^$9!#$=$N8e!"BhFs0z?t!"$D$^$j\e(B <code>Return Left</code> \e$B$r<B9T$7$^$9!#\e(B</p>
+                         
+                         <p>\e$B$3$N$h$&$KF0:n$9$k$3$H$G\e(B <strong>(EDIT-1)</strong> \e$B$H\e(B <strong>(IE-1)</strong> \e$B$O\e(B <strong>(C-k-1)</strong> \e$BAjEv!"\e(B<strong>(EDIT-2)</strong>  \e$B$H\e(B <strong>(IE-2)</strong> \e$B$O\e(B <strong>(C-k-2)</strong> \e$BAjEv$K$J$j$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_HelpMessage"><code>&amp;HelpMessage(<em>title</em>, <em>message</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>IE5.0 \e$B0J9_$,F~$C$F$$$l$P!"%?%9%/%H%l%$IU6a$K%a%C%;!<%8$rI=<($7$^$9!#\e(B<code><em>title</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$H\e(B <code><em>message</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$r>JN,$9$k$H!"I=<($5$l$F$$$k%a%C%;!<%8$r>C$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_HelpVariable"><code>&amp;HelpVariable(<em>title</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>IE5.0 \e$B$,F~$C$F$$$l$P!"%?%9%/%H%l%$IU6a$K\e(B <a href="#function_Variable"><code>&amp;Variable</code></a> \e$B$G@_Dj$5$l$?CM$,\e(B <code><em>title</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$H6&$K$rI=<($5$l$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Ignore"><code>&amp;Ignore</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B$J$K$b5/$3$j$^$;$s!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_InvestigateCommand"><code>&amp;InvestigateCommand</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$XAw$i$l$F$/$k\e(B <code>WM_COMMAND</code> \e$B$H\e(B <code>WM_SYSCOMMAND</code> \e$B$rD4$Y%m%0$K=PNO$7$^$9!#%H%0%k$K$J$C$F$$$^$9$N$G!"D4::$,=*$o$C$?$i$b$&0lEY$3$N\e(B <code><em>FUNCTION</em></code> \e$B$r<B9T$7$F$/$@$5$$!#$5$b$J$$$H%"%W%j%1!<%7%g%s$N<B9TB.EY$,CY$/$J$k2DG=@-$,$"$j$^$9!#%m%0$N=PNO$O\e(B <a href="#function_PostMessage"><code>&amp;PostMessage</code></a> \e$B$G;HMQ$9$k$3$H$,=PMh$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Keymap"><code>&amp;Keymap(<em>\e$B%-!<%^%C%WL>\e(B</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$BJL$N%-!<%^%C%W$N%-!<$r;XDj$7$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         keymap sub : Global<br>
+                         &nbsp;key     C-A = &amp;WindowMinimize<br>
+                         window EditControl /:Edit$/ : Global<br>
+                         &nbsp;key     C-A = &amp;Keymap(sub)
+                         </p>
+                         
+                         <p class="continue">\e$B$H$$$&$h$&$KMxMQ$7$^$9!#$3$N>l9g!"%(%G%#%C%H%3%s%H%m!<%k$G\e(B <kbd>Control</kbd> + <kbd>A</kbd> \e$B$rF~NO$9$k$H!":G>.2=$5$l$^$9!#$"$^$j<BMQE*$J5!G=$O$J$$$+$b$7$l$^$;$s!#%k!<%W$7$J$$$h$&$K5$$r$D$1$FMxMQ$7$F$/$@$5$$!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_KeymapParent"><code>&amp;KeymapParent</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><a href="#parentKeymap">\e$B?F%-!<%^%C%W\e(B</a>\e$B;2>H!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_KeymapPrevPrefix"><code>&amp;KeymapPrevPrefix</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B8=:_$N%-!<%^%C%W\e(B (\e$B2>$K\e(B <code>CURRENT</code> \e$B$H$$$&L>A0$H$9$k\e(B) \e$B$,FsCJ3,%-!<%^%C%W$N>l9g!"\e(B<a href="#function_Prefix"><code>&amp;Prefix</code></a><code>(CURRENT)</code> \e$B$r<B9T$7$?%-!<%^%C%W$GDj5A$5$l$F$$$k%-!<$r;XDj$7$^$9!#0z?t$,L5$$$H\e(B 1 \e$BCJ3,A0$N%-!<%^%C%W$K$J$j$^$9$,!"0z?t$K?t;z$r=q$/$H$=$NCJ3,?tA0$N%-!<%^%C%W$K$J$j$^$9!#$?$H$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         keymap E<br>
+                         &nbsp;key A = &amp;KeymapPrevPrefix(2)<br>
+                         keymap D<br>
+                         &nbsp;key X = &amp;Prefix(E)<br>
+                         &nbsp;key A = D<br>
+                         keymap C<br>
+                         &nbsp;key X = &amp;Prefix(D)<br>
+                         &nbsp;key A = C<br>
+                         &nbsp;key Y = &amp;Prefix(E)<br>
+                         keymap B<br>
+                         &nbsp;key X = &amp;Prefix(C)<br>
+                         &nbsp;key A = B<br>
+                         keymap Global<br>
+                         &nbsp;key X = &amp;Prefix(B)<br>
+                         &nbsp;key A = A
+                         </p>
+                         
+                         <p>\e$B$3$3$G\e(B <kbd>X</kbd> <kbd>X</kbd> <kbd>X</kbd> <kbd>X</kbd> <kbd>A</kbd> \e$B$HF~NO$9$k$H\e(B <kbd>C</kbd> \e$B$,!"\e(B<kbd>X</kbd> <kbd>X</kbd> <kbd>Y</kbd> <kbd>A</kbd> \e$B$HF~NO$9$k$H\e(B <kbd>B</kbd> \e$B$,F~NO$5$l$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_KeymapWindow"><code>&amp;KeymapWindow</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B8=:_$N%&%#%s%I%&$KDj5A$5$l$?%-!<%^%C%W$N%-!<$rF~NO$7$^$9!#%W%l%U%#%C%/%9%-!<$NF~NOCf$K;HMQ$9$k$HJXMx$G$9!#Nc$($P\e(B</p>
+                         
+                         <p class="sample">
+                         keymap2 NotepadC-X<br>
+                         &nbsp;key     A = &amp;KeymapWindow<br>
+                         window Notepad /:Notepad:Edit$/ : Global<br>
+                         &nbsp;key     C-X = &amp;Prefix(NotepadC-X)<br>
+                         &nbsp;key     A = T E S T
+                         </p>
+                         
+                         <p class="continue">\e$B$3$N>l9g!"%a%bD"$G\e(B <kbd>Control</kbd> + <kbd>X</kbd> \e$B$r2!$7$?8e$K\e(B <kbd>A</kbd> \e$B$rF~NO$9$k$H!"\e(B<code>&amp;KeymapWindow</code> \e$B$O\e(B <code>Nodepad</code> \e$B%-!<%^%C%W$KDj5A$5$l$F$$$k%-!<$rF~NO$7$h$&$H$7$^$9!#=>$C$F!"\e(B<code>TEST</code> \e$B$,F~NO$5$l$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_LoadSetting"><code>&amp;LoadSetting(<em>\e$B@_DjL>\e(B</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B@_Dj%U%!%$%k$r:FFI$_9~$_$7$^$9!#\e(B<code><em>\e$B@_DjL>\e(B</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$O!V@_Dj\e(B(I)...\e$B!W$G@_Dj$7$?!VL>A0!W$G!":FFI$_9~$_$9$k@_Dj$r;XDj$7$^$9!#\e(B<code><em>\e$B@_DjL>\e(B</em></code>\e$B$r>JN,$9$k$H8=:_$N@_Dj$r:FFI$_9~$_$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_MayuDialog"><code>&amp;MayuDialog(<em>dialog</em>, <em>show_command</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B!VAk;H$$$NM+]5!W$N%@%$%"%m%0%\%C%/%9$rI=<($7$?$j1#$7$?$j$7$^$9!#\e(B<code><em>dialog</em></code> \e$B$K$O\e(B <code>Investigate</code> \e$B$H\e(B <code>Log</code> \e$B$,;XDj$G$-$^$9!#$=$l$>$l!VD4::!W%@%$%"%m%0$H!V%m%0!W%@%$%"%m%0$G$9!#\e(B<code><em>show_command</em></code> \e$B$K$O!"\e(B<code>HIDE</code>, <code>SHOW</code>, <code>SHOWNA</code> \e$B$J$I$,;XDj$G$-$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_MouseHook"><code>&amp;MouseHook(<em>type</em>, <em>parameter</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%^%&%9%$%Y%s%H$r%U%C%/$7\e(B <code><em>type</em></code> \e$B$G;XDj$5$l$k%"%/%7%g%s$KJQ49$7$^$9!#\e(B <code><em>parameter</em></code> \e$B$O@0?tCM$G\e(B <code><em>type</em></code> \e$BKh$K0UL#$,0[$J$j$^$9!#;XDj$G$-$k\e(B <code><em>type</em></code> \e$B$O0J2<$NDL$j$G$9!#\e(B</p>
+                         <ul>
+                           <li><code>None</code> [\e$B=i4|CM\e(B]\e$BJQ49$7$^$;$s!#\e(B <code><em>parameter</em></code> \e$B$OL5;k$5$l$^$9!#B>$N\e(B <code><em>type</em></code> \e$B$+$i85$KLa$9>l9g$K$O$3$NCM$r;XDj$7$^$9!#\e(B
+                           <li><code>Wheel</code> \e$B%^%&%9$N?bD>J}8~$N0\F0$r%[%$!<%k$N2sE>$KJQ49$7$^$9!#$3$N4V%^%&%9%+!<%=%k$OF0$-$^$;$s!#\e(B <code><em>parameter</em></code> \e$B$OJQ49$N:]$NG\N($G!"@5$HIi$G$O5U2sE>$H$J$j$^$9!#\e(B
+                           <li><code>WindowMove</code> \e$B%^%&%9$N0\F0$r%&%#%s%I%&$N0\F0$KJQ49$7$^$9!#$3$N4V%^%&%9%+!<%=%k$OF0$-$^$9!#\e(B <code><em>parameter</em></code> \e$B$O0\F0$9$k%&%#%s%I%&$N;XDj$G!"\e(B <code>1</code> \e$B$O%"%/%F%#%V%&%#%s%I%&!"\e(B <code>2</code> \e$B$O%^%&%9%+!<%=%k0LCV$N%&%#%s%I%&$r0UL#$7$^$9!#$^$?Id9f$rIi$K$9$k$HBP1~$9$k\e(B MDI \e$B;R%&%#%s%I%&$r0\F0$7$^$9!#\e(B
+                         </ul>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_MouseMove"><code>&amp;MouseMove(<em>dx</em>, <em>dy</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%^%&%9%+!<%=%k$r?eJ?$K\e(B <code><em>dx</em></code>\e$B!"?bD>$K\e(B <code><em>dy</em></code> \e$B0\F0$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_MouseWheel"><code>&amp;MouseWheel(<em>delta</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%[%$!<%k$r2s$7$^$9!#\e(B<code><em>delta</em></code> \e$B$r\e(B <code>-120</code> \e$B$K$9$k$H%[%$!<%k$r<jA0$K\e(B 1 \e$BC10L$^$o$7$?$3$H$K$J$j$^$9!#5U$K\e(B <code>120</code> \e$B$K$9$k$H%[%$!<%k$r1|$X\e(B 1 \e$BC10L$^$o$7$?$3$H$K$J$j$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_OtherWindowClass"><code>&amp;OtherWindowClass</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><a href="#matchManyClasses"><code>window</code> \e$B$KJ#?t3:Ev$9$k>l9g\e(B</a>\e$B;2>H!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_PlugIn"><code>&amp;PlugIn(<em>DLLNAME</em>, <em>FUNCNAME</em>, <em>FUNCPARAM</em>, <em>runAsThread</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%W%i%0%$%s$r<B9T$7$^$9!#\e(B<code>mayu.exe</code> \e$B$N$"$k%G%#%l%/%H%j$NCf$N\e(B <code>Plugins</code> \e$B$H$$$&%G%#%l%/%H%j$K%W%i%0%$%s\e(B DLL \e$B$rCV$$$F$*$/$H$=$N%W%i%0%$%s$NCf$N4X?t$r!VAk;H$$$NM+]5!W$+$iD>@\8F$V$3$H$,=PMh$^$9!#\e(B</p>
+
+                         <p><code><em>DLLNAME</em></code> \e$B$O%W%i%0%$%s\e(B DLL \e$BL>$G$9!#\e(B<code>Plugins\<em>DLLNAME</em>.dll</code> \e$B$,;HMQ$5$l$^$9!#\e(B</p>
+
+                         <p><code><em>FUNCNAME</em></code> \e$B$O\e(B DLL \e$BCf$N4X?tL>$G$9!#\e(BDLL \e$B$O!"0J2<$N4X?t$N$&$A$N$I$l$+<BAu$7$F$$$J$1$l$P$J$j$^$;$s!#$3$N0z?t$O>JN,$9$k$3$H$,$G$-$^$9!#>JN,$9$k$H6uJ8;zNs$K$J$j$^$9!#\e(B</p>
+
+                         <p class="sample">
+                         void WINAPI mayu<em>FUNCNAME</em>W(const wchar_t *<em>FUNCPARAM</em>);<br>
+                         void WINAPI mayu<em>FUNCNAME</em>A(const char *<em>FUNCPARAM</em>);<br>
+                         void WINAPI mayu<em>FUNCNAME</em>(const char *<em>FUNCPARAM</em>);<br>
+                         void WINAPI <em>FUNCNAME</em>(const char *<em>FUNCPARAM</em>);
+                         </p>
+
+                         <p><code><em>FUNCPARAM</em></code> \e$B$O\e(B DLL \e$B$N4X?t$r8F$S=P$9$H$-$KEO$5$l$k0z?t$G$9!#>JN,$9$k$H6uJ8;zNs\e(B (<code>NULL</code> \e$B$G$O$J$$\e(B) \e$B$K$J$j$^$9!#\e(B</p>
+
+                         <p><code><em>runAsThread</em></code> \e$B$K\e(B <code>true</code> \e$B$r;XDj$9$k$H;XDj$N4X?t$r%9%l%C%I$NCf$G<B9T$7$^$9!#>JN,$9$k$H\e(B <code>false</code> \e$B$,;XDj$5$l$?$3$H$K$J$j$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_PostMessage"><code>&amp;PostMessage(<em>window</em>, <em>message</em>, <em>wParam</em>, <em>lParam</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$X%a%C%;!<%8$rAw$k$3$H$,$G$-$^$9!#9bEY$J5!G=$J$N$G40A4$KM}2r$7$F$+$iMxMQ$7$F$/$@$5$$!#\e(B</p>
+                         
+                         <p class="sample">
+                         keyseq $WM_CUT = &amp;PostMessage(ToItself, 0x0300, 0, 0)<br>
+                         window EditControl /:Edit$/ : Global<br>
+                         &nbsp;key C-W = $WM_CUT
+                         </p>
+                         
+                         <p class="continue">\e$B$H=q$/$H!"0lIt$N%&%#%s%I%&$G\e(B <kbd>Control</kbd> + <kbd>W</kbd> \e$B$G%+%C%H$G$-$k$h$&$K$J$j$^$9!#\e(B</p>
+                         
+                         <p><code><em>window</em></code> \e$B$K$O!"%a%C%;!<%8$rAw$k@h$N%&%#%s%I%&$r;XDj$7$^$9!#0J2<$N<oN`$,$"$j$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li><code>ToItself</code> \e$B$O$=$N%&%#%s%I%&<+?H$X!#\e(B
+                           <li><code>ToMainWindow</code> \e$B$O:G$b?F$N%&%#%s%I%&$X!#\e(B
+                           <li><code>ToOverlappedWindow</code> \e$B$O;R$G$J$$:G=i$N%&%#%s%I%&$X!#\e(B
+                           <li><code>ToParentWindow</code> \e$B$O?F%&%#%s%I%&$X!#\e(B
+                           <li><code><em>\e$B@5$N?t\e(B</em></code> \e$B$O\e(B <code>1</code>:\e$B?F%&%#%s%I%&!"\e(B<code>2</code>:\e$B?F$N?F!"\e(B<code>3</code>:\e$B?F$N?F$N?F!D\e(B
+                         </ul>
+                         
+                         <p>\e$B$I$N$h$&$J%a%C%;!<%8$rAw$l$P$h$$$+$O\e(B Spy++ \e$B$J$I$GD4$Y$i$l$^$9$,!"\e(B<code>WM_COMMAND</code> \e$B$H\e(B <code>WM_SYSCOMMAND</code> \e$B$K$D$$$F$O\e(B <a href="#function_InvestigateCommand"><code>&amp;InvestigateCommand</code></a> \e$B$GD4$Y$k$3$H$b$G$-$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Prefix"><code>&amp;Prefix(<em>\e$B%-!<%^%C%WL>\e(B</em>, <em>ignore_modifiers</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%W%l%U%#%C%/%9%-!<$r;XDj$7$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         keymap2 NotepadC-X<br>
+                         &nbsp;key     C-C = &amp;WindowClose<br>
+                         window Notepad /:Notepad:Edit$/ : Global<br>
+                         &nbsp;key     C-X = &amp;Prefix(NotepadC-X)
+                         </p>
+                         
+                         <p class="continue">\e$B$H$$$&$h$&$K5-=R$7$F$*$/$H!"%a%bD"$G\e(B <kbd>Control</kbd> + <kbd>X</kbd> <kbd>Control</kbd> + <kbd>C</kbd> \e$B$HB3$1$FF~NO$9$k$H%a%bD"$r=*N;$9$k$3$H$,$G$-$^$9!#\e(B</p>
+                         
+                         <p><code><em>ignore_modifiers</em></code> \e$B$O>JN,2DG=$J0z?t$G\e(B <code>true</code> \e$B$+\e(B <code>false</code> \e$B$r;XDj$7$^$9!#>JN,$9$k$H\e(B <code>true</code> \e$B$,;XDj$5$l$?$H$_$J$5$l$^$9!#\e(B<code>true</code> \e$B$,;XDj$5$l$?>l9g!"\e(B<code><em>\e$B%-!<%^%C%WL>\e(B</em></code> \e$B$G;X<($5$l$k%-!<%^%C%W$O\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;mod !shift !alt !control !windows \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!mod0 !mod1 !mod2 !mod3 !mod4 \<br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!mod5 !mod6 !mod7 !mod8 !mod9
+                         </p>
+                         
+                         <p class="continue">\e$B$,;XDj$5$l$?$b$N$H$7$F07$o$l$^$9!#$D$^$j!"A4$F$N%b%G%#%U%!%$%d$,\e(B<a href="#trueModifier">\e$B??$N%b%G%#%U%!%$%d\e(B</a>\e$B$H$7$F07$o$l$k$h$&$K$J$j$^$9!#\e(B</p>
+
+                         <p><a href="#keymap2"><code>keymap2</code></a> \e$B$rMxMQ$7$F$$$k$H$-$K$O!"%G%U%)%k%H%-!<$,\e(B <a href="#function_Undefined"><code>&amp;Undefined</code></a> \e$B$K$J$C$F$$$k$N$G!"%b%G%#%U%!%$%d$rF~NO$7$?;~$K$b%Y%k$,LD$k$O$:$G$9$,!"$3$N$h$&$K\e(B <code>true</code> \e$B$r;XDj$7$F$*$1$PLD$i$J$/$J$j$^$9!#\e(B(<a href="#mod"><code>mod</code></a> \e$B$r;2>H\e(B)</p>
+
+                         <p><code>false</code> \e$B$r;XDj$9$l$P!"\e(B2 \e$B%9%H%m!<%/L\$K%b%G%#%U%!%$%d%-!<$=$N$b$N$r;HMQ$9$k$3$H$,$G$-$k2DG=@-$,$"$j$^$9$,!"DL>o$O$=$N$h$&$J;HMQJ}K!$O$7$J$$$H;W$o$l$^$9!#$^$?!"$5$^$6$^$JLdBj$K$h$j\e(B <code>false</code> \e$B$N;XDj$K$O%P%0$,$"$j$^$9$N$G;HMQ$O%*%9%9%a$7$^$;$s!#\e(B</p>
+                         
+                         <blockquote>
+                         <ol>
+                           <li>\e$B%-!<$N2!$9!&N%$9!"$,=gHV$KMh$J$$>l9g\e(B
+                               <div>
+                                 <p>\e$BNc$($P\e(B <kbd>Control</kbd> + <kbd>X</kbd> <kbd>Control</kbd> + <kbd>L</kbd> \e$B$H$$$&F~NO$r%f!<%6!<$,$7$?>l9g!"\e(B<code>D-C-X U-C-X D-C-L U-C-L</code> \e$B$H$$$&=g=x$GF~NO$5$l$k$N$,@5$7$$$N$G$9$,!"\e(B<kbd>X</kbd> \e$B$O:8<j!"\e(B<kbd>L</kbd> \e$B$O1&<j$GF~NO$9$k$?$a!"\e(B <code>D-C-X D-C-L U-C-X U-C-L</code> \e$B$H$$$&=g=x$GF~NO$5$l$F$7$^$&$3$H$,$7$P$7$P$"$j$^$9!#\e(B</p>
+                                 
+                                 <p>\e$B$G$9$+$i!"8=:_$N<BAu$G$O\e(B <a href="#function_Prefix"><code>&amp;Prefix</code></a> \e$B$O%-!<%@%&%s\e(B (<code>D-</code>) \e$BItJ,$G$7$+@5$7$/F0:n$7$J$$$h$&$K$J$C$F$$$^$9!#F~NO$5$l$k%-!<$N=g=x$,F~$lBX$o$k$?$a!"\e(B<code>U-</code> \e$BItJ,$G\e(B <a href="#function_Prefix"><code>&amp;Prefix</code></a> \e$B$,F0:n$7$F$7$^$&$H$*$+$7$J$3$H$K$J$k$+$i$G$9!#\e(B(\e$B8=:_$OCfESH>C<$KF0:n$7$F$$$k$N$G!"%P%0$+$b$7$l$^$;$s!#MWD4::\e(B)</p>
+                               </div>
+
+                           <li>\e$B%-!<%j%T!<%H\e(B
+                               <div>
+                                 <p>\e$B%-!<%j%T!<%H$O!"%-!<%@%&%s\e(B (<code>D-</code>) \e$B$,$?$/$5$sF~NO$5$l$?$"$H$K!"%-!<%"%C%W\e(B (<code>U-</code>) \e$B$,0lEY$@$1F~NO$5$l$^$9!#$3$N>l9g$K\e(B <a href="#function_Prefix"><code>&amp;Prefix</code></a> \e$B$,$I$N$h$&$KF0:n$9$Y$-$+$O<+L@$G$O$"$j$^$;$s!#\e(B</p>
+                               </div>
+                               
+                           <li>\e$B%b%G%#%U%!%$%d%-!<$N%-!<%^%C%W\e(B
+                               <div>
+                                 <p><code>false</code> \e$B$r;XDj$7$?;~$K\e(B <kbd>Control</kbd> + <kbd>X</kbd> <kbd>F</kbd> \e$B$HF~NO$7$?$H$7$^$9!#\e(B<code>D-C-Control D-C-X U-C-X U-Control D-F U-F</code> \e$B$3$N$h$&$J=g=x$G%-!<$,F~NO$5$l$^$9$,!"\e(B<code>U-Control</code> \e$B$O$I$N%-!<%^%C%W$G2r<a$5$l$k$Y$-$G$7$g$&$+!)\e(B</p>
+
+                                 <p>\e$B8=:_$O!"\e(B<a href="#function_Prefix"><code>&amp;Prefix</code></a> \e$B@h$N%-!<%^%C%W$G2r<a$5$l$F$$$^$9$,!"%b%G%#%U%!%$%d$r??$N%b%G%#%U%!%$%d$X<+F0E*$KJQ49$9$k$?$a!"\e(B<code>U-Control</code> \e$B$O2?$N5!G=$b$b$?$J$$$N$G!"$&$^$/F0:n$7$F$$$k$h$&$K8+$($^$9!#$G$9$,!"K\Mh$J$i$P85$N%-!<%^%C%W$G2r<a$5$l$k$Y$-$J$N$G$3$l$O%P%0$J$N$G$9$,!"=$@5$9$kM=Dj$O$"$j$^$;$s!#\e(B</p>
+                               </div>
+                         </ol>
+                         </blockquote>
+
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Recenter"><code>&amp;Recenter</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%(%G%#%C%H%3%s%H%m!<%k$+%j%C%A%(%G%#%C%H%3%s%H%m!<%k$G$N$_F0:n$7!"%+%l%C%H$N0LCV$r=DJ}8~$NCf1{$K0\F0$5$;$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Repeat"><code>&amp;Repeat(<em>\e$B%-!<%7!<%1%s%9\e(B</em>, <em>\e$B:GBg2s?t\e(B</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><a href="#function_Variable"><code>&amp;Variable</code></a> \e$B$G@_Dj$7$?2s?t$@$1\e(B <code><em>\e$B%-!<%7!<%1%s%9\e(B</em></code> \e$B$r<B9T$7$^$9!#$?$@$7!"<B9T$7$9$.$k$H4m81$J$N$G\e(B<em>\e$B:GBg2s?t\e(B</em>\e$B$r;XDj$G$-$^$9!#\e(B<em>\e$B:GBg2s?t\e(B</em>\e$B$O>JN,$9$k$3$H$,$G$-!"$=$N>l9g\e(B 10 \e$B2s$,:GBg$K$J$j$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key A = &amp;Variable(0, 10) &amp;Repeat((X))
+                         </p>
+                         
+                         <p>\e$B>e$NNc$G$O!"\e(B<kbd>A</kbd> \e$B$r2!$9$H!"\e(B<kbd>X</kbd> \e$B$,\e(B 10 \e$B2sF~NO$5$l$^$9\e(B</p>
+                         
+                       </div>
+                       
+                   <dt class="h3"><a name="function_SetImeStatus"><code>&amp;SetImeStatus(<em>status</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>IME \e$B$N\e(B ON/OFF \e$B$r@Z$jBX$($^$9!#\e(B<code><em>status</em></code> \e$B$O\e(B <code>on</code>, <code>off</code>, <code>toggle</code> \e$B$N$$$:$l$+$G!">JN,;~$O\e(B <code>toggle</code> \e$B$H$7$F07$o$l$^$9!#\e(B</p>
+                         <p>MS-IME2002/2003 \e$B$H0lIt$N%"%W%j%1!<%7%g%s\e(B (\e$BNc$($P\e(B MS Word2002/2003) \e$B$NAH$_9g$o$;$G$O!V>\:Y$J%F%-%9%H%5!<%S%9!W$rL58z$K$7$J$$8B$j5!G=$7$^$;$s!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_SetImeString"><code>&amp;SetImeString(<em>text</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>IME \e$B$r7PM3$7$F\e(B <code><em>text</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$rF~NO$7$^$9!#\e(B</p>
+                         <p>Windows2000/XP \e$B$N$_$G5!G=$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_ShellExecute"><code>&amp;ShellExecute(<em>operation</em>, <em>file</em>, <em>parameters</em>, <em>directory</em>, <em>show_command</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%W%m%0%i%`$r<B9T$7$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li><code><em>operation</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$K$O%U%!%$%k$KBP$7$F$I$N$h$&$JA`:n$r$9$k$+$r;X<($7!"DL>o\e(B <code>open</code> \e$B$r;XDj$7$^$9!#\e(B
+                           <li><code><em>file</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$K$O%U%!%$%k$+<B9T%U%!%$%k$r=q$-$^$9!#\e(B
+                           <li><code><em>parameters</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$K$O\e(B <code><em>file</em></code> \e$B$K<B9T%U%!%$%k$r=q$$$?$H$-$K%*%W%7%g%s$r5-=R$7$^$9!#\e(B
+                           <li><code><em>directory</em></code> <a href="#string">\e$BJ8;zNs\e(B</a> \e$B$O:n6H%G%#%l%/%H%j$r;XDj$7$^$9!#\e(B
+                           <li><code><em>show_command</em></code> \e$B$K$O\e(B <code>ShowNormal</code> \e$B$r;XDj$7$^$9!#\e(B
+                         </ul>
+                         
+                         <p>\e$B%3%s%H%m!<%k%Q%M%k$r3+$/Nc\e(B:</p>
+                         
+                         <p class="sample">
+                         &nbsp;key M-B = &amp;ShellExecute("open", "C:\\WINDOWS\\system32\\Control.exe",,, ShowNormal)
+                         </p>
+                         
+                         <p>\e$B%7%9%F%`$N%W%m%Q%F%#$r3+$/Nc\e(B:</p>
+                         
+                         <p class="sample">
+                         &nbsp;key M-C = &amp;ShellExecute("open", "C:/WINDOWS/system32/Control.exe", "sysdm.cpl",, ShowNormal)
+                         </p>
+                         
+                         <p>\e$B%$%s%?!<%M%C%H%(%/%9%W%m!<%i$G!VAk;H$$$NM+]5!W$N%[!<%`%Z!<%8$r3+$/Nc\e(B:</p>
+                         
+                         <p class="sample">
+                         &nbsp;key M-I = &amp;ShellExecute("open", "C:\\Program Files\\Internet Explorer\\iexplore.exe\", "http://mayu.sourceforge.net",, ShowNormal)<br>
+                         &nbsp;key M-H = &amp;ShellExecute("open", "http://mayu.sourceforge.net",,, ShowNormal)
+                         </p>
+                         
+                         <p><code>flourish.mid</code> \e$B$r1iAU$9$kNc\e(B:</p>
+                         
+                         <p class="sample">
+                         &nbsp;key M-R = &amp;ShellExecute("play", "C:\\WINDOWS\\Media\\flourish.mid",,, ShowNormal)
+                         </p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Sync"><code>&amp;Sync</code></a>
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B4pK\E*$K!"\e(BWindows \e$B$X$N%-!<F~NO$H\e(B <code><em>FUNCTION</em></code> \e$B$OHsF14|$K<B9T$5$l$^$9!#$D$^$j%-!<F~NO$H\e(B <code><em>FUNCTION</em></code> \e$B$N<B9T=g=x$OITL@$G$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key C-A = A &amp;WindowMinimize
+                         </p>
+                         
+                         <p class="continue">\e$B$3$N$h$&$K5-=R$7$F\e(B <kbd>Control</kbd> + <kbd>A</kbd> \e$B$rF~NO$9$k$H!"\e(BWindows \e$B$X\e(B <code>A</code> \e$B$,F~NO$5$l$k$N$,@h$+!"\e(B<code>&amp;WindowMinimize</code> \e$B$,<B9T$5$l$k$N$,@h$+$OITL@$G$9!#$=$3$G!"0J2<$N$h$&$K5-=R$9$l$P$A$c$s$H=g=x$,<i$i$l$k$3$H$rJ]>Z$G$-$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key C-A = A &amp;Sync &amp;WindowMinimize
+                         </p>
+                         
+                         <p>\e$B$^$?!"\e(B<code><em>FUNCTION</em></code> \e$B$K$O\e(B<a href="#modifier">\e$B%b%G%#%U%!%$%d\e(B</a>\e$B$r;XDj$9$k$3$H$,2DG=$G$9$,!"\e(B<code><em>FUNCTION</em></code> \e$B$H%b%G%#%U%!%$%d%-!<F~NO$,HsF14|$K<B9T$5$l$k$?$aDL>o$O0UL#$,$"$j$^$;$s!#$7$+$7!"\e(B<code>&amp;Sync</code> \e$B$r;H$($P%b%G%#%U%!%$%d%-!<$N;XDj$K0UL#$,=P$F$-$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         window Explorer /Explorer\.exe/ : Global<br>
+                         &nbsp;key C-S-Z = &amp;Sync &amp;WindowMaximize # \e$B%&%#%s%I%&$N:GBg2=\e(B<br>
+                         &nbsp;key C-A-Z = C-&amp;Sync *&amp;WindowMaximize # \e$B%&%#%s%I%&$NA42hLL2=\e(B
+                         </p>
+                         
+                         <p>\e$BA0<T$N;XDj$G$O!"%&%#%s%I%&$r:GBg2=$9$k$H$-$K\e(B <kbd>Control</kbd> \e$B$H\e(B <kbd>Shift</kbd> \e$B$,F~NO$5$l$F$$$J$$$h$&$K$7$F$$$^$9!#8e<T$G$O!"\e(B<kbd>Control</kbd> \e$B$OF~NO$5$l$k$,!"\e(B<kbd>Alt</kbd> \e$B$OF~NO$5$l$F$$$J$$$h$&$K$7$^$9!#\e(B</p>
+                         
+                         <p><a href="#def_sync"><code>def sync</code></a> \e$B;2>H!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Toggle"><code>&amp;Toggle(Lock<em>N</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%m%C%/%-!<$r%H%0%k$7$^$9!#\e(B<code>&amp;Toggle(Lock0)</code>\e$B!A\e(B<code>&amp;Toggle(Lock9)</code> \e$B$,MxMQ$G$-$^$9!#0z?t$N:G8e$K\e(B <code>on</code>, <code>off</code> \e$B$rDI2C$9$k$H!"%m%C%/%-!<$r6/@)E*$K%*%s$K$7$?$j%*%U$K$7$?$j$G$-$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Undefined"><code>&amp;Undefined</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%-!<$K2?$b3d$jEv$F$i$l$F$$$J$$$3$H$K$7$^$9!#$b$7$=$N%-!<$,2!$5$l$k$H!"%Y%k$,LD$j$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_VK"><code>&amp;VK(<em>virtual_key</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B2>A[%-!<$r\e(B Windows \e$B$XF~NO$7$^$9!#2>A[%-!<$K$O!"J*M}E*$J%-!<%\!<%I$+$iF~NO$G$-$J$$%-!<$bB8:_$7$^$9$N$G$=$N$h$&$J%-!<$NF~NO$K;HMQ$7$^$9!#2>A[%-!<$rD4$Y$k$K$O!"%?%9%/%H%l%$%a%K%e!<\e(B<a href="MANUAL-ja.html#menu-i" class="menu-item">\e$BD4::\e(B(I)...</a>\e$B$N!V2>A[%-!<$ND4::!W$rMxMQ$7$^$9!#Nc$($P!"\e(B</p>
+                         
+                         <p class="sample">
+                         &nbsp;key \e$BJQ49\e(B = &amp;VK(F13)
+                         </p>
+                         
+                         <p class="continue">\e$B$H5-=R$9$k$H\e(B <kbd>\e$BJQ49\e(B</kbd> \e$B%-!<$r2!$9$H\e(B <kbd>F13</kbd> \e$B$rF~NO$G$-$^$9!#Kt!"\e(B<code>E-</code> \e$B$rIU$1$k$H3HD%%-!<$rI=$7!"\e(B<code>D-</code> \e$B$O%-!<$r2!$9!"\e(B<code>U-</code> \e$B$O%-!<$rN%$9$3$H$rI=$7$^$9!#\e(B</p>
+                         
+                         <p><code><em>virtual_key</em></code> \e$B$K\e(B <code>LButton</code>\e$B!"\e(B<code>MButton</code>\e$B!"\e(B<code>RButton</code>\e$B!"\e(B<code>XButton1</code>\e$B!"\e(B<code>XButton2</code> \e$B$r;XDj$9$k$3$H$K$h$C$F!"%^%&%9$N%\%?%s$r%7%_%e%l!<%H$9$k$3$H$,$G$-$^$9!#\e(B</p>
+                         
+                         <p>\e$B$3$N\e(B <code><em>FUNCTION</em></code> \e$B$rMxMQ$9$k$H$-$O!"I,$::G8e$K%-!<$rN%$7$F$$$k$3$H$r3NG'$7$F$/$@$5$$\e(B (\e$B$D$^$j:G8e$K\e(B <code>&amp;VK(U-F13)</code> \e$B$J$I$r=q$$$F$*$/\e(B)\e$B!#$5$b$J$$$H!"$=$N%-!<$,2!$5$l$C$Q$J$7$K$J$j$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Variable"><code>&amp;Variable(<em>mag</em>, <em>inc</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$BFbItJQ?t$r\e(B <code><em>mag</em></code> \e$BG\$7$F$+$i\e(B <code><em>inc</em></code> \e$B$r2C$($^$9!#$3$NJQ?t$O!"\e(B<a href="#function_Repeat"><code>&amp;Repeat</code></a> \e$B$H\e(B <a href="#function_HelpVariable"><code>&amp;HelpVariable</code></a> \e$B$G;HMQ$5$l$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_Wait"><code>&amp;Wait(<em>milli_second</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p><code><em>milli_second</em></code> \e$B%_%jIC$@$1<B9T$rCfCG$7$^$9!#$=$N4V$O%-!<$rF~NO$9$k$3$H$O$G$-$^$;$s!#:GBg\e(B 5 \e$BICBT$D$3$H$,$G$-$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowCling"><code>&amp;WindowClingToLeft</code>, <code>&amp;WindowClingToRight</code>, <code>&amp;WindowClingToTop</code>, <code>&amp;WindowClingToBottom</code>, </a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$r!"$=$l$>$l$NJU$,2hLL$N$=$l$>$l$NJU$K$/$C$D$/$h$&$K0\F0$5$;$^$9!#0z?t$K\e(B <code>MDI</code> \e$B$r;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li><code>&amp;WindowClingToTop</code> \e$B$O\e(B <a href="#function_WindowMoveTo"><code>&amp;WindowMoveTo(N, 0, 0)</code></a>\e$B$HF1$8!#\e(B
+                           <li><code>&amp;WindowClingToRight</code> \e$B$O\e(B <a href="#function_WindowMoveTo"><code>&amp;WindowMoveTo(E, 0, 0)</code></a> \e$B$HF1$8!#\e(B
+                           <li><code>&amp;WindowClingToLeft</code> \e$B$O\e(B <a href="#function_WindowMoveTo"><code>&amp;WindowMoveTo(W, 0, 0)</code></a> \e$B$HF1$8!#\e(B
+                           <li><code>&amp;WindowClingToBottom</code> \e$B$O\e(B <a href="#function_WindowMoveTo"><code>&amp;WindowMoveTo(S, 0, 0)</code></a> \e$B$HF1$8!#\e(B
+                         </ul>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowClose"><code>&amp;WindowClose</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$rJD$8$^$9!#0z?t$K\e(B <code>MDI</code> \e$B$r;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowIdentify"><code>&amp;WindowIdentify</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$N%&%#%s%I%&%/%i%9L>$H%?%$%H%k$rD4$Y%m%0$K=PNO$7$^$9!#Kt!"3F<o%&%#%s%I%&$N0LCV$HBg$-$5$b=PNO$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowMaxMinHVMax"><code>&amp;WindowMinimize</code>, <code>&amp;WindowMaximize</code>, <code>&amp;WindowHMaximize</code>, <code>&amp;WindowVMaximize</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B$=$l$>$l!"%&%#%s%I%&$r:G>.2=!":GBg2=!"2#J}8~$K:GBg2=!"=DJ}8~$K:GBg2=$7$^$9!#0z?t$K\e(B <code>MDI</code> \e$B$r;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowMonitor"><code>&amp;WindowMonitor(<em>monitor</em>, <em>adjust_position</em>, <em>adjust_size</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$r%b%K%?\e(B <code><em>monitor</em></code> \e$B$X0\F0$7$^$9!#\e(B<a href="#function_WindowMonitorTo"><code>&amp;WindowMonitorTo(primary, <em>monitor</em>, <em>adjust_position</em>, <em>adjust_size</em>)</code></a> \e$B$HF1$8F0:n$r$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowMonitorTo"><code>&amp;WindowMonitorTo(<em>from</em>, <em>monitor</em>, <em>adjust_position</em>, <em>adjust_size</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$r\e(B <code><em>from</em></code> \e$B$r4p=`$H$7$F%b%K%?\e(B <code><em>monitor</em></code> \e$B$X0\F0$7$^$9!#\e(B<code><em>from</em></code> \e$B$K$O!"<!$N$b$N$,;XDj$G$-$^$9!#\e(B</p>
+
+                         <ul>
+                           <li><code>primary</code> : \e$B%W%i%$%^%j%b%K%?$r4p=`$H$7$^$9\e(B</li>
+                           <li><code>current</code> : \e$B8=:_%&%#%s%I%&$,$"$k%b%K%?$r4p=`$H$7$^$9\e(B</li>
+                         </ul>
+
+                         <p><code><em>monitor</em></code> \e$B$K$O!"?t;z$,;XDj$G$-$^$9!#\e(B<code>0</code> \e$B$,4p=`$H$J$k%b%K%?!"@5$N?t$O\e(B <code>1</code>: \e$B<!$N%b%K%?!"\e(B<code>2</code>: \e$B<!$N<!$N%b%K%?!D!"Ii$N?t$O\e(B <code>-1</code>: \e$BA0$N%b%K%?!"\e(B<code>-2</code>: \e$BA0$NA0$N%b%K%?!D!"$r0UL#$7$^$9!#\e(B</p>
+                         <p><code><em>adjust_position</em></code> \e$B$O>JN,2DG=$J0z?t$G\e(B <code>true</code> \e$B$+\e(B <code>false</code> \e$B$r;XDj$7$^$9!#>JN,$9$k$H\e(B <code>true</code> \e$B$,;XDj$5$l$?$H$_$J$5$l$^$9!#\e(B<code>true</code> \e$B$,;XDj$5$l$?>l9g!"0\F0@h$,%b%K%?$+$i$O$_=P$9$H$-$K$G$-$k8B$j%b%K%?Fb$K$*$5$^$k0LCV$X0\F0$7$^$9!#\e(B</p>
+                         <p><code><em>adjust_size</em></code> \e$B$O>JN,2DG=$J0z?t$G\e(B <code>true</code> \e$B$+\e(B <code>false</code> \e$B$r;XDj$7$^$9!#>JN,$9$k$H\e(B <code>false</code> \e$B$,;XDj$5$l$?$H$_$J$5$l$^$9!#\e(B<code><em>adjust_position</em></code> \e$B$,\e(B <code>true</code> \e$B$N>l9g$N$_M-8z$G$9!#\e(B<code>true</code> \e$B$,;XDj$5$l$?>l9g!"0\F0@h$,%b%K%?$+$i$O$_=P$9$H$-$K%b%K%?Fb$K$*$5$^$k$h$&%&%#%s%I%&$NBg$-$5$rD4@0$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowMove"><code>&amp;WindowMove(<em>dx</em>, <em>dy</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%$%s%I%&$r?eJ?J}8~$K\e(B <code><em>dx</em></code>\e$B!"?bD>J}8~$K\e(B <code><em>dy</em></code> \e$B0\F0$7$^$9!#\e(B<code>MDI</code> \e$B$r0z?t$N:G8e$KDI2C;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B<code>&amp;WindowMoveTo(C, <em>dx</em>, <em>dy</em>)</code> \e$B$HF1$8F0:n$r$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowMoveTo"><code>&amp;WindowMoveTo(<em>gravity</em>, <em>dx</em>, <em>dy</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B4p=`0LCV$+$iAjBPE*$K%&%$%s%I%&$r?eJ?J}8~$K\e(B <code><em>dx</em></code>\e$B!"?bD>J}8~$K\e(B <code><em>dy</em></code> \e$B0\F0$7$^$9!#\e(B<code>MDI</code> \e$B$r0z?t$N:G8e$KDI2C;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B<code><em>gravity</em></code> \e$B$K$O!"<!$N$b$N$,;XDj$G$-$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li><code>C</code> : \e$B8=:_0LCV$+$i$NAjBP0LCV$K0\F0$7$^$9!#\e(B
+                           <li><code>N</code> : \e$B>e2<J}8~$O%G%9%/%H%C%W$N>e$+$i$NAjBP0LCV!":81&J}8~$O8=:_0LCV$+$i$NAjBP0LCV$K0\F0$7$^$9!#\e(B
+                           <li><code>E</code> : \e$B>e2<J}8~$O8=:_0LCV$+$i$NAjBP0LCV!":81&J}8~$O%G%9%/%H%C%W$N1&$+$i$NAjBP0LCV$K0\F0$7$^$9!#\e(B
+                           <li><code>W</code> : \e$B>e2<J}8~$O8=:_0LCV$+$i$NAjBP0LCV!":81&J}8~$O%G%9%/%H%C%W$N:8$+$i$NAjBP0LCV$K0\F0$7$^$9!#\e(B
+                           <li><code>S</code> : \e$B>e2<J}8~$O%G%9%/%H%C%W$N2<$+$i$NAjBP0LCV!":81&J}8~$O8=:_0LCV$+$i$NAjBP0LCV$K0\F0$7$^$9!#\e(B
+                           <li><code>NE</code> : \e$B%G%9%/%H%C%W1&>e$+$i$NAjBP0LCV$K0\F0!#\e(B
+                           <li><code>NW</code> : \e$B%G%9%/%H%C%W:8>e$+$i$NAjBP0LCV$K0\F0!#\e(B
+                           <li><code>SE</code> : \e$B%G%9%/%H%C%W1&2<$+$i$NAjBP0LCV$K0\F0!#\e(B
+                           <li><code>SW</code> : \e$B%G%9%/%H%C%W:82<$+$i$NAjBP0LCV$K0\F0!#\e(B
+                         </ul>
+                         
+                         <p>\e$B$^$?!"B>$N0\F0\e(B <code><em>FUNCTION</em></code> \e$B$H$O0J2<$N$h$&$J4X78$,$"$j$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li><code>&amp;WindowMoveTo(C, <em>dx</em>, <em>dy</em>)</code> \e$B$O\e(B <a href="#function_WindowMove"><code>&amp;WindowMove(<em>dx</em>, <em>dy</em>)</code></a> \e$B$HF1$8!#\e(B
+                           <li><code>&amp;WindowMoveTo(N, 0, 0)</code> \e$B$O\e(B <a href="#function_WindowCling"><code>&amp;WindowClingToTop</code></a> \e$B$HF1$8!#\e(B
+                           <li><code>&amp;WindowMoveTo(E, 0, 0)</code> \e$B$O\e(B <a href="#function_WindowCling"><code>&amp;WindowClingToRight</code></a> \e$B$HF1$8!#\e(B
+                           <li><code>&amp;WindowMoveTo(W, 0, 0)</code> \e$B$O\e(B <a href="#function_WindowCling"><code>&amp;WindowClingToLeft</code></a> \e$B$HF1$8!#\e(B
+                           <li><code>&amp;WindowMoveTo(S, 0, 0)</code> \e$B$O\e(B <a href="#function_WindowCling"><code>&amp;WindowClingToBottom</code></a> \e$B$HF1$8!#\e(B
+                         </ul>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowMoveVisibly"><code>&amp;WindowMoveVisibly</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&A4BN$,2hLL$KI=<($5$l$k$h$&$J0LCV$X%&%#%s%I%&$r0\F0$7$^$9!#0z?t$K\e(B <code>MDI</code> \e$B$r;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowRedraw"><code>&amp;WindowRedraw</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$r6/@)E*$K:FIA2h$5$;$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowResizeTo"><code>&amp;WindowResizeTo(<em>width</em>, <em>height</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%$%s%I%&$NBg$-$5$rI}\e(B <code><em>width</em></code>\e$B!"9b$5\e(B <code><em>height</em></code> \e$B$KJQ99$7$^$9!#\e(B<code>0</code> \e$B$r;XDj$9$k$H8=:_$NBg$-$5$K!"Ii$NCM$r;XDj$9$k$H%G%9%/%H%C%W$NBg$-$5$h$j;XDj$7$?%T%/%;%k?t$@$1>.$5$$Bg$-$5$K$J$j$^$9!#\e(B<code>MDI</code> \e$B$r0z?t$N:G8e$KDI2C;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowRiseLower"><code>&amp;WindowRaise</code>, <code>&amp;WindowLower</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B$=$l$>$l!"%&%#%s%I%&$r0lHV>e!"0lHV2<$X0\F0$7$^$9!#0z?t$K\e(B <code>MDI</code> \e$B$r;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowSetAlpha"><code>&amp;WindowSetAlpha(<em>alpha</em>)</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$rH>F)L@2=!"Kt$OH>F)L@2=2r=|$7$^$9!#%H%0%k$K$J$C$F$$$^$9!#\e(B<code><em>alpha</em></code> \e$B$OH>F)L@$NEY9g$$$rI=$7!"\e(B<code>0</code> \e$B$GF)L@!"\e(B<code>100</code> \e$B$GITF)L@$K$J$j$^$9!#\e(B<code>-1</code> \e$B$r;XDj$9$k$H!"$3$N\e(B <code><em>FUNCTION</em></code> \e$B$GH>F)L@2=$5$l$?%&%#%s%I%&$rA4$FITF)L@>uBV$KLa$7$^$9!#\e(B</p>
+                       </div>
+                       
+                   <dt class="h3"><a name="function_WindowToggleTopMost"><code>&amp;WindowToggleTopMost</code></a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%&%#%s%I%&$N:GA0LL%U%i%0$r%H%0%k$7$^$9!#\e(B</p>
+                       </div>
+               
+                   <dt class="h3"><a name="arg_subst">\e$B0z?tCV49\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B0z?t$H$7$F\e(B <code>$</code> \e$B$G;O$^$k%-!<%o!<%I$r;XDj$9$k$3$H$K$h$j\e(B <code><em>FUNCTION</em></code> \e$B$K0J2<$NFbMF$rEO$9$3$H$,$G$-$^$9!#\e(B[]\e$BFb$O$=$N%-!<%o!<%I$r;XDj$G$-$k0z?t$N7?$G$9!#CM$N<h$j=P$7$O\e(B <code><em>FUNCTION</em></code> \e$B$N<B9T;~$K9T$o$l$^$9!#\e(B</p>
+                         
+                         <ul>
+                           <li><code>$Clipboard</code>: [\e$BJ8;zNs\e(B] \e$B%/%j%C%W%\!<%I$NCf?H\e(B
+                           <li><code>$WindowClassName</code>: [\e$BJ8;zNs\e(B] \e$B%U%)!<%+%9$5$l$F$$$k%&%#%s%I%&$N%/%i%9L>\e(B
+                           <li><code>$WindowTitleName</code>: [\e$BJ8;zNs\e(B] \e$B%U%)!<%+%9$5$l$F$$$k%&%#%s%I%&$N%?%$%H%kL>\e(B
+                         </ul>
+                         
+                         <p>\e$B%/%j%C%W%\!<%IFb$NJ8;zNs$r\e(B URL \e$B$H$7$F%V%i%&%6$G3+$/Nc\e(B:</p>
+                         <p class="sample">
+                         &nbsp;key M-C-O = &amp;ShellExecute("open", $Clipboard,,, ShowNormal)
+                         </p>
+                         
+                         <p>\e$B%U%)!<%+%9$5$l$F$$$k%&%#%s%I%&$N%/%i%9L>$d%?%$%H%kL>$r%/%j%C%W%\!<%I$K%3%T!<$9$kNc\e(B:</p>
+                         
+                         <p class="sample">
+                         &nbsp;key M-C-C = &amp;ClipboardCopy($WindowClassName)<br>
+                         &nbsp;key M-C-T = &amp;ClipboardCopy($WindowTitleName)
+                         </p>
+                       </div>
+                       
+                   <dt class="h3"><a name="string">\e$BJ8;zNs\e(B</a>
+                       
+                   <dd class="d3">
+                       <div>
+                         <p>\e$BJ8;zNs$,5-=R$G$-$k2U=j$K$O\e(B <code>"\e$BJ8;zNs\e(B"</code> \e$B$H5-=R$9$k$3$H$,$G$-$^$9$,!"\e(B<code>\</code> \e$B$H$$$&J8;z$O!"$=$N<!$K$/$kJ8;z$HAH$_9g$o$;$FFC<l$JJ8;z$rI=$7$^$9!#\e(B</p>
+                         <ul>
+                           <li><code>\a</code> (U+0007) \e$B%Y%kJ8;z\e(B
+                           <li><code>\e</code> (U+001b) ESC \e$BJ8;z\e(B
+                           <li><code>\f</code> (U+000c) \e$B2~JGJ8;z\e(B
+                           <li><code>\n</code> (U+000a) \e$B2~9TJ8;z\e(B
+                           <li><code>\r</code> (U+000d) \e$BI|5"J8;z\e(B
+                           <li><code>\t</code> (U+0009) \e$B%?%VJ8;z\e(B
+                           <li><code>\v</code> (U+000b) \e$B?bD>%?%VJ8;z\e(B
+                           <li><code>\'</code> \e$B!V\e(B<code>'</code>\e$B!W\e(B
+                           <li><code>\"</code> \e$B!V\e(B<code>"</code>\e$B!W\e(B
+                           <li><code>\\</code> \e$B!V\e(B<code>\</code>\e$B!W\e(B
+                           <li><code>\c<em>X</em></code> \e$B%3%s%H%m!<%kJ8;z0lHL!#\e(B<code>^<em>X</em></code>
+                           <li><code>\x<em>XXXX</eM></code> (U+<em>XXXX</em>) 16 \e$B?J?t$GI=8=$7$?\e(B UNICODE \e$BJ8;z!#\e(B<em>X</em> \e$B$O\e(B 0\e$B!A\e(B9 \e$B$H\e(B a\e$B!A\e(Bf\e$B!#\e(B
+                           <li><code>\0<em>XXXX</eM></code> 8 \e$B?J?t$GI=8=$7$?\e(B UNICODE \e$BJ8;z!#\e(B<em>X</em> \e$B$O\e(B 0\e$B!A\e(B7\e$B!#\e(B
+                           <li>\e$B>e5-$KEv$F$O$^$i$J$$\e(B <code>\<em>X</em></code> \e$B$O\e(B <em>X</em> \e$B$H$$$&J8;z$=$N$b$N!#\e(B
+                       </div>
+                 </dl>
+               </div>
+               
+           <dt class="h2"><a name="compile">x. \e$B%S%k%I\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <dl>
+                   <dt class="h3"><a name="compile_tool">\e$BI,MW$J$b$N\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <p>Visual C++ \e$B$r=jM-$7$F$$$J$$>l9g!"%^%$%/%m%=%U%H$+$iL5=~$GDs6!$5$l$F$$$k%3%s%Q%$%i$rMxMQ$9$k$3$H$G%S%k%I2DG=$G$9!#\e(B</p>
+                         <dl>
+                           <dt class="h4">Visual C++
+                           <dd class="d4">
+                               <div>
+                                 <p>\e$B>&MQ$N\e(B Visual C++ 6.0 SP5 \e$B0J9_!"Kt$O%^%$%/%m%=%U%H$+$iL5=~$GDs6!$5$l$F$$$k\e(B <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=272be09d-40bb-49fd-9cb0-4bfa122fa91b&DisplayLang=en">Visual C++ Toolkit 2003</a> \e$B$r%@%&%s%m!<%I$7$F;HMQ$9$k$3$H$,2DG=$G$9!#\e(B</p>
+                               </div>
+
+                           <dt class="h4">Platform SDK 
+                           <dd class="d4">
+                               <div>
+                                 <p>Windows XP \e$B$KBP1~$7$?$b$N$,I,MW$G$9!#\e(BMSDN \e$B$GG[I[$5$l$F$$$^$9$7!"%^%$%/%m%=%U%H$N$+$iL5=~$GDs6!$5$l$F$$$k\e(B <a href="http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm" target="_top">XPSP2 PSDK</a> \e$B$rMxMQ$9$k$3$H$b$G$-$^$9!#\e(B</p>
+                               </div>
+                               
+                           <dt class="h4">(Visual C++ Toolkit 2003 \e$B$rMxMQ$9$k>l9g$N$_\e(B) .NET Framework SDK Version 1.1
+                           <dd class="d4">
+                               <div>
+                                 <p>Visual C++ Toolkit 2003 \e$B$N%Q%C%1!<%8$K$O\e(B nmake \e$B$H\e(B cvtres \e$B$,4^$^$l$F$$$J$$$N$G!"\e(B<a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=9B3A2CA6-3647-4070-9F41-A333C6B9181D&displaylang=ja">.NET Framework SDK Version 1.1</a> \e$B$r%$%s%9%H!<%k\e(B(\e$BL5=~\e(B)\e$B$9$kI,MW$,$"$j$^$9!#\e(B</p>
+
+                                 <p><code>C:\Program Files\Microsoft.NET\SDK\v1.1\Bin\nmake.exe</code> \e$B$H\e(B <code>C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\cvtres.exe</code> \e$B$r\e(B Visual C++ Toolkit 2003 \e$B$N\e(B <code>bin/</code> \e$B%G%#%l%/%H%j$X%3%T!<$7$^$9!#\e(B(<code>cvtres.exe</code> \e$B$OI,$:\e(B <code>link.exe</code> \e$B$HF1$8%G%#%l%/%H%j$KCV$$$F$/$@$5$$!#\e(B<code>nmake.exe</code> \e$B$O%Q%9$,DL$C$F$$$l$P;HMQ2DG=$G$9!#\e(B)</p>
+
+                                 <p>\e$B>&MQ%Q%C%1!<%8$N\e(B Visual C++ \e$B$K$O:G=i$+$i4^$^$l$F$$$k$N$G!"F~$l$kI,MW$O$"$j$^$;$s!#\e(B</p>
+                               </div>
+                               
+                           <dt class="h4">DDK
+                           <dd class="d4">
+                               <div>
+                                 <p>\e$B%G%P%$%9%I%i%$%P$r%S%k%I$9$k>l9g$N$_I,MW$K$J$j$^$9!#\e(BMSDN \e$B$GG[I[$5$l$F$$$^$9$7!"%^%$%/%m%=%U%H$N\e(B<a href="http://www.microsoft.com/whdc/ddk/winddk.mspx" target="_top">\e$B%5%$%H\e(B</a>\e$B$+$iCmJ8$9$k$3$H$b$G$-$^$9!#\e(B</p>
+                               </div>
+                           <dt class="h4">\e$B@55,I=8=%i%$%V%i%j\e(B
+                           <dd class="d4">
+                               <div>
+                                 <p><a href="http://www.boost.org/libs/regex/doc/index.html" target="_top">Boost.Regex</a> \e$B$,I,MW$G$9!#\e(B<a href="http://www.boost.org/" target="_top">Boost \e$B%i%$%V%i%j\e(B</a> \e$B$KF1:-$5$l$F$$$^$9!#8=:_!"!VAk;H$$$NM+]5!W$N%S%k%I$,3NG'$5$l$F$$$k\e(B Boost \e$B$N%P!<%8%g%s$O\e(B 1.32.0 \e$B$N$_$G$9!#\e(B</p>
+                               </div>
+                           <dt class="h4">Perl</a>
+                           <dd class="d4">
+                               <div>
+                                 <p>\e$B$$$/$D$+$N:n6H$N0Y$K\e(B Perl \e$B$,I,MW$G$9!#\e(B<a href="http://www.cygwin.com/" target="_top">Cygwin</a> \e$B$N\e(B perl \e$BKt$O\e(B <a href="http://www.activestate.com/Products/ActivePerl/" target="_top">ActivePerl</a> \e$B$r%$%s%9%H!<%k$7$F$/$@$5$$!#\e(B</p>
+                               </div>
+                           <dt class="h4">bash, cvs, fileutils, sed, tar
+                           <dd class="d4">
+                               <div>
+                                 <p>\e$BG[I[%Q%C%1!<%8$r:n@.$9$k$?$a$K$N$_\e(B <a href="http://www.cygwin.com/" target="_top">Cygwin</a> \e$B$N\e(B bash, fileutils, sed, tar \e$B$,I,MW$G$9!#$^$?!"\e(Bcvs \e$B$O\e(B Cygwin \e$B$N$b$N$r;HMQ$9$k$3$H$r$*$9$9$a$7$^$9!#$5$b$J$$$H2~9T%3!<%I$N0c$$$K$h$k%H%i%V%k$,5/$3$k$+$b$7$l$^$;$s!#\e(Bmayu \e$B$N%=!<%9$N2~9T%3!<%I$O$9$Y$F\e(B LF \e$B$N$_$K$J$C$F$$$^$9!#\e(B</p>
+                               </div>
+                         </dl>
+                       </div>
+                       
+                   <dt class="h3"><a name="compile_source">\e$B%=!<%9$NE83+\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <dl>
+                           <dt class="h4">\e$B%=!<%9$NE83+\e(B
+                           <dd class="d4">
+                               <div>
+                                 <p>SourfeForge \e$B$N\e(B <a href="http://sourceforge.net/project/showfiles.php?group_id=5403">Download</a> \e$B$+$i!"%=!<%9%U%!%$%k$r%@%&%s%m!<%I$7$^$9!#%=!<%9%U%!%$%k$NE83+$K$O\e(B Cygwin \e$B$N\e(B tar \e$B$r;H$&$N$,NI$$$G$7$g$&!#\e(B
+                               </div>
+                           <dt class="h4">cvs \e$B$K$h$k<h$j4s$;\e(B
+                           <dd class="d4">
+                               <div>
+                                 <p>SourfeForge \e$B$+$i\e(B cvs \e$B$r;HMQ$7$F<h$j4s$;$k$3$H$K$h$j8=:_3+H/Cf$G<!$N%P!<%8%g%s$H$J$k$O$:$N%=!<%9$rF~<j$9$k$3$H$,=PMh$^$9!#\e(B</p>
+                                 <p class="sample">
+                                 cvs -z 3 -d :pserver:anonymous@cvs1.sourceforge.net:/cvsroot/mayu checkout mayu
+                                 </p>
+                               </div>
+                           <dt class="h4">\e$B%G%#%l%/%H%j9=@.\e(B
+                           <dd class="d4">
+                               <div>
+                                 <p>\e$B>e5-$N$I$A$i$+$NJ}K!$G!VAk;H$$$NM+]5!WK\BN$N%=!<%9%3!<%I$rE83+8e!"\e(BBoost \e$B$rE83+$7$^$9!#:G=*E*$J%G%#%l%/%H%j9=@.$,0J2<$N$h$&$K$J$k$h$&$KE83+$7$F$/$@$5$$!#\e(B</p>
+                                 <p class="tree">
+                                 ./<br>
+                                 <code>&nbsp;&nbsp;&nbsp;|</code><br>
+                                 <code>&nbsp;&nbsp;&nbsp;+---</code>boost_1_??_?/ ... <span>Boost \e$B$NE83+$K$h$j:n@.$5$l$k\e(B</span><br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;|</code><br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;+---</code>boost/ ... <span>Boost \e$B$NE83+$K$h$j:n@.$5$l$k\e(B</span><br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;|</code><br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;+---</code>detail/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;+---</code>re_detail/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;|</code><br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;+---</code>libs/ ... <span>Boost \e$B$NE83+$K$h$j:n@.$5$l$k\e(B</span><br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</code><br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---</code>regex/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---</code>timer/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;|</code><br>
+                                 <code>&nbsp;&nbsp;&nbsp;+---</code>mayu-3.??/ ... <span>\e$B!VAk;H$$$NM+]5!WK\BN%=!<%9\e(B</span><br>
+                                 <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</code><br>
+                                 <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---</code>contrib/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---</code>d/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---</code>r/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---</code>s/ ...<br>
+                                 <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+---</code>tools/ ...<br>
+                                 </p>
+                               </div>
+                         </dl>
+                       </div>
+                   <dt class="h3"><a name="compile_build">\e$B%S%k%I\e(B</a>
+                   <dd class="d3">
+                       <div>
+                         <dl>
+                           <dt class="h4">Visual C++ \e$B$N>l9g\e(B
+                           <dd class="d4">
+                               <div>
+                                 <p>\e$B$^$:!"$$$/$D$+$N4D6-JQ?t$r@_Dj$7$^$9!#\e(B</p>
+                                 <p> <code>vcvars32.bat</code> \e$B$rMxMQ$9$k$H@_Dj$7$F$/$l$k$O$:$G$9$,!"0J2<$N4D6-JQ?t$N@_Dj$,I,MW$K$J$j$^$9!#\e(B</p>
+                                 <ul>
+                                   <li><code>PATH</code> \e$B!D\e(B \e$B%3%s%Q%$%i$H\e(B nmake \e$B$K%Q%9$rDL$7$^$9!#\e(B
+                                   <li><code>INCLUDE</code> \e$B!D\e(B \e$B%3%s%Q%$%i$H\e(B PSDK \e$B$N\e(B include \e$B%G%#%l%/%H%j%Q%9$r@_Dj$7$^$9!#\e(B
+                                   <li><code>LIB</code> \e$B!D\e(B \e$B%3%s%Q%$%i$H\e(B PSDK \e$B$N\e(B lib \e$B%G%#%l%/%H%j%Q%9$r@_Dj$7$^$9!#\e(B
+                                   <li><code>MSVCDIR</code> \e$B!D\e(B Visual C++ Toolkit 2003 \e$B$r;HMQ$9$k>l9g$O@_Dj$5$l$F$$$J$$$N$G!"4D6-JQ?t\e(B <code>VCTOOLKITINSTALLDIR</code> \e$B$HF1$8FbMF$K@_Dj$7$^$9!#\e(B
+                                 </ul>
+                                 
+                                 <p>\e$B<!$K%3%s%Q%$%k$r9T$$$^$9!#\e(B</p>
+
+                                 <p>Visual C++ Toolkit 2003 \e$B$N>l9g$O!"0J2<$N$h$&$K$7$^$9!#\e(B</p>
+                                 <p class="sample">
+                                 mayu-3.??&gt; nmake MAYU_VC=vct
+                                 </p>
+                                 <p>Visual C++ 7.1 \e$B$N>l9g$O!"0J2<$N$h$&$K$7$^$9!#\e(B</p>
+                                 <p class="sample">
+                                 mayu-3.??&gt; nmake MAYU_VC=vc71
+                                 </p>
+                                 <p>Visual C++ 7.0 \e$B$N>l9g$O!"0J2<$N$h$&$K$7$^$9!#\e(B</p>
+                                 <p class="sample">
+                                 mayu-3.??&gt; nmake MAYU_VC=vc7
+                                 </p>
+                                 <p>Visual C++ 6.0 \e$B$N>l9g$O!"0J2<$N$h$&$K$7$^$9!#\e(B</p>
+                                 <p class="sample">
+                                 mayu-3.??&gt; nmake MAYU_VC=vc6
+                                 </p>
+                                 <p><code>out$(MAYU_VC)_winnt/</code>, <code>out$(MAYU_VC)_winnt_debug/</code> \e$B$N3F%G%#%l%/%H%j$K<B9T%U%!%$%k$,:n@.$5$l$^$9!#\e(B</p>
+                                 <p><code>d/</code> \e$B%G%#%l%/%H%j0J2<$K$O%I%i%$%P$N%=!<%9$,F~$C$F$$$k$N$G!"I,MW$J$iE,Ev$K%3%s%Q%$%k$7$F$/$@$5$$!#\e(B</p>
+                                 
+                                 <hr>
+                                 
+                                 <p>Visual C++ Toolkit 2003 \e$B$r;HMQ$9$k>l9g$O!"\e(B<code>libcpmtd.lib</code> \e$B$,Ds6!$5$l$F$$$J$$$?$a!"%G%P%C%0%P!<%8%g%s$N\e(B mayu \e$B$O%S%k%I$G$-$^$;$s!#\e(B</p>
+                                 
+                               </div>
+                         </dl>
+                       </div>
+                 </dl>
+               </div>
+         </dl>
+       </div>
+  </dl>
+</div>
+
+</body>
+</html>
diff --git a/doc/MANUAL-ja.html b/doc/MANUAL-ja.html
new file mode 100644 (file)
index 0000000..072efff
--- /dev/null
@@ -0,0 +1,1159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+<html lang="ja">
+<head>
+<meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp">
+<link rel="stylesheet" type="text/css" href="README.css">
+<link rel="prev" href="CONTENTS-ja.html">
+<link rel="next" href="CUSTOMIZE-ja.html">
+<title>\e$BAk;H$$$NM+]5\e(B - MANUAL</title>
+</head>
+
+<body class="manual">
+
+<div class="title">
+  <a href="http://mayu.sourceforge.net" target="_top" class="title"><img src="banner-ja.gif" alt="\e$BAk;H$$$NM+]5\e(B"></a>
+</div>
+<div class="copyright">
+  Copyright &copy; 1999-2005, <a href="http://www.ganaware.jp" target="_top">TAGA Nayuta</a> &lt;nayuta&#64;users.sourceforge.net&gt;
+</div>
+<div class="main">
+<dl>
+  <dt class="h1"><a name="ABSTRACT">1. abstract</a>
+      
+  <dd class="d1">
+      <p>\e$B$$$+$s$H$b$7$,$?$$M}M3$K$h$j\e(B UN*X Wizard \e$B$,Ak;H$$$K%8%g%V%A%'%s%8$9$k;~!"$=$NA`:nBN7O$N0c$$$K$h$jM+]5$JF|!9$rAw$i$6$k$rF@$J$$$3$H$OA[A|$KFq$/$"$j$^$;$s!#!VAk;H$$$NM+]5!W$O!"$=$NM+]5$r>/$7$@$1OB$i$2$k$3$H$,$G$-$k%"%$%F%`$G$9!#\e(B</p>
+      
+      <ul>
+       <li>Windows2000, WindowsXP \e$B$GF0$/HFMQ%-!<%P%$%s%G%#%s%0JQ99%=%U%H$G$9!#\e(B
+       <li>2 \e$B%9%H%m!<%/%-!<$r@_Dj$G$-$^$9!#\e(B
+       <li>\e$B8D!9$N%&%#%s%I%&$KJL!9$N%-!<%P%$%s%G%#%s%0$r3d$jEv$F$k$3$H$,$G$-$^$9!#\e(B
+       <li>Control \e$B$J$I$N%b%G%#%U%!%$%d%-!<$r<+M3$K:n@.$9$k$3$H$,$G$-$^$9!#\e(B
+       <li>\e$B%&%#%s%I%&$r0\F0$5$;$?$j:GBg\e(B/\e$B:G>.2=$9$k%-!<$J$I$r:n@.$G$-$^$9!#\e(B
+       <li>\e$B%(%G%#%C%H%3%s%H%m!<%k$r\e(B Emacs \e$BIw$K$9$k$3$H$,$G$-$^$9!#\e(B
+       <li>U*IX \e$BE*$JAGE($J%+%9%?%^%$%:5!G=$rDs6!$7$F$$$^$9!#\e(B
+      </ul>
+      
+      <p>\e$B$7$+$7!"<!$N$h$&$J4m81@-$,$"$j$^$9!#\e(B</p>
+      
+      <ul>
+       <li><strong>\e$BI8=`$G$J$$\e(B</strong> \e$B%-!<%\!<%I%I%i%$%P$rMxMQ$7$F$$$k$H\e(B Windows2000/XP \e$B$,@D2hLL$K$J$C$F=*N;$7$F$7$^$&$3$H$,$"$j$^$9!#$=$N$h$&$J>l9g$O!"I8=`$G$J$$%I%i%$%P$r%"%s%$%s%9%H!<%k$9$k$+!"!VAk;H$$$NM+]5!W$NMxMQ$r$"$-$i$a$k$7$+$"$j$^$;$s!#\e(B
+       <li>\e$BI8=`$G$J$$%I%i%$%P$H$O!"\e(B<strong>\e$B%m%8%F%C%/%^%&%9\e(B</strong>\e$B$KIUB0$N%I%i%$%P$d\e(B <strong>AltIME</strong> \e$B$N%I%i%$%P$J$I$G$9!#\e(B
+       <li>\e$BB>?M$,;HMQ$9$k2DG=@-$N$"$k\e(B PC \e$B$X$N%$%s%9%H!<%k$O4m81$G$9!#\e(B(<a href="#SECURITY">security</a> \e$B$N>O$r;2>H\e(B)
+      </ul>
+      
+  <dt class="h1"><a name="INSTALL">2. install</a>
+
+  <dd class="d1">
+      
+      <ol class="decimal">
+       <li>\e$BAk;H$$$NM+]50J30$N%-!<%\!<%I%+%9%?%^%$%:%=%U%H$rMxMQ$7$F$$$k>l9g$O%"%s%$%s%9%H!<%k$7$^$9!#\e(B
+           <ul>
+             <li>\e$B$?$H$($P!"\e(B<strong>AltIME</strong> \e$B$d\e(B <strong>RemapKey</strong> \e$B$d\e(B<strong>\e$B!VG-$^$M$-!W\e(B</strong>\e$B$J$I$G$9!#\e(B
+             <li>\e$BFC$K\e(B <strong>AltIME</strong> \e$B$r;HMQ$7$F$$$?>l9g$O!"\e(B<a href="#FAQ">FAQ</a> \e$B$N:G=i$N9`L\$r$h$/FI$s$G$/$@$5$$!#\e(B
+             <li><a href="http://www.pgpi.org/products/pgp/versions/freeware/win32/7.0.3/" target="_top"><strong>PGPi</strong></a> \e$B$rMxMQ$7$F$$$k$H$&$^$/F0$+$J$$$h$&$G$9!#\e(B
+           </ul>
+       <li>\e$B0JA0$N%P!<%8%g%s$N!VAk;H$$$NM+]5!W$rMxMQ$7$F$$$k>l9g$O!"=*N;$5$;$^$9!#\e(B
+           <ul>
+             <li>\e$B=*N;$5$;$k$@$1$G$h$/!"%"%s%$%s%9%H!<%k$9$kI,MW$O$"$j$^$;$s!#\e(B
+           </ul>
+       <li>\e$B%@%&%s%m!<%I$7$?<B9T%U%!%$%k$r\e(B <strong>Administrator</strong> \e$B8"8B$G<B9T$7$F$/$@$5$$!#$9$k$H!VAk;H$$$NM+]5!W$,%$%s%9%H!<%k$5$l$^$9!#\e(B
+       <li>\e$B%$%s%9%H!<%k$,=*$o$C$?$i%3%s%T%e!<%?$r:F5/F0$7$^$9!#\e(B
+       <li>\e$B$*9%$_$K$h$j!"%9%?!<%H%"%C%W$K%7%g!<%H%+%C%H$r:n$k$N$b$$$$$G$7$g$&!#\e(B
+       <li><code>mayu.exe</code> \e$B$r<B9T$9$k$3$H$G3+;O$7$^$9!#\e(B
+      </ol>
+      
+      <dl>
+       <dt class="h2"><a name="rescue_driver">\e$BI|5lMQ%I%i%$%P$K$D$$$F\e(B</a></dt>
+       <dd class="d2">
+           <div>
+             <p>Windows2000/XP \e$B$N>l9g!VAk;H$$$NM+]5!W%I%i%$%P$O\e(B <code>mayu.exe</code> \e$B$N<B9T$NM-L5$K4X$o$i$:%m!<%I$5$l$^$9!#$3$N$?$a!"$?$H$(!VAk;H$$$NM+]5!W$r<+F05/F0$K$7$F$$$J$/$F$b!"%I%i%$%P$NIT6q9g$K$h$C$F!VAk;H$$$NM+]5!W$N%"%s%$%s%9%H!<%k$b4^$a$?A`:n$,ITG=$K$J$k>l9g$,$"$j$^$9!#$=$N>l9g$G$b2<5-$N<j=g$K$h$C$F\e(B Windows \e$B$N:F%$%s%9%H!<%k$r2sHr$9$k$3$H$,$G$-$k>l9g$,$"$j$^$9!#\e(B</p>
+             
+             <ol class="decimal">
+               <li>\e$BEE8;%\%?%s$ND92!$7Ey$K$h$C$F0lC6!"6/@)E*$KEE8;$rMn$7$?$"$H2sI|%3%s%=!<%k$r5/F0$7$^$9!#>0!"2sI|%3%s%=!<%k$G$N5/F0$,$G$-$k$3$H$r\e(B<strong>\e$B!VAk;H$$$NM+]5!W$N%$%s%9%H!<%kA0$K\e(B</strong>\e$B3NG'$7$F$*$/$3$H$r$*4+$a$7$^$9!#\e(B</strong>(\e$B;29M\e(B: <a href="http://support.microsoft.com/default.aspx?scid=kb;ja;314058">Windows XP \e$B2sI|%3%s%=!<%k$K$D$$$F\e(B</a>)
+               <li><code>%windir%\system32\drivers</code> \e$BFb$N\e(B <code>mayudrsc.sys</code> \e$B$r\e(B <code>mayud.sys</code> \e$B$NL>A0$G>e=q$-%3%T!<$7$^$9!#\e(B(\e$BB($A\e(B <code>mayud.sys</code> \e$B$r\e(B <code>mayudrsc.sys</code>\e$B$GCV$-49$($k!#\e(B)
+               <li>\e$B:F5/F0$7$^$9!#\e(B
+               <li>\e$B%3%s%H%m!<%k%Q%M%k$+$i!VAk;H$$$NM+]5!W$r%"%s%$%s%9%H!<%k$7$^$9!#\e(B
+             </ol>
+           </div>
+       </dd>
+      </dl>
+      
+  <dt class="h1"><a name="UNINSTALL">3. uninstall</a>
+      
+  <dd class="d1">
+      <p>\e$B%3%s%H%m!<%k%Q%M%k$+$i!VAk;H$$$NM+]5!W$r%"%s%$%s%9%H!<%k$7$F$/$@$5$$!#%"%s%$%s%9%H!<%k8e$K:F$S%$%s%9%H!<%k$9$k>l9g$O!":F5/F08e$K%$%s%9%H!<%k$7$F2<$5$$!#$^$?!"%"%s%$%s%9%H!<%k8e$K\e(B <code>mayu.dll</code> \e$B$,;D$k>l9g$,$"$k$N$G!"$=$N>l9g$O:F5/F08e$K<j:n6H$G>C$7$F$/$@$5$$!#\e(B</p>
+      
+    <dt class="h1"><a name="MENU">4. menu</a>
+
+    <dd class="d1">
+       <div>
+         <p>\e$B!VAk;H$$$NM+]5!W$r<B9T$9$k$H!"%?%9%/%H%l%$$K!VAk;H$$$NM+]5!W$N%"%$%3%s$,I=<($5$l$^$9!#$3$N!VAk;H$$$NM+]5!W$N%"%$%3%s$r1&%/%j%C%/$9$k$H%a%K%e!<$,=P$F$-$^$9!#\e(B</p>
+
+         <p><img src="menu-ja.png"></p>
+
+         <dl>
+           <dt><span class="menu-item"><a name="menu-r">\e$B:FFI$_9~$_\e(B(<u>R</u>)</a></span>
+           <dd>
+               <div>
+                 <p>\e$B@_Dj%U%!%$%k$r:FFI$_9~$_$7$^$9!#\e(B<a href="CUSTOMIZE-ja.html#function_LoadSetting"><code>&amp;LoadSetting</code></a> \e$B$HF1$8$G$9!#\e(B</p>
+               </div>
+               
+           <dt><span class="menu-item"><a name="menu-c"></a>\e$BA*Br\e(B(<u>C</u>) &#9658;</span>
+           <dd>
+               <div>
+                 <p>\e$B%5%V%a%K%e!<$+$i@_Dj%U%!%$%k$N@Z$jBX$($r9T$$$^$9!#!VAk;H$$$NM+]5!W$,%G%U%)%k%H$GMQ0U$7$F$$$k%5%s%W%k@_Dj$O\e(B 8 \e$B$D$"$j$^$9!#0J2<$N>r7o$NAH$_9g$o$;$H$J$j$^$9!#\e(B</p>
+                 
+                 <ol style="list-style-type: lower-alpha;">
+                   <li>\e$B%-!<%\!<%I$OF|K\8l\e(B 109 \e$B%-!<%\!<%I$+!"1Q8l\e(B104 \e$B%-!<%\!<%I$+!#\e(B
+                   <li>\e$B%-!<%H%C%W$NI=<($NDL$j$K;H$&$N$+!"\e(B109 (\e$B$^$?$O\e(B 104) \e$B%-!<%\!<%I$r;H$C$F$$$k$,!"\e(B104 (\e$B$^$?$O\e(B 109) \e$B%-!<%\!<%I$HF1$8G[CV$G;H$&$N$+!#\e(B
+                   <li>Emacs (UNIX \e$B$GI8=`E*$J%(%G%#%?$N0l$D\e(B) \e$B$K;w$;$?%P%$%s%G%#%s%0$r;H$&$+$I$&$+!#\e(B
+                 </ol>
+                 
+                 <p>\e$B$3$N$&$A!"\e(Ba \e$B$O%$%s%9%H!<%k;~$K7hDj$5$l$k$N$G!"%5%V%a%K%e!<$KI=<($5$l$k$b$N$O\e(B b, c \e$B$NAH$_9g$o$;\e(B 4 \e$B<oN`$K$J$j$^$9!#\e(B</p>
+                 
+                 <p>\e$B%G%U%)%k%H@_Dj0J30$KFH<+$N@_Dj$,I,MW$J>l9g$O!"\e(B<a href="CUSTOMIZE-ja.html#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>\e$B$K\e(B <code>.mayu</code> \e$B%U%!%$%k$r:n$j$=$N%U%!%$%k$K@_Dj$r5-=R$7$^$9!#$=$7$F%5%V%a%K%e!<$G\e(B (\e$B%[!<%`%G%#%l%/%H%j$+$i\e(B) \e$B$rA*$S$^$9!#>\$7$/$O\e(B<a href="#TUTORIAL">\e$B%A%e!<%H%j%"%k\e(B</a>\e$B$H\e(B<a href="CUSTOMIZE-ja.html">\e$B%+%9%?%^%$%:\e(B</a>\e$B$r;2>H$7$F$/$@$5$$!#\e(B</p>
+               </div>
+               
+           <dt><span class="menu-item"><a name="menu-s">\e$B@_Dj\e(B(<u>S</u>)...</a></span>
+           <dd>
+               <div>
+                 <p><span class="menu-item">\e$BA*Br\e(B(<u>C</u>) &#9658;</span>\e$B$NA*Br;h$H$J$k@_Dj%U%!%$%k$r:n@.$7$^$9!#\e(B</p>
+                 
+                 <p class="noindent"><img src="setting-ja.png"></p>
+                 
+                 <p>\e$B1&B&$NLp0u%\%?%s$G%a%K%e!<$KI=<($5$l$k=g=x$rJQ99$9$k$3$H$,$G$-$^$9!#\e(B</p>
+                 
+                 <p>\e$B!VDI2C\e(B(<u>A</u>)\e$B!WKt$O!VJT=8\e(B(<u>E</u>)\e$B!W%\%?%s$r2!$9$+!"9T$r%@%V%k%/%j%C%/$9$k$HJT=8%@%$%"%m%0%\%C%/%9$,I=<($5$l$^$9!#\e(B</p>
+                 
+                 <p class="noindent"><img src="edit-setting-ja.png"></p>
+                 
+                 <p>\e$B!VL>A0\e(B(<u>N</u>)\e$B!W$K$O!"%a%K%e!<$KI=<($5$l$kL>A0$r5-=R$7$^$9!#!V%U%!%$%kL>\e(B(<u>F</u>)\e$B!W$r6uMs$K$9$k$H\e(B<a href="CUSTOMIZE-ja.html#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>\e$B$+$i\e(B <code>.mayu</code> \e$B$rFI$_9~$_$^$9!#!V%7%s%\%k\e(B(<u>S</u>)\e$B!W$K$O!"\e(B<a href="CUSTOMIZE-ja.html#cond">\e$B>r7oJ,4t\e(B</a>\e$B$G;HMQ$5$l$k%7%s%\%k$r5-=R$7$^$9!#%7%s%\%k$NF,$K\e(B <code>-D</code> \e$B$r$D$1!"J#?t$N%7%s%\%k$O\e(B <code>;</code> \e$B$G6h@Z$j$^$9!#\e(B</p>
+               </div>
+               
+           <dt><span class="menu-item">\e$B0l;~Dd;_\e(B(<u>T</u>)</span>
+           <dd>
+               <div>
+                 <p>\e$B!VAk;H$$$NM+]5!W$N5!G=$r0l;~E*$KDd;_$7$^$9!#%-!<%\!<%I$+$i$NF~NO$O!"!VAk;H$$$NM+]5!W$,B8:_$7$J$$;~$HF1$8F0:n$r$7$^$9!#$3$N$H$-!"%?%9%/%H%l%$$N%"%$%3%s$O\e(B <img src="pause-ja.png" align="top"> \e$B$K$J$j$^$9!#\e(B</p>
+               </div>
+
+           <dt><span class="menu-item"><strong><a name="menu-i">\e$BD4::\e(B</a>(<u>I</u>)...</strong></span>
+           <dd>
+               <div>
+                 <p>\e$BD4::%&%$%s%I%&$H%m%0%&%$%s%I%&$rI=<($7$^$9!#\e(B</p>
+                 
+                 <p><img src="investigate-ja.png"></p>
+                 
+                 <p>\e$B$=$l$>$l$N>l=j$G%-!<$r2!$9$3$H$K$h$j!"%-!<$N%9%-%c%s%3!<%I$d2>A[%-!<%3!<%I$rD4$Y$k$3$H$,$G$-$^$9!#\e(B</p>
+                 
+                 <p>\e$B$^$?!"\e(B<img src="target.png" alt="\e$B%?!<%2%C%H\e(B"> \e$B$rD4$Y$?$$%&%#%s%I%&$^$G%I%i%C%0$9$k$H%&%#%s%I%&%/%i%9$H%&%#%s%I%&%?%$%H%k$,%m%0$K=PNO$5$l$^$9!#$3$3$GD4::$7$?%&%#%s%I%&%/%i%9L>$H%&%#%s%I%&%?%$%H%k$O!"@_Dj%U%!%$%k$G\e(B <a href="CUSTOMIZE-ja.html#keymap"><code>window</code></a> \e$B$K5-=R$9$k$3$H$,$G$-$^$9!#\e(B(\e$B$3$3$GD4::$9$kBe$o$j$K!"\e(B<code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowIdentify"><code>&amp;WindowIdentify</code></a> \e$B$rMxMQ$7$F$bD4$Y$k$3$H$,$G$-$^$9\e(B)</p>
+               </div>
+               
+           <dt><span class="menu-item"><a name="menu-l">\e$B%m%0\e(B(<u>L</u>)...</a></span>
+           <dd>
+               <div>
+                 <p>\e$B%m%0%&%$%s%I%&$rI=<($7$^$9!#\e(B</p>
+                 
+                 <p><img src="log-ja.png"></p>
+
+                 <p><a href="#menu-i" class="menu-item">\e$BD4::\e(B(<u>I</u>)...</a>\e$B$N7k2L$d%(%i!<$J$I$,$3$3$KI=<($5$l$^$9!#\e(B(\e$B!V"">\:Y\e(B(<u>D</u>)\e$B!W$r%A%'%C%/$9$k$H!"!VAk;H$$$NM+]5!W$NFbIt$NJQ49=hM}$,>\:Y$KI=<($5$l$^$9$,Hs>o$KFq2r$G$9\e(B)</p>
+               </div>
+
+           <dt><span class="menu-item">\e$B%P!<%8%g%s\e(B(<u>V</u>)...</span>
+           <dd>
+               <div>
+                 <p>\e$B%P!<%8%g%s>pJs$J$I$rI=<($7$^$9!#%P%0%l%]!<%H$r$9$k;~$K$3$NFbMF$r%3%T!<$9$k$HJXMx$G$9!#\e(B</p>
+
+                 <p><img src="version-ja.png"></p>
+               </div>
+
+           <dt><span class="menu-item">\e$B%X%k%W\e(B(<u>H</u>)...</span>
+           <dd>
+               <div>
+                 <p>\e$B$3$N%^%K%e%"%k$rI=<($7$^$9!#\e(B</p>
+               </div>
+               
+         </dl>
+       </div>
+       
+    <dt class="h1"><a name="TUTORIAL">5. tutorial</a>
+
+    <dd class="d1">
+       <div>
+         <!--p>\e$B!VAk;H$$$NM+]5!W$OHs>o$K9b5!G=$J%-!<%P%$%s%G%#%s%0JQ99%D!<%k$J$N$G$9$,!"%A%e!<%H%j%"%k$b\e(BGUI\e$B$G$N@_Dj%D!<%k$b$J$/!"0lJ}$G%^%K%e%"%k$OD9Bg$J$?$a!"=i$a$F;H$&%f!<%6!<$K$OJB30$l$FI_5o$N9b$$>uBV$,B3$$$F$$$^$7$?!#\e(B</p-->
+         
+         <p>\e$B$3$N>O$G$O!"!VAk;H$$$NM+]5!W$r=i$a$F;H$&%f!<%6!<$,!"<B:]$K@_Dj$r7+$jJV$7$J$,$i!"4JC1$J%+%9%?%^%$%:$G$"$l$PLdBj$J$/$G$-$k%l%Y%k$KE~C#$9$k$3$H$rL\;X$7$^$9!#$^$:$O$3$NJ8>O$K1h$C$F!"<B:]$K%5%s%W%k$N@_Dj$r;n$7$F$_$F$/$@$5$$!#>\:Y$,CN$j$?$$>l9g$K$O!"3F>O$N%j%s%/@h$G>\:Y$rFI$`$3$H$,$G$-$^$9$N$G!"5?LdE@$,$"$l$P\e(B 2 \e$B<~L\0J9_$G%j%s%/@h$r8+$F$$$1$P$h$$$G$7$g$&!#\e(B</p>
+
+         <p>\e$B$5$F!"\e(B<a href="#INSTALL">\e$B%$%s%9%H!<%k\e(B</a>\e$B$O:Q$s$G$$$^$9$h$M!)\e(B<a href="#menu-c">\e$B%G%U%)%k%H@_Dj\e(B</a>\e$B$G$OK0$-B-$i$J$$$+$i$3$l$rFI$s$G$$$k$s$G$9$h$M!)$G$O!"!VAk;H$$$NM+]5!W$N??2A$rH/4x$9$k$?$a$N!"D9$$F;$N$j$NBh0lJb$rF'$_=P$7$^$7$g$&!#\e(B</p>
+
+         <dl>
+           <dt class="h2"><a name="dotmayu">i. \e$B<+J,MQ$N@_Dj%U%!%$%k$r:n$k\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p>\e$B$^$:!"%?%9%/%H%l%$%a%K%e!<$N\e(B<a href="#menu-c" class="menu-item">\e$BA*Br\e(B(<u>C</u>) &#9658;</a>\e$B$N\e(B<span class="menu-item">(\e$B%[!<%`%G%#%l%/%H%j$+$i\e(B)</span>\e$B$G;H$o$l$k<+J,MQ$N@_Dj%U%!%$%k!"\e(B<code>.mayu</code> \e$B%U%!%$%k$r:n$j$^$9!#\e(B(\e$B%$%s%9%H!<%k$7$?%G%#%l%/%H%j$KB8:_$9$k\e(B <code>dot.mayu</code> \e$B$rJT=8$7$F$O$$$1$^$;$s\e(B)</p>
+
+                 <p>\e$B$^$:!"4D6-JQ?t\e(B <code>HOME</code> \e$B$G!"\e(B<a href="CUSTOMIZE-ja.html#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>\e$B$N0LCV$r;XDj$7$^$9!#%[!<%`%G%#%l%/%H%j$O!"Nc$($P$"$J$?$NL>A0$,\e(B mayu \e$B$G$"$l$P!"!V\e(B<code>c:\home\mayu</code>\e$B!W$N$h$&$J%G%#%l%/%H%j$r:n$k$N$,\e(B UNIX \e$BIw$G$*A&$a$G$9!#\e(B</p>
+
+                 <dl>
+                   <dt class="h3">Windows2000/XP \e$B$N>l9g\e(B
+                   <dd class="d3">
+                       <div>
+                         <p>\e$B%G%9%/%H%C%W$N!V%^%$%3%s%T%e!<%?!W$N1&%/%j%C%/%a%K%e!<$N!V%W%m%Q%F%#!W$N!V>\:Y!W$N!V4D6-JQ?t!W$G!"%f!<%6!<4D6-JQ?t\e(B <code>HOME</code> \e$B$r:n@.$7!"\e(B<code>c:\home\mayu</code> \e$B$K@_Dj$7$^$9!#\e(B</p>
+                       </div>
+
+                 </dl>
+                 
+                 <p>\e$B$=$7$F\e(B <code>c:\home\mayu</code> \e$B$H$$$&%G%#%l%/%H%j$r:n@.$7$F$*$-$^$9!#\e(B</p>
+                 
+                 <p>\e$B$3$N%G%#%l%/%H%j$K!"\e(B<code>.mayu</code> \e$B$H$$$&%U%!%$%k$r:n$j$^$9!#0lIt$N%(%G%#%?$G$O%I%C%H$+$i;O$^$k%U%!%$%kL>$O:n$l$J$$$+$b$7$l$^$;$s$,!"$=$N$h$&$J%(%G%#%?$r;H$C$F$$$k>l9g$K$O!"$3$N:]>h$j49$($^$7$g$&!#M-L>$I$3$m$N%F%-%9%H%(%G%#%?$G$OBgDq:n$l$k$H;W$$$^$9$,!"FC$K\e(B Emacs \e$B$,K:$l$i$l$J$$?M$K$O\e(B <a href="http://www.jsdlab.co.jp/~kamei/" target="_top">xyzzy</a> \e$B$d\e(B Meadow \e$B$J$I$,$*A&$a$G$9!#\e(B</p>
+                         
+                 <p>\e$B?7$?$K\e(B <code>.mayu</code> \e$B$r@_Dj$7$?$j!"%G%#%l%/%H%j$r:n$k$N$,7y$J>l9g$O!"%^%$%I%-%e%a%s%H$ND>2<$K:n$C$F$b\e(B OK \e$B$G$9!#\e(B</p>
+                 
+                 <p>\e$B;2>H\e(B: <a href="CUSTOMIZE-ja.html#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a></p>
+               </div>
+               
+           <dt class="h2"><a name="minimum">ii. \e$B:n$C$?@_Dj%U%!%$%k$K:GDc8B$N@_Dj$r=q$/\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 
+                 <p>\e$B$^$:!"$$$/$D$+$NI,MW$J%U%!%$%k$NFbMF$r<h$j9~$`I,MW$,$"$j$^$9!#\e(B<!-- \e$B>\:Y$O\e(B <a href="../contrib/mayu-settings.txt"><code>contrib/mayu-settings.txt</code></a> \e$B$r8+$F$/$@$5$$!#\e(B --></p>
+
+                 <dl>
+                   <dt class="h3">109 \e$BF|K\8l%-!<%\!<%I$N>l9g\e(B
+                   <dd class="d3">
+                       <div>
+                         <p><code>.mayu</code> \e$B%U%!%$%k$N@hF,$K0J2<$N$h$&$K5-=R$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         include "109.mayu"    # 109 \e$B%-!<%\!<%I@_Dj\e(B
+                         </p>
+                         
+                         <p>\e$B9%$_$K1~$8$F!"0J2<$N3F9T$r=q$/$+=q$+$J$$$+$r7h$a$F$/$@$5$$!#\e(B(\e$B%?%9%/%H%l%$%a%K%e!<\e(B<a href="#menu-c" class="menu-item">\e$BA*Br\e(B(<u>C</u>) &#9658;</a>\e$B$N%G%U%)%k%H@_Dj$KBP1~$7$F$$$^$9\e(B) </p>
+                         
+                         <p class="sample">
+                         include "104on109.mayu"       # 109 \e$B%-!<%\!<%I$r\e(B 104 \e$B%-!<%\!<%IIw$K\e(B<br>
+                         include "default.mayu"        # Emacs \e$B%i%$%/$J$5$^$6$^$J@_Dj\e(B
+                         </p>
+                       </div>
+
+                   <dt class="h3">104 \e$B1Q8l%-!<%\!<%I$N>l9g\e(B
+                   <dd class="d3">
+                       <div>
+                         <p><code>.mayu</code> \e$B%U%!%$%k$N@hF,$K0J2<$N$h$&$K5-=R$7$^$9!#\e(B</p>
+                         
+                         <p class="sample">
+                         include "104.mayu"    # 104 \e$B%-!<%\!<%I@_Dj\e(B
+                         </p>
+                         
+                         <p>\e$B9%$_$K1~$8$F!"0J2<$N3F9T$r=q$/$+=q$+$J$$$+$r7h$a$F$/$@$5$$!#\e(B (\e$B%?%9%/%H%l%$%a%K%e!<\e(B<a href="#menu-c" class="menu-item">\e$BA*Br\e(B(<u>C</u>) &#9658;</a>\e$B$N%G%U%)%k%H@_Dj$KBP1~$7$F$$$^$9\e(B) </p>
+                         
+                         <p class="sample">
+                         include "109on104.mayu"       # 104 \e$B%-!<%\!<%I$r\e(B 109 \e$B%-!<%\!<%IIw$K\e(B<br>
+                         include "default.mayu"        # Emacs \e$B%i%$%/$J$5$^$6$^$J@_Dj\e(B
+                         </p>
+                       </div>
+                       
+                 </dl>
+                 
+                 <p>\e$B$3$3$^$G=q$-9~$s$@$i!"%?%9%/%H%l%$%a%K%e!<$G\e(B<a href="#menu-c" class="menu-item">\e$BA*Br\e(B(<u>C</u>) &#9658;</a>\e$B$+$i\e(B<span class="menu-item">(\e$B%[!<%`%G%#%l%/%H%j$+$i\e(B)</span>\e$B$rA*$s$G$/$@$5$$!#\e(B<a href="#menu-l">\e$B%m%0%&%$%s%I%&\e(B</a>\e$B$K%(%i!<%a%C%;!<%8$,=P$J$$$h$&$G$"$l$P!"$3$3$^$G$O$&$^$/$$$C$F$$$^$9!#$3$l$G%+%9%?%^%$%:$N=`Hw$,$G$-$^$7$?!#$3$N@h$K<+J,9%$_$N@_Dj$r=q$-2C$($F$$$/$3$H$K$J$j$^$9!#$=$7$F=q$-2C$($?$i\e(B<a href="#menu-r" class="menu-item">\e$B:FFI$_9~$_\e(B(<u>R</u>)</a>\e$B$7$^$9!#\e(B</p>
+
+                 <p>\e$B%m%0%&%$%s%I%&$K!V\e(Berror: failed to load.\e$B!W$H=P$F$$$?>l9g!"\e(B
+\e$B@_Dj%U%!%$%k$NFI$_9~$_$K<:GT$7$F$$$^$9!#@_Dj%U%!%$%k$N%Q%9$H!"9T?t!"%(%i!<%a%C%;!<%8$,I=<($5$l$F$$$k$N$G!"$=$l$r;29M$K=$@5$7$F$/$@$5$$!#\e(B</p>
+
+                 <p>\e$B;2>H\e(B: <a href="../contrib/mayu-settings.txt"><code>contrib/mayu-settings.txt</code></a></p>
+               </div>
+               
+           <dt class="h2"><a name="key">iii. \e$BIaDL$N%-!<$rF~$lBX$($F$_$k\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 
+                 <p>\e$B0J2<!"@bL@$NJX59>e\e(B 109 \e$B%-!<%\!<%I$r;H$C$F$$$k$b$N$H$7$FOC$r$9$9$a$^$9\e(B</p>
+
+                 <p>\e$B$^$:!"\e(B<kbd>Esc</kbd> \e$B%-!<$H\e(B <kbd>\e$BH>3Q\e(B/\e$BA43Q\e(B</kbd> \e$B%-!<$rF~$lBX$($F$_$^$9!#$3$l$O!"\e(B<code>.mayu</code> \e$B%U%!%$%k$NKvHx$K0J2<$N$h$&$KDI2C$7$^$9!#\e(B</p>
+
+                 <p class="sample">
+                 keymap Global<br>
+                 key Esc       = \e$BH>3Q\e(B/\e$BA43Q\e(B<br>
+                 key \e$BH>3Q\e(B/\e$BA43Q\e(B = Esc<br>
+                 </p>
+                 
+                 <p><a href="#menu-r" class="menu-item">\e$B:FFI$_9~$_\e(B(<u>R</u>)</a>\e$B$r$7$F3NG'$7$F$_$F$/$@$5$$!#\e(B</p>
+
+                 <p>1 \e$B9TL\$N\e(B <code>keymap Global</code> \e$B$O!"<!$N\e(B <code>keymap</code> \e$B;XDj$^$G$N5-=R$OA4$F$N%&%$%s%I%&$GM-8z$J@_Dj$H$9$k!"$H$$$&;X<($G$9!#\e(B</p>
+
+                 <p>2, 3 \e$B9TL\$N$h$&$K\e(B <code>key \e$B%-!<L>\e(B = \e$B%-!<L>\e(B</code> \e$B$H=q$/$3$H$G!"$"$k%-!<$r2!$7$?$H$-$N5sF0$rJQ99$G$-$^$9!#>e$NNc$G$"$l$P!"\e(B<kbd>Esc</kbd> \e$B$,2!$5$l$?$H$-$O\e(B <kbd>\e$BH>3Q\e(B/\e$BA43Q\e(B</kbd> \e$B$,2!$5$l$?$h$&$K!"\e(B<kbd>\e$BH>3Q\e(B/\e$BA43Q\e(B</kbd> \e$B$,2!$5$l$?$H$-$O\e(B <kbd>Esc</kbd> \e$B$,2!$5$l$?$h$&$JF0:n$K$J$j$^$9!#\e(B</p>
+
+                 <p>\e$B%-!<L>$O!"%?%9%/%H%l%$%a%K%e!<\e(B<a href="#menu-i" class="menu-item">\e$BD4::\e(B(I)...</a>\e$B$N!V%9%-%c%s%3!<%I$ND4::!W$GD4$Y$?$$%-!<$r2!$9$3$H$G$o$+$j$^$9!#\e(B<kbd>Esc</kbd> \e$B%-!<$H!"\e(B<kbd>\e$BH>3Q\e(B/\e$BA43Q\e(B</kbd> \e$B%-!<$r=g$K2!$7$?$H$-$N%m%0%&%$%s%I%&$K$O!"Nc$($P0J2<$N$h$&$KI=<($5$l$F$$$k$O$:$G$9!#\e(B</p>
+
+                 <p class="sample">
+                 0x01   D-Esc<br>
+                 0x01   U-Esc<br>
+                 0x29   D-\e$BH>3Q\e(B/\e$BA43Q\e(B<br>
+                 0x29   U-\e$BH>3Q\e(B/\e$BA43Q\e(B<br>
+                 </p>
+
+                 <p>\e$B%-!<L>$NA0$N\e(B <code>D-</code> \e$B$H$$$&$N$O%-!<$,2!$5$l$?!"\e(B<code>U-\e$BH>3Q\e(B/\e$BA43Q\e(B</code> \e$B$N\e(B <code>U-</code> \e$B$H$$$&$N$O%-!<$,N%$5$l$?!"$H$$$&>uBV$r$=$l$>$lI=$7$^$9!#\e(B</p>
+                 
+                 <p>\e$B;2>H\e(B: <a href="CUSTOMIZE-ja.html#key">\e$B%-!<3d$jEv$F$NJQ99\e(B</a></p>
+               </div>
+
+           <dt class="h2"><a name="window">iv. \e$BFCDj$N%&%$%s%I%&$N$_$G%-!<3d$jEv$F$rJQ99$7$F$_$k\e(B</a>
+
+           <dd class="d2">
+               <div>
+                 
+                 <p>\e$B$D$.$K!"\e(BInternet Explorer \e$B$G$N$_\e(B <kbd>PageUp</kbd>/<kbd>PageDown</kbd> \e$B%-!<$G!"\e(B<kbd>Home</kbd>/<kbd>End</kbd> \e$B$NF0$-$r$5$;$F$_$^$9!#\e(B<code>.mayu</code> \e$B$NKvHx$K0J2<$N$h$&$KDI2C$7$^$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 window        InternetExplorer /iexplore\.exe/ : Global<br>
+                 key     PageUp = Home<br>
+                 key     PageDown = End<br>
+                 </p>
+                 
+                 <p>1 \e$B9TL\$N!"\e(B<code>window \e$B%-!<%^%C%WL>\e(B /\e$B%&%#%s%I%&%/%i%9L>\e(B/ : \e$B?F%-!<%^%C%WL>\e(B</code> \e$B$O!"0J9_$N;XDj$OFCDj$N%&%$%s%I%&$K$D$$$F$N$_M-8z$H$9$k!"$H$$$&;X<($G$9!#%-!<%^%C%WL>$O$o$+$j$d$9$$E,Ev$JL>A0$r$D$1$^$9!#?F%-!<%^%C%WL>$O\e(B Emacs \e$B$C$]$/$9$k$J$i\e(B <code>EmacsMove</code> \e$B$d\e(B <code>EmacsEdit</code> \e$B$K!"$=$&$G$J$1$l$P\e(B <code>Global</code> \e$B$K$9$l$P$h$$$G$7$g$&!#\e(B</p>
+                 
+                 <p>\e$B%&%$%s%I%&%/%i%9L>$rD4::$9$k$K$O!"%?%9%/%H%l%$%a%K%e!<\e(B<a href="#menu-i" class="menu-item">\e$BD4::\e(B(I)...</a>\e$B$N!V%&%#%s%I%&$ND4::!W$G!"D4$Y$?$$%&%#%s%I%&$d%3%s%H%m!<%k$K\e(B <img src="target.png" alt="\e$B%?!<%2%C%H\e(B"> \e$B$r%I%i%C%0$7$^$9!#\e(B</p>
+                 
+                 <p>Internet Explorer \e$B$X%I%i%C%0$9$k$H\e(B (\e$BESCf$K$5$o$C$?A4$F$N%&%$%s%I%&$d%3%s%H%m!<%k$N>pJs$,=P$k$N$G!"B>$K$b$$$m$$$m=P$k$O$:$G$9$,\e(B)\e$B!"<!$N$h$&$JI=<($,=P$k$O$:$G$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 CLASS:        C:\Program Files\Internet Explorer\iexplore.exe:IEFrame<br>
+                 TITLE:        C:\Program Files\Internet Explorer\iexplore.exe:\e$BAk;H$$$NM+]5\e(B - README - Microsoft Internet Explorer<br>
+                 Toplevel Window Position/Size: (-4, -4) / (1032x748)<br>
+                 Desktop Window Position/Size: (0, 0) / (1024x740)<br>
+                 </p>
+                 
+                 <p>\e$B$3$N\e(B <code>CLASS</code> \e$B$NItJ,$+$iFCD'E*$JJ8;zNs$rCj=P$7!"\e(B<a href="CUSTOMIZE-ja.html#regexp">\e$B@55,I=8=\e(B</a>\e$B$H8F$P$l$k5-K!$G\e(B <code>/\e$BJ8;zNs\e(B/</code> \e$B$N$h$&$K=q$1$P\e(B OK \e$B$G$9!#@55,I=8=$,$h$/$o$+$i$J$$>l9g$K$O!"\e(B<code>\</code> \e$B$O\e(B <code>\\</code>\e$B!"\e(B<code>.</code> \e$B$O\e(B <code>\.</code> \e$B$H=q$/$3$H$KCm0U$9$l$P$H$j$"$($:$"$^$jLdBj$O$J$$$G$7$g$&!#\e(B</p>
+                 
+                 <p>\e$B;2>H\e(B: <a href="CUSTOMIZE-ja.html#windowClass">\e$B%&%#%s%I%&%/%i%9\e(B/\e$B%?%$%H%kL>\e(B</a>\e$B!&\e(B<a href="CUSTOMIZE-ja.html#regexp">\e$B@55,I=8=\e(B</a></p>
+               </div>
+               
+           <dt class="h2"><a name="modifier">v. \e$B%-!<$,%b%G%#%U%!%$%d%-!<$H6&$K2!$5$l$?>l9g$KCV$-49$($F$_$k\e(B</a>
+
+           <dd class="d2">
+               <div>
+                 
+                 <p>\e$B$D$.$K!"\e(BInternet Explorer \e$B$G$NF0:n$r$5$i$KJQ99$7$F!"\e(B<kbd>Ctrl</kbd> + <kbd>PageUp</kbd>/<kbd>PageDown</kbd> \e$B$G!"\e(B<kbd>Home</kbd>/<kbd>End</kbd> \e$B$r2!$7$?$h$&$KF0$+$7$F$_$^$9!#A0>O$GDI2C$7$?FbMF$rJQ99$7$F0J2<$N$h$&$K=q$-49$($^$9!#\e(B(<code>C-</code> \e$B$,%-!<L>$NA0$KDI2C$5$l$^$7$?\e(B)</p>
+                 
+                 <p class="sample">
+                 window        InternetExplorer /iexplore\.exe/ : Global<br>
+                 key     C-PageUp = Home<br>
+                 key     C-PageDown = End<br>
+                 </p>
+                 
+                 <p>2, 3 \e$B9TL\$N%-!<$N;XDj$K$D$$$F$O!"$d$O$j%9%-%c%s%3!<%I$ND4::$GD4$Y$^$9!#\e(B<kbd>Ctrl</kbd> + <kbd>PageDown</kbd> \e$B$rF~NO$9$k$H!"<!$N$h$&$KI=<($5$l$^$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 &nbsp;&nbsp;&nbsp;0x1d   D-LeftControl<br>
+                 E0-0x51   D-C-PageDown<br>
+                 E0-0x51   U-C-PageDown<br>
+                 &nbsp;&nbsp;&nbsp;0x1d   U-LeftControl<br>
+                 </p>
+                 
+                 <p>1, 4 \e$B9TL\$O\e(B <kbd>Ctrl</kbd> \e$B%-!<$N2!$7\e(B/\e$BN%$7$G$9!#\e(B2, 3 \e$B9TL\$+$i!"\e(B<code>C-PageDown</code> \e$B$,=q$/$Y$-%-!<L>$H$$$&$3$H$K$J$j$^$9!#$3$3$N\e(B <code>C-</code> \e$B$H$$$&$N$O!"\e(B<kbd>Ctrl</kbd> \e$B$,2!$5$l$F$$$k!"$H$$$&%-!<$N>uBV$rI=$95-9f$G$9!#\e(B<kbd>Ctrl</kbd> \e$B%-!<0J30$K$b!"\e(B<kbd>Windows</kbd> \e$B$d\e(B <kbd>Alt</kbd> \e$B$d\e(B <kbd>Shift</kbd> \e$B$N>uBV!"$^$?\e(B <kbd>CapsLock</kbd> \e$B$d\e(B <kbd>NumLock</kbd> \e$B$J$I$N%-!<$,%m%C%/>uBV$K$"$k$+$I$&$+$b$d$O$jF1MM$G$9!#$3$l$i$NFCJL$J%-!<$r!"!VAk;H$$$NM+]5!W$G$O!"%b%G%#%U%!%$%d$H8F$s$G$$$^$9!#\e(B
+\e$B%-!<3d$jEv$FJQ99$O!"$3$N$h$&$K%b%G%#%U%!%$%d$r4^$a$F;XDj$9$k$3$H$,$G$-$^$9!#\e(B
+  </p>
+<p>
+\e$B5U$K$$$&$H!"A0>O$^$G$N%-!<3d$jEv$FJQ99$G$O\e(B
+\e$B%b%G%#%U%!%$%d$r2?$b;XDj$7$F$$$^$;$s$+$i!"\e(B
+<kbd>Ctrl</kbd>\e$B$d\e(B<kbd>Alt</kbd>\e$B$J$I$,2!$5$l$F$$$k$H\e(B
+\e$B%-!<%$%Y%s%H$NCV$-49$($r9T$$$^$;$s!#\e(B
+</p>
+                 
+                 <p>\e$B;2>H\e(B: <a href="CUSTOMIZE-ja.html#modifier">\e$B%b%G%#%U%!%$%d$N;XDj\e(B</a></p>
+               </div>
+               
+           <dt class="h2"><a name="modifier2">vi. \e$B%b%G%#%U%!%$%d%-!<$N>uBV$HL54X78$KCV$-49$($F$_$k\e(B</a>
+
+           <dd class="d2">
+               <div>
+
+                 <p>\e$BA0>O$N@_Dj$G$O!"\e(B<kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>PageUp</kbd>/<kbd>PageDown</kbd> \e$B$HF~NO$7$?>l9g!"JQ49$5$l$:$K$=$N$^$^F~NO$5$l$F$7$^$$$^$9!#4{$K@bL@$7$?DL$j!"$3$l$O@5$7$$F0:n$G$9!#\e(B(\e$BIT@53N$J8@$$J}$G$9$,!"%b%G%#%U%!%$%d$,2!$5$l$F$$$k$HJL$N%-!<L>$K$J$k$N$G!"A0>O$N;XDj$G$OCV$-49$($,5/$-$J$$!"$HM}2r$7$F$/$@$5$$\e(B)</p>
+
+                 <p><kbd>Alt</kbd> \e$B$,2!$5$l$F$$$k$+$I$&$+$K$+$+$o$i$:\e(B <kbd>Ctrl</kbd> + <kbd>PageUp</kbd>/<kbd>PageDown</kbd> \e$B$r\e(B <kbd>Home</kbd>/<kbd>End</kbd> \e$B$N$h$&$KF0:n$5$;$k$K$O!"A0>O$N@_Dj$rJQ99$7$F0J2<$N$h$&$K=$@5$7$^$9!#\e(B</p>
+
+                 <p class="sample">
+                 window        InternetExplorer /iexplore\.exe/ : Global<br>
+                 key     *A-C-PageUp = *A-Home<br>
+                 key     *A-C-PageDown = *A-End<br>
+                 </p>
+
+                 <p>\e$B$3$l$O!"\e(B<kbd>Alt</kbd> \e$B$,2!$5$l$F$$$k$+$I$&$+$HL54X78$K\e(B <kbd>Ctrl</kbd> + <kbd>PageUp</kbd>/<kbd>PageDown</kbd> \e$B$r\e(B <kbd>Home</kbd>/<kbd>End</kbd> \e$B$HCV$-49$(!"$=$N:]$K\e(B <kbd>Alt</kbd> \e$B$N>uBV$OJ]B8$7$?$^$^$K$9$k@_Dj$G$9!#$D$^$j!"\e(B<kbd>Alt</kbd> \e$B$,2!$5$l$F$$$J$1$l$PA0>O$HF1MM$NCV$-49$($r9T$$!"\e(B<kbd>Alt</kbd> \e$B$,2!$5$l$F$$$l$P\e(B <kbd>Ctrl</kbd> + <kbd>Alt</kbd> + <kbd>PageUp</kbd> \e$B$r\e(B <kbd>Alt</kbd> + <kbd>Home</kbd> \e$B$N$h$&$KCV$-49$($^$9!#\e(B</p>
+                 
+                 <p>\e$B$3$l$r2!$7?J$a$k$H!"$"$i$f$k%b%G%#%U%!%$%d$N>uBV$K94$o$i$:$KCV$-49$($r$7$F!"$+$D$"$i$f$k%b%G%#%U%!%$%d$N>uBV$rJ]B8$7$FCV$-49$($k!"$H$$$&@_Dj$,2DG=$G$9!#6qBNE*$K$O!"\e(B<kbd>PageUp</kbd>/<kbd>PageDown</kbd> \e$B$r\e(B <kbd>Home</kbd>/<kbd>End</kbd> \e$B$HA4$/F1MM$K;H$$$?$$$H$$$&>l9g$K!"0J2<$N$h$&$J@_Dj$,$G$-$^$9!#\e(B</p>
+                 
+                 <p class="sample">
+                 window        InternetExplorer /iexplore\.exe/ : Global<br>
+                 key     *PageUp = *Home<br>
+                 key     *PageDown = *End<br>
+                 </p>
+
+                 <p>\e$B$3$N$h$&$K$9$l$P!"$"$i$f$k%b%G%#%U%!%$%d$N>uBV$K4X78$J$/!"\e(BInternet Explorer \e$B$G$N\e(B <kbd>PageUp</kbd>/<kbd>PageDown</kbd> \e$B$,\e(B <kbd>Home</kbd>/<kbd>End</kbd> \e$B$N$h$&$KF/$-$^$9!#\e(B</p>
+                 
+                 <p>\e$B;2>H\e(B: <a href="CUSTOMIZE-ja.html#ignoreModifier">\e$B%b%G%#%U%!%$%d%-!<$NL5;k\e(B</a>\e$B!&\e(B<a href="CUSTOMIZE-ja.html#inputModifier">\e$BF~NO$5$l$?%-!<$HF1$8%b%G%#%U%!%$%d$N;XDj\e(B</a></p>
+               </div>
+
+           <dt class="h2"><a name="mod">vii. \e$B%b%G%#%U%!%$%d$K$J$C$F$$$k%-!<$rCV$-49$($k\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 <p>\e$B%-!<3d$jEv$F$NJQ99$N:]$K!"%b%G%#%U%!%$%d%-!<$rCV$-49$($?$j!"%b%G%#%U%!%$%d%-!<$KCV$-49$($k>l9g$K$O!"FCJL$J@_Dj$,I,MW$K$J$j$^$9!#\e(B</p>
+                 
+                 <p>\e$B$?$H$($P!"\e(B<kbd>\e$BL5JQ49\e(B</kbd> \e$B%-!<$r:8\e(B <kbd>Alt</kbd> \e$B%-!<$H$7$F;HMQ$9$k$K$O!"\e(B</p>
+
+                 <p class="sample">
+                 keymap Global<br>
+                 mod alt += \e$BL5JQ49\e(B<br>
+                 key *\e$BL5JQ49\e(B = *LeftAlt<br>
+                 </p>
+
+                 <p>\e$B$N$h$&$K$J$j$^$9!#\e(B3 \e$B9TL\$O:#$^$GDL$j$N;XDj$G$9$,!"\e(B2 \e$B9TL\$N$h$&$K!"\e(B<code>mod \e$B%b%G%#%U%!%$%dL>\e(B += \e$B%-!<L>\e(B</code> \e$B$H$$$&;XDj$K$h$j!"?7$?$K%b%G%#%U%!%$%d$H$7$F\e(B<kbd>\e$BL5JQ49\e(B</kbd> \e$B%-!<$rEPO?$9$kI,MW$,$"$j$^$9!#\e(B</p>
+
+                 <p>\e$B5U$K!"%b%G%#%U%!%$%d$H$J$C$F$$$k%-!<$r%b%G%#%U%!%$%d$G$O$J$$%-!<$K3d$jEv$F$?$$>l9g$O!"\e(B<code>mod \e$B%b%G%#%U%!%$%dL>\e(B -= \e$B%-!<L>\e(B</code> \e$B$K$h$j!"%b%G%#%U%!%$%d@_Dj$r:o=|$9$kI,MW$,$"$j$^$9!#\e(B</p>
+                 
+                 <p>\e$B$?$H$($P!"1&\e(B <kbd>Windows</kbd> \e$B%-!<$G\e(B IME \e$B$N%*%s%*%U$r$9$k$K$O!"\e(B</p>
+                 
+                 <p class="sample">mod windows -= RightWindows<br>
+                 key RightWindows = $ToggleIME<br>
+                 </p>
+
+                 <p>\e$B$N$h$&$K$9$kI,MW$,$"$j$^$9!#$A$J$_$K!"\e(B<code>$ToggleIME</code> \e$B$H$$$&$N$O!"\e(B<a href="../109.mayu"><code>109.mayu</code></a> \e$B$^$?$O\e(B <a href="../104.mayu"><code>104.mayu</code></a> \e$B$GDj5A$5$l$F$$$k\e(B<a href="CUSTOMIZE-ja.html#keyseq">\e$B%-!<%7!<%1%s%9\e(B</a>\e$B$G!"\e(B109 \e$B%-!<%\!<%I$J$i$P\e(B <code>A-\e$BH>3Q\e(B/\e$BA43Q\e(B</code> \e$B$H=q$/$N$HF1$80UL#$K$J$j$^$9!#\e(B</p>
+
+                 <p>\e$B;2>H\e(B: <a href="CUSTOMIZE-ja.html#mod">\e$B%b%G%#%U%!%$%d%-!<3d$jEv$F$NJQ99\e(B</a></p>
+               </div>
+               
+           <dt class="h2"><a name="more">viii. \e$B$h$j9bEY$J@_Dj\e(B</a>
+               
+           <dd class="d2">
+               <div>
+                 
+                 <p>\e$B$3$3$^$GFI$a$P$b$&%A%e!<%H%j%"%k$OB46H$G$9!#$3$3$^$G$NFbMF$,40`z$J$i!">e5i<T$rL>>h$l$k$[$I$N%l%Y%k$^$GMh$F$$$^$9!#0l2s$GM}2r$9$k$N$OFq$7$$$+$b$7$l$^$;$s$,!"=,$&$h$j47$l$m$G!"D4::%&%$%s%I%&$G$"$l$3$l;n$7$F$_$F$/$@$5$$!#<+J,9%$_$N@_Dj$r$"$l$3$l=q$-2C$($F$$$/$&$A$K!">e$K$"$k3F%j%s%/$NFbMF$KL\$rDL$9I,MW$,=P$F$/$k$O$:$G$9$,!"$=$&$7$F$$$k$&$A$K%^%K%e%"%k$N8+J}$K$b47$l$F$/$k$O$:$G$9!#\e(B</p>
+                 
+                 <p>\e$B$5$i$J$k5!G=$H$7$F$O!"\e(B<a href="CUSTOMIZE-ja.html#function_Prefix">2 \e$B%9%H%m!<%/%-!<$N@_Dj\e(B</a>\e$B!"\e(B<a href="CUSTOMIZE-ja.html#oneShotModifier">OneShot \e$B%b%G%#%U%!%$%d\e(B</a>\e$B!"\e(BWindow\e$BA`:n$r$O$8$a$H$7$?\e(B<a href="CUSTOMIZE-ja.html#function">\e$BK-IY$J4X?t72\e(B</a>\e$B!"\e(B<a href="CUSTOMIZE-ja.html#def_subst">\e$BBeMQDj5A\e(B</a>\e$B$J$I$,$"$j$^$9!#$3$l$i$OI,MW$J>l9g$N$_L\$rDL$;$P==J,$G$9!#\e(B</p>
+               </div>
+               
+         </dl>
+       </div>
+
+  <dt class="h1"><a name="FAQ">6. frequently asked questions</a>
+
+  <dd class="d1">
+      <div>
+       <dl>
+         <dt class="h2">Q1. \e$B!VAk;H$$$NM+]5!W$r;H$C$F$$$k$H>!<j$K%-!<%j%T!<%H$7$F$7$^$$$^$9!#\e(B
+         <dt class="h2">Q2. \e$B!VAk;H$$$NM+]5!W$r=*N;8e$K\e(B Windows \e$B$,0[>o=*N;$7$^$9!#\e(B
+         <dt class="h2">Q3. \e$B!VAk;H$$$NM+]5!W$r;H$C$F$$$k$H$$$m$$$mJQ$K$J$j$^$9!#\e(B
+         <dd class="d2">
+             <p>\e$B$"$J$?$O0JA0\e(B AltIME \e$B$r;HMQ$7$F$$$?$O$:$G$9!#$3$l$i$N>I>u$O\e(B AltIME \e$B$,@5$7$/%"%s%$%s%9%H!<%k$5$l$F$$$J$$;~$K=P$^$9!#\e(B</p>
+             
+             <p>AltIME 2.27 \e$B$N\e(B README \e$B$K$h$l$P0J2<$N$h$&$K$9$k$=$&$G$9$N$G!"$=$N$h$&$K$7$F$/$@$5$$!#\e(B</p>
+             
+             <ol>
+               <li><p>AltIME \e$B$N@_Dj$G>oCs$5$;$F$$$k$J$i0lC6>oCs$N%*%W%7%g%s$r$O$:$7$F$/$@$5$$!#\e(B</p>
+                   <p>\e$B%9%?!<%H%"%C%W$G5/F0$7$F$$$k$H$-$O%9%?!<%H%"%C%W$+$i:o=|$7$F$/$@$5$$!#\e(B</p>
+                   <p>\e$B%5%&%s%I$r;HMQ$7$F$$$k>l9g$O@_Dj$r30$7!"@_Dj$r40A4$K:o=|$7$F$/$@$5$$!#\e(B</p>
+               <li><p>\e$B%?%9%/%H%l%$>e$N%"%$%3%s$r:8%/%j%C%/$7$F\e(B AltIME \e$B$N%*%W%7%g%s%@%$%"%m%0$rI=<($5$;!"%"%s%$%s%9%H!<%k%\%?%s$r2!$7$F$/$@$5$$!#\e(B</p>
+               <li><p>\e$B$$$C$?$s:F5/F08e!"\e(B<code>ALTIME*.*</code> \e$B$N%U%!%$%k$r:o=|$7$F$/$@$5$$!#\e(B</p>
+             </ol>
+             <p class="noindent">\e$B!ZCm0U![\e(BWindows2000\e$B$G$O%"%s%$%s%9%H!<%k%\%?%s$r;HMQ$;$:$K\e(B <code>\winnt\system32\drivers\altime.sys</code> \e$B$r:o=|$9$k$H\e(B Windows \e$B$,5/F0$G$-$J$/$J$k$3$H$,$"$j$^$9!#\e(B</p>
+
+         <dt class="h2">Q4. Explorer \e$B$G!"I=<(\e(B(V) \e$B$r\e(B <kbd>ALT</kbd> + <kbd>v</kbd> \e$B$GA*$Y$^$;$s!#\e(B(2ch \e$B$NK?%9%l$h$j\e(B)
+         <dt class="h2">Q5. PowerPoint \e$B$G!"\e(B<code>C-x</code>, <code>C-c</code>, <code>C-v</code> \e$B$J$I$G%3%T!<!&%Z!<%9%H$G$-$^$;$s!#\e(B
+         <dd class="d2">
+             <p>\e$B$"$J$?$O$*$=$i$/\e(B <a href="../default.mayu"><code>default.mayu</code></a> \e$B$r;H$C$F$$$^$9!#$3$l$rMxMQ$9$k$H$+$J$j?'!9$JA`:n$r\e(B Emacs \e$BIw$K$5$l$F$7$^$$$^$9$N$G!"$"$J$?$N\e(B Windows \e$B1x@wEY$,9b$+$C$?$j!"\e(BEmacs \e$B1x@wEY$,Dc$+$C$?$j$9$k$H8MOG$&$3$H$G$7$g$&!#\e(B<a href="../contrib/mayu-settings.txt"><code>contrib/mayu-settings.txt</code></a> \e$B$r;29M$K!"<+J,9%$_$K%+%9%?%^%$%:$7$F$/$@$5$$!#\e(B</p>
+
+             <p>\e$B$A$J$_$K!"\e(BWindows \e$B$J$s$@$7\e(B <code>C-z</code>, <code>C-x</code>, <code>C-c</code>, <code>C-v</code> \e$B$@$1$O;H$o$;$m!"$H$$$&?M$N$?$a$K!"\e(B<code>ZXCV</code> \e$B$H$$$&%7%s%\%k$,Dj5A$5$l$F$$$^$9!#\e(B<code>-DZXCV</code> \e$B$9$k$J$j\e(B <code>define ZXCV</code> \e$B$9$l$P!"$=$l$@$1$O\e(B Windows \e$B$C$]$/F0$-$^$9!#\e(B</p>
+             
+         <dt class="h2">Q6. IME\e$B%*%s$N$H$-$N!VAk;H$$$NM+]5!W$N%-!<F~$lBX$($N5sF0$,L/$G$9!#\e(B1\e$B$D$a$N%-!<F~NO0J30$&$^$/F~$lBX$($i$l$^$;$s!#\e(B
+
+         <dd class="d2"><p>IME\e$B%*%s$N>uBV$G$O\e(B <code>IL-</code>(IME\e$B%*%s\e(B) \e$B$G$9$,!"\e(B1\e$BJ8;zF~NO$7$?;~E@$G$5$i$K\e(B <code>IC-</code> \e$B!J\e(BIME\e$BJQ49Cf!K$H$J$j$^$9!#0lJ}$GI8=`$N%G%U%)%k%H%b%G%#%U%!%$%d$O\e(B <code>*IL-~IC-</code> \e$B$G$9!#;W$$DL$j$K%-!<F~$lBX$($5$l$F$$$J$$$o$1$G$O$J$/!"%G%U%)%k%H%b%G%#%U%!%$%d$N@_Dj$K=>$C$FF~$lBX$($r9T$C$F$$$J$$$@$1$G$O$J$$$G$7$g$&$+!#\e(B</p>
+
+         <dt class="h2">Q7. \e$B%G%U%)%k%H%b%G%#%U%!%$%d$,>e5-$N$h$&$J@_Dj$K$J$C$F$$$k$N$O$J$<$G$9$+!#ITJX$G$9!#\e(B
+
+         <dd class="d2"><p>\e$B:n<T$O\e(BIME2000\e$B$r;H$C$F$*$j!"\e(BIME\e$BJQ49Cf$N%-!<%P%$%s%G%#%s%0$K$D$$$F$O!V%W%m%Q%F%#!W\e(B-\e$B!VA4HL!W\e(B-\e$B!V@_Dj!W$G%+%9%?%^%$%:$9$k$3$H$rA[Dj$7$F$$$^$9!#$`$d$_$K\e(BIME\e$BJQ49Cf$N%-!<%P%$%s%G%#%s%0$,JQ99$5$l$k$H!"$3$N\e(BIME\e$B$N%+%9%?%^%$%:$,$d$j$K$/$$$N$G$O$J$$$+$H;W$$$^$9!#\e(B</p>
+
+             <p>\e$B$b$7ITJX$9$.$F2fK}$G$-$J$$!"$H$$$&>l9g$K$O!"\e(B <code>key *IC- =</code> \e$B$N$h$&$K\e(B<a href="./CUSTOMIZE-ja.html#defaultModifier">\e$B%G%U%)%k%H%b%G%#%U%!%$%d$rJQ99\e(B</a>\e$B$7$F$b$$$$$+$b$7$l$^$;$s!#5U$KITJX$J$3$H$b$"$k$+$H;W$$$^$9$N$G!"$*A&$a$7$^$;$s$1$I!#\e(B</p>
+
+
+         <dt class="h2">Q8.\e$B%N!<%H%Q%=%3%s$N\e(B<kbd>Fn</kbd>\e$B%-!<$K2?$+5!G=$r3d$jEv$F$k$3$H$O$G$-$^$9$+!)\e(B 
+         <dd class="d2"><p>\e$B$[$H$s$I$N%-!<%\!<%I$G$OIT2DG=$G$9!#\e(B</p>
+<p><kbd>Fn</kbd> \e$B%-!<$rC1BN$G2!$7$F$b\e(B Windows \e$B$K%-!<%$%Y%s%H$OMh$J$$$O$:$G$9\e(B (\e$B%9%-%c%s%3!<%I$ND4::$GD4$Y$i$l$^$9\e(B)\e$B!#EvA3$J$,$i!"$3$N$h$&$J%-!<$K5!G=$r3d$jEv$F$k$3$H$O$G$-$^$;$s!#\e(B</p>
+             
+         <dt class="h2">Q9. <kbd>Caps/\e$B1Q?t\e(B</kbd> \e$B$r\e(B <kbd>Ctrl</kbd> \e$B$K$7$F$$$^$9!#\e(B<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>x</kbd> \e$B$K5!G=$r3d$j?6$C$F$*$j!"@5>o$KF0$$$F$$$k$N$G$9$,!"\e(B<kbd>Caps/\e$B1Q?t\e(B</kbd> + <kbd>Shift</kbd> + <kbd>x</kbd> \e$B$rBG$C$F$b!"2?$b5/$-$^$;$s!#$J$<$G$9$+!#\e(B
+         <dd class="d2"><p>\e$B!VAk;H$$$NM+]5!W$NLdBj$G$O$J$/!"$"$J$?$N;H$C$F$$$k%-!<%\!<%I$NLdBj$@$H;W$o$l$^$9!#\e(B</p>
+<p>\e$B%-!<%\!<%I$K$h$C$F$O!"FCDj$N\e(B3\e$B%-!<$NF1;~2!$7$rG'<1$G$-$J$$$b$N$,$"$j$^$9!#%9%-%c%s%3!<%I$ND4::$G!"$I$s$J%-!<%$%Y%s%H$,H/@8$7$F$$$k$+$r%A%'%C%/$7$F$_$F$/$@$5$$!#%b%G%#%U%!%$%d\e(B2\e$B8D$r2!$7$?>uBV$G!"\e(B3\e$B8DL\$N%-!<$r2!$7$?$H$-$K%-!<%$%Y%s%H$,H/@8$7$F$$$J$$$h$&$G$"$l$P!"$=$N%-!<%\!<%I$G$O;H$($J$$%-!<$NAH$_9g$o$;$H$$$&$3$H$G$9!#\e(B</p>
+
+         <dt class="h2">Q10. \e$B%9%-%c%s%3!<%I$ND4::$G!"Nc$($P\e(B <kbd>Shift</kbd> + <kbd>\e$B",\e(B</kbd> \e$B$r2!$7$?$H$-$J$I!"$?$^$K=P$k$O$:$N$J$$\e(B <code>E0-0x2a</code> \e$B$H$$$&%-!<%$%Y%s%H$,=P$k$h$&$G$9$,!"$3$l$O2?$G$9$+!)\e(B
+         <dd class="d2"><p>\e$BITL@$G$9!#$3$N%9%-%c%s%3!<%I$K4X$9$k>pJs$r$*BT$A$7$F$*$j$^$9!#\e(B</p>
+
+         <dt class="h2">Q11. \e$B1&\e(B <kbd>Windows</kbd> \e$B%-!<$r2!$9$H\e(B IME \e$B$N%*%s%*%U$,$G$-$k$h$&$K$7$?$$!#\e(B
+         <dd class="d2">
+             <p class="sample">mod windows -= RightWindows # ... (1)<br>
+             key RightWindows = $ToggleIME<br>
+             </p>
+             
+             <p>\e$B1&\e(B <kbd>Windows</kbd> \e$B%-!<$O%b%G%#%U%!%$%d%-!<$J$N$GFCJL07$$$5$l$^$9!#$7$?$,$C$FIaDL$N%-!<$N$h$&$KF0:n$9$k$h$&$K$9$k$K$O!"\e(B<code>(1)</code> \e$B$N$h$&$K$7$F%b%G%#%U%!%$%d%-!<$H$7$FF0:n$7$J$$$h$&$K$7$^$9!#$3$l$O\e(B <kbd>Alt</kbd> \e$B$d\e(B <kbd>Shift</kbd> \e$B$d\e(B <kbd>Control</kbd> \e$B$G$bF1MM$G$9!#\e(B</p>
+             
+         <dt class="h2">Q12. \e$B%&%$%s%I%&$N%/%i%9L>$O$I$&$d$C$FD4$Y$k$s$G$9$+!)\e(B
+         <dd class="d2"><p>\e$B%?%9%/%H%l%$$N!VAk;H$$$NM+]5!W$N%"%$%3%s$G%^%&%9$N1&%\%?%s$r2!$7$F\e(B<a href="#menu-i" class="menu-item">\e$BD4::\e(B(I)...</a>\e$B$rA*$S$^$9!#\e(B</p>
+             
+         <dt class="h2">Q13. \e$B%"%/%F%#%V$J;~$K$7$+8+$($J$$Ak$J$I$N>l9g!">e5-$NJ}K!$G$OD4::$G$-$J$$$G$9$,!)\e(B
+         <dd class="d2"><p><a href="CUSTOMIZE-ja.html#function_WindowIdentify"><code>&amp;WindowIdentify</code></a> \e$B$r;H$C$F$/$@$5$$!#\e(B<a href="../default.mayu"><code>default.mayu</code></a> \e$B$G$O\e(B <kbd>Ctrl</kbd> +<kbd>Shift</kbd> + <kbd>D</kbd> \e$B$K3d$j?6$C$F$"$j$^$9!#\e(B</p>
+             
+         <dt class="h2">Q14. \e$B%$%s%9%H!<%k;~$K$O\e(B 109 \e$B%-!<%\!<%I$@$C$?$N$G$9$,!":#EY\e(B 104 \e$B%-!<%\!<%I$r9XF~$7$^$7$?!#$7$+$7!"%?%9%/%H%l%$%a%K%e!<$N\e(B<span class="menu-item">\e$BA*Br\e(B(<u>C</u>) &#9658;</span>\e$B$K$O\e(B 109 \e$B$7$+=P$F$-$^$;$s!#$I$&$9$l$P$$$$$G$9$+!#\e(B
+         <dd class="d2">
+             <p>\e$B%$%s%9%H!<%k;~$NA*Br$K$h$j!"0J2<$NI=$N>e\e(B 4 \e$B$D$^$?$O2<\e(B 4 \e$B$D$,A*$P$l$^$9!#!V@_Dj!W%@%$%"%m%0%\%C%/%9$GE,@Z$K@_Dj$7$F$/$@$5$$!#\e(B(<code>%MAYU_DIR%</code> \e$B$O\e(B mayu \e$B$r%$%s%9%H!<%k$7$?%G%#%l%/%H%j$G$9\e(B)</p>
+             
+             <table class="default-settings">
+               <tr class="name-japanese"><th>\e$BL>A0\e(B</th><td>\e$BF|K\8l\e(B 109 \e$B%-!<%\!<%I\e(B (Emacs \e$BIw\e(B)</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE109;-DUSEdefault</code></td></tr>
+               <tr class="name"><th>\e$BL>A0\e(B</th><td>\e$BF|K\8l\e(B 109 \e$B%-!<%\!<%I\e(B (104 \e$BIw\e(B, Emacs \e$BIw\e(B)</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE109;-DUSEdefault;-DUSE104on109</code></td></tr>
+               <tr class="name"><th>\e$BL>A0\e(B</th><td>\e$BF|K\8l\e(B 109 \e$B%-!<%\!<%I\e(B</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE109</code></td></tr>
+               <tr class="name"><th>\e$BL>A0\e(B</th><td>\e$BF|K\8l\e(B 109 \e$B%-!<%\!<%I\e(B (104 \e$BIw\e(B)</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE109;-DUSE104on109</code></td></tr>
+               <tr class="name-english"><th>\e$BL>A0\e(B</th><td>\e$B1Q8l\e(B 104 \e$B%-!<%\!<%I\e(B (Emacs \e$BIw\e(B)</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE104;-DUSEdefault</code></td></tr>
+               <tr class="name"><th>\e$BL>A0\e(B</th><td>\e$B1Q8l\e(B 104 \e$B%-!<%\!<%I\e(B (109 \e$BIw\e(B, Emacs \e$BIw\e(B)</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE104;-DUSEdefault;-DUSE109on104</code></td></tr>
+               <tr class="name"><th>\e$BL>A0\e(B</th><td>\e$B1Q8l\e(B 104 \e$B%-!<%\!<%I\e(B</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE104</code></td></tr>
+               <tr class="name"><th>\e$BL>A0\e(B</th><td>\e$B1Q8l\e(B 104 \e$B%-!<%\!<%I\e(B (109 \e$BIw\e(B)</td></tr>
+               <tr class="filename"><th>\e$B@_Dj%U%!%$%kL>\e(B</th><td><code>%MAYU_DIR%\dot.mayu</code></td></tr>
+               <tr class="symbol"><th>\e$B%7%s%\%k\e(B</th><td><code>-DUSE104;-DUSE109on104</code></td></tr>
+             </table>
+             
+         <dt class="h2">Q15. \e$B!VAk;H$$$NM+]5!W$G$O%^%&%9%$%Y%s%H$rCV$-49$($i$l$J$$$N$G$9$+!#\e(B
+         <dd class="d2"><p>\e$B!VAk;H$$$NM+]5!W$NA0?H$K$"$?$k\e(B cmkey \e$B$G$O%^%&%9%$%Y%s%H$rCV$-49$($k$3$H$,$G$-$^$7$?$,!"!VAk;H$$$NM+]5!W$O\e(B cmkey \e$B$H$O0[$J$k%l%$%d!<$G<B8=$7$F$$$k$N\e(B
+\e$B$G!"CV$-49$($k$3$H$O$G$-$^$;$s!#>/$J$/$H$b:n<T$OI,MW@-$r46$8$F$$$J$$$N$G$9$,!"%^%&%9%I%i%$%P$r=q$1$P<B8=$G$-$^$9$N$G!"%9%-%k$bI,MW@-$b$"$kJ}$,$$$l$P!":n$C$F%=!<%9$rAw$C$F$/$@$5$$!#!VAk;H$$$NM+]5!W$K:NMQ$5$;$F$$$?$@$-$^$9!#\e(B
+</p>
+       </dl>
+      </div>
+      
+  <dt class="h1"><a name="CUSTOMIZE" href="CUSTOMIZE-ja.html">7. customize</a>
+      
+  <dd class="d1">
+      <p><a href="CUSTOMIZE-ja.html">\e$B%+%9%?%^%$%:\e(B</a>\e$B!#\e(B</p>
+
+
+  <dt class="h1"><a name="SECURITY">8. security</a>
+      
+  <dd class="d1">
+      <p class="bug">\e$BB>?M$,;HMQ$9$k2DG=@-$N$"$k\e(B PC \e$B$X!VAk;H$$$NM+]5!W$r%$%s%9%H!<%k$7$F$O$$$1$^$;$s!#\e(B</p>
+      
+      <p>\e$B!VAk;H$$$NM+]5!W$O%I%i%$%P$r;HMQ$7$F%-!<%\!<%I$KF~NO$5$l$?%-!<$rG'<1$7$^$9$,!"$=$N%I%i%$%P$X$OA4$F$N%f!<%6!<$,%"%/%;%9$G$-$^$9!#$G$9$+$i!"B>?M$N%-!<%\!<%IF~NO$rFI$_<h$k$3$H$,2DG=$G$9!#\e(B</p>
+
+      <p>\e$BNc$($P!"%m%0%$%s2hLL$G$NB>?M$N%Q%9%o!<%I$rF@$k$3$H$b!"$=$N$h$&$J%"%W%j%1!<%7%g%s$r:n@.$9$k$3$H$G2DG=$K$J$j$^$9!#\e(B</p>
+  </dd>
+
+
+  <dt class="h1"><a name="BUGS">9. bugs</a>
+
+  <dd class="d1">
+      <ul>
+       <li><span class="bug">[\e$B;EMM\e(B]</span> \e$B%3%^%s%I%W%m%s%W%H$G$O%m%C%/%-!<$H\e(BIME\e$B$N>uBV$r6hJL$9$k$3$H$,$G$-$^$;$s!#$^$?!"%3%^%s%I%W%m%s%W%H$N%W%m%Q%F%#$KBP$7$F$OL5NO$G$9!#\e(B
+       <li><span class="bug">[\e$B%P%0\e(B]</span> <a href="http://www.pgpi.org/products/pgp/versions/freeware/win32/7.0.3/" target="_top">PGPi</a> \e$B$rMxMQ$7$F$$$k$H$&$^$/F0$+$J$$$h$&$G$9!#\e(B
+       <li><a href="http://www.microsoft.com/japan/support/kb/articles/J054/8/50.htm" target="_top">USB \e$B%-!<%\!<%I%G%P%$%9@\B38e$K1Q8l\e(B 101 \e$B%-!<%\!<%IG[Ns$K$J$k\e(B</a>
+           
+      </ul>
+
+  <dt class="h1"><a name="RELATEDWORK">10. related work</a>
+      
+  <dd class="d1">
+      <div>
+       <p>\e$B0J2<$N%=%U%H$HF1;~$K$O;H$o$J$$$h$&$K$7$F$/$@$5$$!#$=$b$=$b;H$($J$$$b$N$b$"$j$^$9$7!";H$($?$H$7$F$b$-$C$H$o$1$N$o$+$i$J$$$3$H$K$J$k$G$7$g$&!#\e(B</p>
+       
+       <dl>
+         <dt class="h2"><a href="http://lukewarm.s101.xrea.com/" target="_top">AUtoHotkey</a>
+         <dd class="d2">\e$B%9%/%j%W%H$r=q$/$3$H$G%-!<%\!<%I$J$I$K$5$^$6$^$JF0:n$r3d$jEv$F$k$3$H$,$G$-$^$9!#\e(B
+
+         <dt class="h2"><a href="http://www.remus.dti.ne.jp/~kurotora/" target="_top">\e$BG-$^$M$-\e(B</a>
+         <dd class="d2">\e$B!VAk;H$$$NM+]5!W$N$[$&$,%+%9%?%^%$%:$N<+M3EY$O9b$$$N$G$9$,!"G-$^$M$-$K$O\e(B GUI \e$B$,$D$$$F$$$F=i?4<T$K$b$d$5$7$$$+$b$7$l$^$;$s!#!VAk;H$$$NM+]5!W$K$J$$5!G=$bB8:_$7$^$9!#%U%j!<%&%'%"!#\e(B
+         <dt class="h2"><a href="http://hp.vector.co.jp/authors/VA000092/tools/" target="_top">RemapKey</a>
+         <dd class="d2">\e$B%-!<%\!<%I$N%-!<$rJL$N%-!<$XF~$lBX$($k$3$H$,$G$-$k%=%U%H$G$9!#Ak;H$$$NM+]5$G$O%m%0%$%s2hLL$G$N%-!<$rJQ99$9$k$3$H$,$G$-$^$;$s$,\e(B RemapKey \e$B$G$O$G$-$^$9!#\e(B
+
+         <dt class="h2"><a href="http://sbcookie.hp.infoseek.co.jp/MetaX.html" target="_top">MetaX</a>
+         <dd class="d2">\e$B%3%s%;%W%HE*$K!VAk;H$$$NM+]5!W$d\e(B cmkey \e$B$HHs>o$K$h$/;w$F$$$^$9$,!"$h$j\e(B Emacs \e$BE*$J@_Dj%U%!%$%k$r=q$-!"%_%K%P%C%U%!$rMxMQ$7$?Jd40$J$I$,2DG=$G$9!#\e(B
+             
+         <dt class="h2"><a href="http://www.cam.hi-ho.ne.jp/oishi/" target="_top">Xkeymacs</a>
+         <dd class="d2">Windows \e$B>e$NA4$F$N%"%W%j%1!<%7%g%s$K$*$$$F\e(B Emacs like \e$B$JA`:n@-$r<B8=$9$k$?$a$N%-!<%\!<%I%f!<%F%#%j%#%F%#$G$9!#\e(BEmacs like \e$B$JA`:n@-$K$7$?$$$,!"!VAk;H$$$NM+]5!W$N@_Dj$9$k$N$OLLE]$H$$$&?M$K$*4+$a$G$9!#\e(B
+             
+         <dt class="h2">
+
+             <a href="http://www.chombo.com/" target="_top">AltIME</a> / 
+             <a href="http://hp.vector.co.jp/authors/VA012411/index.html" target="_top">CraftKeytrans</a> /
+             <a href="http://hp.vector.co.jp/authors/VA009883/" target="_top">dvorak kr, swap2k</a> / 
+             <a href="http://www.vector.co.jp/soft/win95/util/se026760.html" target="_top">Easy Punch</a> / 
+             <a href="http://hp.vector.co.jp/authors/VA008030/" target="_top">IME Start</a> /
+             <a href="http://www.e-douguya.com/win/win.shtml#KBAT" target="_top">Key Bat</a> /
+             <a href="http://www.jomon.ne.jp/~yukihiro/" target="_top">Keylay</a> / 
+             <a href="http://nogu.org/keymacs.html" target="_top">Keymacs</a> /
+             <a href="http://michiko.shiratori.riec.tohoku.ac.jp/~jir/windows/keymacs+" target="_top">Keymacs+</a> /
+             <a href="http://homepage2.nifty.com/mamao2/down/Mmkbd/Mmkbd.htm" target="_top">Max Min Keybord</a> / 
+
+             <a href="http://www.vector.co.jp/soft/win95/util/se042027.html" target="_top">\e$B$M$3$]$$\e(B</a> / 
+             <a href="http://hide.maruo.co.jp/software/hidecaps.html" target="_top">\e$B=(\e(BCAPS</a> /
+             <a href="http://hp.vector.co.jp/authors/VA011751/software/himeodorikosou/" target="_top">\e$BI1MY;RAp\e(B</a>
+         <dd class="d2">\e$B%-!<%\!<%I$K$h$kA`:n$r2~A1$7$h$&$H$5$^$6$^$J%=%U%H$,3+H/$5$l$F$$$^$9!#\e(B
+       </dl>
+      </div>
+      
+  <dt class="h1"><a name="REFERENCES">11. references</a>
+      
+  <dd class="d1">
+      <div>
+       <p>\e$B5$$K$J$kJ8>O$X$N%j%s%/!#\e(B</p>
+
+       <dl>
+         <dt class="h2"><a href="http://jisx6004.client.jp/mayu.html" target="_top">\e$BKz;H$$$NM+]5\e(B</a>
+         <dd class="d2">\e$B%A%e!<%H%j%"%k$NJ,$+$j$K$/$$8D=j$J$I$rJ,$+$j0W$/2r@b$7$F$"$j$^$9!#\e(B
+         <dt class="h2"><a href="http://www.ric.hi-ho.ne.jp/giraffe/" target="_top">Giraffe+ software index</a>
+         <dd class="d2"><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_PlugIn"><code>&amp;PlugIn</code></a> \e$B$KMxMQ$G$-$k%W%i%0%$%s$,G[I[$5$l$F$$$^$9!#$=$b$=$b%W%i%0%$%s$N5!G=$O\e(B Giraffe+ \e$B$5$s$K$h$j<BAu$5$l$^$7$?!#\e(B
+         <dt class="h2"><a href="http://www.fiercewinds.net/programming/SakuraLayout/VariousMethods.htm" target="_top">\e$B$$$m$$$m$J2>L>F~NOJ}K!\e(B</a>
+         <dd class="d2">\e$B$$$m$$$m$J2>L>F~NOJ}K!$N!VAk;H$$$NM+]5!WMQ@_Dj%U%!%$%k$,$"$j$^$9!#\e(B
+         <dt class="h2"><a href="http://www.geocities.co.jp/SiliconValley-PaloAlto/5093/tron.txt" target="_top">Commutative Field in GeoCities</a>
+         <dd class="d2">tron\e$BG[Ns@_Dj%U%!%$%k$J$I$,$"$j$^$9!#\e(B
+             
+         <dt class="h2"><a href="http://ohkubo.s53.xrea.com/xyzzy/index.html#mayu-mode" target="_top">\e$B;(5-D!\e(B</a>
+         <dd class="d2">mayu-mode.l \e$B$,G[I[$5$l$F$$$^$9!#\e(B
+
+         <dt class="h2"><a href="http://homepage3.nifty.com/songs/tcode/mayu/" target="_top">\e$B!VAk;H$$$NM+]5!W$r;H$C$F\e(B T-Code \e$BF~NO$7$F$_$k\e(B</a>
+         <dd class="d2">T-Code \e$BMQ@_Dj%U%!%$%k$J$I$,G[I[$5$l$F$$$^$9!#\e(B
+
+         <dt class="h2"><a href="http://www.tamanegi.org/prog/mayu-plugins/" target="_top">mayu-plugins -- \e$BAk;H$$$NM+]5MQ%W%i%0%$%s\e(B</a>
+         <dd class="d2">window-select, migemo-isearch, ie-migemo-search \e$B$H$$$C$?%W%i%0%$%s$,G[I[$5$l$F$$$^$9!#\e(B
+             
+         <dt class="h2"><a href="http://www.vector.co.jp/magazine/softnews/050427/n0504273.html" target="_top">Vector: \e$B?7Ce%=%U%H%l%S%e!<\e(B</a>
+         <dd class="d2">\e$B?7Ce%=%U%H%l%S%e!<\e(B
+       </dl>
+       
+      </div>
+      
+  <dt class="h1"><a name="COPYRIGHT">12. copyright</a>
+
+  <dd class="d1">
+      <div>
+       <dl>
+         <dt class="h2">\e$BAk;H$$$NM+]5\e(B
+         <dd class="d2">
+             <p class="noindent">
+             Copyright (C) 1999-2005, <a href="http://www.ganaware.jp" target="_top">TAGA Nayuta</a> &lt;nayuta&#64;users.sourceforge.net&gt;<br>
+             All rights reserved.</p>
+             
+             <p class="noindent">Redistribution and use in source and binary
+             forms, with or without modification, are permitted provided that
+             the following conditions are met:</p>
+             
+             <ol>
+               <li>Redistributions of source code must retain the above
+                   copyright notice, this list of conditions and the following
+                   disclaimer.
+               <li>Redistributions in binary form must reproduce the
+                   above copyright notice, this list of conditions and
+                   the following disclaimer in the documentation and/or
+                   other materials provided with the distribution.
+               <li>The name of the author may not be used to endorse or
+                   promote products derived from this software without
+                   specific prior written permission.
+             </ol>
+
+             <p class="noindent">
+             THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+             EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+             TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+             FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT
+             SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+             INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+             (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+             GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+             BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+             LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+             OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+             POSSIBILITY OF SUCH DAMAGE.</p>
+             
+         <dt class="h2">Boost.Regex
+         <dd class="d2">
+             <p class="noindent">Copyright (c) 1998-2003 Dr John Maddock</p>
+             
+             <p class="noindent">Boost Software License - Version 1.0 - August 17th, 2003</p>
+
+             <p class="noindent">Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following:</p>
+
+             <p class="noindent">The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor.</p>
+
+             <p class="noindent">THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>
+       </dl>
+      </div>
+      
+  <dt class="h1"><a name="SUPPORT">13. support</a>
+      
+  <dd class="d1">
+      <div>
+       <dl>
+         <dt class="h2">\e$B!VAk;H$$$NM+]5!W%[!<%`%Z!<%8\e(B
+         <dd class="d2"><p><a href="http://mayu.sourceforge.net" target="_top">http://mayu.sourceforge.net</a></p>
+         <dt class="h2">\e$B!VAk;H$$$NM+]5!W%a!<%j%s%0%j%9%H\e(B
+         <dd class="d2">
+             <p><a href="http://lists.sourceforge.net/mailman/listinfo/mayu-support" target="_top">Mayu-support Info Page</a> \e$B$N\e(B Subscribing to Mayu-support \e$B$N%U%)!<%`$K!"<+J,$N%a!<%k%"%I%l%9$H!"\e(BMayu-support \e$B%a!<%j%s%0%j%9%H$N0Y$N%Q%9%o!<%I$rF~$l$F\e(B Subscribe \e$B$7$F$/$@$5$$!#\e(B</p>
+         <dt class="h2">\e$B!VAk;H$$$NM+]5!W\e(B2ch \e$B%9%l\e(B
+         <dd class="d2">
+             <p><a href="http://pc8.2ch.net/test/read.cgi/win/1118469602/" target="_top">2ch \e$B$K%9%l\e(B</a>\e$B$,$?$C$F$7$^$C$?$h$&$J$N$GE,Ev$K3hMQ$7$^$7$g$&!#:n<T$b;~!98+$F$$$^$9!#\e(B</p>
+       </dl>
+      </div>
+      
+  <dt class="h1"><a name="ACKNOWLEDGEMENT">14. acknowledgements</a>
+
+  <dd class="d1">
+      <div>
+       <p>Windows9x/XP \e$BMQ$N%I%i%$%P$r:n@.$7$F$/$@$5$C$?>.NS5AL@$5$s!"$"$j$,$H$&$4$6$$$^$9!#\e(B</p>
+       
+       <p>\e$B:G$b?H6a$J%f!<%6!<$G$"$j!"?tB?$/$N=u8@$r$7$F$/$l$?H9M?;VIW$5$s$K46<U$7$^$9!#2?$h$jH`$NG4$j6/$$MW5a$OBUBF$J:n<T$K?75,%j%j!<%9$X$N3hNO$rM?$($F$/$l$^$7$?!#\e(B</p>
+       
+       <p>\e$B2OIt=$OB$5$s!"\e(BKANAI Makoto \e$B$5$s!"\e(BHAJANO Na&ograve;qui \e$B$5$s$K$O@_Dj%U%!%$%k$rDs6!$7$F$$$?$@$-$^$7$?!#$*Ni$r?=$7>e$2$^$9!#\e(B</p>
+
+       <p>Hosaka Yuji \e$B$5$s$K$O!"%^%k%A%b%K%?BP1~%Q%C%A$r$$$?$@$-$^$7$?!#$"$j$,$H$&$4$6$$$^$9!#\e(B</p>
+       
+       <p>\e$B!VAk;H$$$NM+]5!W$O$?$/$5$s$N?M$N9W8%$N>e$K@.$jN)$C$F$$$^$9!#$3$3$KL>A0$r5s$2$F$$$J$$J}$K$b?4$+$i46<U$7$^$9!#\e(B</p>
+      </div>
+
+  <dt class="h1"><a name="HISTORY">15. history</a>
+      
+  <dd class="d1">
+      <div>
+       <dl class="history">
+         <dt>200?/??/?? 3.31
+         <dd>
+             <ul>
+               <li>\e$B!VAk;H$$$NM+]5!W0J30$N%"%W%j%1!<%7%g%s$+$i!VAk;H$$$NM+]5!W$NF0:n$r\e(B on/off \e$B$G$-$k$h$&$J;EAH$_$rMQ0U$7$^$7$?!#;HMQ$9$k>l9g$O!"%=!<%9$N\e(B <code>mayuipc.h</code> \e$B$r8+$F$/$@$5$$!#\e(B
+               <li>WindowsXP \e$B$N!V%f!<%6!<$N@Z$jBX$(!W5!G=$K:#EY$3$=BP1~!D$7$?$D$b$j!#\e(B
+               <li><a href="#secrity">security</a> \e$B$H$$$&>O$rDI2C!#\e(B
+             </ul>
+         </dd>
+         <dt>2005/04/18 3.30
+         <dd>
+             <dl>
+               <dt>\e$B%b%G%#%U%!%$%d\e(B
+               <dd>
+                   <ul>
+                     <li>\e$B%+%J%m%C%/$rI=$9%b%G%#%U%!%$%d\e(B <a href="CUSTOMIZE-ja.html#modifier"><code>KL-</code></a> \e$B$rDI2C!#\e(B<a href="CUSTOMIZE-ja.html#def_option_KL" target="MANUAL">\e$B%*%W%7%g%s\e(B (KL-)</a>\e$B$r$h$/FI$`$3$H!#\e(B
+                     <li>\e$B%b%G%#%U%!%$%d\e(B <a href="CUSTOMIZE-ja.html#modifier"><code>MAX-, MIN-, MMAX-, MMIN-</code></a> \e$B$rDI2C!#\e(B(Thanks to \e$B>.NS\e(B)
+                     <li>Java \e$B%"%W%j%1!<%7%g%s$J$I$G\e(B <a href="CUSTOMIZE-ja.html#modifier"><code>IL-</code></a> \e$B$,8!=P$5$l$J$$$3$H$,$"$k%P%0$r=$@5!#\e(B
+                     <li><a href="CUSTOMIZE-ja.html#oneShotRepeatableModifier">\e$B%-!<%j%T!<%HM-\e(B One Shot (<code>!!!</code>)</a> \e$B$N%-!<%j%T!<%H$,;O$^$k$^$G$N;~4V$r\e(B <a href="CUSTOMIZE-ja.html#def_option_delay_of_oneShotRepeatableModifier" target="MANUAL">\e$B%*%W%7%g%s\e(B (delay-of !!!)</a> \e$B$G;XDj$G$-$k$h$&$K$7$?!#\e(B
+                   </ul>
+               </dd>
+                   
+               <dt><code><em>FUNCTION</em></code>
+               <dd>
+                   <ul>
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_LoadSetting"><code>&amp;LoadSetting</code></a> \e$B$J$I$G!"@_Dj%U%!%$%k$r%m!<%I$7$?;~$K!"%m%0$K%m!<%I$7$?$3$H$,I=<($5$l$k$h$&$K$7$?!#\e(B
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Prefix"><code>&amp;Prefix</code></a> \e$B$N@bL@$r@5$7$/=$@5!#\e(B
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_SetImeStatus"><code>&amp;SetImeStatus</code></a> \e$B$rDI2C!#\e(B(Thanks to \e$B>.NS\e(B)
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_SetImeString"><code>&amp;SetImeString</code></a> \e$B$rDI2C!#\e(B(Thanks to \e$B>.NS\e(B)
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_ShellExecute"><code>&amp;ShellExecute</code></a> \e$B$,<:GT$7$?;~$N%(%i!<%a%C%;!<%8$,I=<($5$l$J$$$3$H$,$"$k%P%0$r=$@5!#\e(B
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_VK"><code>&amp;VK</code></a> \e$B$GF~NO$G$-$k%^%&%9%\%?%s$K\e(B XBUTTON1 \e$B$H\e(B XBUTTON2 \e$B$rDI2C!#B>!"$5$^$6$^$J2>A[%-!<$rDI2C!#\e(B
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowMonitor"><code>&amp;WindowMonitor</code></a> \e$B$rDI2C!#\e(B(Thanks to Hosaka Yuji)
+                     <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowMonitorTo"><code>&amp;WindowMonitorTo</code></a> \e$B$rDI2C!#\e(B(Thanks to Hosaka Yuji)
+                     <li><code><em>FUNCTION</em></code> \e$B$N\e(B<a href="CUSTOMIZE-ja.html#arg_subst">\e$B0z?tCV49\e(B</a>\e$B5!G=$rDI2C!#\e(B(Thanks to \e$B>.NS\e(B)
+                     <li>\e$B4{B8\e(B <code><em>FUNCTION</em></code> \e$B$N%^%k%A%b%K%?BP1~!#\e(B(Thanks to Hosaka Yuji)
+                   </ul>
+               </dd>
+                   
+               <dt>\e$B%^%K%e%"%k\e(B
+               <dd>
+                   <ul>
+                     <li><a href="#ACKNOWLEDGEMENT">acknowledgements</a> \e$B99?7!#\e(B
+                     <li><a href="#RELATEDWORK">related work</a> \e$B$r99?7!#\e(B
+                     <li><a href="#REFERENCES">references</a> \e$B$r99?7!#\e(B
+                   </ul>
+               </dd>
+
+               <dt>\e$B%S%k%I\e(B
+               <dd>
+                   <ul>
+                     <li>Windows9x/Me/NT4.0 \e$BHsBP1~$K$J$j$^$7$?!#\e(B
+                     <li>Borland C++ 5.5.1 \e$B$G%S%k%IIT2DG=$K$J$j$^$7$?!#\e(B
+                     <li>Visual C++ Toolkit 2003 \e$B$G\e(B<a href="CUSTOMIZE-ja.html#compile">\e$B%S%k%I\e(B</a>\e$B$9$k$?$a$NMM!9$JCm0U;v9`$r5-:\!#\e(B(Thanks to \e$B>.NS\e(B)
+                   </ul>
+               </dd>
+                   
+               <dt>\e$B%I%i%$%P\e(B
+               <dd>
+                   <ul>
+                     <li>2000/XP \e$BMQ%I%i%$%P$N\e(B SMP/HT \e$BBP1~!#\e(B(Thanks to \e$B>.NS\e(B)
+                     <li>2000/XP \e$BMQ%I%i%$%P$N\e(B PS/2 \e$B@lMQHG$H\e(B USB \e$BBP1~HG$N%P%$%J%jE}9g!#\e(B(Thanks to \e$B>.NS\e(B)
+                     <li><a href="#rescue_driver">\e$BI|5lMQ%I%i%$%P\e(B</a>\e$B$rDI2C!#\e(B(Thanks to \e$B>.NS\e(B)
+                   </ul>
+               </dd>
+
+               <dt>\e$B$=$NB>\e(B
+               <dd>
+                   <ul>
+                     <li>WindowsXP \e$B$N!V%f!<%6!<$N@Z$jBX$(!W5!G=$KBP1~!#\e(B
+                     <li>\e$B$4$/$?$^$K!"\e(B<a href="http://support.microsoft.com/kb/835874/JA/" target="_top">\e$B%?%9%/%H%l%$$N%"%$%3%s$,I=<($5$l$J$$LdBj\e(B</a>\e$B$r=$@5$7$?$D$b$j!#$^$?!"I=<($5$l$F$$$J$$$H$-$K!"$b$&0lEY5/F0$9$l$P%"%$%3%s$,%?%9%/%l%$$KI=<($5$l$k$h$&$K$7$?!#\e(B(\e$B!V4{$KAk;H$$$NM+]5$OF0:nCf$G$9!W$H$$$&%@%$%"%m%0%\%C%/%9$,=P$k$HF1;~$K%"%$%3%s$,I=<($5$l$^$9\e(B)
+                     <li>\e$B%m%0$r>C5n$7$?;~9o$r%m%0I=<($9$k$h$&$K$7$?!#\e(B
+                     <li><a href="../109.mayu"><code>109.mayu</code></a> \e$B$K\e(B MultiMedia Keyboard \e$BMQ$NFC<l%-!<$J$I$rDI2C!#\e(B
+                     <li>\e$B%9%J%C%W%7%g%C%HHG$G!V","-"+"*!W$H$$$&J8;z$,%-!<L>$H$7$F;HMQ$G$-$J$/$J$C$F$$$?%P%0$N=$@5!#\e(B
+                   </ul>
+               </dd>
+             </dl>
+             
+         <dt>2003/07/16 3.29
+         <dd>
+             <ul>
+               <li>Windows XP \e$BMQ$N%I%i%$%P!#\e(B(Thanks to \e$B>.NS\e(B)
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_PlugIn"><code>&amp;PlugIn</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Recenter"><code>&amp;Recenter</code></a> \e$B$rDI2C!#\e(B
+               <li><a href="../contrib/109onAX.mayu"><code>contrib/109onAX.mayu</code></a> \e$B$rDI2C!#\e(B(Thanks to \e$B>>K\Gn5*\e(B)
+               <li><a href="../104.mayu"><code>104.mayu</code></a> \e$B$H\e(B <a href="../contrib/ax.mayu"><code>contrib/ax.mayu</code></a> \e$B$N5-=R%_%9$r=$@5!#\e(B(Thanks to \e$B>>K\Gn5*\e(B)
+               <li><a href="../contrib/DVORAKon109.mayu"><code>contrib/DVORAKon109.mayu</code></a> \e$B$rDI2C!#\e(B(Thanks to 2ch)
+               <li>\e$B$=$NB>=$@5!D\e(B
+             </ul>
+         <dt>2001/10/08 3.28
+         <dd>
+             <ul>
+               <li><a href="#TUTORIAL">\e$B%A%e!<%H%j%"%k\e(B</a>\e$B$H\e(B<a href="#MENU">\e$B%?%9%/%H%l%$%a%K%e!<\e(B</a>\e$B$N>O$rDI2C!#\e(B(Thanks to hanawa)
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B Key Bat \e$B$rDI2C!#\e(B
+               <li>\e$B%a%K%e!<$r%"%/%;%9$7$F$$$k;~$N%&%#%s%I%&%/%i%9L>$O:G8e$K\e(B <code>:MENU</code> \e$B$,$D$/!#\e(B
+               <li><code>=&gt;</code> \e$B$NBe$o$j$K\e(B <code>=</code> \e$B$,;H$($k$h$&$K$7$?!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#def_subst">subst</a> \e$B$N1&B&$K\e(B <code>M0-</code> \e$B$J$I$N%b%G%#%U%!%$%d$,;XDj$G$-$J$$%P%0$r=$@5!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#perKeymapDefinition">\e$B%-!<%^%C%W$,1F6A$9$kDj5A\e(B</a>\e$B$N@bL@$rDI2C!#\e(B
+               <li>W2k \e$B$G\e(B USB \e$B%I%i%$%P$r4JC1$K%$%s%9%H!<%k$G$-$k$h$&$K$7$?!#\e(B
+               <li>\e$B$=$NB>=$@5!#\e(B(Thanks to \e$B>.NS\e(B)
+             </ul>
+         <dt>2001/09/02 3.27
+         <dd>
+             <ul>
+               <li>3.26 \e$B$G\e(B <code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Sync"><code>&amp;Sync</code></a> \e$B$,F0:n$7$J$/$J$C$F$$$?%P%0$r=$@5!#\e(B<code>C-k</code> \e$B$b$A$c$s$HF0:n$7$^$9!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_KeymapPrevPrefix"><code>&amp;KeymapPrevPrefix</code></a> \e$B$rDI2C!#\e(B
+               <li><a href="#FAQ">FAQ</a> \e$B$K!V1&\e(B <kbd>Windows</kbd> \e$B%-!<$r2!$9$H\e(B IME \e$B$N%*%s%*%U$,$G$-$k$h$&$K$7$?$$!#!W$rDI2C!#\e(B
+             </ul>
+         <dt>2001/08/26 3.26
+         <dd>
+             <ul>
+               <li><a href="CUSTOMIZE-ja.html#oneShotModifier">One Shot \e$B%b%G%#%U%!%$%d\e(B</a>\e$B$NNc$,4V0c$C$F$$$?$N$G=$@5!#\e(B(Thanks to \e$B>.NS\e(B)
+               <li>Windows \e$BB&$G$ON%$5$l$F$$$k$3$H$K$J$C$F$$$k%-!<$K$D$$$F!"!VAk;H$$$NM+]5!W$,%-!<$rN%$9%9%-%c%s%3!<%I$r\e(B Windows \e$BB&$XAw$k$3$H$,$J$$$h$&$K$7$?!#\e(B(Thanks to \e$B>.NS\e(B)
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B Word Emacs \e$B$rDI2C!#\e(B
+               <li><a href="../mayu-mode.el" target="MANUAL"><code>mayu-mode.el</code></a> \e$B$G\e(B <code>M-;</code> (<code>indent-for-comment</code>) \e$B$,;HMQ$G$-$k$h$&$K$J$C$?\e(B (Thanks to \e$B1JLn7=0lO:\e(B)
+               <li>\e$B5:$l$K\e(B <code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_DirectSSTP"><code>&amp;DirectSSTP</code></a> \e$B$rDI2C$7$F$_$?!#\e(B
+             </ul>
+         <dt>2001/08/13 3.25
+         <dd>
+             <ul>
+               <li><code>*.mayu</code> \e$B$N%"%$%3%s$,4V0c$C$F$$$?$N$rD>$7$?!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#mod"><code>-=</code></a> \e$B$GJ#?t%-!<$r@_Dj$7$F$b0l$D$7$+M-8z$K$J$i$J$$%P%0$N=$@5!#\e(B
+               <li>WindowsNT4.0 \e$B0J30\e(B (9x, Me, 2000) \e$B$G!"!VAk;H$$$NM+]5!W$r=*N;$5$;$?$"$H$K2?$+$N%-!<$r2!$5$J$$$H=*N;$7$J$$%P%0$NB`<#!#\e(B(Thanks to \e$B>.NS\e(B)
+               <li>\e$B@_Dj%U%!%$%k$GNY$j9g$&J#?t$NJ8;zNs$r0l$D$NJ8;zNs$H$7$F<h$j07$&$h$&$K$7$?!#\e(B
+                   <p class="sample">
+                   key X = &HelpMessage("\e$B%5%s%W%k\e(B C-x-", \<br>
+                   &nbsp;"C-x C-s\t\e$B>e=q$-J]B8\e(B\r\n" \<br>
+                   &nbsp;"C-x C-f\t\e$B3+$/\e(B\t\r\n" \<br>
+                   &nbsp;"C-x k\t\t\e$B?75,:n@.\e(B\r\n" \<br>
+                   &nbsp;"C-x C-c\t\e$B=*N;\e(B")
+                   </p>
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_DescribeBindings"><code>&amp;DescribeBindings</code></a> \e$B$rHyL/$K2~NI!#\e(B
+               <li>\e$B%"%s%$%s%9%H!<%k$,$G$-$J$/$J$C$F$$$?$N$r=$@5!#\e(B(Thanks to \e$B>.NS\e(B)
+             </ul>
+         <dt>2001/08/05 3.24
+         <dd>
+             <ul>
+               <li><a href="../default.mayu"><code>default.mayu</code></a> \e$B$G!"\e(B<kbd>\e$B1Q?t\e(B</kbd> \e$B$r\e(B <kbd>Control</kbd> \e$B$H$7$F;HMQ$7$F$$$k>l9g$K\e(B <code>C-Q</code> \e$B$,@5$7$/F/$+$J$$LdBj$r=$@5!#\e(Bversion 3.19 \e$B$G=$@5$7$?$b$N$H860x$OF1$8!#\e(B(Thanks to hanawa)
+               <li>Windows9x \e$B$N%I%i%$%P$r99?7!#@D2hLL$G$bA`:n$G$-$k$h$&$K$J$j$^$7$?!#\e(B(Thanks to \e$B>.NS\e(B)
+               <li><a href="CUSTOMIZE-ja.html#oneShotModifier">One Shot \e$B%b%G%#%U%!%$%d\e(B</a>\e$B$G$"$k$H@k8@$7$?%-!<$,2!$5$l$F$$$k4V$K%-!<$,2!$5$l$?;~$N$_!"%b%G%#%U%!%$%d$H$7$F07$o$l$k$h$&$K$7$?!#:#$^$G$O!"N%$5$l$?;~$K$b%b%G%#%U%!%$%d07$$$K$J$C$F$$$?!#\e(B
+               <li>\e$B0l;~Dd;_$K$7$?$H$-$K%?%9%/%H%l%$$N%"%$%3%s$rJQ2=$5$;$k$h$&$K$7$?!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#keyRepeat"><code>R-</code></a> \e$B$r?7@_!#\e(B(Thanks to hanawa)\e$B!#\e(B<a href="../mayu-mode.el" target="MANUAL"><code>mayu-mode.el</code></a> \e$B$G?'$,$D$/$h$&$K$7$?!#\e(B
+               <li><a href="http://www.borland.co.jp/cppbuilder/freecompiler/index.html" target="_top">Borland C++ 5.5.1</a> \e$B$G\e(B<a href="CUSTOMIZE-ja.html#compile">\e$B%S%k%I\e(B</a>\e$B$G$-$k$h$&$K$7$?!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#oneShotModifier">One Shot \e$B%b%G%#%U%!%$%d\e(B</a>\e$B$rN%$7$?$H$-$KM-8z$J%b%G%#%U%!%$%d$O2!$7$?$H$-$HF1$8$K$J$k$h$&$K$7$?!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#function_EmacsEditKillLine"><code>&amp;EmacsEditKillLineFunc</code></a>, <a href="CUSTOMIZE-ja.html#function_EmacsEditKillLine"><code>&amp;EmacsEditKillLinePred</code></a> \e$B$N@bL@$rDI2C!#\e(B
+               <li>USB \e$BBP1~%I%i%$%P$O:#2s$O<}O?$7$F$$$^$;$s!#\e(B
+               <li>BETA \e$B$G$O$J$$$G$9!#\e(B
+             </ul>
+         <dt>2001/07/06 3.23 (BETA)
+         <dd>
+             <ul>
+               <li><a href="../104on109.mayu"><code>104on109.mayu</code></a> \e$B$G!V\e(B`\e$B!W$,F~NO$G$-$J$+$C$?%P%0$rD>$7$?!#\e(B(Thanks to Oiwa)
+               <li><a href="CUSTOMIZE-ja.html#oneShotRepeatableModifier">One Shot (\e$B%-!<%j%T!<%HM-\e(B)</a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Toggle"><code>&amp;Toggle</code></a> \e$B$G!"6/@)E*$K%*%s%*%U$G$-$k$h$&$K$7$?!#\e(B
+               <li><a href="../109.mayu"><code>109.mayu</code></a> \e$B$K\e(B VAIO \e$B%?%o!<MQ$NFC<l%-!<$rDI2C!#\e(B
+               <li>WindowsNT4.0 \e$B$G%$%s%9%H!<%k$G$-$J$/$J$C$F$$$?LdBj$r=$@5!#\e(B(Makefile \e$B$N=q$-J}$N%_%9\e(B)
+               <li>Windows9x \e$B$N%I%i%$%P$r99?7!#\e(B
+               <li>\e$B?75,%$%s%9%H!<%k$7$?;~$K!V%[!<%`%G%#%l%/%H%j$+$i!W$,A*Br$5$l$F$$$F%-!<F~NO$,$G$-$J$/$J$C$F$7$^$&LdBj$r=$@5!#\e(B
+               <li><a href="#SUPPORT">support</a> \e$B$K\e(B 2ch \e$B$rDI2C!#\e(B
+             </ul>
+         <dt>2001/03/24 3.22 (BETA)
+         <dd>
+             <ul>
+               <li><a href="CUSTOMIZE-ja.html#def_subst">\e$BBeMQDj5A\e(B</a>\e$B$rDI2C$7$?!#$*$+$2$G\e(B <a href="../104on109.mayu"><code>104on109.mayu</code></a> \e$B$J$I$,%9%^!<%H$KDj5A$G$-$k$h$&$K$J$C$?!#\e(B
+               <li><a href="../mayu-mode.el" target="MANUAL"><code>mayu-mode.el</code></a> \e$B$GBeMQDj5A$K$b?'$,$D$/$h$&$K$7$?!#\e(B
+               <li>\e$B4V0c$C$F%G%P%C%0%S%k%I$7$?$b$N$r<}O?$7$F$$$?$N$r%j%j!<%9%S%k%I$r<}O?$9$k$h$&$K$7$?!#\e(B
+               <li>\e$B4V0c$C$F2u$l$?\e(B Windows9x \e$B$N%I%i%$%P$r<}O?$7$F$7$^$C$?$N$G@5$7$$%I%i%$%P$rF~$l$?!#\e(B
+             </ul>
+         <dt>2001/03/23 version 3.21 (BETA)
+         <dd>
+             <ul>
+               <li>Windows95 \e$B$G\e(B CPU \e$B;~4V$r\e(B 100% \e$B@j$a$F$7$^$&LdBj$,$J$*$C$?!#\e(B(Thanks to \e$B>.NS5AL@\e(B)
+               <li>NEC PC-98x1 \e$B$GF0:n$7$J$$LdBj$,$J$*$C$?!#\e(B(Thanks to \e$B>.NS5AL@\e(B)
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_LoadSetting"><code>&amp;LoadSetting</code></a> \e$B$G!"$I$N@_Dj$r%m!<%I$9$k$+;XDj$G$-$k$h$&$K$J$C$?!#\e(B
+               <li><a href="../contrib/98x1.mayu"><code>contrib/98x1.mayu</code></a> \e$B$rDI2C!#\e(B(Thanks to HAJANO Na&ograve;qui)
+               <li><a href="CUSTOMIZE-ja.html#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a> \e$B$K!"\e(B<code>mayu.exe</code> \e$B$N%+%l%s%H%G%#%l%/%H%j$rDI2C!#\e(B            
+             </ul>
+         <dt>2001/03/10 version 3.20 (BETA)
+         <dd>
+             <ul>
+               <li>Windows95 \e$B$G$bF0:n$9$k$h$&$K$J$C$?!#\e(B
+               <li><a href="#ACKNOWLEDGEMENT">acknowledgements</a> \e$B99?7!#\e(B
+               <li><code>cab32.dll</code> \e$B$G$O$J$/\e(B <code>iexpress</code> \e$B$r;HMQ$7$F%Q%C%1!<%8$r:n@.$9$k$h$&$K$7$?!#\e(B
+               <li>\e$B%=!<%9$r%Q%C%1!<%8$+$iJ,N%$7$?!#\e(B
+             </ul>
+         <dt>2001/03/05 version 3.19 (BETA)
+         <dd>
+             <ul>
+               <li>\e$B$3$N%P!<%8%g%s$OFbIt9=B$$rBgI}$KJQ$($?$N$GIT0BDj$G$"$k2DG=@-$,9b$$$G$9!#$I$&$7$F$b$3$N%P!<%8%g%s$,I,MW$J?M$N$_;HMQ$7$F$/$@$5$$!#\e(B
+               <li><kbd>Control</kbd> + <kbd>U</kbd> \e$BA`:n$N2~NI!#\e(B
+               <li><a href="../default.mayu"><code>default.mayu</code></a> \e$B$r;H$C$F$$$k>l9g$O!"\e(B<code>Global</code> \e$B%-!<%^%C%W$G\e(B <kbd>\e$B1Q?t\e(B</kbd> \e$B$r\e(B <kbd>Control</kbd> \e$B$K$7$F$$$k$,!"\e(B<code>Global</code> \e$B%-!<%^%C%W$r?F%-!<%^%C%W$H$7$F;}$?$J$$\e(B <a href="CUSTOMIZE-ja.html#keymap2"><code>keymap2</code></a> \e$B$NCf$G$O\e(B (\e$BEvA3$J$,$i\e(B) <kbd>\e$B1Q?t\e(B</kbd> \e$B$r\e(B <kbd>Control</kbd> \e$B$H$7$F;HMQ$G$-$J$$$N$G!"$A$c$s$H\e(B <code>Global</code> \e$B%-!<%^%C%W$r?F%-!<%^%C%W$H$7$F;}$D$h$&$K@_Dj%U%!%$%k$r=$@5!#\e(B
+               <li><a href="../default.mayu"><code>default.mayu</code></a> \e$B$G!"\e(B<code>-DMAP-ESCAPE-TO-META</code> \e$B$H$9$k$H\e(B <kbd>Alt</kbd> + <kbd>X</kbd> \e$B$J$I$r\e(B <kbd>ESCAPE] [X</kbd> \e$B$GBeMQ$9$k$h$&$K$7$?!#\e(B
+               <li>WindowsNT/2000 \e$BHG$N%W%m%0%i%`FbIt$G$OA4$F\e(B UNICODE \e$B$G=hM}$9$k$h$&$K$7$?!#\e(B
+               <li>WindowsNT/2000 \e$BHG$G$O!"@_Dj%U%!%$%k$NJ8;z%3!<%I$K!"\e(Bshift_jis \e$B$@$1$G$J$/\e(B UTF-16LE/BE \e$B$d\e(B UTF-8 \e$B$r;HMQ$G$-$k$h$&$K$J$C$?!#!V%a%bD"!W$G!"!V\e(BUnicode\e$B!W$d!V\e(BUnicode big endien\e$B!W$d!V\e(BUTF-8\e$B!W$rA*$s$G%;!<%V$9$l$P!"F|K\8l$@$1$G$J$/%O%s%0%k$J$I$N\e(B UNICODE \e$B$G07$($kJ8;z$,A4$F@_Dj%U%!%$%k$K=q$1$k$h$&$K$J$k!#8=:_$OJ8;z%3!<%I$O<+F0H=JL$5$l!"<+F0H=JL$K<:GT$7$?>l9g$N5_:QA<CV$O$J$$!#<+F0H=JL$K<:GT$9$k$h$&$J$i<+F0H=JL$G$-$=$&$JJ8;z$r%3%a%s%H$K$G$b=q$$$F$*$/$3$H!#\e(B
+               <li>\e$B@55,I=8=%i%$%V%i%j$r\e(B <a href="http://ourworld.compuserve.com/homepages/John_Maddock/regexpp.htm" target="_top">Regex++</a> \e$B$KJQ99$7$?!#\e(B
+               <li>\e$B$$$m$$$mJQ$($?7k2LB?J,\e(B bcc32 \e$B$G$O%3%s%Q%$%k$G$-$J$/$J$C$?!#>/$7=$@5$9$k$@$1$@$H;W$&$,!#\e(B
+               <li><a href="../contrib/ax.mayu"><code>contrib/ax.mayu</code></a> \e$B$rDI2C!#\e(B(Thanks to KAWABE Nobukazu)
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B MetaX \e$B$rDI2C!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#defaultModifier">\e$B%G%U%)%k%H%b%G%#%U%!%$%d$NJQ99\e(B</a>\e$B$N%5%s%W%k$,4V0c$C$F$$$?$N$GD>$7$?!#\e(B(<code>key IC-* =</code> \e$B$G$O$J$/\e(B <code>key *IC- =</code> \e$B$,@5$7$$\e(B) (Thanks to Hirotaka Kasaki)
+               <li><a href="CUSTOMIZE-ja.html#defaultKey">\e$B%G%U%)%k%H%-!<\e(B</a>\e$B$NCf$GDj5ACf$N%-!<%^%C%WL>$r;2>H$G$-$J$+$C$?%P%0$r=$@5$7$?!#$D$^$j!"\e(B<code>keymap Hoge = &amp;Prefix(Hoge)</code> \e$B$J$I$,$G$-$k$h$&$K$J$C$?!#\e(B(Thanks to HANAWA Yoshio)
+               <li>Windows9x \e$BMQ$N%I%i%$%P$r:n@.$5$l$?$N$G!"$3$N%P!<%8%g%s$+$i\e(B WindowsNT/2000 \e$BMQ$N%Q%C%1!<%8$H\e(B Windows9x \e$BMQ$N%Q%C%1!<%8$,B8:_$7$^$9!#\e(B(Thanks to \e$B>.NS5AL@\e(B)
+               <li>\e$B8=:_!"\e(BWindows9x \e$B$G$O!"\e(B<a href="CUSTOMIZE-ja.html#function_HelpMessage"><code>&amp;HelpMessage</code></a>\e$B!"\e(B<a href="CUSTOMIZE-ja.html#function_HelpVariable"><code>&amp;HelpVariable</code></a>\e$B!"\e(B<a href="CUSTOMIZE-ja.html#function_WindowSetAlpha"><code>&amp;WindowSetAlpha</code></a> \e$B$O;HMQ$G$-$^$;$s!#\e(B
+               <li><a href="../default.mayu"><code>default.mayu</code></a> \e$B$r;HMQ$7$F$$$k>l9g!"%7%s%\%k\e(B <code>ZXCV</code> \e$B$rDj5A$7$F$*$/$H!"\e(B<kbd>Control</kbd> + <kbd>Z</kbd>, <kbd>Control</kbd> + <kbd>X</kbd>, <kbd>Control</kbd> + <kbd>C</kbd>, <kbd>Control</kbd> + <kbd>V</kbd> \e$B$,\e(B Windows \e$B$HF1$8F0$-$r$9$k$h$&$K$J$j$^$9!#\e(B(Thanks to HANAWA Yoshio)
+             </ul>
+         <dt>2000/12/17 version 3.18
+         <dd>
+             <ul>
+               <li>\e$B%X%k%W$,3+$1$J$$%P%0$N=$@5!#\e(B
+               <li><a href="../mayu-mode.el" target="MANUAL"><code>mayu-mode.el</code></a> \e$B$,E83+$5$l$F$$$J$+$C$?$N$rD>$7$?!#$D$$$G$K>/$7$@$1=$@5!#\e(B
+               <li><code>IC-</code> \e$B$,;~!9L5;k$5$l$k%P%0$,D>$C$?$O$:!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_HelpMessage"><code>&amp;HelpMessage</code></a> \e$B$rDI2C!#\e(B<a href="../default.mayu"><code>default.mayu</code></a> \e$B$r;H$C$F$$$k>l9g$O%a%bD"$G\e(B <kbd>Control</kbd> + <kbd>X</kbd> \e$B$r2!$7$F$_$h$&\e(B (\e$B$?$@$7\e(B IE5.0 \e$B0J>e$r;H$C$F$$$k>l9g$N$_\e(B)\e$B!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#event"><code>event</code></a> \e$B$rDI2C!#\e(B
+               <li>\e$B$3$l$i$NDI2C$K$h$j!"%W%l%U%#%C%/%9%-!<$,2!$5$l$?;~$K%a%C%;!<%8$rI=<($9$k$3$H$,2DG=$K$J$C$?!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_KeymapWindow"><code>&amp;KeymapWindow</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Variable"><code>&amp;Variable</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Repeat"><code>&amp;Repeat</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_HelpVariable"><code>&amp;HelpVariable</code></a> \e$B$rDI2C!#\e(B
+               <li>\e$B$3$l$i$NDI2C$K$h$j\e(B Emacs \e$B$N\e(B <kbd>Control</kbd> + <kbd>U</kbd> \e$B$,2DG=$K$J$C$?!#;d$K%a!<%k$rAw$k$?$a$K\e(B 1000000000000000000000000000000000000000000000000000000000000@tsg.ne.jp \e$B$HF~NO$9$k$N$b$i$/$i$/$G$9!#\e(B
+               <li>\e$B%A%e!<%H%j%"%k!&\e(BFAQ \e$B$N=<<B$O<!2s$K1d4|!#\e(B
+             </ul>
+         <dt>2000/12/03 version 3.17
+         <dd>
+             <ul>
+               <li>\e$B%a!<%j%s%0%j%9%H$r\e(B <a href="http://lists.sourceforge.net/mailman/listinfo/mayu-support" target="_top">Source Forge</a> \e$B$X0\F0!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowMoveTo"><code>&amp;WindowMoveTo</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowResizeTo"><code>&amp;WindowResizeTo</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_MayuDialog"><code>&amp;MayuDialog</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_DescribeBindings"><code>&amp;DescribeBindings</code></a> \e$B$rDI2C!#I=<(7A<0$,$$$^$$$AJ,$+$j$K$/$$$N$G$I$&$7$h$&$+;W0FCf!#\e(B
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B Pastel Touch \e$B$rDI2C!#\e(B
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B KeyMap \e$B$rDI2C!#\e(B
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B dvorak kr, swap2k \e$B$rDI2C!#\e(B
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B Q's Nicolatter \e$B$rDI2C!#\e(B
+               <li><a href="#FAQ">FAQ</a> \e$B$rDI2C!#\e(B
+               <li><code>mailto:</code> \e$B$r%I%-%e%a%s%H$+$i:o=|!#\e(B
+               <li><a href="http://www.linuxsupportline.com/~doc++/" target="_top">DOC++</a> \e$B$GI=<($G$-$k$h$&$K%=!<%9$N%3%a%s%H$r=q$-49$($?!#\e(B
+               <li>Emacs \e$B$G@_Dj%U%!%$%k$rJT=8$9$k?M$N$?$a$K\e(B <a href="../mayu-mode.el"><code>mayu-mode.el</code></a> \e$B$rDI2C!#$?$@$7!"?'$,$D$/$@$1$G$9!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowIdentify"><code>&amp;WindowIdentify</code></a> \e$B$G!"%&%#%s%I%&$N0LCV$HBg$-$5$bI=<($9$k$h$&$K$7$?!#\e(B
+               <li><a href="../contrib/keitai.mayu"><code>contrib/keitai.mayu</code></a> \e$B$rDI2C!#%F%s%-!<$G7HBSEEOC<0$R$i$,$JF~NO$r$7$h$&$H$$$&2h4|E*@_Dj%U%!%$%k\e(B (\e$BCm\e(B:Joke)\e$B!#\e(B(Thanks to HANAWA Yoshio)
+               <li>\e$B@_Dj%U%!%$%k$,8+$D$+$i$J$+$C$?$H$-$O%(%i!<$r=P$9$h$&$K$J$C$?!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+               <li>\e$BD4::%@%$%"%m%0$rF0$+$9$H%m%0%&%#%s%I%&$bF0$/$h$&$K$7$?!#\e(B
+               <li>\e$B@_Dj%@%$%"%m%0\e(B
+                   <ul>
+                     <li>\e$B%?%9%/%H%l%$$N%a%K%e!<$+$iBt;33+$1$k%P%0$r=$@5!#\e(B
+                     <li>\e$B!VJT=8!W$r2!$7$FJT=8%@%$%"%m%0$,=P$F$$$k:GCf$K$b$&0lEY!VJT=8!W$r2!$;$k%P%0$N=$@5!#\e(B
+                     <li>\e$B!VJT=8!W$G!"%U%!%$%kL>$r6u$K$G$-$J$$%P%0$N=$@5!#\e(B
+                     <li>\e$B%5%$%:JQ99$G$-$k$h$&$K$7$?!#\e(B
+                   </ul>
+             </ul>
+         <dt>2000/05/28 version 3.16
+         <dd>
+             <ul>
+               <li>\e$B%$%s%9%H!<%i$,%F%s%]%i%j%U%)%k%@$K:n$C$?\e(B contrib \e$B$r:o=|$7$J$$%P%0$rD>$7$?!#\e(B
+               <li>\e$B%"%s%$%s%9%H!<%i$,!VAk;H$$$NM+]5!W4XO"$N%l%8%9%H%j$rA4$F>C$9$h$&$KJQ99!#\e(B
+               <li>\e$B%P!<%8%g%s%@%$%"%m%0$N!V:G?7%P!<%8%g%s$N%@%&%s%m!<%I!W%\%?%s$,Mx$+$J$/$J$C$F$$$?%P%0$rD>$7$?!#\e(B
+             </ul>
+         <dt>2000/05/23 version 3.15
+         <dd>
+             <ul>
+               <li>\e$B%I%i%$%P$r5/F0;~$K%9%?!<%H$5$;$k$3$H$K$7$?!#$N$G!"\e(BAdministrator \e$B$8$c$J$/$F$bAk;H$$$NM+]5$r5/F0$G$-$k$h$&$K$J$C$?$O$:!#$?$@$7$3$l$rM-8z$K$9$k$K$O!"Ak;H$$$NM+]5$r0lC6%"%s%$%s%9%H!<%k$7$F!"%3%s%T%e!<%?$r%j%;%C%H$7$F$+$i:F$S%$%s%9%H!<%k$9$k$3$H!#\e(B
+               <li>\e$B%"%W%j%1!<%7%g%s=*N;;~$K;~!9%(%i!<$,5/$-$F$$$?%P%0$rB`<#!#\e(B
+               <li>\e$B!VAk;H$$$NM+]5$N@_Dj!W%@%$%"%m%0$N2~NI!#\e(B
+               <li>version 3.10 \e$B$"$?$j$+$i!"\e(B<a href="CUSTOMIZE-ja.html#HOME">\e$B%[!<%`%G%#%l%/%H%j\e(B</a>\e$B$N$&$A!V@_Dj\e(B(S)... \e$B$G;XDj$7$?%U%!%$%k$N$"$k%G%#%l%/%H%j!W$,8!:w$5$l$J$/$J$C$F$$$?%P%0$r=$@5!#\e(B
+               <li>\e$B0J2<$N\e(B <code><em>FUNCTION</em></code> \e$B$N:G8e$N0z?t$K\e(B <code>MDI</code> \e$B$r;XDj$9$k$H!"\e(BMDI \e$B;R%&%#%s%I%&$rA`:n$G$-$k$h$&$K$7$?!#\e(B
+                   <a href="CUSTOMIZE-ja.html#function_WindowCling"><code>&amp;WindowClingToBottom</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowCling"><code>&amp;WindowClingToLeft</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowCling"><code>&amp;WindowClingToRight</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowCling"><code>&amp;WindowClingToTop</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowClose"><code>&amp;WindowClose</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax"><code>&amp;WindowHMaximize</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowRiseLower"><code>&amp;WindowLower</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax"><code>&amp;WindowMaximize</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax"><code>&amp;WindowMinimize</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowMove"><code>&amp;WindowMove</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowMoveVisibly"><code>&amp;WindowMoveVisibly</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowRiseLower"><code>&amp;WindowRaise</code></a>,
+                   <a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax"><code>&amp;WindowVMaximize</code></a>
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+             </ul>
+         <dt>2000/05/19 version 3.14
+         <dd>
+             <ul>
+               <li>\e$B@55,I=8=%i%$%V%i%j$r:F$S\e(B BUG FIX\e$B!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+             </ul>
+         <dt>2000/05/13 version 3.13
+         <dd>
+             <ul>
+               <li>\e$B@55,I=8=%i%$%V%i%j$N\e(B BUG FIX\e$B!#\e(B
+             </ul>
+         <dt>2000/05/08 version 3.12
+         <dd>
+             <ul>
+               <li>\e$B@55,I=8=%i%$%V%i%j$N\e(B BUG FIX\e$B!#!V%^%$%s%9%$!<%Q!W$K%^%C%A$5$;$k$3$H$,$G$-$k$h$&$K$J$C$?!#\e(B
+             </ul>
+         <dt>2000/05/06 version 3.11
+         <dd>
+             <ul>
+               <li><a href="../contrib/dvorak.mayu"><code>contrib/dvorak.mayu</code></a> \e$B$r99?7!#\e(B(Thanks to KANAI Makoto)
+               <li><a href="../contrib/mayu-settings.txt"><code>contrib/mayu-settings.txt</code></a> \e$B$r99?7!#\e(B(Thanks to HANAWA Yoshio)
+             </ul>
+         <dt>2000/05/05 version 3.10
+         <dd>
+             <ul>
+               <li><a href="http://www.inprise.com/bcppbuilder/freecompiler" target="_top">Borland C++ Compiler 5.5</a> \e$B$G\e(B<a href="CUSTOMIZE-ja.html#compile">\e$B%S%k%I\e(B</a>\e$B$G$-$k$h$&$K$7$?!#\e(B(Thanks to HANAWA Yoshio)
+               <li><a href="CUSTOMIZE-ja.html#inputModifier">\e$BF~NO$5$l$?%-!<$HF1$8%b%G%#%U%!%$%d$N;XDj\e(B</a> \e$B$,$G$-$k$h$&$K$7$?!#\e(B
+               <li>\e$BJ#?t$N%-!<@_Dj$r%a%K%e!<$G@Z$jBX$(2DG=$K$7$?!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+               <li><a href="#INSTALL">DLL \e$B99?7\e(B</a>\e$B!#\e(B
+               <li>(\e$BHs8x3+\e(B)
+             </ul>
+         <dt>2000/04/24 version 3.09
+         <dd>
+             <ul>
+               <li><a href="../contrib/dvorak.mayu"><code>contrib/dvorak.mayu</code></a> \e$B$rDI2C!#\e(B(Thanks to KANAI Makoto)
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_InvestigateCommand"><code>&amp;InvestigateCommand</code></a> \e$B$rDI2C!#\e(B<a href="CUSTOMIZE-ja.html#function_PostMessage"><code>&amp;PostMessage</code></a> \e$B$N0Y$ND4::MQ!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_EditNextModifier"><code>&amp;EditNextModifier</code></a> \e$B$rDI2C!#\e(B<kbd>Alt</kbd> + <kbd>X</kbd> \e$B$J$I$r\e(B <kbd>ESCAPE</kbd> <kbd>X</kbd> \e$B$J$I$GBeMQ$9$k$3$H$,2DG=$K!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Prefix"><code>&amp;Prefix</code></a> \e$B$rJQ99!#\e(B<a href="CUSTOMIZE-ja.html#keymap2"><code>keymap2</code></a> \e$B$r;H$&$H$-$N$*LsB+\e(B (<code>mod !shift !alt !control !windows</code>) \e$B$,ITMW$K!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+             </ul>
+         <dt>2000/04/15 version 3.08
+         <dd>
+             <ul>
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowSetAlpha"><code>&amp;WindowSetAlpha</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowRedraw"><code>&amp;WindowRedraw</code></a> \e$B$rDI2C!#\e(B
+               <li><a href="#RELATEDWORK">related work</a> \e$B$K\e(B KillGates \e$B$rDI2C!#\e(B
+               <li><a href="../contrib/mayu-settings.txt"><code>contrib/mayu-settings.txt</code></a> \e$B$r99?7!#\e(B(Thanks to HANAWA Yoshio)
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+             </ul>
+         <dt>2000/04/01 version 3.07
+         <dd>
+             <ul>
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_Wait"><code>&amp;Wait</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_MouseWheel"><code>&amp;MouseWheel</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_VK"><code>&amp;VK</code></a> \e$B$r3HD%$7$F%^%&%9%\%?%s$rF~NO$G$-$k$h$&$K$7$?!#\e(B
+               <li>\e$B%^%K%e%"%k$NFbMF$r\e(B<a href="#ABSTRACT">\e$B$$\e(B</a> <a href="#INSTALL">\e$B$/\e(B</a> <a href="#BUGS">\e$B$D\e(B</a>\e$B$+=$@5!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+               <li>\e$B1Q8l%j%=!<%9$r$D$1$F$_$?!#$,!";H$$J}ITL@!#\e(B
+               <li>\e$BO"Mm@h$N=$@5!#\e(B
+               <li>\e$B$o$?$7$O%(%$%W%j%k%U!<%k$O7y$$$G$9!#\e(B
+             </ul>
+         <dt>2000/03/21 version 3.06
+         <dd>
+             <ul>
+               <li>\e$B$$$/$D$+$N\e(B typo \e$B$r=$@5!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax"><code>&amp;WindowHMaximize</code>, <code>&amp;WindowVMaximize</code></a> \e$B$G!"\e(BH \e$B$H\e(B V \e$B$rN>J}F1$8%&%#%s%I%&$XE,MQ$7$?>l9g$NF0:n$r=$@5!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_ClipboardCopy"><code>&amp;ClipboardCopy</code></a> \e$B$rDI2C!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$r99?7!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#modifier"><code>IL-</code></a> \e$B$rF3F~$7!"\e(B<code>I-</code> \e$B$O\e(B <code>IC-</code> \e$B$KL>A0$rJQ99!#$?$@$7!"8_49@-$N0Y\e(B <code>I-</code> \e$B$b0z$-B3$-;HMQ2DG=$G$9!#\e(B
+               <li>\e$B%3%s%=!<%k$N%U%)!<%+%9$NDI@W$K;~!9<:GT$7$F$$$?$N$,D>$C$?$+$b$7$l$J$$!#\e(B(\e$B$+$b$7$l$J$$$P$C$+$@!D\e(B)
+             </ul>
+         <dt>2000/03/10 version 3.05
+         <dd>
+             <ul>
+               <li>\e$B%;%C%H%"%C%W$r=$@5!#\e(B
+               <li>\e$B%3%s%=!<%k$N%U%)!<%+%9$NDI@W$K;~!9<:GT$7$F$$$?$N$,D>$C$?$+$b$7$l$J$$!#\e(B
+               <li>(\e$BHs8x3+\e(B)
+             </ul>
+         <dt>2000/03/08 version 3.04
+         <dd>
+             <ul>
+               <li>\e$B@_Dj%U%!%$%k$r=$@5!#\e(B(\e$B%G%U%)%k%H$G1Q?t%-!<$r\e(B Control \e$B$K\e(B)
+               <li>\e$B%^%K%e%"%k$N%P%0$rD>$7$?!#\e(B
+               <li>\e$B%^%K%e%"%k$r\e(B Mozilla \e$B$G$b$A$c$s$HI=<($G$-$k$h$&$K$7$?!#\e(B(IE \e$B$G8+$k$H$-$O%U%)%s%H%5%$%:!V>.!W$K$9$k$H$+$C$3$$$$$,!"$h$_$K$/$$$N$G$7$J$/$F$$$$$G$9\e(B)
+             </ul>
+         <dt>2000/03/04 version 3.03
+         <dd>
+             <ul>
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowMaxMinHVMax"><code>&amp;WindowHMaximize</code></a> \e$B$rDI2C!#\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_WindowIdentify"><code>&amp;WindowIdentify</code></a> \e$B$rDI2C!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$rBgI}$K99?7$7$?!#\e(B
+               <li><a href="../contrib/mayu-settings.txt"><code>contrib/mayu-settings.txt</code></a> \e$B$NDI2C!#\e(B(Thanks to HANAWA Yoshio)
+               <li>Windows2000 \e$BMQ$N%I%i%$%P$r%Q%o!<%^%M%8%a%s%HBP1~$K$7$?!#\e(B
+               <li>\e$B%3%s%=!<%k$N%U%)!<%+%9$NDI@W$K;~!9<:GT$7$F$$$?$N$,D>$C$?$+$b$7$l$J$$!#\e(B
+               <li>PlayStation2 \e$B$NH/GdF|!#\e(B
+             </ul>
+         <dt>1999/11/01 version 3.02
+         <dd>
+             <ul>
+               <li>setup \e$B;~$K%-!<%\!<%I$N<oN`$rJ9$/$h$&$K$7$?!#\e(B
+               <li>KeyboardLayout/\e$B$[$2$[$2\e(B \e$B$NGQ;_\e(B (\e$BF|K\8l$N>l9g$O%-!<%\!<%I$K$h$i$:!"\e(BIME \e$B$K$h$C$F7hDj$5$l$k$?$a\e(B)\e$B!#\e(B
+               <li>\e$B@_Dj%U%!%$%k$r:FFI$_9~$_$7$?8e$K!"%3%s%H%m!<%k%-!<$J$I$,2!$5$l$C$Q$J$7$K$J$k$3$H$,$"$k%P%0$rD>$7$?!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#oneShotModifier">One Shot \e$B%b%G%#%U%!%$%d\e(B</a>\e$B$N@bL@$,4V0c$C$F$$$?$N$G=$@5!#\e(B
+               <li>\e$B%G%U%)%k%H$N%b%G%#%U%!%$%d$r\e(B<a href="CUSTOMIZE-ja.html#defaultModifier">\e$BJQ99\e(B</a>\e$B$G$-$k$h$&$K$7$?!#\e(B
+               <li><a href="CUSTOMIZE-ja.html#include">include</a> \e$B$G$O!"$^$:!"%l%8%9%H%j$G;XDj$7$F$"$k@_Dj%U%!%$%k$HF1$8%U%)%k%@$r8!:w$9$k$h$&$K$7$?!#\e(B
+               <li>\e$B%$%s%9%H!<%i$r>/!9JQ99\e(B
+               <li><code><em>FUNCTION</em></code> <a href="CUSTOMIZE-ja.html#function_VK"><code>&amp;VK</code></a>  \e$B$G!"\e(B<code>U-</code> \e$B$H\e(B <code>D-</code> \e$B$,5U$K$J$C$F$$$?%P%0$r=$@5!#\e(B
+             </ul>
+         <dt>1999/10/30 version 3.01
+         <dd>
+             <ul>
+               <li><a href="../104on109.mayu"><code>104on109.mayu</code></a> \e$B$H\e(B <a href="../109on104.mayu"><code>109on104.mayu</code></a> \e$B$r:n$C$?!#\e(B
+             </ul>
+         <dt>1999/10/29 version 3.00
+         <dt>1999/09/08 cmkey version 2.21
+         <dt>1999/09/05 cmkey version 2.20
+         <dt>1999/05/31 cmkey version 2.19
+         <dt>1999/05/31 cmkey version 2.18
+         <dt>1999/05/30 cmkey version 2.17
+         <dt>1999/05/29 cmkey version 2.16
+         <dt>1999/05/26 cmkey version 2.15
+         <dt>1999/05/26 cmkey version 2.14
+         <dt>1999/02/10 cmkey version 2.13
+         <dt>1998/12/02 cmkey version 2.12
+         <dt>1998/10/07 cmkey version 2.11
+         <dt>1998/07/23 cmkey version 2.10
+         <dt>1998/07/20 cmkey version 2.09
+         <dt>1998/07/17 cmkey version 2.08
+         <dt>1998/07/12 cmkey version 2.07
+         <dt>1998/07/11 cmkey version 2.06
+         <dt>1998/07/11 cmkey version 2.05
+         <dt>1998/07/05 cmkey version 2.04
+         <dt>1998/06/07 cmkey version 2.03
+         <dt>1998/05/24 cmkey version 2.02
+         <dt>1998/05/19 cmkey version 2.01
+         <dt>1998/05/19 cmkey version 2.00
+         <dt>1996/07/?? WinModMap version 1.03
+         <dt>1996/06/30 WinModMap version 1.02
+         <dt>1996/06/22 WinModMap version 1.01
+         <dt>1996/06/21 WinModMap version 1.00
+       </dl>
+      </div>
+</dl>
+</div>
+
+</body>
+</html>
diff --git a/doc/README-ja.html b/doc/README-ja.html
new file mode 100644 (file)
index 0000000..a387b84
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+<html lang="ja">
+<head>
+<meta http-equiv="Content-Type" content="text/html;charset=iso-2022-jp">
+<link rel="next" href="MANUAL-ja.html">
+<title>\e$BAk;H$$$NM+]5\e(B - README</title>
+<link rel="stylesheet" type="text/css" href="README.css">
+</head>
+
+<frameset cols="30%,70%" title="README">
+<frame src="CONTENTS-ja.html" name="CONTENTS" title="CONTENTS">
+<frame src="MANUAL-ja.html" name="MANUAL" title="MANUAL">
+</frameset>
+
+<noframes>
+<body>
+\e$B%U%l!<%`$r%5%]!<%H$7$F$J$$%V%i%&%6$G$O!"\e(B<a href="MANUAL-ja.html">MANUAL-ja.html</a> \e$B$H\e(B <a href="CUSTOMIZE-ja.html">CUSTOMIZE-ja.html</a> \e$B$rD>@\FI$s$G2<$5$$!#;DG0$J$,$i\e(B<a href="CONTENTS-ja.html">\e$BL\<!\e(B</a>\e$B$rFI$`$3$H$O$G$-$^$;$s$,!#\e(B
+</body>
+</noframes>
+
+</html>
diff --git a/doc/README.css b/doc/README.css
new file mode 100644 (file)
index 0000000..230105e
--- /dev/null
@@ -0,0 +1,319 @@
+/* general */
+
+frameset {
+  border-width: 0px;
+}
+body {
+  color: #000;
+  font-size: medium;
+  font-family: Arial, sans-serif;
+  background-color: #fff;
+  margin: 0pt;
+  padding: 0pt;
+ }
+a {
+  color: #000;
+}
+a:hover, a:active {
+  text-decoration: underline;
+  background-color: #ffa;
+}
+img {
+  border-width: 0pt;
+}
+code, code a {
+  font-size: 100%;
+  font-family: Courier New, monospace;
+  color: #a00;
+}
+em {
+  color: #000;
+  font-weight: bold;
+}
+kbd {
+  font-size: 100%;
+  font-weight: bold;
+  font-family: monospace;
+  color: #55a;
+
+  background-color: #ccc;
+  border-color: #fff;
+  border-width: 4px;
+  border-style: outset;
+  color: #000;
+  padding: 0px 3px 0px 3px;
+  margin: 0px 2px 0px 2px;
+}
+p {
+  text-justify: distribute;
+  text-align: justify;
+}
+p.noindent {
+  text-indent: 0em;
+}
+
+/* contents */
+
+.contents {
+  font-size: smaller;
+}
+.contents code, .contents code a {
+  font-size: 100%;
+}
+.contents a {
+  text-decoration: none;
+  color: #fff;
+}
+.contents a:hover, .contents a:active {
+  color: #000;
+  background-color: #fff;
+}
+.contents .section, .contents .appendix {
+  color: #fff;
+  background-color: #000;
+  font-weight: bold;
+}
+.contents .section ol, .contents .appendix ol {
+  margin: 0pt;
+  padding: 0px 1.1em 0px 3em;
+}
+.contents .appendix ol {
+  list-style-type: upper-alpha;
+}
+.contents .subsection {
+  color: #000;
+  font-weight: normal;
+  background-color: #fff;
+  margin: 0px -1.1em 0px -3em;
+  padding: 1ex 1.1em 1ex 0px;
+
+  border-color: #aaa;
+  border-width: 3px;
+  border-style: solid none none none;
+}
+.contents .subsection a { 
+  color: #000;
+}
+.contents .subsection a:hover,
+.contents .subsection a:active {
+  color: #000;
+  background-color: #ffa;
+  text-decoration: underline;
+}
+.contents .subsection ol {
+  margin: 0px;
+  padding: 0px 0px 0px 3em;
+  list-style-type: lower-roman;
+}
+.contents .subsubsection {
+  margin: 0px -1.1em 0px -3em;
+  background-color: #eef;
+}
+.contents .subsubsection ul {
+  margin: .5ex 0pt .5ex 0pt;
+  padding: .5ex 1.1em .5ex 4em;
+  list-style-type: disc;
+}
+
+/* manual */
+
+.manual {
+  font-size: smaller;
+  line-height: 150%;
+}
+.manual a {
+  text-decoration: underline;
+}
+.manual a code {
+  text-decoration: underline;
+}
+.manual .title {
+  text-align: center;
+}
+.manual .copyright {
+  text-align: right;
+  font-weight: bold;
+  margin-bottom: 4ex;
+}
+.manual .main {
+  margin-bottom: 1024px;
+}
+.manual dl {
+  padding: 0pt;
+  margin: 0pt;
+}
+.manual .h1 {
+  padding: 4pt;
+  padding-left: 10pt;
+  margin: 0pt;
+  font-weight:bold;
+  background-color: #000;
+  color: #fff;
+
+  border-color: #aaa;
+  border-width: 3px;
+  border-style: none none solid none;
+}
+.manual .h1 a, .manual .h1 a code {
+  text-decoration: none;
+  color: #fff;
+}
+.manual .h1 a:hover,
+.manual .h1 a:active {
+  text-decoration: none;
+  color: #000;
+  background-color: #fff;
+}
+.manual .d1 {
+  padding: 2ex 1em 2ex 1em;
+  margin: 0pt;
+  background-color:#fff;
+}
+.manual .d1 p {
+  margin: 1ex 0px 1ex 0px;
+  text-indent: 1em;
+}
+.manual .d1 p.continue {
+  text-indent: 0em;
+}
+.manual .d1 ol, .manual .d1 ul {
+  margin-top: 1ex;
+  margin-bottom: 1ex;
+}
+.manual .d1 ol li, .manual .d1 ul li {
+  margin-left: -1em;
+}
+.manual .h2 {
+  padding: .5ex;
+  font-weight: bold;
+}
+.manual .h2 a, .manual .h2 a code {
+  text-decoration: none;
+}
+.manual .d2 {
+  background-color: #eef;
+  margin: 0pt 1em 0pt 1em;
+  padding: 1ex 1em 1ex 1em;
+}
+.manual .h3 {
+  padding: 0px 0px 0px 1em;
+  margin: 1ex 0px 0px 0px;
+  font-weight: bold;
+  background-color: #7a96df;
+  color: #fff;
+  
+  border-color: #7a96df;
+  border-width: 1px;
+  border-style: solid;
+}
+.manual .h3 a, .manual .h3 a code {
+  text-decoration: none;
+  color: #fff;
+}
+.manual .d3 {
+  margin: 0px 0px 1ex 0ex;
+  padding: 0ex 1em 0ex 1em;
+  background-color: #fff;
+  border-color: #7a96df;
+  border-width: 1px;
+  border-style: solid;
+}
+.manual .d3 blockquote {
+  margin: 1ex 2em 1ex 2em;
+  padding: 1em;
+  background-color: #eef;
+}
+.manual .h4 {
+  font-weight: bold;
+  margin: 1ex 0pt 1ex 0pt;
+}
+.manual .d4 {
+  margin: 0pt 0pt 0pt 1em;
+}
+.manual .history dt {
+  font-weight:bold;
+}
+.manual .history ul li {
+  margin-left: -4em;
+}
+.manual .history ul ul li {
+  margin-left: 0pt;
+}
+.manual .sample, .manual p.sample {
+  white-space: nowrap;
+  text-indent: 0em;
+  padding: 0pt 1em 0pt 1em;
+  font-family: Courier New, monospace;
+  color: #a00;
+  border-color: #a00;
+  border-width: 1px;
+  border-style: solid;
+  margin-left: 4pt;
+  background-color: #fff;
+  overflow: auto;
+}
+.manual .bug {
+  font-weight: bold;
+  color: #f00;
+}
+.manual .menu-item {
+  background-color: #fff;
+  border-color: #000;
+  border-width: 1px;
+  border-style: solid;
+  padding: 3px .5em 3px .5em;
+  margin: 0px .5em 0px .5em;
+  font-family: "MS UI Gothic", sans-serif;
+}
+.manual .menu-item a {
+  text-decoration: none;
+}
+.manual .default-settings {
+  border-width: 1px;
+  border-color: #000;
+  border-style: solid;
+  background-color: #7a96df;
+  border-collapse: collapse;
+  border-spacing: 0pt;
+}
+.manual .default-settings th {
+  font-family: Arial, sans-serif;
+  padding: 0pt .5em 0pt .5em;
+  font-size: 10pt;
+  color: #fff;
+}
+.manual .default-settings td {
+  font-family: Arial, sans-serif;
+  background-color: #fff;
+  padding: 0pt .5em 0pt .5em;
+  font-size: 10pt;
+  color: #000;
+}
+.manual .default-settings .name th {
+  border-width: 1px;
+  border-color: #000;
+  border-style: solid none none none;
+}
+.manual .default-settings .name td {
+  border-width: 1px;
+  border-color: #000;
+  border-style: solid none none none;
+}
+.manual .default-settings .name-english th {
+  border-width: 3px;
+  border-color: #000;
+  border-style: double none none none;
+}
+.manual .default-settings .name-english td {
+  border-width: 3px;
+  border-color: #000;
+  border-style: double none none none;
+}
+.manual p.tree {
+  white-space: nowrap;
+  text-indent: 0em;
+  line-height: 90%;
+}
+.manual p.tree span {
+  color: #55a;
+}
diff --git a/doc/banner-ja.gif b/doc/banner-ja.gif
new file mode 100755 (executable)
index 0000000..cc1de78
Binary files /dev/null and b/doc/banner-ja.gif differ
diff --git a/doc/edit-setting-ja.png b/doc/edit-setting-ja.png
new file mode 100644 (file)
index 0000000..921869e
Binary files /dev/null and b/doc/edit-setting-ja.png differ
diff --git a/doc/investigate-ja.png b/doc/investigate-ja.png
new file mode 100644 (file)
index 0000000..b190850
Binary files /dev/null and b/doc/investigate-ja.png differ
diff --git a/doc/log-ja.png b/doc/log-ja.png
new file mode 100644 (file)
index 0000000..06eae30
Binary files /dev/null and b/doc/log-ja.png differ
diff --git a/doc/menu-ja.png b/doc/menu-ja.png
new file mode 100644 (file)
index 0000000..cfd9bd2
Binary files /dev/null and b/doc/menu-ja.png differ
diff --git a/doc/pause-ja.png b/doc/pause-ja.png
new file mode 100644 (file)
index 0000000..89e443c
Binary files /dev/null and b/doc/pause-ja.png differ
diff --git a/doc/setting-ja.png b/doc/setting-ja.png
new file mode 100644 (file)
index 0000000..29f241f
Binary files /dev/null and b/doc/setting-ja.png differ
diff --git a/doc/syntax.txt b/doc/syntax.txt
new file mode 100644 (file)
index 0000000..09d5343
--- /dev/null
@@ -0,0 +1,312 @@
+###############################################################################
+#
+# mayu file syntax
+#
+###############################################################################
+
+
+#
+# NOTE:
+#      * case insensitive
+#      * <...> is a non-terminal symbol
+#      * "..." is a terminal symbol
+#      * /.../ is a terminal symbol (regular expression)
+#      * namespace is
+#              1. KEY_NAME
+#              2. KEYSEQ_NAME
+#              3. KEYMAP_NAME
+#              4. ALIAS_NAME
+#              5. FUNCTION_NAME
+#              6. SYMBOL
+#      * the default of <...MODIFIED_KEY_NAME>'s modifier-settings is:
+#              1. "IL-", "NL-", "CL-", "SL-", "KL-",
+#                 "MAX-", "MIN-", "MMAX-", "MMIN-",
+#                 "T-", "TS-",
+#                 /L[0-9]/, "U-" and "D-"
+#                 are specified with "*"
+#              2. all other modifiers are specified with "~"
+#              3. they can be changed by
+#                 "key" <ASSIGN_MODIFIER> "=" <ASSIGN_MODIFIER>
+#
+
+#
+# FILE STRUCTURE
+#
+
+       <MAYU_FILE> : ( <LINE> <COMMENT>? <CRLF> )*
+       <LINE> :
+                 <COND_SYMBOL>
+               | <INCLUDE>
+               | <KEYBOARD_DEFINITION>
+               | <KEYMAP_DEFINITION>
+               | <KEY_ASSIGN>
+               | <EVENT_ASSIGN>
+               | <KEYSEQ_DEFINITION>
+               | <MODIFIER_ASSIGNMENT>
+       # each <LINE> can be divided into some lines by \
+       <COMMENT> : /#.*/
+       <CRLF> : "\r\n"
+
+#
+# BASIC TYPE
+#
+
+       <number> :
+                 /[-+]?[0-9]+/         # decimal
+               | /[-+]?0[0-9]+/        # octal
+               | /[-+]?0x[0-9a-f]+/    # hexadecimal
+
+       <bool> :
+                 "false"               # false
+               | <string>              # true
+
+       <string> :
+                 /([/?_a-z]|\MBCS|\EC)([-+/?_a-z0-9]|\MBCS|\EC)*/
+               | /"([^"]|\MBCS|\EC)*"/
+               | /'([^']|\MBCS|\EC)*'/
+       # \MBCS : Multi Byte Character (such as Shift_JIS)
+       # \EC : Escaped Characters
+       #       | "\a"  # bell
+       #       | "\e"  # escape
+       #       | "\f"  # form feed
+       #       | "\n"  # newline
+       #       | "\r"  # carriage return
+       #       | "\t"  # horizontal tab
+       #       | "\\"  # \
+       #       | /\\[0-7]+/            # character as octal
+       #       | /\\x[0-9a-f]+/        # character as hexadecimal
+
+       <regexp> :
+                 /\REGEXP/
+               | \m@\REGEXP@           # @ can be any character
+       # \REGEXP :
+       #       | "|"           # Alternation
+       #       | "*"           # Match 0 or more times
+       #       | "+"           # Match 1 or more times
+       #       | "?"           # Match 1 or 0 times
+       #       | "."           # Match any character
+       #       | "^"           # Match the beginning of the string
+       #       | "$"           # Match the end of the string
+       #       | "\b"          # Match a word boundary
+       #       | "\B"          # Match a non word boundary
+       #       | "\w"          # Match a word character (alphanumeric, "_")
+       #       | "\W"          # Match a non word character
+       #       | "\s"          # Match a whitespace character
+       #       | "\S"          # Match a non-whitespace character
+       #       | "\d"          # Match a digit character
+       #       | "\D"          # Match a non-digit character
+       #       | "(" ")"       # Grouping
+       #       | "[" "]"       # Character class
+
+#
+# COND SYMBOL
+#
+
+       <COND_SYMBOL> : <DEFINE> | <IF> | <ELSE> | <ELSEIF> | <ENDIF>
+       <DEFINE> : "define" <SYMBOL>
+       <IF> : ( "if" | "and" ) <IF_BODY>
+       <IF_BODY> : "(" "!"? <SYMBOL> ")" ( <LINE> )?
+       <ELSE> : "else" ( <LINE> )?
+       <ELSEIF> : ( "elseif" | "elsif" | "elif" ) <IF_BODY>
+       <ENDIF> : "endif"
+       <SYMBOL> : <string>
+
+#
+# INCLUDE
+#
+
+       <INCLUDE> : "include" <MAYU_FILE_NAME>
+       <MAYU_FILE_NAME> : <string>
+
+#
+# KEYBOARD DEFINITION
+#
+
+       <KEYBOARD_DEFINITION>
+               : "def" <DEFINE_KEY>
+               | "def" <DEFINE_MODIFIER>
+               | "def" <DEFINE_LOCK>
+               | "def" <DEFINE_SYNC_KEY>
+               | "def" <DEFINE_ALIAS>
+               | "def" <DEFINE_SUBSTITUTE>
+               | "def" <DEFINE_OPTION>
+
+       <DEFINE_KEY> : "key" <KEY_NAMES> "=" <SCAN_CODES>
+
+       <KEY_NAMES>
+               : "(" <KEY_NAME>+ ")"
+               | <KEY_NAME>+
+       <KEY_NAME> : <string>
+       <SCAN_CODES> : <SCAN_CODE> <SCAN_CODE>? <SCAN_CODE>? <SCAN_CODE>?
+       <SCAN_CODE> : <SCAN_CODE_EXTENTION>* <number>
+       <SCAN_CODE_EXTENTION> : "E0-" | "E1-"
+
+       <DEFINE_MODIFIER> : "mod" <BASIC_MODIFIER_NAME> "=" <KEY_NAME>*
+       <BASIC_MODIFIER_NAME>
+               : "shift"
+               | "alt" | "meta" | "menu"
+               | "control" | "ctrl"
+               | "windows" | "win"
+
+       <BASIC_LOCK_NAME> : "num" | "caps" | "scroll"
+       <BASIC_MODIFIER> : "S-" | "A-" | "M-" | "C-" | "W-"
+               | "*"           # we don't care the next modifier
+               | "~"           # the next modifier must be released
+
+       <DEFINE_SYNC_KEY> : "sync" "=" <SCAN_CODES>
+
+       <DEFINE_ALIAS> : "alias" <ALIAS_NAME> "=" <KEY_NAME>
+       <ALIAS_NAME> : <string>
+       <ALIASED_KEY_NAME>
+               : <ALIAS_NAME>
+               | <KEY_NAME>
+
+       <DEFINE_SUBSTITUTE>
+               : "subst" <ASSIGN_MODIFIED_KEY_NAME>+ "=" <SUBST_KEY_SEQUENCE>
+
+       <DEFINE_OPTION>
+               : "option" "KL-" "=" <bool>
+               | "option" "delay-of" "!!!" "=" <number>
+
+#
+# KEYMAP DEFINITION
+#
+
+       <KEYMAP_DEFINITION>
+               : "keymap" <KEYMAP_NAME> <KEYMAP_PARENT>? <KEYSEQ_DEFAULT>?
+               | "keymap2" <KEYMAP_NAME> <KEYMAP_PARENT>? <KEYSEQ_DEFAULT>?
+               | "window" <KEYMAP_NAME> <WINDOW>? <KEYMAP_PARENT>? \
+                                                       <KEYSEQ_DEFAULT>?
+       <KEYMAP_NAME> : <string>
+       <KEYMAP_PARENT> : ":" <KEYMAP_NAME>
+       <KEYSEQ_DEFAULT> : "=" <KEY_SEQUENCE>
+       <WINDOW>
+               : <WINDOW_CLASS_NAME>
+               | "(" <WINDOW_CLASS_NAME> "&&" <WINDOW_TITLE_NAME> ")"
+               | "(" <WINDOW_CLASS_NAME> "||" <WINDOW_TITLE_NAME> ")"
+       <WINDOW_CLASS_NAME> : <regexp>
+       <WINDOW_TITLE_NAME> : <regexp>
+
+#
+# KEY TO KEY SEQUENCE ASSIGNMENT
+#
+
+       <KEY_ASSIGN>
+               : "key" <ASSIGN_MODIFIED_KEY_NAME>+ "=" <KEY_SEQUENCE>
+               | "key" <ASSIGN_MODIFIER>* "=" <KEYSEQ_MODIFIER>*
+       <ASSIGN_MODIFIED_KEY_NAME> : <ASSIGN_MODIFIER>* <ALIASED_KEY_NAME>
+       <ASSIGN_MODIFIER>
+               : <KEYSEQ_MODIFIER>
+               | "R-"          # auto repeated key
+               | "IL-"         # if IME on
+               | "IC-" | "I-"  # if IME on and compositioning
+               | "NL-"         # if Num Lock on
+               | "CL-"         # if Caps Lock on
+               | "SL-"         # if Scroll Lock on
+               | "KL-"         # if Kana Lock on
+               | "MAX-"        # if Window maximized
+               | "MIN-"        # if Window minimized
+               | "MMAX-"       # if MDI child Window maximized
+               | "MMIN-"       # if MDI child Window minimized
+               | "T-"          # if finger on touchpad
+               | "TS-" # same as "T-" except for sticky up to release all keys
+               | /M[0-9]/      # user defined modifier
+               | /L[0-9]/      # user defined lock
+
+#
+# EVENT TO KEY SEQUENCE ASSIGNMENT
+#
+
+       <EVENT_ASSIGN>
+               : "event" <EVENT_NAME> "=" <KEY_SEQUENCE>
+       <EVENT_NAME>
+               : "prefixed"
+               | "before-key-down"
+               | "after-key-up"
+
+#
+# MODIFIER ASSIGNMENT
+#
+
+       <MODIFIER_ASSIGNMENT>
+               : "mod" ( <ASSIGN_MODE> <MODIFIER_NAME> )* \
+                       <MODIFIER_NAME> <ASSIGN_OP> \
+                                       ( <ASSIGN_MODE>? <ALIASED_KEY_NAME> )+
+       <MODIFIER_NAME> : <BASIC_MODIFIER_NAME> | /mod[0-9]/
+
+       <ASSIGN_OP> : "=" | "-=" | "+="
+       <ASSIGN_MODE>
+               : "!"           # true modifier (doesn't generate scan code)
+               | "!!"          # one shot modifier
+               | "!!!"         # one shot repeatable modifier
+
+#
+# KEY SEQUENCE DEFINITION
+#
+
+       <KEYSEQ_DEFINITION>
+               : "keyseq" "$" <KEYSEQ_NAME> "=" <KEY_SEQUENCE>
+               | "keyseq" "$" <SUBST_KEYSEQ_NAME> "=" <SUBST_KEY_SEQUENCE>
+
+       <SUBST_KEY_SEQUENCE> : <SUBST_ACTION>+
+       <SUBST_ACTION>
+               : <ASSIGN_MODIFIED_KEY_NAME>
+               | "$" ( <SUBST_KEYSEQ_NAME> | <KEYSEQ_NAME> )
+               | <ASSIGN_MODIFIER>* "&" <FUNCTION_NAME> <ARGUMENTS>?
+               | "(" <SUBST_KEY_SEQUENCE> ")"
+
+       <KEY_SEQUENCE> : <ACTION>+
+       <ACTION>
+               : <KEYSEQ_MODIFIED_KEY_NAME>
+               | "$" <KEYSEQ_NAME>
+               | <KEYSEQ_MODIFIER>* "&" <FUNCTION_NAME> <ARGUMENTS>?
+               | "(" <KEY_SEQUENCE> ")"
+       <ARGUMENTS> : "(" ( <ARGUMENT> ( "," <ARGUMENT> )* )? ")"
+       <KEYSEQ_MODIFIED_KEY_NAME> : <KEYSEQ_MODIFIER>* <ALIASED_KEY_NAME>
+       <KEYSEQ_MODIFIED_KEY_NAME> : <KEYSEQ_MODIFIER>* <ALIASED_KEY_NAME>
+       <KEYSEQ_MODIFIER>
+               : <BASIC_MODIFIER>
+               | "U-"          # up
+               | "D-"          # down
+       <KEYSEQ_NAME> : <string>
+       <SUBST_KEYSEQ_NAME> : <string>
+       <FUNCTION_NAME> : <string>
+       <ARGUMENT>
+               : <KEYMAP_NAME>
+               | "$" <KEYSEQ_NAME> | "(" <KEY_SEQUENCE> ")"
+               | <ARGUMENT_LOCK>
+               | <string>
+               | <number>
+               | <ARGUMENT_VK>
+               | <ARGUMENT_SHOW_WINDOW>
+               | <ARGUMENT_WINDOW>
+               | <ARGUMENT_TARGET_WINDOW_TYPE>
+               | <ASSIGN_MODIFIER>*
+               | <bool>
+
+       <ARGUMENT_LOCK> : /lock\d/      # &Toggle()
+
+       <ARGUMENT_VK>                   # &VK()
+               : <VK_MODIFIER>* <VK_NAME>
+       <VK_MODIFIER> : "E-" | "U-" | "D-"
+       <VK_NAME> : <string>
+
+       <ARGUMENT_SHOW_WINDOW>          # &ShellExecute()
+               : "HIDE" | "MAXIMIZE" | "MINIMIZE" | "RESTORE" | "SHOW"
+               | "SHOWDEFAULT" | "SHOWMAXIMIZED" | "SHOWMINIMIZED"
+               | "SHOWMINNOACTIVE" | "SHOWNA" | "SHOWNOACTIVATE"
+               | "SHOWNORMAL"
+
+       <ARGUMENT_WINDOW>               # &PostMessage()
+               : <number>
+               | "toOverlappedWindow"
+               | "toMainWindow"
+               | "toItself"
+               | "toParentWindow"
+
+       <ARGUMENT_TARGET_WINDOW_TYPE> : "overlapped" | "mdi"
+
+# Local Variables:
+# mode: text
+# eval: (progn (font-lock-mode) (font-lock-add-keywords  nil '(("#.*$" . font-lock-comment-face) ("\\\\$" (0 font-lock-warning-face)) ("/\\(\\[[^]\n]*\\]\\|[^/\n]\\)*/" (0 font-lock-string-face)) ("'[^'\n]*'" (0 font-lock-string-face)) ("\"[^\"\n]*\"" (0 font-lock-string-face)) ("<\\([A-Za-z_][A-Za-z_0-9]*\\)>"  (1 font-lock-constant-face)) ("[*?+]" (0 font-lock-keyword-face)) )) (font-lock-fontify-buffer))
+# End:
diff --git a/doc/target.png b/doc/target.png
new file mode 100644 (file)
index 0000000..1a86319
Binary files /dev/null and b/doc/target.png differ
diff --git a/doc/version-ja.png b/doc/version-ja.png
new file mode 100644 (file)
index 0000000..db23165
Binary files /dev/null and b/doc/version-ja.png differ
diff --git a/dot.mayu b/dot.mayu
new file mode 100644 (file)
index 0000000..f18dd87
--- /dev/null
+++ b/dot.mayu
@@ -0,0 +1,27 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - dot.mayu
+# Copyright (C) 1999-2005, TAGA Nayuta <nayuta@users.sourceforge.net>
+#
+
+# \82Ü\82¸\83L\81[\83{\81[\83h\92è\8b`\82ð\93Ç\82Ý\8d\9e\82Þ
+if ( USE104 )
+  include "104.mayu"           # 104 \83L\81[\83{\81[\83h\90Ý\92è
+  if ( USE109on104 )
+    include "109on104.mayu"    # 104 \83L\81[\83{\81[\83h\82ð 109 \83L\81[\83{\81[\83h\95\97\82É
+  endif
+else
+  include "109.mayu"           # 109 \83L\81[\83{\81[\83h\90Ý\92è
+  if ( USE104on109 )
+    include "104on109.mayu"    # 109 \83L\81[\83{\81[\83h\82ð 104 \83L\81[\83{\81[\83h\95\97\82É
+  endif
+endif
+
+if ( USEdefault )
+  include      "default.mayu"  # Emacs \83\89\83C\83N\82È\82³\82Ü\82´\82Ü\82È\90Ý\92è
+endif
+
+keymap Global
+
+# \82±\82Ì\83t\83@\83C\83\8b\82ð\83z\81[\83\80\83f\83B\83\8c\83N\83g\83\8a\82É\83R\83s\81[\82µ\82Ä\82©\82ç\81A
+# \88È\89º\82É\8e©\95ª\82Ì\8dD\82Ý\82Ì\83L\81[\83o\83C\83\93\83f\83B\83\93\83O\82ð\90Ý\92è\82·\82é\82Æ\82æ\82¢\81B
+# \82±\82Ì\83t\83@\83C\83\8b\8e©\91Ì\82ð\95Ï\8dX\82µ\82È\82¢\82±\82Æ\81B
diff --git a/driver.h b/driver.h
new file mode 100644 (file)
index 0000000..965981e
--- /dev/null
+++ b/driver.h
@@ -0,0 +1,70 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// driver.h
+
+
+#ifndef _DRIVER_H
+#  define _DRIVER_H
+
+#  include <winioctl.h>
+
+
+#  if defined(_WINNT)
+
+/// mayu device file name
+#    define MAYU_DEVICE_FILE_NAME _T("\\\\.\\MayuDetour1")
+///
+#    define MAYU_DRIVER_NAME _T("mayud")
+
+#  elif defined(_WIN95)
+
+///
+#    define MAYU_DEVICE_FILE_NAME _T("\\\\.\\mayud.vxd")
+
+#  endif
+
+/// Ioctl value
+#include "d/ioctl.h"
+
+
+/// derived from w2kddk/inc/ntddkbd.h
+class KEYBOARD_INPUT_DATA
+{
+public:
+  ///
+  enum
+  {
+    /// key release flag
+    BREAK = 1,
+    /// extended key flag
+    E0 = 2,
+    /// extended key flag
+    E1 = 4,
+    /// extended key flag (E0 | E1)
+    E0E1 = 6,
+    ///
+    TERMSRV_SET_LED = 8,
+    /// Define the keyboard overrun MakeCode.
+    KEYBOARD_OVERRUN_MAKE_CODE_ = 0xFF,
+  };
+
+public:
+  /** Unit number.  E.g., for \Device\KeyboardPort0 the unit is '0', for
+      \Device\KeyboardPort1 the unit is '1', and so on. */
+  USHORT UnitId;
+  
+  /** The "make" scan code (key depression). */
+  USHORT MakeCode;
+  
+  /** The flags field indicates a "break" (key release) and other miscellaneous
+      scan code information defined above. */
+  USHORT Flags;
+  
+  ///
+  USHORT Reserved;
+  
+  /** Device-specific additional information for the event. */
+  ULONG ExtraInformation;
+};
+
+
+#endif // !_DRIVER_H
diff --git a/emacsedit.mayu b/emacsedit.mayu
new file mode 100644 (file)
index 0000000..9b8a3b6
--- /dev/null
@@ -0,0 +1,155 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# \91\8b\8eg\82¢\82Ì\97J\9fT - emacsedit.mayu
+# Copyright (C) 1999-2005, TAGA Nayuta <nayuta@users.sourceforge.net>
+#
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Emacs \95\97\88Ú\93®\83R\83}\83\93\83h
+#
+
+keymap EmacsMove : Global
+ key Home              = C-Home                # \95\93ª
+ key End               = C-End                 # \95\96\96
+ key C-Space           = &Undefined            # Mark
+ key C-A               = Home                  # \8ds\93ª
+ key C-B               = Left                  # \81©
+ key M-B               = C-Left                # \81©(\92P\8cê)
+ key C-E               = End                   # \8ds\96\96
+ key C-F               = Right                 # \81¨
+ key M-F               = C-Right               # \81¨(\92P\8cê)
+ key C-G               = Escape                # CANCEL
+ key C-L               = &WindowRedraw &Recenter # \8dÄ\95`\89æ
+ key C-N               = Down                  # \81«
+ key C-P               = Up                    # \81ª
+ key C-Q               = &Prefix(KeymapDefault) # mayu \82É\8d\89E\82³\82ê\82È\82¢\83L\81[\93ü\97Í
+ key C-S               = C-F                   # \8c\9f\8dõ
+ if ( !ZXCV ) key C-V  = Next                  # \8e\9f\95Å
+ key M-V               = Prior                 # \91O\95Å
+ key S-Home            = S-C-Home              # \95\93ª(\91I\91ð)
+ key S-End             = S-C-End               # \95\96\96(\91I\91ð)
+ key S-M-Comma         = C-Home                # \95\93ª
+ key S-M-Period                = C-End                 # \95\96\96
+
+ if ( EmacsMove/ShiftSelection )
+   key S-C-A           = S-Home                # \8ds\93ª(\91I\91ð)
+   key S-C-B           = S-Left                # \81©(\91I\91ð)
+   key S-C-E           = S-End                 # \8ds\96\96(\91I\91ð)
+   key S-C-F           = S-Right               # \81¨(\91I\91ð)
+   key S-C-N           = S-Down                # \81«(\91I\91ð)
+   key S-C-P           = S-Up                  # \81ª(\91I\91ð)
+   key S-C-V           = S-Next                # \8e\9f\95Å(\91I\91ð)
+   key S-M-V           = S-Prior               # \91O\95Å(\91I\91ð)
+ endif
+
+
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Emacs \95\97\95Ò\8fW\83R\83}\83\93\83h
+#
+
+ keyseq        $EmacsEdit/kill-word            = S-C-Right C-X
+ keyseq        $EmacsEdit/backward-kill-word   = S-C-Left C-X
+ keyseq        $EmacsEdit/transpose-chars      = S-Right C-X Left C-V Right
+ keyseq        $EmacsEdit/upcase-word          = S-C-Right C-C *&Sync \
+                                         &ClipboardUpcaseWord C-V
+ keyseq        $EmacsEdit/downcase-word        = S-C-Right C-C *&Sync \
+                                         &ClipboardDowncaseWord C-V
+ keyseq        $EmacsEdit/kill-line            = &EmacsEditKillLineFunc S-End C-X \
+                       &Sync &EmacsEditKillLinePred((Delete), (Return Left))
+ keyseq        $EmacsMark/cancel               = Left Right
+
+
+keymap EmacsEdit : EmacsMove
+keymap2        EmacsMark : EmacsEdit = $EmacsMark/cancel &KeymapWindow
+keymap2 EmacsMarkEscape : EmacsMark = &KeymapParent
+
+keymap2        EmacsC-X : EmacsEdit
+ event prefixed                = &HelpMessage("EmacsEdit C-x-", "C-x u\tundo")
+ event before-key-down = &HelpMessage
+ key *U                        = C-Z                                   # UNDO
+
+keymap2 EmacsC-U0_9C-U : Global \
+               = &Repeat((&KeymapWindow), 100) &HelpMessage &Variable(0, 0)
+ key C-G       = &HelpMessage &Variable(0, 0) &Ignore
+keymap2 EmacsC-U0_9 : EmacsC-U0_9C-U
+ event prefixed                = &HelpVariable("\8cJ\82è\95Ô\82µ")
+ key _0 Num0           = &Variable(10, 0) &Prefix(EmacsC-U0_9)
+ key _1 Num1           = &Variable(10, 1) &Prefix(EmacsC-U0_9)
+ key _2 Num2           = &Variable(10, 2) &Prefix(EmacsC-U0_9)
+ key _3 Num3           = &Variable(10, 3) &Prefix(EmacsC-U0_9)
+ key _4 Num4           = &Variable(10, 4) &Prefix(EmacsC-U0_9)
+ key _5 Num5           = &Variable(10, 5) &Prefix(EmacsC-U0_9)
+ key _6 Num6           = &Variable(10, 6) &Prefix(EmacsC-U0_9)
+ key _7 Num7           = &Variable(10, 7) &Prefix(EmacsC-U0_9)
+ key _8 Num8           = &Variable(10, 8) &Prefix(EmacsC-U0_9)
+ key _9 Num9           = &Variable(10, 9) &Prefix(EmacsC-U0_9)
+ key C-U               = &Prefix(EmacsC-U0_9C-U)
+
+keymap2 EmacsC-U : EmacsC-U0_9C-U
+ event prefixed                = &HelpVariable("\8cJ\82è\95Ô\82µ")
+ key _0 Num0           = &Variable(0, 0) &Prefix(EmacsC-U0_9)
+ key _1 Num1           = &Variable(0, 1) &Prefix(EmacsC-U0_9)
+ key _2 Num2           = &Variable(0, 2) &Prefix(EmacsC-U0_9)
+ key _3 Num3           = &Variable(0, 3) &Prefix(EmacsC-U0_9)
+ key _4 Num4           = &Variable(0, 4) &Prefix(EmacsC-U0_9)
+ key _5 Num5           = &Variable(0, 5) &Prefix(EmacsC-U0_9)
+ key _6 Num6           = &Variable(0, 6) &Prefix(EmacsC-U0_9)
+ key _7 Num7           = &Variable(0, 7) &Prefix(EmacsC-U0_9)
+ key _8 Num8           = &Variable(0, 8) &Prefix(EmacsC-U0_9)
+ key _9 Num9           = &Variable(0, 9) &Prefix(EmacsC-U0_9)
+ key C-U               = &Variable(4, 0) &Prefix(EmacsC-U)
+
+keymap EmacsEdit
+ key C-Space           = &Prefix(EmacsMark)                    # Mark
+ key M-BackSpace       = $EmacsEdit/backward-kill-word         # BS(\92P\8cê)
+ key C-D               = Delete                                # \8dí\8f\9c
+ key M-D               = $EmacsEdit/kill-word                  # \8dí\8f\9c(\92P\8cê)
+ key C-H               = BackSpace                             # BS
+ key C-J               = Return                                # RETURN
+ key C-K               = $EmacsEdit/kill-line                  # \8ds\96\96\82Ü\82Å\8dí\8f\9c
+ key C-M               = Return                                # RETURN
+ key C-O               = Return Left                           # \88ê\8ds\91\9d\82â\82·
+ if ( !GANA ) key C-T  = $EmacsEdit/transpose-chars            # \95\8e\9a\93ü\82ê\91Ö\82¦
+ key C-W               = C-X                                   # CUT
+ key M-W               = C-C                                   # COPY
+ key C-U               = &Variable(0, 4) &Prefix(EmacsC-U)
+ if ( !ZXCV ) key C-X  = &Prefix(EmacsC-X)
+ key C-Y               = C-V                                   # PASTE
+ key C-Slash           = C-Z                                   # UNDO
+ key M-U               = $EmacsEdit/upcase-word                # \91å\95\8e\9a
+ key M-L               = $EmacsEdit/downcase-word              # \8f¬\95\8e\9a
+
+keymap2        EmacsMark
+ key Home              = S-C-Home      &Prefix(EmacsMark)      # \95\93ª
+ key End               = S-C-End       &Prefix(EmacsMark)      # \95\96\96
+ key C-A               = S-Home        &Prefix(EmacsMark)      # \8ds\93ª
+ key C-B               = S-Left        &Prefix(EmacsMark)      # \81©
+ key M-B               = S-C-Left      &Prefix(EmacsMark)      # \81©(\92P\8cê)
+ key C-E               = S-End         &Prefix(EmacsMark)      # \8ds\96\96
+ key C-F               = S-Right       &Prefix(EmacsMark)      # \81¨
+ key M-F               = S-C-Right     &Prefix(EmacsMark)      # \81¨(\92P\8cê)
+ key C-G               = $EmacsMark/cancel &Undefined          # \83L\83\83\83\93\83Z\83\8b
+ key C-N               = S-Down        &Prefix(EmacsMark)      # \81«
+ key C-P               = S-Up          &Prefix(EmacsMark)      # \81ª
+ if ( !ZXCV ) key C-V  = S-Next        &Prefix(EmacsMark)      # \8e\9f\95Å
+ key M-V               = S-Prior       &Prefix(EmacsMark)      # \91O\95Å
+ key C-W               = C-X Left Right                        # CUT
+ key M-W               = C-C Left Right                        # COPY
+ key S-M-Comma         = S-C-Home      &Prefix(EmacsMark)      # \95\93ª
+ key S-M-Period                = S-C-End       &Prefix(EmacsMark)      # \95\96\96
+ key Left              = S-Left        &Prefix(EmacsMark)      # \81©
+ key Up                        = S-Up          &Prefix(EmacsMark)      # \81ª
+ key Right             = S-Right       &Prefix(EmacsMark)      # \81¨
+ key Down              = S-Down        &Prefix(EmacsMark)      # \81«
+ if ( MAP-ESCAPE-TO-META )
+   key Escape          = &Prefix(EmacsMarkEscape) &EditNextModifier(M-)
+   if ( KBD109 ) and ( ! KBD104on109 )
+     key \94¼\8ap/\91S\8ap     = &Prefix(EmacsMarkEscape) &EditNextModifier(M-)
+   endif
+ endif
+
+keymap2 EmacsMarkEscape
+ event prefixed                = &HelpMessage("EmacsMark ESC-", " ")
+ event before-key-down = &HelpMessage
+ key M-C-G             = &Ignore
diff --git a/engine.cpp b/engine.cpp
new file mode 100644 (file)
index 0000000..b92efc0
--- /dev/null
@@ -0,0 +1,1635 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// engine.cpp
+
+
+#include "misc.h"
+
+#include "engine.h"
+#include "errormessage.h"
+#include "hook.h"
+#include "mayurc.h"
+#include "windowstool.h"
+
+#include <iomanip>
+
+#include <process.h>
+
+
+// check focus window
+void Engine::checkFocusWindow()
+{
+  int count = 0;
+  
+  restart:
+  count ++;
+  
+  HWND hwndFore = GetForegroundWindow();
+  DWORD threadId = GetWindowThreadProcessId(hwndFore, NULL);
+
+  if (hwndFore)
+  {
+    {
+      Acquire a(&m_cs);
+      if (m_currentFocusOfThread &&
+         m_currentFocusOfThread->m_threadId == threadId &&
+         m_currentFocusOfThread->m_hwndFocus == m_hwndFocus)
+       return;
+
+      m_emacsEditKillLine.reset();
+      
+      // erase dead thread
+      if (!m_detachedThreadIds.empty())
+      {
+       for (DetachedThreadIds::iterator i = m_detachedThreadIds.begin();
+            i != m_detachedThreadIds.end(); i ++)
+       {
+         FocusOfThreads::iterator j = m_focusOfThreads.find((*i));
+         if (j != m_focusOfThreads.end())
+         {
+           FocusOfThread *fot = &((*j).second);
+           Acquire a(&m_log, 1);
+           m_log << _T("RemoveThread") << std::endl;
+           m_log << _T("\tHWND:\t") << std::hex << (int)fot->m_hwndFocus
+                 << std::dec << std::endl;
+           m_log << _T("\tTHREADID:") << fot->m_threadId << std::endl;
+           m_log << _T("\tCLASS:\t") << fot->m_className << std::endl;
+           m_log << _T("\tTITLE:\t") << fot->m_titleName << std::endl;
+           m_log << std::endl;
+           m_focusOfThreads.erase(j);
+         }
+       }
+       m_detachedThreadIds.erase
+         (m_detachedThreadIds.begin(), m_detachedThreadIds.end());
+      }
+      
+      FocusOfThreads::iterator i = m_focusOfThreads.find(threadId);
+      if (i != m_focusOfThreads.end())
+      {
+       m_currentFocusOfThread = &((*i).second);
+       if (!m_currentFocusOfThread->m_isConsole || 2 <= count)
+       {
+         if (m_currentFocusOfThread->m_keymaps.empty())
+           setCurrentKeymap(NULL);
+         else
+           setCurrentKeymap(*m_currentFocusOfThread->m_keymaps.begin());
+         m_hwndFocus = m_currentFocusOfThread->m_hwndFocus;
+         checkShow(m_hwndFocus);
+       
+         Acquire a(&m_log, 1);
+         m_log << _T("FocusChanged") << std::endl;
+         m_log << _T("\tHWND:\t")
+               << std::hex << (int)m_currentFocusOfThread->m_hwndFocus
+               << std::dec << std::endl;
+         m_log << _T("\tTHREADID:")
+               << m_currentFocusOfThread->m_threadId << std::endl;
+         m_log << _T("\tCLASS:\t")
+               << m_currentFocusOfThread->m_className << std::endl;
+         m_log << _T("\tTITLE:\t")
+               << m_currentFocusOfThread->m_titleName << std::endl;
+         m_log << std::endl;
+         return;
+       }
+      }
+    }
+    
+    _TCHAR className[GANA_MAX_ATOM_LENGTH];
+    if (GetClassName(hwndFore, className, NUMBER_OF(className)))
+    {
+      if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0)
+      {
+       _TCHAR titleName[1024];
+       if (GetWindowText(hwndFore, titleName, NUMBER_OF(titleName)) == 0)
+         titleName[0] = _T('\0');
+       setFocus(hwndFore, threadId, className, titleName, true);
+       Acquire a(&m_log, 1);
+       m_log << _T("HWND:\t") << std::hex << reinterpret_cast<int>(hwndFore)
+             << std::dec << std::endl;
+       m_log << _T("THREADID:") << threadId << std::endl;
+       m_log << _T("CLASS:\t") << className << std::endl;
+       m_log << _T("TITLE:\t") << titleName << std::endl << std::endl;
+       goto restart;
+      }
+    }
+  }
+  
+  Acquire a(&m_cs);
+  if (m_globalFocus.m_keymaps.empty())
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("NO GLOBAL FOCUS") << std::endl;
+    m_currentFocusOfThread = NULL;
+    setCurrentKeymap(NULL);
+  }
+  else
+  {
+    if (m_currentFocusOfThread != &m_globalFocus)
+    {
+      Acquire a(&m_log, 1);
+      m_log << _T("GLOBAL FOCUS") << std::endl;
+      m_currentFocusOfThread = &m_globalFocus;
+      setCurrentKeymap(m_globalFocus.m_keymaps.front());
+    }
+  }
+  m_hwndFocus = NULL;
+}
+
+
+
+// is modifier pressed ?
+bool Engine::isPressed(Modifier::Type i_mt)
+{
+  const Keymap::ModAssignments &ma = m_currentKeymap->getModAssignments(i_mt);
+  for (Keymap::ModAssignments::const_iterator i = ma.begin();
+       i != ma.end(); ++ i)
+    if ((*i).m_key->m_isPressed)
+      return true;
+  return false;
+}
+
+
+// fix modifier key (if fixed, return true)
+bool Engine::fixModifierKey(ModifiedKey *io_mkey, Keymap::AssignMode *o_am)
+{
+  // for all modifier ...
+  for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)
+  {
+    // get modifier assignments (list of modifier keys)
+    const Keymap::ModAssignments &ma =
+      m_currentKeymap->getModAssignments(static_cast<Modifier::Type>(i));
+    
+    for (Keymap::ModAssignments::const_iterator
+          j = ma.begin(); j != ma.end(); ++ j)
+      if (io_mkey->m_key == (*j).m_key) // is io_mkey a modifier ?
+      {
+       {
+         Acquire a(&m_log, 1);
+         m_log << _T("* Modifier Key") << std::endl;
+       }
+       // set dontcare for this modifier
+       io_mkey->m_modifier.dontcare(static_cast<Modifier::Type>(i));
+       *o_am = (*j).m_assignMode;
+       return true;
+      }
+  }
+  *o_am = Keymap::AM_notModifier;
+  return false;
+}
+
+
+// output to m_log
+void Engine::outputToLog(const Key *i_key, const ModifiedKey &i_mkey,
+                        int i_debugLevel)
+{
+  size_t i;
+  Acquire a(&m_log, i_debugLevel);
+
+  // output scan codes
+  for (i = 0; i < i_key->getScanCodesSize(); ++ i)
+  {
+    if (i_key->getScanCodes()[i].m_flags & ScanCode::E0) m_log << _T("E0-");
+    if (i_key->getScanCodes()[i].m_flags & ScanCode::E1) m_log << _T("E1-");
+    if (!(i_key->getScanCodes()[i].m_flags & ScanCode::E0E1))
+      m_log << _T("   ");
+    m_log << _T("0x") << std::hex << std::setw(2) << std::setfill(_T('0'))
+         << static_cast<int>(i_key->getScanCodes()[i].m_scan)
+         << std::dec << _T(" ");
+  }
+  
+  if (!i_mkey.m_key) // key corresponds to no phisical key
+  {
+    m_log << std::endl;
+    return;
+  }
+  
+  m_log << _T("  ") << i_mkey << std::endl;
+}
+
+
+// describe bindings
+void Engine::describeBindings()
+{
+  Acquire a(&m_log, 0);
+
+  Keymap::DescribeParam dp;
+  for (KeymapPtrList::iterator i = m_currentFocusOfThread->m_keymaps.begin();
+       i != m_currentFocusOfThread->m_keymaps.end(); ++ i)
+    (*i)->describe(m_log, &dp);
+  m_log << std::endl;
+}
+
+
+// update m_lastPressedKey
+void Engine::updateLastPressedKey(Key *i_key)
+{
+  m_lastPressedKey[1] = m_lastPressedKey[0];
+  m_lastPressedKey[0] = i_key;
+}
+
+// set current keymap
+void Engine::setCurrentKeymap(const Keymap *i_keymap, bool i_doesAddToHistory)
+{
+  if (i_doesAddToHistory)
+  {
+    m_keymapPrefixHistory.push_back(const_cast<Keymap *>(m_currentKeymap));
+    if (MAX_KEYMAP_PREFIX_HISTORY < m_keymapPrefixHistory.size())
+      m_keymapPrefixHistory.pop_front();
+  }
+  else
+    m_keymapPrefixHistory.clear();
+  m_currentKeymap = i_keymap;
+}
+
+
+// get current modifiers
+Modifier Engine::getCurrentModifiers(Key *i_key, bool i_isPressed)
+{
+  Modifier cmods;
+  cmods.add(m_currentLock);
+
+  cmods.press(Modifier::Type_Shift  , isPressed(Modifier::Type_Shift  ));
+  cmods.press(Modifier::Type_Alt    , isPressed(Modifier::Type_Alt    ));
+  cmods.press(Modifier::Type_Control, isPressed(Modifier::Type_Control));
+  cmods.press(Modifier::Type_Windows, isPressed(Modifier::Type_Windows));
+  cmods.press(Modifier::Type_Up     , !i_isPressed);
+  cmods.press(Modifier::Type_Down   , i_isPressed);
+
+  cmods.press(Modifier::Type_Repeat , false);
+  if (m_lastPressedKey[0] == i_key)
+  {
+    if (i_isPressed)
+      cmods.press(Modifier::Type_Repeat, true);
+    else
+      if (m_lastPressedKey[1] == i_key)
+       cmods.press(Modifier::Type_Repeat, true);
+  }
+
+  for (int i = Modifier::Type_Mod0; i <= Modifier::Type_Mod9; ++ i)
+    cmods.press(static_cast<Modifier::Type>(i),
+               isPressed(static_cast<Modifier::Type>(i)));
+  
+  return cmods;
+}
+
+
+// generate keyboard event for a key
+void Engine::generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign)
+{
+  // check if key is event
+  bool isEvent = false;
+  for (Key **e = Event::events; *e; ++ e)
+    if (*e == i_key)
+    {
+      isEvent = true;
+      break;
+    }
+
+  bool isAlreadyReleased = false;
+    
+  if (!isEvent)
+  {
+    if (i_doPress && !i_key->m_isPressedOnWin32)
+      ++ m_currentKeyPressCountOnWin32;
+    else if (!i_doPress)
+    {
+      if (i_key->m_isPressedOnWin32)
+       -- m_currentKeyPressCountOnWin32;
+      else
+       isAlreadyReleased = true;
+    }
+    i_key->m_isPressedOnWin32 = i_doPress;
+    
+    if (i_isByAssign)
+      i_key->m_isPressedByAssign = i_doPress;
+
+    Key *sync = m_setting->m_keyboard.getSyncKey();
+    
+    if (!isAlreadyReleased || i_key == sync)
+    {
+      KEYBOARD_INPUT_DATA kid = { 0, 0, 0, 0, 0 };
+      const ScanCode *sc = i_key->getScanCodes();
+      for (size_t i = 0; i < i_key->getScanCodesSize(); ++ i)
+      {
+       kid.MakeCode = sc[i].m_scan;
+       kid.Flags = sc[i].m_flags;
+       if (!i_doPress)
+         kid.Flags |= KEYBOARD_INPUT_DATA::BREAK;
+       DWORD len;
+#if defined(_WINNT)
+       WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
+       CHECK_TRUE( GetOverlappedResult(m_device, &m_ol, &len, TRUE) );
+#elif defined(_WIN95)
+       DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
+#else
+#  error
+#endif
+      }
+      
+      m_lastGeneratedKey = i_doPress ? i_key : NULL;
+    }
+  }
+  
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("\t\t    =>\t");
+    if (isAlreadyReleased)
+      m_log << _T("(already released) ");
+  }
+  ModifiedKey mkey(i_key);
+  mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);
+  mkey.m_modifier.on(Modifier::Type_Down, i_doPress);
+  outputToLog(i_key, mkey, 1);
+}
+
+
+// genete event
+void Engine::generateEvents(Current i_c, const Keymap *i_keymap, Key *i_event)
+{
+  // generate
+  i_c.m_keymap = i_keymap;
+  i_c.m_mkey.m_key = i_event;
+  if (const Keymap::KeyAssignment *keyAssign =
+      i_c.m_keymap->searchAssignment(i_c.m_mkey))
+  {
+    {
+      Acquire a(&m_log, 1);
+      m_log << std::endl << _T("           ")
+           << i_event->getName() << std::endl;
+    }
+    generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);
+  }
+}
+
+
+// genete modifier events
+void Engine::generateModifierEvents(const Modifier &i_mod)
+{
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("* Gen Modifiers\t{") << std::endl;
+  }
+
+  for (int i = Modifier::Type_begin; i < Modifier::Type_BASIC; ++ i)
+  {
+    Keyboard::Mods &mods =
+      m_setting->m_keyboard.getModifiers(static_cast<Modifier::Type>(i));
+
+    if (i_mod.isDontcare(static_cast<Modifier::Type>(i)))
+      // no need to process
+      ;
+    else if (i_mod.isPressed(static_cast<Modifier::Type>(i)))
+      // we have to press this modifier
+    {
+      bool noneIsPressed = true;
+      bool noneIsPressedByAssign = true;
+      for (Keyboard::Mods::iterator i = mods.begin(); i != mods.end(); ++ i)
+      {
+       if ((*i)->m_isPressedOnWin32)
+         noneIsPressed = false;
+       if ((*i)->m_isPressedByAssign)
+         noneIsPressedByAssign = false;
+      }
+      if (noneIsPressed)
+      {
+       if (noneIsPressedByAssign)
+         generateKeyEvent(mods.front(), true, false);
+       else
+         for (Keyboard::Mods::iterator
+                i = mods.begin(); i != mods.end(); ++ i)
+           if ((*i)->m_isPressedByAssign)
+             generateKeyEvent((*i), true, false);
+      }
+    }
+
+    else
+      // we have to release this modifier
+    {
+      // avoid such sequences as  "Alt U-ALt" or "Windows U-Windows"
+      if (i == Modifier::Type_Alt || i == Modifier::Type_Windows)
+      {
+       for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)
+         if ((*j) == m_lastGeneratedKey)
+         {
+           Keyboard::Mods *mods =
+             &m_setting->m_keyboard.getModifiers(Modifier::Type_Shift);
+           if (mods->size() == 0)
+             mods = &m_setting->m_keyboard.getModifiers(
+               Modifier::Type_Control);
+           if (0 < mods->size())
+           {
+             generateKeyEvent(mods->front(), true, false);
+             generateKeyEvent(mods->front(), false, false);
+           }
+           break;
+         }
+      }
+      
+      for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)
+      {
+       if ((*j)->m_isPressedOnWin32)
+         generateKeyEvent((*j), false, false);
+      }
+    }
+  }
+  
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("\t\t}") << std::endl;
+  }
+}
+
+
+// generate keyboard events for action
+void Engine::generateActionEvents(const Current &i_c, const Action *i_a,
+                                 bool i_doPress)
+{
+  switch (i_a->getType())
+  {
+    // key
+    case Action::Type_key:
+    {
+      const ModifiedKey &mkey
+       = reinterpret_cast<ActionKey *>(
+         const_cast<Action *>(i_a))->m_modifiedKey;
+
+      // release
+      if (!i_doPress &&
+         (mkey.m_modifier.isOn(Modifier::Type_Up) ||
+          mkey.m_modifier.isDontcare(Modifier::Type_Up)))
+       generateKeyEvent(mkey.m_key, false, true);
+
+      // press
+      else if (i_doPress &&
+              (mkey.m_modifier.isOn(Modifier::Type_Down) ||
+               mkey.m_modifier.isDontcare(Modifier::Type_Down)))
+      {
+       Modifier modifier = mkey.m_modifier;
+       modifier.add(i_c.m_mkey.m_modifier);
+       generateModifierEvents(modifier);
+       generateKeyEvent(mkey.m_key, true, true);
+      }
+      break;
+    }
+
+    // keyseq
+    case Action::Type_keySeq:
+    {
+      const ActionKeySeq *aks = reinterpret_cast<const ActionKeySeq *>(i_a);
+      generateKeySeqEvents(i_c, aks->m_keySeq,
+                          i_doPress ? Part_down : Part_up);
+      break;
+    }
+
+    // function
+    case Action::Type_function:
+    {
+      const ActionFunction *af = reinterpret_cast<const ActionFunction *>(i_a);
+      bool is_up = (!i_doPress &&
+                   (af->m_modifier.isOn(Modifier::Type_Up) ||
+                    af->m_modifier.isDontcare(Modifier::Type_Up)));
+      bool is_down = (i_doPress &&
+                     (af->m_modifier.isOn(Modifier::Type_Down) ||
+                      af->m_modifier.isDontcare(Modifier::Type_Down)));
+
+      if (!is_down && !is_up)
+       break;
+      
+      {
+       Acquire a(&m_log, 1);
+       m_log << _T("\t\t     >\t") << af->m_functionData;
+      }
+      
+      FunctionParam param;
+      param.m_isPressed = i_doPress;
+      param.m_hwnd = m_currentFocusOfThread->m_hwndFocus;
+      param.m_c = i_c;
+      param.m_doesNeedEndl = true;
+      param.m_af = af;
+      
+      param.m_c.m_mkey.m_modifier.on(Modifier::Type_Up, !i_doPress);
+      param.m_c.m_mkey.m_modifier.on(Modifier::Type_Down, i_doPress);
+
+      af->m_functionData->exec(this, &param);
+      
+      if (param.m_doesNeedEndl)
+      {
+       Acquire a(&m_log, 1);
+       m_log << std::endl;
+      }
+      break;
+    }
+  }
+}
+
+
+// generate keyboard events for keySeq
+void Engine::generateKeySeqEvents(const Current &i_c, const KeySeq *i_keySeq,
+                                 Part i_part)
+{
+  const KeySeq::Actions &actions = i_keySeq->getActions();
+  if (actions.empty())
+    return;
+  if (i_part == Part_up)
+    generateActionEvents(i_c, actions[actions.size() - 1], false);
+  else
+  {
+    size_t i;
+    for (i = 0 ; i < actions.size() - 1; ++ i)
+    {
+      generateActionEvents(i_c, actions[i], true);
+      generateActionEvents(i_c, actions[i], false);
+    }
+    generateActionEvents(i_c, actions[i], true);
+    if (i_part == Part_all)
+      generateActionEvents(i_c, actions[i], false);
+  }
+}
+
+
+// generate keyboard events for current key
+void Engine::generateKeyboardEvents(const Current &i_c)
+{
+  if (++ m_generateKeyboardEventsRecursionGuard ==
+      MAX_GENERATE_KEYBOARD_EVENTS_RECURSION_COUNT)
+  {
+    Acquire a(&m_log);
+    m_log << _T("error: too deep keymap recursion.  there may be a loop.")
+         << std::endl;
+    return;
+  }
+
+  const Keymap::KeyAssignment *keyAssign
+    = i_c.m_keymap->searchAssignment(i_c.m_mkey);
+  if (!keyAssign)
+  {
+    const KeySeq *keySeq = i_c.m_keymap->getDefaultKeySeq();
+    ASSERT( keySeq );
+    generateKeySeqEvents(i_c, keySeq, i_c.isPressed() ? Part_down : Part_up);
+  }
+  else
+  {
+    if (keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Up) ||
+       keyAssign->m_modifiedKey.m_modifier.isOn(Modifier::Type_Down))
+      generateKeySeqEvents(i_c, keyAssign->m_keySeq, Part_all);
+    else
+      generateKeySeqEvents(i_c, keyAssign->m_keySeq,
+                          i_c.isPressed() ? Part_down : Part_up);
+  }
+  m_generateKeyboardEventsRecursionGuard --;
+}
+
+
+// generate keyboard events for current key
+void Engine::beginGeneratingKeyboardEvents(
+  const Current &i_c, bool i_isModifier)
+{
+  //             (1)             (2)             (3)  (4)   (1)
+  // up/down:    D-              U-              D-   U-    D-
+  // keymap:     m_currentKeymap m_currentKeymap X    X     m_currentKeymap
+  // memo:       &Prefix(X)      ...             ...  ...   ...
+  // m_isPrefix: false           true            true false false
+
+  Current cnew(i_c);
+
+  bool isPhysicallyPressed
+    = cnew.m_mkey.m_modifier.isPressed(Modifier::Type_Down);
+  
+  // substitute
+  ModifiedKey mkey = m_setting->m_keyboard.searchSubstitute(cnew.m_mkey);
+  if (mkey.m_key)
+  {
+    cnew.m_mkey = mkey;
+    if (isPhysicallyPressed)
+    {
+      cnew.m_mkey.m_modifier.off(Modifier::Type_Up);
+      cnew.m_mkey.m_modifier.on(Modifier::Type_Down);
+    }
+    else
+    {
+      cnew.m_mkey.m_modifier.on(Modifier::Type_Up);
+      cnew.m_mkey.m_modifier.off(Modifier::Type_Down);
+    }
+    for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)
+    {
+      Modifier::Type type = static_cast<Modifier::Type>(i);
+      if (cnew.m_mkey.m_modifier.isDontcare(type) &&
+         !i_c.m_mkey.m_modifier.isDontcare(type))
+       cnew.m_mkey.m_modifier.press(
+         type, i_c.m_mkey.m_modifier.isPressed(type));
+    }
+    
+    {
+      Acquire a(&m_log, 1);
+      m_log << _T("* substitute") << std::endl;
+    }
+    outputToLog(mkey.m_key, cnew.m_mkey, 1);
+  }
+  
+  // for prefix key
+  const Keymap *tmpKeymap = m_currentKeymap;
+  if (i_isModifier || !m_isPrefix) ; 
+  else if (isPhysicallyPressed)                        // when (3)
+    m_isPrefix = false;
+  else if (!isPhysicallyPressed)               // when (2)
+    m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();
+  
+  // for m_emacsEditKillLine function
+  m_emacsEditKillLine.m_doForceReset = !i_isModifier;
+
+  // generate key event !
+  m_generateKeyboardEventsRecursionGuard = 0;
+  if (isPhysicallyPressed)
+    generateEvents(cnew, cnew.m_keymap, &Event::before_key_down);
+  generateKeyboardEvents(cnew);
+  if (!isPhysicallyPressed)
+    generateEvents(cnew, cnew.m_keymap, &Event::after_key_up);
+      
+  // for m_emacsEditKillLine function
+  if (m_emacsEditKillLine.m_doForceReset)
+    m_emacsEditKillLine.reset();
+
+  // for prefix key
+  if (i_isModifier)
+    ;
+  else if (!m_isPrefix)                                // when (1), (4)
+    m_currentKeymap = m_currentFocusOfThread->m_keymaps.front();
+  else if (!isPhysicallyPressed)               // when (2)
+    m_currentKeymap = tmpKeymap;
+}
+
+
+// pop all pressed key on win32
+void Engine::keyboardResetOnWin32()
+{
+  for (Keyboard::KeyIterator
+        i = m_setting->m_keyboard.getKeyIterator();  *i; ++ i)
+  {
+    if ((*i)->m_isPressedOnWin32)
+      generateKeyEvent((*i), false, true);
+  }
+}
+
+
+// keyboard handler thread
+unsigned int WINAPI Engine::keyboardHandler(void *i_this)
+{
+  reinterpret_cast<Engine *>(i_this)->keyboardHandler();
+  _endthreadex(0);
+  return 0;
+}
+void Engine::keyboardHandler()
+{
+  // initialize ok
+  CHECK_TRUE( SetEvent(m_threadEvent) );
+    
+  // loop
+  Key key;
+  while (!m_doForceTerminate)
+  {
+    KEYBOARD_INPUT_DATA kid;
+    
+    DWORD len;
+#if defined(_WINNT)
+    {
+      Acquire a(&m_log, 1);
+      m_log << _T("begin ReadFile();") << std::endl;
+    }
+    if (!ReadFile(m_device, &kid, sizeof(kid), &len, &m_ol))
+    {
+      if (GetLastError() != ERROR_IO_PENDING)
+       continue;
+      
+      HANDLE handles[] = { m_readEvent, m_interruptThreadEvent };
+    rewait:
+      switch (MsgWaitForMultipleObjects(NUMBER_OF(handles), &handles[0],
+                                    FALSE, INFINITE, QS_POSTMESSAGE))
+      {
+       case WAIT_OBJECT_0:                     // m_readEvent
+         if (!GetOverlappedResult(m_device, &m_ol, &len, FALSE))
+           continue;
+         break;
+         
+       case WAIT_OBJECT_0 + 1:                 // m_interruptThreadEvent
+         CancelIo(m_device);
+         switch (m_interruptThreadReason) {
+           default: {
+             ASSERT( false );
+             Acquire a(&m_log, 0);
+             m_log << _T("internal error: m_interruptThreadReason == ")
+                   << m_interruptThreadReason << std::endl;
+             break;
+           }
+             
+           case InterruptThreadReason_Terminate:
+             goto break_while;
+             
+           case InterruptThreadReason_Pause: {
+             CHECK_TRUE( SetEvent(m_threadEvent) );
+             while (WaitForMultipleObjects(1, &m_interruptThreadEvent,
+                                           FALSE, INFINITE) != WAIT_OBJECT_0)
+               ;
+             switch (m_interruptThreadReason) {
+               case InterruptThreadReason_Terminate:
+                 goto break_while;
+
+               case InterruptThreadReason_Resume:
+                 break;
+
+               default:
+                 ASSERT( false );
+                 break;
+             }
+             CHECK_TRUE( SetEvent(m_threadEvent) );
+             break;
+           }
+         }
+         break;
+         
+        case WAIT_OBJECT_0 + NUMBER_OF(handles):
+       {
+         MSG message;
+
+         while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
+         {
+           switch (message.message)
+           {
+             case WM_APP + 201:
+             {
+               if (message.wParam)
+               {
+                 m_currentLock.on(Modifier::Type_Touchpad);
+                 m_currentLock.on(Modifier::Type_TouchpadSticky);
+               }
+               else
+                 m_currentLock.off(Modifier::Type_Touchpad);
+               Acquire a(&m_log, 1);
+               m_log << _T("touchpad: ") << message.wParam
+                     << _T(".") << (message.lParam & 0xffff)
+                     << _T(".") << (message.lParam >> 16 & 0xffff)
+                     << std::endl;
+               break;
+             }
+             default:
+               break;
+           }
+         }
+         goto rewait;
+       }
+
+       default:
+         ASSERT( false );
+         continue;
+      }
+    }
+    {
+      Acquire a(&m_log, 1);
+      m_log << _T("end ReadFile();") << std::endl;
+    }
+#elif defined(_WIN95)
+    if (!DeviceIoControl(m_device, 1, NULL, 0, &kid, sizeof(kid), &len, NULL))
+    {
+      continue; // TODO
+    }
+#else
+#  error
+#endif
+
+    checkFocusWindow();
+
+    if (!m_setting ||  // m_setting has not been loaded
+       !m_isEnabled)   // disabled
+    {
+      if (m_isLogMode)
+      {
+       Key key;
+       key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));
+       outputToLog(&key, ModifiedKey(), 0);
+      }
+      else
+      {
+#if defined(_WINNT)
+       WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
+       GetOverlappedResult(m_device, &m_ol, &len, TRUE);
+#elif defined(_WIN95)
+       DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
+#else
+#  error
+#endif
+      }
+      updateLastPressedKey(NULL);
+      continue;
+    }
+    
+    Acquire a(&m_cs);
+
+    if (!m_currentFocusOfThread ||
+       !m_currentKeymap)
+    {
+#if defined(_WINNT)
+      WriteFile(m_device, &kid, sizeof(kid), &len, &m_ol);
+      GetOverlappedResult(m_device, &m_ol, &len, TRUE);
+#elif defined(_WIN95)
+      DeviceIoControl(m_device, 2, &kid, sizeof(kid), NULL, 0, &len, NULL);
+#else
+#  error
+#endif
+      Acquire a(&m_log, 0);
+      if (!m_currentFocusOfThread)
+       m_log << _T("internal error: m_currentFocusOfThread == NULL")
+             << std::endl;
+      if (!m_currentKeymap)
+       m_log << _T("internal error: m_currentKeymap == NULL")
+             << std::endl;
+      updateLastPressedKey(NULL);
+      continue;
+    }
+    
+    Current c;
+    c.m_keymap = m_currentKeymap;
+    c.m_i = m_currentFocusOfThread->m_keymaps.begin();
+    
+    // search key
+    key.addScanCode(ScanCode(kid.MakeCode, kid.Flags));
+    c.m_mkey = m_setting->m_keyboard.searchKey(key);
+    if (!c.m_mkey.m_key)
+    {
+      c.m_mkey.m_key = m_setting->m_keyboard.searchPrefixKey(key);
+      if (c.m_mkey.m_key)
+       continue;
+    }
+
+    // press the key and update counter
+    bool isPhysicallyPressed
+      = !(key.getScanCodes()[0].m_flags & ScanCode::BREAK);
+    if (c.m_mkey.m_key)
+    {
+      if (!c.m_mkey.m_key->m_isPressed && isPhysicallyPressed)
+       ++ m_currentKeyPressCount;
+      else if (c.m_mkey.m_key->m_isPressed && !isPhysicallyPressed)
+       -- m_currentKeyPressCount;
+      c.m_mkey.m_key->m_isPressed = isPhysicallyPressed;
+    }
+    
+    // create modifiers
+    c.m_mkey.m_modifier = getCurrentModifiers(c.m_mkey.m_key,
+                                             isPhysicallyPressed);
+    Keymap::AssignMode am;
+    bool isModifier = fixModifierKey(&c.m_mkey, &am);
+    if (m_isPrefix)
+    {
+      if (isModifier && m_doesIgnoreModifierForPrefix)
+       am = Keymap::AM_true;
+      if (m_doesEditNextModifier)
+      {
+       Modifier modifier = m_modifierForNextKey;
+       modifier.add(c.m_mkey.m_modifier);
+       c.m_mkey.m_modifier = modifier;
+      }
+    }
+    
+    if (m_isLogMode)
+      outputToLog(&key, c.m_mkey, 0);
+    else if (am == Keymap::AM_true)
+    {
+      {
+       Acquire a(&m_log, 1);
+       m_log << _T("* true modifier") << std::endl;
+      }
+      // true modifier doesn't generate scan code
+      outputToLog(&key, c.m_mkey, 1);
+    }
+    else if (am == Keymap::AM_oneShot || am == Keymap::AM_oneShotRepeatable)
+    {
+      {
+       Acquire a(&m_log, 1);
+       if (am == Keymap::AM_oneShot)
+         m_log << _T("* one shot modifier") << std::endl;
+       else
+         m_log << _T("* one shot repeatable modifier") << std::endl;
+      }
+      // oneShot modifier doesn't generate scan code
+      outputToLog(&key, c.m_mkey, 1);
+      if (isPhysicallyPressed)
+      {
+       if (am == Keymap::AM_oneShotRepeatable  // the key is repeating
+           && m_oneShotKey.m_key == c.m_mkey.m_key)
+       {
+         if (m_oneShotRepeatableRepeatCount <
+             m_setting->m_oneShotRepeatableDelay) {
+           ; // delay
+         } else {
+           Current cnew = c;
+           beginGeneratingKeyboardEvents(cnew, false);
+         }
+         ++ m_oneShotRepeatableRepeatCount;
+       } else {
+         m_oneShotKey = c.m_mkey;
+         m_oneShotRepeatableRepeatCount = 0;
+       }
+      }
+      else
+      {
+       if (m_oneShotKey.m_key)
+       {
+         Current cnew = c;
+         cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;
+         cnew.m_mkey.m_modifier.off(Modifier::Type_Up);
+         cnew.m_mkey.m_modifier.on(Modifier::Type_Down);
+         beginGeneratingKeyboardEvents(cnew, false);
+         
+         cnew = c;
+         cnew.m_mkey.m_modifier = m_oneShotKey.m_modifier;
+         cnew.m_mkey.m_modifier.on(Modifier::Type_Up);
+         cnew.m_mkey.m_modifier.off(Modifier::Type_Down);
+         beginGeneratingKeyboardEvents(cnew, false);
+       }
+       m_oneShotKey.m_key = NULL;
+       m_oneShotRepeatableRepeatCount = 0;
+      }
+    }
+    else if (c.m_mkey.m_key)
+      // normal key
+    {
+      outputToLog(&key, c.m_mkey, 1);
+      if (isPhysicallyPressed)
+       m_oneShotKey.m_key = NULL;
+      beginGeneratingKeyboardEvents(c, isModifier);
+    }
+    
+    // if counter is zero, reset modifiers and keys on win32
+    if (m_currentKeyPressCount <= 0)
+    {
+      {
+       Acquire a(&m_log, 1);
+       m_log << _T("* No key is pressed") << std::endl;
+      }
+      generateModifierEvents(Modifier());
+      if (0 < m_currentKeyPressCountOnWin32)
+       keyboardResetOnWin32();
+      m_currentKeyPressCount = 0;
+      m_currentKeyPressCountOnWin32 = 0;
+      m_oneShotKey.m_key = NULL;
+      if (m_currentLock.isOn(Modifier::Type_Touchpad) == false)
+       m_currentLock.off(Modifier::Type_TouchpadSticky);
+    }
+    
+    key.initialize();
+    updateLastPressedKey(isPhysicallyPressed ? c.m_mkey.m_key : NULL);
+  }
+#if defined(_WINNT)
+  break_while:
+#endif
+  CHECK_TRUE( SetEvent(m_threadEvent) );
+}
+  
+
+Engine::Engine(tomsgstream &i_log)
+  : m_hwndAssocWindow(NULL),
+    m_setting(NULL),
+    m_device(INVALID_HANDLE_VALUE),
+    m_didMayuStartDevice(false),
+    m_threadEvent(NULL),
+    m_mayudVersion(_T("unknown")),
+#if defined(_WINNT)
+    m_readEvent(NULL),
+    m_interruptThreadEvent(NULL),
+    m_sts4mayu(NULL),
+    m_cts4mayu(NULL),
+#endif // _WINNT
+    m_doForceTerminate(false),
+    m_isLogMode(false),
+    m_isEnabled(true),
+    m_isSynchronizing(false),
+    m_eSync(NULL),
+    m_generateKeyboardEventsRecursionGuard(0),
+    m_currentKeyPressCount(0),
+    m_currentKeyPressCountOnWin32(0),
+    m_lastGeneratedKey(NULL),
+    m_oneShotRepeatableRepeatCount(0),
+    m_isPrefix(false),
+    m_currentKeymap(NULL),
+    m_currentFocusOfThread(NULL),
+    m_hwndFocus(NULL),
+    m_afShellExecute(NULL),
+    m_variable(0),
+    m_log(i_log)
+{
+  for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)
+    m_lastPressedKey[i] = NULL;
+    
+  // set default lock state
+  for (int i = 0; i < Modifier::Type_end; ++ i)
+    m_currentLock.dontcare(static_cast<Modifier::Type>(i));
+  for (int i = Modifier::Type_Lock0; i <= Modifier::Type_Lock9; ++ i)
+    m_currentLock.release(static_cast<Modifier::Type>(i));
+
+  if (!open()) {
+      throw ErrorMessage() << loadString(IDS_driverNotInstalled);
+  }
+  
+  {
+    TCHAR versionBuf[256];
+    DWORD length = 0;
+
+    if (DeviceIoControl(m_device, IOCTL_MAYU_GET_VERSION, NULL, 0,
+                       versionBuf, sizeof(versionBuf), &length, NULL)
+       && length
+       && length < sizeof(versionBuf))                 // fail safe
+       m_mayudVersion = tstring(versionBuf, length / 2);
+  }
+  // create event for sync
+  CHECK_TRUE( m_eSync = CreateEvent(NULL, FALSE, FALSE, NULL) );
+#if defined(_WINNT)
+  // create named pipe for &SetImeString
+  m_hookPipe = CreateNamedPipe(addSessionId(HOOK_PIPE_NAME).c_str(),
+                              PIPE_ACCESS_OUTBOUND,
+                              PIPE_TYPE_BYTE, 1,
+                              0, 0, 0, NULL);
+#endif // _WINNT
+  StrExprArg::setEngine(this);
+}
+
+
+// open mayu device
+bool Engine::open()
+{
+  // open mayu m_device
+#if defined(_WINNT)
+  m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,
+                       0, NULL, OPEN_EXISTING,
+                       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
+#elif defined(_WIN95)
+  m_device = CreateFile(MAYU_DEVICE_FILE_NAME, 0,
+                       0, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+#else
+#  error
+#endif
+
+  if (m_device != INVALID_HANDLE_VALUE) {
+    return true;
+  }
+
+#if defined(_WINNT)
+  // start mayud
+  SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+  if (hscm)
+  {
+    SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_START);
+    if (hs)
+    {
+      StartService(hs, 0, NULL);
+      CloseServiceHandle(hs);
+      m_didMayuStartDevice = true;
+    }
+    CloseServiceHandle(hscm);
+  }
+  
+  // open mayu m_device
+  m_device = CreateFile(MAYU_DEVICE_FILE_NAME, GENERIC_READ | GENERIC_WRITE,
+                       0, NULL, OPEN_EXISTING,
+                       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
+#endif // _WINNT
+  return (m_device != INVALID_HANDLE_VALUE);
+}
+
+
+// close mayu device
+void Engine::close()
+{
+  if (m_device != INVALID_HANDLE_VALUE) {
+    CHECK_TRUE( CloseHandle(m_device) );
+  }
+  m_device = INVALID_HANDLE_VALUE;
+}
+
+
+// start keyboard handler thread
+void Engine::start()
+{
+  CHECK_TRUE( m_threadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );
+  
+#if defined(_WINNT)
+  CHECK_TRUE( m_readEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );
+  CHECK_TRUE( m_interruptThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL) );
+  m_ol.Offset = 0;
+  m_ol.OffsetHigh = 0;
+  m_ol.hEvent = m_readEvent;
+#endif // _WINNT
+  
+  CHECK_TRUE( m_threadHandle = (HANDLE)_beginthreadex(NULL, 0, keyboardHandler, this, 0, &m_threadId) );
+  CHECK( WAIT_OBJECT_0 ==, WaitForSingleObject(m_threadEvent, INFINITE) );
+}
+
+
+// stop keyboard handler thread
+void Engine::stop()
+{
+  if (m_threadEvent)
+  {
+    m_doForceTerminate = true;
+    do
+    {
+#if defined(_WINNT)
+      m_interruptThreadReason = InterruptThreadReason_Terminate;
+      SetEvent(m_interruptThreadEvent);
+#elif defined(_WIN95)
+      DeviceIoControl(m_device, 3, NULL, 0, NULL, 0, NULL, NULL);
+#endif
+      //DWORD buf;
+      //M_DeviceIoControl(m_device, IOCTL_MAYU_DETOUR_CANCEL,
+      //                &buf, sizeof(buf), &buf, sizeof(buf), &buf, NULL);
+      
+      // wait for message handler thread terminate
+    } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);
+    CHECK_TRUE( CloseHandle(m_threadEvent) );
+    m_threadEvent = NULL;
+    WaitForSingleObject(m_threadHandle, 100);
+    CHECK_TRUE( CloseHandle(m_threadHandle) );
+    m_threadHandle = NULL;
+
+#if defined(_WINNT)
+    // stop mayud
+    if (m_didMayuStartDevice)
+    {
+      SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+      if (hscm)
+      {
+       SC_HANDLE hs = OpenService(hscm, MAYU_DRIVER_NAME, SERVICE_STOP);
+       if (hs)
+       {
+         SERVICE_STATUS ss;
+         ControlService(hs, SERVICE_CONTROL_STOP, &ss);
+         CloseServiceHandle(hs);
+       }
+       CloseServiceHandle(hscm);
+      }
+    }
+    
+    CHECK_TRUE( CloseHandle(m_readEvent) );
+    m_readEvent = NULL;
+    CHECK_TRUE( CloseHandle(m_interruptThreadEvent) );
+    m_interruptThreadEvent = NULL;
+#endif // _WINNT
+  }
+}
+
+bool Engine::pause()
+{
+#if defined(_WINNT)
+  if (m_device != INVALID_HANDLE_VALUE) {
+    do {
+      m_interruptThreadReason = InterruptThreadReason_Pause;
+      SetEvent(m_interruptThreadEvent);
+    } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);
+    close();
+  }
+#endif // _WINNT
+  return true;
+}
+
+
+bool Engine::resume()
+{
+#if defined(_WINNT)
+  if (m_device == INVALID_HANDLE_VALUE) {
+    if (!open()) {
+      return false;                            // FIXME
+    }
+    do {
+      m_interruptThreadReason = InterruptThreadReason_Resume;
+      SetEvent(m_interruptThreadEvent);
+    } while (WaitForSingleObject(m_threadEvent, 100) != WAIT_OBJECT_0);
+  }
+#endif // _WINNT
+  return true;
+}
+
+
+bool Engine::prepairQuit()
+{
+  // terminate and unload DLL for ThumbSense support if loaded
+  manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),
+               false, &m_sts4mayu);
+  manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),
+               false, &m_cts4mayu);
+  return true;
+}
+
+
+Engine::~Engine()
+{
+  stop();
+  CHECK_TRUE( CloseHandle(m_eSync) );
+  
+  // close m_device
+  close();
+#if defined(_WINNT)
+  // destroy named pipe for &SetImeString
+  DisconnectNamedPipe(m_hookPipe);
+  CHECK_TRUE( CloseHandle(m_hookPipe) );
+#endif // _WINNT
+}
+
+
+void Engine::manageTs4mayu(TCHAR *i_ts4mayuDllName,
+                          TCHAR *i_dependDllName,
+                          bool i_load, HMODULE *i_pTs4mayu)
+{
+  Acquire a(&m_log, 0);
+
+  if (i_load == false)
+  {
+    if (*i_pTs4mayu)
+    {
+      bool (WINAPI *pTs4mayuTerm)();
+
+      pTs4mayuTerm = (bool (WINAPI*)())GetProcAddress(*i_pTs4mayu, "ts4mayuTerm");
+      if (pTs4mayuTerm() == true)
+       FreeLibrary(*i_pTs4mayu);
+      *i_pTs4mayu = NULL;
+      m_log << i_ts4mayuDllName <<_T(" unloaded") << std::endl;
+    }
+  }
+  else
+  {
+    if (*i_pTs4mayu)
+    {
+      m_log << i_ts4mayuDllName << _T(" already loaded") << std::endl;
+    }
+    else
+    {
+      if (SearchPath(NULL, i_dependDllName, NULL, 0, NULL, NULL) == 0)
+      {
+       m_log << _T("load ") << i_ts4mayuDllName
+             << _T(" failed: can't find ") << i_dependDllName
+             << std::endl;
+      }
+      else
+      {
+       *i_pTs4mayu = LoadLibrary(i_ts4mayuDllName);
+       if (*i_pTs4mayu == NULL)
+       {
+         m_log << _T("load ") << i_ts4mayuDllName
+               << _T(" failed: can't find it") << std::endl;
+       }
+       else
+       {
+         bool (WINAPI *pTs4mayuInit)(UINT);    
+
+         pTs4mayuInit = (bool (WINAPI*)(UINT))GetProcAddress(*i_pTs4mayu, "ts4mayuInit");
+         if (pTs4mayuInit(m_threadId) == true)
+           m_log << i_ts4mayuDllName <<_T(" loaded") << std::endl;
+         else
+           m_log << i_ts4mayuDllName
+                 <<_T(" load failed: can't initialize") << std::endl;
+       }
+      }
+    }
+  }
+}
+
+
+// set m_setting
+bool Engine::setSetting(Setting *i_setting)
+{
+  Acquire a(&m_cs);
+  if (m_isSynchronizing)
+    return false;
+
+  if (m_setting)
+  {
+    for (Keyboard::KeyIterator i = m_setting->m_keyboard.getKeyIterator();
+        *i; ++ i)
+    {
+      Key *key = i_setting->m_keyboard.searchKey(*(*i));
+      if (key)
+      {
+       key->m_isPressed = (*i)->m_isPressed;
+       key->m_isPressedOnWin32 = (*i)->m_isPressedOnWin32;
+       key->m_isPressedByAssign = (*i)->m_isPressedByAssign;
+      }
+    }
+    if (m_lastGeneratedKey)
+      m_lastGeneratedKey =
+       i_setting->m_keyboard.searchKey(*m_lastGeneratedKey);
+    for (size_t i = 0; i < NUMBER_OF(m_lastPressedKey); ++ i)
+      if (m_lastPressedKey[i])
+       m_lastPressedKey[i] =
+         i_setting->m_keyboard.searchKey(*m_lastPressedKey[i]);
+  }
+  
+  m_setting = i_setting;
+
+  manageTs4mayu(_T("sts4mayu.dll"), _T("SynCOM.dll"),
+               m_setting->m_sts4mayu, &m_sts4mayu);
+  manageTs4mayu(_T("cts4mayu.dll"), _T("TouchPad.dll"),
+               m_setting->m_cts4mayu, &m_cts4mayu);
+
+  g_hookData->m_correctKanaLockHandling = m_setting->m_correctKanaLockHandling;
+  if (m_currentFocusOfThread)
+  {
+    for (FocusOfThreads::iterator i = m_focusOfThreads.begin();
+        i != m_focusOfThreads.end(); i ++)
+    {
+      FocusOfThread *fot = &(*i).second;
+      m_setting->m_keymaps.searchWindow(&fot->m_keymaps,
+                                       fot->m_className, fot->m_titleName);
+    }
+  }
+  m_setting->m_keymaps.searchWindow(&m_globalFocus.m_keymaps, _T(""), _T(""));
+  if (m_globalFocus.m_keymaps.empty())
+  {
+    Acquire a(&m_log, 0);
+    m_log << _T("internal error: m_globalFocus.m_keymap is empty")
+         << std::endl;
+  }
+  m_currentFocusOfThread = &m_globalFocus;
+  setCurrentKeymap(m_globalFocus.m_keymaps.front());
+  m_hwndFocus = NULL;
+  return true;
+}
+
+
+void Engine::checkShow(HWND i_hwnd)
+{
+  // update show style of window
+  // this update should be done in hook DLL, but to
+  // avoid update-loss for some applications(such as
+  // cmd.exe), we update here.
+  bool isMaximized = false;
+  bool isMinimized = false;
+  bool isMDIMaximized = false;
+  bool isMDIMinimized = false;
+  while (i_hwnd)
+  {
+    LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
+    if (exStyle & WS_EX_MDICHILD)
+    {
+      WINDOWPLACEMENT placement;
+      placement.length = sizeof(WINDOWPLACEMENT);
+      if (GetWindowPlacement(i_hwnd, &placement))
+      {
+        switch (placement.showCmd)
+        {
+          case SW_SHOWMAXIMIZED:
+            isMDIMaximized = true;
+            break;
+          case SW_SHOWMINIMIZED:
+            isMDIMinimized = true;
+            break;
+          case SW_SHOWNORMAL:
+          default:
+            break;
+        }
+      }
+    }
+
+    LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+    if ((style & WS_CHILD) == 0)
+    {
+      WINDOWPLACEMENT placement;
+      placement.length = sizeof(WINDOWPLACEMENT);
+      if (GetWindowPlacement(i_hwnd, &placement))
+      {
+        switch (placement.showCmd)
+        {
+          case SW_SHOWMAXIMIZED:
+            isMaximized = true;
+            break;
+          case SW_SHOWMINIMIZED:
+            isMinimized = true;
+            break;
+          case SW_SHOWNORMAL:
+          default:
+            break;
+        }
+      }
+    }  
+    i_hwnd = GetParent(i_hwnd);
+  }
+  setShow(isMDIMaximized, isMDIMinimized, true);
+  setShow(isMaximized, isMinimized, false);
+}
+
+
+// focus
+bool Engine::setFocus(HWND i_hwndFocus, DWORD i_threadId, 
+                     const tstringi &i_className, const tstringi &i_titleName,
+                     bool i_isConsole)
+{
+  Acquire a(&m_cs);
+  if (m_isSynchronizing)
+    return false;
+  if (i_hwndFocus == NULL)
+    return true;
+
+  // remove newly created thread's id from m_detachedThreadIds
+  if (!m_detachedThreadIds.empty())
+  {
+    DetachedThreadIds::iterator i;
+    do
+    {
+      for (i = m_detachedThreadIds.begin();
+          i != m_detachedThreadIds.end(); ++ i)
+       if (*i == i_threadId)
+       {
+         m_detachedThreadIds.erase(i);
+         break;
+       }
+    } while (i != m_detachedThreadIds.end());
+  }
+  
+  FocusOfThread *fot;
+  FocusOfThreads::iterator i = m_focusOfThreads.find(i_threadId);
+  if (i != m_focusOfThreads.end())
+  {
+    fot = &(*i).second;
+    if (fot->m_hwndFocus == i_hwndFocus &&
+       fot->m_isConsole == i_isConsole &&
+       fot->m_className == i_className &&
+       fot->m_titleName == i_titleName)
+      return true;
+  }
+  else
+  {
+    i = m_focusOfThreads.insert(
+      FocusOfThreads::value_type(i_threadId, FocusOfThread())).first;
+    fot = &(*i).second;
+    fot->m_threadId = i_threadId;
+  }
+  fot->m_hwndFocus = i_hwndFocus;
+  fot->m_isConsole = i_isConsole;
+  fot->m_className = i_className;
+  fot->m_titleName = i_titleName;
+  
+  if (m_setting)
+  {
+    m_setting->m_keymaps.searchWindow(&fot->m_keymaps,
+                                     i_className, i_titleName);
+    ASSERT(0 < fot->m_keymaps.size());
+  }
+  else
+    fot->m_keymaps.clear();
+  checkShow(i_hwndFocus);
+  return true;
+}
+
+
+// lock state
+bool Engine::setLockState(bool i_isNumLockToggled,
+                         bool i_isCapsLockToggled,
+                         bool i_isScrollLockToggled,
+                         bool i_isKanaLockToggled,
+                         bool i_isImeLockToggled,
+                         bool i_isImeCompToggled)
+{
+  Acquire a(&m_cs);
+  if (m_isSynchronizing)
+    return false;
+  m_currentLock.on(Modifier::Type_NumLock, i_isNumLockToggled);
+  m_currentLock.on(Modifier::Type_CapsLock, i_isCapsLockToggled);
+  m_currentLock.on(Modifier::Type_ScrollLock, i_isScrollLockToggled);
+  m_currentLock.on(Modifier::Type_KanaLock, i_isKanaLockToggled);
+  m_currentLock.on(Modifier::Type_ImeLock, i_isImeLockToggled);
+  m_currentLock.on(Modifier::Type_ImeComp, i_isImeCompToggled);
+  return true;
+}
+
+
+// show
+bool Engine::setShow(bool i_isMaximized, bool i_isMinimized,
+                    bool i_isMDI)
+{
+  Acquire a(&m_cs);
+  if (m_isSynchronizing)
+    return false;
+  Acquire b(&m_log, 1);
+  Modifier::Type max, min;
+  if (i_isMDI == true) {
+    max = Modifier::Type_MdiMaximized;
+    min = Modifier::Type_MdiMinimized;
+  }
+  else
+  {
+    max = Modifier::Type_Maximized;
+    min = Modifier::Type_Minimized;
+  }
+  m_currentLock.on(max, i_isMaximized);
+  m_currentLock.on(min, i_isMinimized);
+  m_log << _T("Set show to ") << (i_isMaximized ? _T("Maximized") :
+                                 i_isMinimized ? _T("Minimized") : _T("Normal"));
+  if (i_isMDI == true)
+  {
+    m_log << _T(" (MDI)");
+  }
+  m_log << std::endl;
+  return true;
+}
+
+
+// sync
+bool Engine::syncNotify()
+{
+  Acquire a(&m_cs);
+  if (!m_isSynchronizing)
+    return false;
+  CHECK_TRUE( SetEvent(m_eSync) );
+  return true;
+}
+
+
+// thread detach notify
+bool Engine::threadDetachNotify(DWORD i_threadId)
+{
+  Acquire a(&m_cs);
+  m_detachedThreadIds.push_back(i_threadId);
+  return true;
+}
+
+
+// get help message
+void Engine::getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle)
+{
+  Acquire a(&m_cs);
+  *o_helpMessage = m_helpMessage;
+  *o_helpTitle = m_helpTitle;
+}
+
+
+// command notify
+void Engine::commandNotify(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
+{
+  Acquire b(&m_log, 0);
+  HWND hf = m_hwndFocus;
+  if (!hf)
+    return;
+
+  if (GetWindowThreadProcessId(hf, NULL) == 
+      GetWindowThreadProcessId(m_hwndAssocWindow, NULL))
+    return;    // inhibit the investigation of MADO TSUKAI NO YUUTSU
+
+  const _TCHAR *target = NULL;
+  int number_target = 0;
+  
+  if (i_hwnd == hf)
+    target = _T("ToItself");
+  else if (i_hwnd == GetParent(hf))
+    target = _T("ToParentWindow");
+  else
+  {
+    // Function::toMainWindow
+    HWND h = hf;
+    while (true)
+    {
+      HWND p = GetParent(h);
+      if (!p)
+       break;
+      h = p;
+    }
+    if (i_hwnd == h)
+      target = _T("ToMainWindow");
+    else
+    {
+      // Function::toOverlappedWindow
+      HWND h = hf;
+      while (h)
+      {
+       LONG style = GetWindowLong(h, GWL_STYLE);
+       if ((style & WS_CHILD) == 0)
+         break;
+       h = GetParent(h);
+      }
+      if (i_hwnd == h)
+       target = _T("ToOverlappedWindow");
+      else
+      {
+       // number
+       HWND h = hf;
+       for (number_target = 0; h; number_target ++, h = GetParent(h))
+         if (i_hwnd == h)
+           break;
+       return;
+      }
+    }
+  }
+
+  m_log << _T("&PostMessage(");
+  if (target)
+    m_log << target;
+  else
+    m_log << number_target;
+  m_log << _T(", ") << i_message
+       << _T(", 0x") << std::hex << i_wParam
+       << _T(", 0x") << i_lParam << _T(") # hwnd = ")
+       << reinterpret_cast<int>(i_hwnd) << _T(", ")
+       << _T("message = ") << std::dec;
+  if (i_message == WM_COMMAND)
+    m_log << _T("WM_COMMAND, ");
+  else if (i_message == WM_SYSCOMMAND)
+    m_log << _T("WM_SYSCOMMAND, ");
+  else
+    m_log << i_message << _T(", ");
+  m_log << _T("wNotifyCode = ") << HIWORD(i_wParam) << _T(", ")
+       << _T("wID = ") << LOWORD(i_wParam) << _T(", ")
+       << _T("hwndCtrl = 0x") << std::hex << i_lParam << std::dec << std::endl;
+}
diff --git a/engine.h b/engine.h
new file mode 100644 (file)
index 0000000..0bcddca
--- /dev/null
+++ b/engine.h
@@ -0,0 +1,584 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// engine.h
+
+
+#ifndef _ENGINE_H
+#  define _ENGINE_H
+
+#  include "multithread.h"
+#  include "setting.h"
+#  include "msgstream.h"
+#  include <set>
+
+
+enum
+{
+  ///
+  WM_APP_engineNotify = WM_APP + 110,
+};
+
+
+///
+enum EngineNotify
+{
+  EngineNotify_shellExecute,                   ///
+  EngineNotify_loadSetting,                    ///
+  EngineNotify_showDlg,                                ///
+  EngineNotify_helpMessage,                    ///
+  EngineNotify_setForegroundWindow,            ///
+  EngineNotify_clearLog,                       ///
+};
+
+
+///
+class Engine
+{
+private:
+  enum
+  {
+    MAX_GENERATE_KEYBOARD_EVENTS_RECURSION_COUNT = 64, ///
+    MAX_KEYMAP_PREFIX_HISTORY = 64, ///
+  };
+
+  typedef Keymaps::KeymapPtrList KeymapPtrList;        /// 
+  
+  /// focus of a thread
+  class FocusOfThread
+  {
+  public:
+    DWORD m_threadId;                          /// thread id
+    HWND m_hwndFocus;                          /** window that has focus on
+                                                    the thread */
+    tstringi m_className;                      /// class name of hwndFocus
+    tstringi m_titleName;                      /// title name of hwndFocus
+    bool m_isConsole;                          /// is hwndFocus console ?
+    KeymapPtrList m_keymaps;                   /// keymaps
+
+  public:
+    ///
+    FocusOfThread() : m_threadId(0), m_hwndFocus(NULL), m_isConsole(false) { }
+  };
+  typedef std::map<DWORD /*ThreadId*/, FocusOfThread> FocusOfThreads;  ///
+
+  typedef std::list<DWORD /*ThreadId*/> DetachedThreadIds;     ///
+
+  /// current status in generateKeyboardEvents
+  class Current
+  {
+  public:
+    const Keymap *m_keymap;                    /// current keymap
+    ModifiedKey m_mkey;                /// current processing key that user inputed
+                               /// index in currentFocusOfThread-&gt;keymaps
+    Keymaps::KeymapPtrList::iterator m_i;
+
+  public:
+    ///
+    bool isPressed() const
+    { return m_mkey.m_modifier.isOn(Modifier::Type_Down); }
+  };
+
+  friend class FunctionParam;
+  
+  /// part of keySeq
+  enum Part
+  {
+    Part_all,                                  ///
+    Part_up,                                   ///
+    Part_down,                                 ///
+  };
+
+  ///
+  class EmacsEditKillLine
+  {
+    tstring m_buf;     /// previous kill-line contents
+
+  public:
+    bool m_doForceReset;       ///
+  
+  private:
+    ///
+    HGLOBAL makeNewKillLineBuf(const _TCHAR *i_data, int *i_retval);
+
+  public:
+    ///
+    void reset() { m_buf.resize(0); }
+    /** EmacsEditKillLineFunc.
+       clear the contents of the clopboard
+       at that time, confirm if it is the result of the previous kill-line
+    */
+    void func();
+    /// EmacsEditKillLinePred
+    int pred();
+  };
+
+  /// window positon for &amp;WindowHMaximize, &amp;WindowVMaximize
+  class WindowPosition
+  {
+  public:
+    ///
+    enum Mode
+    {
+      Mode_normal,                             ///
+      Mode_H,                                  ///
+      Mode_V,                                  ///
+      Mode_HV,                                 ///
+    };
+
+  public:
+    HWND m_hwnd;                               ///
+    RECT m_rc;                                 ///
+    Mode m_mode;                               ///
+
+  public:
+    ///
+    WindowPosition(HWND i_hwnd, const RECT &i_rc, Mode i_mode)
+      : m_hwnd(i_hwnd), m_rc(i_rc), m_mode(i_mode) { }
+  };
+  typedef std::list<WindowPosition> WindowPositions;
+
+  typedef std::list<HWND> WindowsWithAlpha; /// windows for &amp;WindowSetAlpha
+
+  enum InterruptThreadReason
+  {
+    InterruptThreadReason_Terminate,
+    InterruptThreadReason_Pause,
+    InterruptThreadReason_Resume,
+  };
+
+private:
+  CriticalSection m_cs;                                /// criticalSection
+  
+  // setting
+  HWND m_hwndAssocWindow;                      /** associated window (we post
+                                                    message to it) */
+  Setting * volatile m_setting;                        /// setting
+  
+  // engine thread state
+  HANDLE m_device;                             /// mayu device
+  bool m_didMayuStartDevice;                   /** Did the mayu start the
+                                                    mayu-device ? */
+  HANDLE m_threadEvent;                                /** 1. thread has been started
+                                                   2. thread is about to end*/
+  HANDLE m_threadHandle;
+  unsigned m_threadId;
+  tstring m_mayudVersion;                      /// version of mayud.sys
+#if defined(_WINNT)
+  HANDLE m_readEvent;                          /** reading from mayu device
+                                                    has been completed */
+  HANDLE m_interruptThreadEvent;               /// interrupt thread event
+  volatile InterruptThreadReason
+  m_interruptThreadReason;                     /// interrupt thread reason
+  OVERLAPPED m_ol;                             /** for async read/write of
+                                                   mayu device */
+  HANDLE m_hookPipe;                           /// named pipe for &SetImeString
+  HMODULE m_sts4mayu;                          /// DLL module for ThumbSense
+  HMODULE m_cts4mayu;                          /// DLL module for ThumbSense
+#endif // _WINNT
+  bool volatile m_doForceTerminate;            /// terminate engine thread
+  bool volatile m_isLogMode;                   /// is logging mode ?
+  bool volatile m_isEnabled;                   /// is enabled  ?
+  bool volatile m_isSynchronizing;             /// is synchronizing ?
+  HANDLE m_eSync;                              /// event for synchronization
+  int m_generateKeyboardEventsRecursionGuard;  /** guard against too many
+                                                    recursion */
+  
+  // current key state
+  Modifier m_currentLock;                      /// current lock key's state
+  int m_currentKeyPressCount;                  /** how many keys are pressed
+                                                    phisically ? */
+  int m_currentKeyPressCountOnWin32;           /** how many keys are pressed
+                                                    on win32 ? */
+  Key *m_lastGeneratedKey;                     /// last generated key
+  Key *m_lastPressedKey[2];                    /// last pressed key
+  ModifiedKey m_oneShotKey;                    /// one shot key
+  unsigned int m_oneShotRepeatableRepeatCount; /// repeat count of one shot key
+  bool m_isPrefix;                             /// is prefix ?
+  bool m_doesIgnoreModifierForPrefix;          /** does ignore modifier key
+                                                    when prefixed ? */
+  bool m_doesEditNextModifier;                 /** does edit next user input
+                                                    key's modifier ? */
+  Modifier m_modifierForNextKey;               /** modifier for next key if
+                                                    above is true */
+
+  /** current keymaps.
+      <dl>
+      <dt>when &amp;OtherWindowClass
+      <dd>currentKeymap becoms currentKeymaps[++ Current::i]
+      <dt>when &amp;KeymapParent
+      <dd>currentKeymap becoms currentKeyamp-&gt;parentKeymap
+      <dt>other
+      <dd>currentKeyamp becoms *Current::i
+      </dl>
+  */
+  const Keymap * volatile m_currentKeymap;     /// current keymap
+  FocusOfThreads /*volatile*/ m_focusOfThreads;        ///
+  FocusOfThread * volatile m_currentFocusOfThread; ///
+  FocusOfThread m_globalFocus;                 ///
+  HWND m_hwndFocus;                            /// current focus window
+  DetachedThreadIds m_detachedThreadIds;       ///
+  
+  // for functions
+  KeymapPtrList m_keymapPrefixHistory;         /// for &amp;KeymapPrevPrefix
+  EmacsEditKillLine m_emacsEditKillLine;       /// for &amp;EmacsEditKillLine
+  const ActionFunction *m_afShellExecute;      /// for &amp;ShellExecute
+  
+  WindowPositions m_windowPositions;           ///
+  WindowsWithAlpha m_windowsWithAlpha;         ///
+  
+  tstring m_helpMessage;                       /// for &amp;HelpMessage
+  tstring m_helpTitle;                         /// for &amp;HelpMessage
+  int m_variable;                              /// for &amp;Variable,
+                                               ///  &amp;Repeat
+
+public:
+  tomsgstream &m_log;                          /** log stream (output to log
+                                                    dialog's edit) */
+  
+private:
+  /// keyboard handler thread
+  static unsigned int WINAPI keyboardHandler(void *i_this);
+  ///
+  void keyboardHandler();
+
+  /// check focus window
+  void checkFocusWindow();
+  /// is modifier pressed ?
+  bool isPressed(Modifier::Type i_mt);
+  /// fix modifier key
+  bool fixModifierKey(ModifiedKey *io_mkey, Keymap::AssignMode *o_am);
+
+  /// output to log
+  void outputToLog(const Key *i_key, const ModifiedKey &i_mkey,
+                  int i_debugLevel);
+
+  /// genete modifier events
+  void generateModifierEvents(const Modifier &i_mod);
+  
+  /// genete event
+  void generateEvents(Current i_c, const Keymap *i_keymap, Key *i_event);
+  
+  /// generate keyboard event
+  void generateKeyEvent(Key *i_key, bool i_doPress, bool i_isByAssign);
+  ///
+  void generateActionEvents(const Current &i_c, const Action *i_a,
+                           bool i_doPress);
+  ///
+  void generateKeySeqEvents(const Current &i_c, const KeySeq *i_keySeq,
+                           Part i_part);
+  ///
+  void generateKeyboardEvents(const Current &i_c);
+  ///
+  void beginGeneratingKeyboardEvents(const Current &i_c, bool i_isModifier);
+  
+  /// pop all pressed key on win32
+  void keyboardResetOnWin32();
+  
+  /// get current modifiers
+  Modifier getCurrentModifiers(Key *i_key, bool i_isPressed);
+
+  /// describe bindings
+  void describeBindings();
+
+  /// update m_lastPressedKey
+  void updateLastPressedKey(Key *i_key);
+
+  /// set current keymap
+  void setCurrentKeymap(const Keymap *i_keymap,
+                       bool i_doesAddToHistory = false);
+  /** open mayu device
+      @return true if mayu device successfully is opened
+  */
+  bool open();
+
+  /// close mayu device
+  void close();
+
+  /// load/unload [sc]ts4mayu.dll
+  void manageTs4mayu(TCHAR *i_ts4mayuDllName, TCHAR *i_dependDllName,
+                    bool i_load, HMODULE *i_pTs4mayu);
+
+private:
+  // BEGINING OF FUNCTION DEFINITION
+  /// send a default key to Windows
+  void funcDefault(FunctionParam *i_param);
+  /// use a corresponding key of a parent keymap
+  void funcKeymapParent(FunctionParam *i_param);
+  /// use a corresponding key of a current window
+  void funcKeymapWindow(FunctionParam *i_param);
+  /// use a corresponding key of the previous prefixed keymap
+  void funcKeymapPrevPrefix(FunctionParam *i_param, int i_previous);
+  /// use a corresponding key of an other window class, or use a default key
+  void funcOtherWindowClass(FunctionParam *i_param);
+  /// prefix key
+  void funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,
+                 BooleanType i_doesIgnoreModifiers = BooleanType_true);
+  /// other keymap's key
+  void funcKeymap(FunctionParam *i_param, const Keymap *i_keymap);
+  /// sync
+  void funcSync(FunctionParam *i_param);
+  /// toggle lock
+  void funcToggle(FunctionParam *i_param, ModifierLockType i_lock,
+                 ToggleType i_toggle = ToggleType_toggle);
+  /// edit next user input key's modifier
+  void funcEditNextModifier(FunctionParam *i_param,
+                           const Modifier &i_modifier);
+  /// variable
+  void funcVariable(FunctionParam *i_param, int i_mag, int i_inc);
+  /// repeat N times
+  void funcRepeat(FunctionParam *i_param, const KeySeq *i_keySeq,
+                 int i_max = 10);
+  /// undefined (bell)
+  void funcUndefined(FunctionParam *i_param);
+  /// ignore
+  void funcIgnore(FunctionParam *i_param);
+  /// post message
+  void funcPostMessage(FunctionParam *i_param, ToWindowType i_window,
+                      UINT i_message, WPARAM i_wParam, LPARAM i_lParam);
+  /// ShellExecute
+  void funcShellExecute(FunctionParam *i_param, const StrExprArg &i_operation,
+                       const StrExprArg &i_file, const StrExprArg &i_parameters,
+                       const StrExprArg &i_directory,
+                       ShowCommandType i_showCommand);
+  /// SetForegroundWindow
+  void funcSetForegroundWindow(FunctionParam *i_param,
+                              const tregex &i_windowClassName,
+                              LogicalOperatorType i_logicalOp
+                              = LogicalOperatorType_and,
+                              const tregex &i_windowTitleName
+                              = tregex(_T(".*")));
+  /// load setting
+  void funcLoadSetting(FunctionParam *i_param,
+                      const StrExprArg &i_name = StrExprArg());
+  /// virtual key
+  void funcVK(FunctionParam *i_param, VKey i_vkey);
+  /// wait
+  void funcWait(FunctionParam *i_param, int i_milliSecond);
+  /// investigate WM_COMMAND, WM_SYSCOMMAND
+  void funcInvestigateCommand(FunctionParam *i_param);
+  /// show mayu dialog box
+  void funcMayuDialog(FunctionParam *i_param, MayuDialogType i_dialog,
+                     ShowCommandType i_showCommand);
+  /// describe bindings
+  void funcDescribeBindings(FunctionParam *i_param);
+  /// show help message
+  void funcHelpMessage(FunctionParam *i_param,
+                      const StrExprArg &i_title = StrExprArg(),
+                      const StrExprArg &i_message = StrExprArg());
+  /// show variable
+  void funcHelpVariable(FunctionParam *i_param, const StrExprArg &i_title);
+  /// raise window
+  void funcWindowRaise(FunctionParam *i_param,
+                      TargetWindowType i_twt = TargetWindowType_overlapped);
+  /// lower window
+  void funcWindowLower(FunctionParam *i_param, 
+                      TargetWindowType i_twt = TargetWindowType_overlapped);
+  /// minimize window
+  void funcWindowMinimize(FunctionParam *i_param, TargetWindowType i_twt
+                         = TargetWindowType_overlapped);
+  /// maximize window
+  void funcWindowMaximize(FunctionParam *i_param, TargetWindowType i_twt
+                         = TargetWindowType_overlapped);
+  /// maximize window horizontally
+  void funcWindowHMaximize(FunctionParam *i_param, TargetWindowType i_twt
+                          = TargetWindowType_overlapped);
+  /// maximize window virtically
+  void funcWindowVMaximize(FunctionParam *i_param, TargetWindowType i_twt
+                          = TargetWindowType_overlapped);
+  /// maximize window virtically or horizontally
+  void funcWindowHVMaximize(FunctionParam *i_param, BooleanType i_isHorizontal,
+                           TargetWindowType i_twt
+                           = TargetWindowType_overlapped);
+  /// move window
+  void funcWindowMove(FunctionParam *i_param, int i_dx, int i_dy,
+                     TargetWindowType i_twt
+                     = TargetWindowType_overlapped);
+  /// move window to ...
+  void funcWindowMoveTo(FunctionParam *i_param, GravityType i_gravityType,
+                       int i_dx, int i_dy, TargetWindowType i_twt
+                       = TargetWindowType_overlapped);
+  /// move window visibly
+  void funcWindowMoveVisibly(FunctionParam *i_param, 
+                            TargetWindowType i_twt
+                            = TargetWindowType_overlapped);
+  /// move window to other monitor
+  void funcWindowMonitorTo(FunctionParam *i_param,
+                           WindowMonitorFromType i_fromType, int i_monitor,
+                           BooleanType i_adjustPos = BooleanType_true,
+                           BooleanType i_adjustSize = BooleanType_false);
+  /// move window to other monitor
+  void funcWindowMonitor(FunctionParam *i_param, int i_monitor,
+                         BooleanType i_adjustPos = BooleanType_true,
+                         BooleanType i_adjustSize = BooleanType_false);
+  ///
+  void funcWindowClingToLeft(FunctionParam *i_param, 
+                            TargetWindowType i_twt
+                            = TargetWindowType_overlapped);
+  ///
+  void funcWindowClingToRight(FunctionParam *i_param, 
+                             TargetWindowType i_twt
+                             = TargetWindowType_overlapped);
+  ///
+  void funcWindowClingToTop(FunctionParam *i_param, 
+                           TargetWindowType i_twt
+                           = TargetWindowType_overlapped);
+  ///
+  void funcWindowClingToBottom(FunctionParam *i_param, 
+                              TargetWindowType i_twt
+                              = TargetWindowType_overlapped);
+  /// close window
+  void funcWindowClose(FunctionParam *i_param, 
+                      TargetWindowType i_twt = TargetWindowType_overlapped);
+  /// toggle top-most flag of the window
+  void funcWindowToggleTopMost(FunctionParam *i_param);
+  /// identify the window
+  void funcWindowIdentify(FunctionParam *i_param);
+  /// set alpha blending parameter to the window
+  void funcWindowSetAlpha(FunctionParam *i_param, int i_alpha);
+  /// redraw the window
+  void funcWindowRedraw(FunctionParam *i_param);
+  /// resize window to
+  void funcWindowResizeTo(FunctionParam *i_param, int i_width, int i_height, 
+                         TargetWindowType i_twt
+                         = TargetWindowType_overlapped);
+  /// move the mouse cursor
+  void funcMouseMove(FunctionParam *i_param, int i_dx, int i_dy);
+  /// send a mouse-wheel-message to Windows
+  void funcMouseWheel(FunctionParam *i_param, int i_delta);
+  /// convert the contents of the Clipboard to upper case or lower case
+  void funcClipboardChangeCase(FunctionParam *i_param,
+                              BooleanType i_doesConvertToUpperCase);
+  /// convert the contents of the Clipboard to upper case
+  void funcClipboardUpcaseWord(FunctionParam *i_param);
+  /// convert the contents of the Clipboard to lower case
+  void funcClipboardDowncaseWord(FunctionParam *i_param);
+  /// set the contents of the Clipboard to the string
+  void funcClipboardCopy(FunctionParam *i_param, const StrExprArg &i_text);
+  ///
+  void funcEmacsEditKillLinePred(FunctionParam *i_param,
+                                const KeySeq *i_keySeq1,
+                                const KeySeq *i_keySeq2);
+  ///
+  void funcEmacsEditKillLineFunc(FunctionParam *i_param);
+  /// clear log
+  void funcLogClear(FunctionParam *i_param);
+  /// recenter
+  void funcRecenter(FunctionParam *i_param);
+  /// Direct SSTP
+  void funcDirectSSTP(FunctionParam *i_param,
+                     const tregex &i_name,
+                     const StrExprArg &i_protocol,
+                     const std::list<tstringq> &i_headers);
+  /// PlugIn
+  void funcPlugIn(FunctionParam *i_param,
+                 const StrExprArg &i_dllName,
+                 const StrExprArg &i_funcName = StrExprArg(),
+                 const StrExprArg &i_funcParam = StrExprArg(),
+                 BooleanType i_doesCreateThread = BooleanType_false);
+  /// set IME open status
+  void funcSetImeStatus(FunctionParam *i_param, ToggleType i_toggle = ToggleType_toggle);
+  /// set string to IME
+  void funcSetImeString(FunctionParam *i_param, const StrExprArg &i_data);
+  /// enter to mouse event hook mode
+  void funcMouseHook(FunctionParam *i_param, MouseHookType i_hookType, int i_hookParam);
+
+  // END OF FUNCTION DEFINITION
+#  define FUNCTION_FRIEND
+#  include "functions.h"
+#  undef FUNCTION_FRIEND
+  
+public:
+  ///
+  Engine(tomsgstream &i_log);
+  ///
+  ~Engine();
+
+  /// start/stop keyboard handler thread
+  void start();
+  ///
+  void stop();
+
+  /// pause keyboard handler thread and close device
+  bool pause();
+  
+  /// resume keyboard handler thread and re-open device
+  bool resume();
+
+  /// do some procedure before quit which must be done synchronously
+  /// (i.e. not on WM_QUIT)
+  bool prepairQuit();
+
+  /// logging mode
+  void enableLogMode(bool i_isLogMode = true) { m_isLogMode = i_isLogMode; }
+  ///
+  void disableLogMode() { m_isLogMode = false; }
+  
+  /// enable/disable engine
+  void enable(bool i_isEnabled = true) { m_isEnabled = i_isEnabled; }
+  ///
+  void disable() { m_isEnabled = false; }
+  ///
+  bool getIsEnabled() const { return m_isEnabled; }
+
+  /// associated window
+  void setAssociatedWndow(HWND i_hwnd) { m_hwndAssocWindow = i_hwnd; }
+  
+  /// associated window
+  HWND getAssociatedWndow() const { return m_hwndAssocWindow; }
+  
+  /// setting
+  bool setSetting(Setting *i_setting);
+
+  /// focus
+  bool setFocus(HWND i_hwndFocus, DWORD i_threadId,
+               const tstringi &i_className,
+               const tstringi &i_titleName, bool i_isConsole);
+
+  /// lock state
+  bool setLockState(bool i_isNumLockToggled, bool i_isCapsLockToggled,
+                   bool i_isScrollLockToggled, bool i_isKanaLockToggled,
+                   bool i_isImeLockToggled, bool i_isImeCompToggled);
+
+  /// show
+  void checkShow(HWND i_hwnd);
+  bool setShow(bool i_isMaximized, bool i_isMinimized, bool i_isMDI);
+
+  /// sync
+  bool syncNotify();
+
+  /// thread detach notify
+  bool threadDetachNotify(DWORD i_threadId);
+
+  /// shell execute
+  void shellExecute();
+  
+  /// get help message
+  void getHelpMessages(tstring *o_helpMessage, tstring *o_helpTitle);
+
+  /// command notify
+  void commandNotify(HWND i_hwnd, UINT i_message, WPARAM i_wParam,
+                    LPARAM i_lParam);
+
+  /// get current window class name
+  const tstringi &getCurrentWindowClassName() const { return m_currentFocusOfThread->m_className; }
+
+  /// get current window title name
+  const tstringi &getCurrentWindowTitleName() const { return m_currentFocusOfThread->m_titleName; }
+
+  /// get mayud version
+  const tstring &getMayudVersion() const { return m_mayudVersion; }
+};
+
+
+///
+class FunctionParam
+{
+public:
+  bool m_isPressed;                            /// is key pressed ?
+  HWND m_hwnd;                                 /// 
+  Engine::Current m_c;                         /// new context
+  bool m_doesNeedEndl;                         /// need endl ?
+  const ActionFunction *m_af;                  /// 
+};
+
+
+#endif // !_ENGINE_H
diff --git a/errormessage.h b/errormessage.h
new file mode 100644 (file)
index 0000000..a02e4a5
--- /dev/null
@@ -0,0 +1,86 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// errormessage.h
+
+
+#ifndef _ERRORMESSAGE_H
+#  define _ERRORMESSAGE_H
+
+#  include "stringtool.h"
+#  include <sstream>
+
+
+///
+class ErrorMessage
+{
+  tstringstream m_ost;                         ///
+  
+public:
+  ///
+  ErrorMessage() { }
+  ///
+  ErrorMessage(const ErrorMessage &i_em) { m_ost << i_em.getMessage(); }
+
+  /// get error message
+  tstring getMessage() const
+  {
+    return m_ost.str();
+  }
+
+  /// add message
+  template<class T> ErrorMessage &operator<<(const T &i_value)
+  {
+    m_ost << i_value;
+    return *this;
+  }
+
+  /// ios manipulator 
+  ErrorMessage &operator<<(
+    std::ios_base &(*i_manip)(std::ios_base&))
+  {
+    m_ost << i_manip;
+    return *this;
+  }
+
+#ifdef UNICODE
+  /// add message
+  template<> ErrorMessage &operator<<(const std::string &i_value)
+  {
+    m_ost << to_wstring(i_value);
+    return *this;
+  }
+
+  /// add message
+  typedef const char *const_char_ptr;
+  template<> ErrorMessage &operator<<(const const_char_ptr &i_value)
+  {
+    m_ost << to_wstring(i_value);
+    return *this;
+  }
+#endif
+  
+  /// stream output
+  friend tostream &operator<<(tostream &i_ost, const ErrorMessage &i_em);
+};
+
+
+/// stream output
+inline tostream &operator<<(tostream &i_ost, const ErrorMessage &i_em)
+{
+  return i_ost << i_em.getMessage();
+}
+
+
+///
+class WarningMessage : public ErrorMessage
+{
+public:
+  /// add message
+  template<class T> WarningMessage &operator<<(const T &i_value)
+  {
+    ErrorMessage::operator<<(i_value);
+    return *this;
+  }
+};
+
+
+#endif // !_ERRORMESSAGE_H
diff --git a/focus.cpp b/focus.cpp
new file mode 100644 (file)
index 0000000..3871bdc
--- /dev/null
+++ b/focus.cpp
@@ -0,0 +1,70 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// focus.cpp
+
+
+#include "focus.h"
+#include "windowstool.h"
+
+
+///
+static LRESULT CALLBACK WndProc(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
+{
+  switch (i_message)
+  {
+    case WM_KEYDOWN:
+    case WM_SYSKEYDOWN:
+    case WM_KEYUP:
+    case WM_SYSKEYUP:
+      SendMessage(GetParent(i_hwnd), WM_APP_notifyVKey, i_wParam, i_lParam);
+      return 0;
+    case WM_CHAR:
+    case WM_DEADCHAR:
+      return 0;
+    case WM_LBUTTONDOWN:
+    {
+      SetFocus(i_hwnd);
+      return 0;
+    }
+    case WM_SETFOCUS:
+    {
+      RECT rc;
+      GetClientRect(i_hwnd, &rc);
+      CreateCaret(i_hwnd, reinterpret_cast<HBITMAP>(NULL), 2,
+                 rcHeight(&rc) / 2);
+      ShowCaret(i_hwnd);
+      SetCaretPos(rcWidth(&rc) / 2, rcHeight(&rc) / 4);
+      SendMessage(GetParent(i_hwnd), WM_APP_notifyFocus,
+                 TRUE, (LPARAM)i_hwnd);
+      return 0;
+    }
+    case WM_KILLFOCUS:
+    {
+      HideCaret(i_hwnd);
+      DestroyCaret();
+      SendMessage(GetParent(i_hwnd), WM_APP_notifyFocus,
+                 FALSE, (LPARAM)i_hwnd);
+      return 0;
+    }
+    case WM_GETDLGCODE:
+      return DLGC_WANTALLKEYS;
+  }
+  return DefWindowProc(i_hwnd, i_message, i_wParam, i_lParam);
+}
+
+
+ATOM Register_focus()
+{
+  WNDCLASS wc;
+  wc.style         = CS_HREDRAW | CS_VREDRAW;
+  wc.lpfnWndProc   = WndProc;
+  wc.cbClsExtra    = 0;
+  wc.cbWndExtra    = 0;
+  wc.hInstance     = g_hInst;
+  wc.hIcon         = NULL;
+  wc.hCursor       = LoadCursor(NULL, IDC_IBEAM);
+  wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
+  wc.lpszMenuName  = NULL;
+  wc.lpszClassName = _T("mayuFocus");
+  return RegisterClass(&wc);
+}
diff --git a/focus.h b/focus.h
new file mode 100644 (file)
index 0000000..5f7da36
--- /dev/null
+++ b/focus.h
@@ -0,0 +1,21 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// focus.h
+
+
+#ifndef _FOCUS_H
+#  define _FOCUS_H
+
+#  include <windows.h>
+
+
+///
+extern ATOM Register_focus();
+
+enum
+{
+  WM_APP_notifyFocus = WM_APP + 103,
+  WM_APP_notifyVKey  = WM_APP + 104,
+};
+
+
+#endif // !_FOCUS_H
diff --git a/function.cpp b/function.cpp
new file mode 100644 (file)
index 0000000..16f7294
--- /dev/null
@@ -0,0 +1,2506 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// function.cpp
+
+
+#include "engine.h"
+#include "hook.h"
+#include "mayu.h"
+#include "mayurc.h"
+#include "misc.h"
+#include "registry.h"
+#include "vkeytable.h"
+#include "windowstool.h"
+#include <algorithm>
+#include <process.h>
+
+#define FUNCTION_DATA
+#include "functions.h"
+#undef FUNCTION_DATA
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// TypeTable
+
+
+template <class T> class TypeTable
+{
+public:
+  T m_type;
+  const _TCHAR *m_name;
+};
+
+
+template <class T> static inline
+bool getTypeName(tstring *o_name, T i_type,
+                const TypeTable<T> *i_table, size_t i_n)
+{
+  for (size_t i = 0; i < i_n; ++ i)
+    if (i_table[i].m_type == i_type)
+    {
+      *o_name = i_table[i].m_name;
+      return true;
+    }
+  return false;
+}
+
+template <class T> static inline
+bool getTypeValue(T *o_type, const tstringi &i_name,
+                 const TypeTable<T> *i_table, size_t i_n)
+{
+  for (size_t i = 0; i < i_n; ++ i)
+    if (i_table[i].m_name == i_name)
+    {
+      *o_type = i_table[i].m_type;
+      return true;
+    }
+  return false;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// VKey
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, VKey i_data)
+{
+  if (i_data & VKey_extended)
+    i_ost << _T("E-");
+  if (i_data & VKey_released)
+    i_ost << _T("U-");
+  if (i_data & VKey_pressed)
+    i_ost << _T("D-");
+
+  u_int8 code = i_data & ~(VKey_extended | VKey_released | VKey_pressed);
+  const VKeyTable *vkt;
+  for (vkt = g_vkeyTable; vkt->m_name; ++ vkt)
+    if (vkt->m_code == code)
+      break;
+  if (vkt->m_name)
+    i_ost << vkt->m_name;
+  else
+    i_ost << _T("0x") << std::hex << code << std::dec;
+  return i_ost;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ToWindowType
+
+
+// ToWindowType table
+typedef TypeTable<ToWindowType> TypeTable_ToWindowType;
+static const TypeTable_ToWindowType g_toWindowTypeTable[] =
+{
+  { ToWindowType_toOverlappedWindow, _T("toOverlappedWindow") },
+  { ToWindowType_toMainWindow,       _T("toMainWindow")       },
+  { ToWindowType_toItself,           _T("toItself")           },
+  { ToWindowType_toParentWindow,     _T("toParentWindow")     },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, ToWindowType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data,
+                 g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable)))
+    i_ost << name;
+  else
+    i_ost << static_cast<int>(i_data);
+  return i_ost;
+}
+
+
+// get value of ToWindowType
+bool getTypeValue(ToWindowType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name,
+                     g_toWindowTypeTable, NUMBER_OF(g_toWindowTypeTable));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// GravityType
+
+
+// GravityType table
+typedef TypeTable<GravityType> TypeTable_GravityType;
+static const TypeTable_GravityType g_gravityTypeTable[] =
+{
+  { GravityType_C,  _T("C")  },
+  { GravityType_N,  _T("N")  },
+  { GravityType_E,  _T("E")  },
+  { GravityType_W,  _T("W")  },
+  { GravityType_S,  _T("S")  },
+  { GravityType_NW, _T("NW") },
+  { GravityType_NW, _T("WN") },
+  { GravityType_NE, _T("NE") },
+  { GravityType_NE, _T("EN") },
+  { GravityType_SW, _T("SW") },
+  { GravityType_SW, _T("WS") },
+  { GravityType_SE, _T("SE") },
+  { GravityType_SE, _T("ES") },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, GravityType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data,
+                 g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable)))
+    i_ost << name;
+  else
+    i_ost << _T("(GravityType internal error)");
+  return i_ost;
+}
+
+
+// get value of GravityType
+bool getTypeValue(GravityType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name,
+                     g_gravityTypeTable, NUMBER_OF(g_gravityTypeTable));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// MouseHookType
+
+
+// MouseHookType table
+typedef TypeTable<MouseHookType> TypeTable_MouseHookType;
+static const TypeTable_MouseHookType g_mouseHookTypeTable[] =
+{
+  { MouseHookType_None,  _T("None")  },
+  { MouseHookType_Wheel,  _T("Wheel")  },
+  { MouseHookType_WindowMove,  _T("WindowMove")  },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, MouseHookType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data,
+                 g_mouseHookTypeTable, NUMBER_OF(g_mouseHookTypeTable)))
+    i_ost << name;
+  else
+    i_ost << _T("(MouseHookType internal error)");
+  return i_ost;
+}
+
+
+// get value of MouseHookType
+bool getTypeValue(MouseHookType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_mouseHookTypeTable,
+                     NUMBER_OF(g_mouseHookTypeTable));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// MayuDialogType
+
+
+// ModifierLockType table
+typedef TypeTable<MayuDialogType> TypeTable_MayuDialogType;
+static const TypeTable_MayuDialogType g_mayuDialogTypeTable[] =
+{
+  { MayuDialogType_investigate, _T("investigate")  },
+  { MayuDialogType_log,         _T("log")          },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, MayuDialogType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data,
+                 g_mayuDialogTypeTable, NUMBER_OF(g_mayuDialogTypeTable)))
+    i_ost << name;
+  else
+    i_ost << _T("(MayuDialogType internal error)");
+  return i_ost;
+}
+
+
+// get value of MayuDialogType
+bool getTypeValue(MayuDialogType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_mayuDialogTypeTable,
+                     NUMBER_OF(g_mayuDialogTypeTable));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ToggleType
+
+
+// ToggleType table
+typedef TypeTable<ToggleType> TypeTable_ToggleType;
+static const TypeTable_ToggleType g_toggleType[] =
+{
+  { ToggleType_toggle, _T("toggle") },
+  { ToggleType_off, _T("off") },
+  { ToggleType_off, _T("false") },
+  { ToggleType_off, _T("released") },
+  { ToggleType_on,  _T("on")  },
+  { ToggleType_on,  _T("true")  },
+  { ToggleType_on,  _T("pressed")  },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, ToggleType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data, g_toggleType, NUMBER_OF(g_toggleType)))
+    i_ost << name;
+  else
+    i_ost << _T("(ToggleType internal error)");
+  return i_ost;
+}
+
+
+// get value of ToggleType
+bool getTypeValue(ToggleType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_toggleType,
+                     NUMBER_OF(g_toggleType));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ModifierLockType
+
+
+// ModifierLockType table
+typedef TypeTable<ModifierLockType> TypeTable_ModifierLockType;
+static const TypeTable_ModifierLockType g_modifierLockTypeTable[] =
+{
+  { ModifierLockType_Lock0, _T("lock0") },
+  { ModifierLockType_Lock1, _T("lock1") },
+  { ModifierLockType_Lock2, _T("lock2") },
+  { ModifierLockType_Lock3, _T("lock3") },
+  { ModifierLockType_Lock4, _T("lock4") },
+  { ModifierLockType_Lock5, _T("lock5") },
+  { ModifierLockType_Lock6, _T("lock6") },
+  { ModifierLockType_Lock7, _T("lock7") },
+  { ModifierLockType_Lock8, _T("lock8") },
+  { ModifierLockType_Lock9, _T("lock9") },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, ModifierLockType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data,
+                 g_modifierLockTypeTable, NUMBER_OF(g_modifierLockTypeTable)))
+    i_ost << name;
+  else
+    i_ost << _T("(ModifierLockType internal error)");
+  return i_ost;
+}
+
+
+// get value of ModifierLockType
+bool getTypeValue(ModifierLockType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_modifierLockTypeTable,
+                     NUMBER_OF(g_modifierLockTypeTable));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ShowCommandType
+
+
+// ShowCommandType table
+typedef TypeTable<ShowCommandType> TypeTable_ShowCommandType;
+static const TypeTable_ShowCommandType g_showCommandTypeTable[] =
+{
+  { ShowCommandType_hide,            _T("hide")            },
+  { ShowCommandType_maximize,        _T("maximize")        },
+  { ShowCommandType_minimize,        _T("minimize")        },
+  { ShowCommandType_restore,         _T("restore")         },
+  { ShowCommandType_show,            _T("show")            },
+  { ShowCommandType_showDefault,     _T("showDefault")     },
+  { ShowCommandType_showMaximized,   _T("showMaximized")   },
+  { ShowCommandType_showMinimized,   _T("showMinimized")   },
+  { ShowCommandType_showMinNoActive, _T("showMinNoActive") },
+  { ShowCommandType_showNA,          _T("showNA")          },
+  { ShowCommandType_showNoActivate,  _T("showNoActivate")  },
+  { ShowCommandType_showNormal,      _T("showNormal")      },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, ShowCommandType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data,
+                 g_showCommandTypeTable, NUMBER_OF(g_showCommandTypeTable)))
+    i_ost << name;
+  else
+    i_ost << _T("(ShowCommandType internal error)");
+  return i_ost;
+}
+
+
+// get value of ShowCommandType
+bool getTypeValue(ShowCommandType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_showCommandTypeTable,
+                     NUMBER_OF(g_showCommandTypeTable));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// TargetWindowType
+
+
+// ModifierLockType table
+typedef TypeTable<TargetWindowType> TypeTable_TargetWindowType;
+static const TypeTable_TargetWindowType g_targetWindowType[] =
+{
+  { TargetWindowType_overlapped, _T("overlapped") },
+  { TargetWindowType_mdi,        _T("mdi")        },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, TargetWindowType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data,
+                 g_targetWindowType, NUMBER_OF(g_targetWindowType)))
+    i_ost << name;
+  else
+    i_ost << _T("(TargetWindowType internal error)");
+  return i_ost;
+}
+
+
+// get value of TargetWindowType
+bool getTypeValue(TargetWindowType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_targetWindowType,
+                     NUMBER_OF(g_targetWindowType));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// BooleanType
+
+
+// BooleanType table
+typedef TypeTable<BooleanType> TypeTable_BooleanType;
+static const TypeTable_BooleanType g_booleanType[] =
+{
+  { BooleanType_false, _T("false") },
+  { BooleanType_true,  _T("true")  },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, BooleanType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data, g_booleanType, NUMBER_OF(g_booleanType)))
+    i_ost << name;
+  else
+    i_ost << _T("(BooleanType internal error)");
+  return i_ost;
+}
+
+
+// get value of BooleanType
+bool getTypeValue(BooleanType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_booleanType,
+                     NUMBER_OF(g_booleanType));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LogicalOperatorType
+
+
+// LogicalOperatorType table
+typedef TypeTable<LogicalOperatorType> TypeTable_LogicalOperatorType;
+static const TypeTable_LogicalOperatorType g_logicalOperatorType[] =
+{
+  { LogicalOperatorType_or, _T("||") },
+  { LogicalOperatorType_and,  _T("&&")  },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, LogicalOperatorType i_data)
+{
+  tstring name;
+  if (getTypeName(&name, i_data, g_logicalOperatorType,
+                 NUMBER_OF(g_logicalOperatorType)))
+    i_ost << name;
+  else
+    i_ost << _T("(LogicalOperatorType internal error)");
+  return i_ost;
+}
+
+
+// get value of LogicalOperatorType
+bool getTypeValue(LogicalOperatorType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_logicalOperatorType,
+                     NUMBER_OF(g_logicalOperatorType));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// WindowMonitorFromType
+
+
+// WindowMonitorFromType table
+typedef TypeTable<WindowMonitorFromType> TypeTable_WindowMonitorFromType;
+static const TypeTable_WindowMonitorFromType g_windowMonitorFromType[] =
+{
+  { WindowMonitorFromType_primary, _T("primary") },
+  { WindowMonitorFromType_current, _T("current") },
+};
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, WindowMonitorFromType i_data)
+{
+  tstring name;
+  if(getTypeName(&name, i_data, g_windowMonitorFromType,
+                 NUMBER_OF(g_windowMonitorFromType)))
+    i_ost << name;
+  else
+    i_ost << _T("(WindowMonitorFromType internal error)");
+  return i_ost;
+}
+
+
+// get value of WindowMonitorFromType
+bool getTypeValue(WindowMonitorFromType *o_type, const tstring &i_name)
+{
+  return getTypeValue(o_type, i_name, g_windowMonitorFromType,
+                      NUMBER_OF(g_windowMonitorFromType));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// std::list<tstringq>
+
+
+/// stream output
+tostream &operator<<(tostream &i_ost, const std::list<tstringq> &i_data)
+{
+  for (std::list<tstringq>::const_iterator
+        i = i_data.begin(); i != i_data.end(); ++ i)
+  {
+    i_ost << *i << _T(", ");
+  }
+  return i_ost;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// FunctionData
+
+
+//
+FunctionData::~FunctionData()
+{
+}
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, const FunctionData *i_data)
+{
+  return i_data->output(i_ost);
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// FunctionCreator
+
+
+///
+class FunctionCreator
+{
+public:
+  typedef FunctionData *(*Creator)();          /// 
+  
+public:
+  const _TCHAR *m_name;                                /// function name
+  Creator m_creator;                           /// function data creator
+};
+
+
+// create function
+FunctionData *createFunctionData(const tstring &i_name)
+{
+  static 
+#define FUNCTION_CREATOR
+#include "functions.h"
+#undef FUNCTION_CREATOR
+    ;
+
+  for (size_t i = 0; i != NUMBER_OF(functionCreators); ++ i)
+    if (i_name == functionCreators[i].m_name)
+      return functionCreators[i].m_creator();
+  return NULL;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// misc. functions
+
+
+//
+bool getSuitableWindow(FunctionParam *i_param, HWND *o_hwnd)
+{
+  if (!i_param->m_isPressed)
+    return false;
+  *o_hwnd = getToplevelWindow(i_param->m_hwnd, NULL);
+  if (!*o_hwnd)
+    return false;
+  return true;
+}
+
+//
+bool getSuitableMdiWindow(FunctionParam *i_param, HWND *o_hwnd,
+                         TargetWindowType *io_twt,
+                         RECT *o_rcWindow = NULL, RECT *o_rcParent = NULL)
+{
+  if (!i_param->m_isPressed)
+    return false;
+  bool isMdi = *io_twt == TargetWindowType_mdi;
+  *o_hwnd = getToplevelWindow(i_param->m_hwnd, &isMdi);
+  *io_twt = isMdi ? TargetWindowType_mdi : TargetWindowType_overlapped;
+  if (!*o_hwnd)
+    return false;
+  switch (*io_twt)
+  {
+    case TargetWindowType_overlapped:
+      if (o_rcWindow)
+       GetWindowRect(*o_hwnd, o_rcWindow);
+      if (o_rcParent) {
+        HMONITOR hm = monitorFromWindow(i_param->m_hwnd,
+                                        MONITOR_DEFAULTTONEAREST);
+        MONITORINFO mi;
+        mi.cbSize = sizeof(mi);
+        getMonitorInfo(hm, &mi);
+        *o_rcParent = mi.rcWork;
+      }
+      break;
+    case TargetWindowType_mdi:
+      if (o_rcWindow)
+       getChildWindowRect(*o_hwnd, o_rcWindow);
+      if (o_rcParent)
+       GetClientRect(GetParent(*o_hwnd), o_rcParent);
+      break;
+  }
+  return true;
+}
+
+// get clipboard text (you must call closeClopboard())
+static const _TCHAR *getTextFromClipboard(HGLOBAL *o_hdata)
+{
+  *o_hdata = NULL;
+  
+  if (!OpenClipboard(NULL))
+    return NULL;
+
+#ifdef UNICODE
+  *o_hdata = GetClipboardData(CF_UNICODETEXT);
+#else
+  *o_hdata = GetClipboardData(CF_TEXT);
+#endif
+  if (!*o_hdata)
+    return NULL;
+  
+  _TCHAR *data = reinterpret_cast<_TCHAR *>(GlobalLock(*o_hdata));
+  if (!data)
+    return NULL;
+  return data;
+}
+
+// close clipboard that opend by getTextFromClipboard()
+static void closeClipboard(HGLOBAL i_hdata, HGLOBAL i_hdataNew = NULL)
+{
+  if (i_hdata)
+    GlobalUnlock(i_hdata);
+  if (i_hdataNew)
+  {
+    EmptyClipboard();
+#ifdef UNICODE
+    SetClipboardData(CF_UNICODETEXT, i_hdataNew);
+#else
+    SetClipboardData(CF_TEXT, i_hdataNew);
+#endif
+  }
+  CloseClipboard();
+}
+
+
+// EmacsEditKillLineFunc.
+// clear the contents of the clopboard
+// at that time, confirm if it is the result of the previous kill-line
+void Engine::EmacsEditKillLine::func()
+{
+  if (!m_buf.empty())
+  {
+    HGLOBAL g;
+    const _TCHAR *text = getTextFromClipboard(&g);
+    if (text == NULL || m_buf != text)
+      reset();
+    closeClipboard(g);
+  }
+  if (OpenClipboard(NULL))
+  {
+    EmptyClipboard();
+    CloseClipboard();
+  }
+}
+
+
+/** if the text of the clipboard is
+@doc
+<pre>
+1: EDIT Control (at EOL C-K): ""            =&gt; buf + "\r\n", Delete   
+0: EDIT Control (other  C-K): "(.+)"        =&gt; buf + "\1"             
+0: IE FORM TEXTAREA (at EOL C-K): "\r\n"    =&gt; buf + "\r\n"           
+2: IE FORM TEXTAREA (other C-K): "(.+)\r\n" =&gt; buf + "\1", Return Left
+^retval
+</pre>
+*/
+HGLOBAL Engine::EmacsEditKillLine::makeNewKillLineBuf(
+  const _TCHAR *i_data, int *o_retval)
+{
+  size_t len = m_buf.size();
+  len += _tcslen(i_data) + 3;
+  
+  HGLOBAL hdata = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
+                             len * sizeof(_TCHAR));
+  if (!hdata)
+    return NULL;
+  _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdata));
+  *dataNew = _T('\0');
+  if (!m_buf.empty())
+    _tcscpy(dataNew, m_buf.c_str());
+  
+  len = _tcslen(i_data);
+  if (3 <= len &&
+      i_data[len - 2] == _T('\r') && i_data[len - 1] == _T('\n'))
+  {
+    _tcscat(dataNew, i_data);
+    len = _tcslen(dataNew);
+    dataNew[len - 2] = _T('\0'); // chomp
+    *o_retval = 2;
+  }
+  else if (len == 0)
+  {
+    _tcscat(dataNew, _T("\r\n"));
+    *o_retval = 1;
+  }
+  else
+  {
+    _tcscat(dataNew, i_data);
+    *o_retval = 0;
+  }
+  
+  m_buf = dataNew;
+  
+  GlobalUnlock(hdata);
+  return hdata;
+}
+
+
+// EmacsEditKillLinePred
+int Engine::EmacsEditKillLine::pred()
+{
+  HGLOBAL g;
+  const _TCHAR *text = getTextFromClipboard(&g);
+  int retval;
+  HGLOBAL hdata = makeNewKillLineBuf(text ? text : _T(""), &retval);
+  closeClipboard(g, hdata);
+  return retval;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// functions
+
+
+// send a default key to Windows
+void Engine::funcDefault(FunctionParam *i_param)
+{
+  {
+    Acquire a(&m_log, 1);
+    m_log << std::endl;
+    i_param->m_doesNeedEndl = false;
+  }
+  if (i_param->m_isPressed)
+    generateModifierEvents(i_param->m_c.m_mkey.m_modifier);
+  generateKeyEvent(i_param->m_c.m_mkey.m_key, i_param->m_isPressed, true);
+}
+
+// use a corresponding key of a parent keymap
+void Engine::funcKeymapParent(FunctionParam *i_param)
+{
+  Current c(i_param->m_c);
+  c.m_keymap = c.m_keymap->getParentKeymap();
+  if (!c.m_keymap)
+  {
+    funcDefault(i_param);
+    return;
+  }
+  
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
+  }
+  i_param->m_doesNeedEndl = false;
+  generateKeyboardEvents(c);
+}
+
+// use a corresponding key of a current window
+void Engine::funcKeymapWindow(FunctionParam *i_param)
+{
+  Current c(i_param->m_c);
+  c.m_keymap = m_currentFocusOfThread->m_keymaps.front();
+  c.m_i = m_currentFocusOfThread->m_keymaps.begin();
+  generateKeyboardEvents(c);
+}
+
+// use a corresponding key of the previous prefixed keymap
+void Engine::funcKeymapPrevPrefix(FunctionParam *i_param, int i_previous)
+{
+  Current c(i_param->m_c);
+  if (0 < i_previous && 0 <= m_keymapPrefixHistory.size() - i_previous)
+  {
+    int n = i_previous - 1;
+    KeymapPtrList::reverse_iterator i = m_keymapPrefixHistory.rbegin();
+    while (0 < n && i != m_keymapPrefixHistory.rend())
+      --n, ++i;
+    c.m_keymap = *i;
+    generateKeyboardEvents(c);
+  }
+}
+
+// use a corresponding key of an other window class, or use a default key
+void Engine::funcOtherWindowClass(FunctionParam *i_param)
+{
+  Current c(i_param->m_c);
+  ++ c.m_i;
+  if (c.m_i == m_currentFocusOfThread->m_keymaps.end())
+  {
+    funcDefault(i_param);
+    return;
+  }
+  
+  c.m_keymap = *c.m_i;
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
+  }
+  i_param->m_doesNeedEndl = false;
+  generateKeyboardEvents(c);
+}
+
+// prefix key
+void Engine::funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,
+                       BooleanType i_doesIgnoreModifiers)
+{
+  if (!i_param->m_isPressed)
+    return;
+  
+  setCurrentKeymap(i_keymap, true);
+  
+  // generate prefixed event
+  generateEvents(i_param->m_c, m_currentKeymap, &Event::prefixed);
+  
+  m_isPrefix = true;
+  m_doesEditNextModifier = false;
+  m_doesIgnoreModifierForPrefix = !!i_doesIgnoreModifiers;
+
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("(") << i_keymap->getName() << _T(", ")
+         << (i_doesIgnoreModifiers ? _T("true") : _T("false")) << _T(")");
+  }
+}
+
+// other keymap's key
+void Engine::funcKeymap(FunctionParam *i_param, const Keymap *i_keymap)
+{
+  Current c(i_param->m_c);
+  c.m_keymap = i_keymap;
+  {
+    Acquire a(&m_log, 1);
+    m_log << _T("(") << c.m_keymap->getName() << _T(")") << std::endl;
+    i_param->m_doesNeedEndl = false;
+  }
+  generateKeyboardEvents(c);
+}
+
+// sync
+void Engine::funcSync(FunctionParam *i_param)
+{
+  if (i_param->m_isPressed)
+    generateModifierEvents(i_param->m_af->m_modifier);
+  if (!i_param->m_isPressed || m_currentFocusOfThread->m_isConsole)
+    return;
+  
+  Key *sync = m_setting->m_keyboard.getSyncKey();
+  if (sync->getScanCodesSize() == 0)
+    return;
+  const ScanCode *sc = sync->getScanCodes();
+  
+  // set variables exported from mayu.dll
+  g_hookData->m_syncKey = sc->m_scan;
+  g_hookData->m_syncKeyIsExtended = !!(sc->m_flags & ScanCode::E0E1);
+  m_isSynchronizing = true;
+#if defined(_WINNT)
+  generateKeyEvent(sync, false, false);
+#elif defined(_WIN95)
+  generateKeyEvent(sync, true, false);
+#else
+#  error
+#endif
+  
+  m_cs.release();
+  DWORD r = WaitForSingleObject(m_eSync, 5000);
+  if (r == WAIT_TIMEOUT)
+  {
+    Acquire a(&m_log, 0);
+    m_log << _T(" *FAILED*") << std::endl;
+  }
+  m_cs.acquire();
+  m_isSynchronizing = false;
+}
+
+// toggle lock
+void Engine::funcToggle(FunctionParam *i_param, ModifierLockType i_lock,
+                       ToggleType i_toggle)
+{
+  if (i_param->m_isPressed)                    // ignore PRESS
+    return;
+
+  Modifier::Type mt = static_cast<Modifier::Type>(i_lock);
+  switch (i_toggle)
+  {
+    case ToggleType_toggle:
+      m_currentLock.press(mt, !m_currentLock.isPressed(mt));
+      break;
+    case ToggleType_off:
+      m_currentLock.press(mt, false);
+      break;
+    case ToggleType_on:
+      m_currentLock.press(mt, true);
+      break;
+  }
+}
+
+// edit next user input key's modifier
+void Engine::funcEditNextModifier(FunctionParam *i_param,
+                                 const Modifier &i_modifier)
+{
+  if (!i_param->m_isPressed)
+    return;
+  
+  m_isPrefix = true;
+  m_doesEditNextModifier = true;
+  m_doesIgnoreModifierForPrefix = true;
+  m_modifierForNextKey = i_modifier;
+}
+
+// variable
+void Engine::funcVariable(FunctionParam *i_param, int i_mag, int i_inc)
+{
+  if (!i_param->m_isPressed)
+    return;
+  m_variable *= i_mag;
+  m_variable += i_inc;
+}
+
+// repeat N times
+void Engine::funcRepeat(FunctionParam *i_param, const KeySeq *i_keySeq,
+                       int i_max)
+{
+  if (i_param->m_isPressed)
+  {
+    int end = MIN(m_variable, i_max);
+    for (int i = 0; i < end - 1; ++ i)
+      generateKeySeqEvents(i_param->m_c, i_keySeq, Part_all);
+    if (0 < end)
+      generateKeySeqEvents(i_param->m_c, i_keySeq, Part_down);
+  }
+  else
+    generateKeySeqEvents(i_param->m_c, i_keySeq, Part_up);
+}
+
+// undefined (bell)
+void Engine::funcUndefined(FunctionParam *i_param)
+{
+  if (!i_param->m_isPressed)
+    return;
+  MessageBeep(MB_OK);
+}
+
+// ignore
+void Engine::funcIgnore(FunctionParam *)
+{
+  // do nothing
+}
+
+// post message
+void Engine::funcPostMessage(FunctionParam *i_param, ToWindowType i_window,
+                            UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
+{
+  if (!i_param->m_isPressed)
+    return;
+
+  int window = static_cast<int>(i_window);
+  
+  HWND hwnd = i_param->m_hwnd;
+  if (0 < window)
+  {
+    for (int i = 0; i < window; ++ i)
+      hwnd = GetParent(hwnd);
+  }
+  else if (window == ToWindowType_toMainWindow)
+  {
+    while (true)
+    {
+      HWND p = GetParent(hwnd);
+      if (!p)
+       break;
+      hwnd = p;
+    }
+  }
+  else if (window == ToWindowType_toOverlappedWindow)
+  {
+    while (hwnd)
+    {
+      LONG style = GetWindowLong(hwnd, GWL_STYLE);
+      if ((style & WS_CHILD) == 0)
+       break;
+      hwnd = GetParent(hwnd);
+    }
+  }
+
+  if (hwnd)
+    PostMessage(hwnd, i_message, i_wParam, i_lParam);
+}
+
+
+// ShellExecute
+void Engine::funcShellExecute(FunctionParam *i_param,
+                             const StrExprArg &/*i_operation*/,
+                             const StrExprArg &/*i_file*/,
+                             const StrExprArg &/*i_parameters*/,
+                             const StrExprArg &/*i_directory*/,
+                             ShowCommandType /*i_showCommand*/)
+{
+  if (!i_param->m_isPressed)
+    return;
+  m_afShellExecute = i_param->m_af;
+  PostMessage(m_hwndAssocWindow,
+             WM_APP_engineNotify, EngineNotify_shellExecute, 0);
+}
+
+
+// shell execute
+void Engine::shellExecute()
+{
+  Acquire a(&m_cs);
+  
+  FunctionData_ShellExecute *fd =
+    reinterpret_cast<FunctionData_ShellExecute *>(
+      m_afShellExecute->m_functionData);
+  
+  int r = (int)ShellExecute(
+    NULL,
+    fd->m_operation.eval().empty() ? _T("open") : fd->m_operation.eval().c_str(),
+    fd->m_file.eval().empty() ? NULL : fd->m_file.eval().c_str(),
+    fd->m_parameters.eval().empty() ? NULL : fd->m_parameters.eval().c_str(),
+    fd->m_directory.eval().empty() ? NULL : fd->m_directory.eval().c_str(),
+    fd->m_showCommand);
+  if (32 < r)
+    return; // success
+
+  typedef TypeTable<int> ErrorTable;
+  static const ErrorTable errorTable[] =
+  {
+    { 0, _T("The operating system is out of memory or resources.") },
+    { ERROR_FILE_NOT_FOUND, _T("The specified file was not found.") },
+    { ERROR_PATH_NOT_FOUND, _T("The specified path was not found.") },
+    { ERROR_BAD_FORMAT, _T("The .exe file is invalid ")
+      _T("(non-Win32R .exe or error in .exe image).") },
+    { SE_ERR_ACCESSDENIED,
+      _T("The operating system denied access to the specified file.") },
+    { SE_ERR_ASSOCINCOMPLETE,
+      _T("The file name association is incomplete or invalid.") },
+    { SE_ERR_DDEBUSY,
+      _T("The DDE transaction could not be completed ")
+      _T("because other DDE transactions were being processed. ") },
+    { SE_ERR_DDEFAIL, _T("The DDE transaction failed.") },
+    { SE_ERR_DDETIMEOUT, _T("The DDE transaction could not be completed ")
+      _T("because the request timed out.") },
+    { SE_ERR_DLLNOTFOUND,
+      _T("The specified dynamic-link library was not found.") },
+    { SE_ERR_FNF, _T("The specified file was not found.") },
+    { SE_ERR_NOASSOC, _T("There is no application associated ")
+      _T("with the given file name extension.") },
+    { SE_ERR_OOM,
+      _T("There was not enough memory to complete the operation.") },
+    { SE_ERR_PNF, _T("The specified path was not found.") },
+    { SE_ERR_SHARE, _T("A sharing violation occurred.") },
+  };
+
+  tstring errorMessage(_T("Unknown error."));
+  getTypeName(&errorMessage, r, errorTable, NUMBER_OF(errorTable));
+  
+  Acquire b(&m_log, 0);
+  m_log << _T("error: ") << fd << _T(": ") << errorMessage << std::endl;
+}
+
+
+struct EnumWindowsForSetForegroundWindowParam
+{
+  const FunctionData_SetForegroundWindow *m_fd;
+  HWND m_hwnd;
+
+public:
+  EnumWindowsForSetForegroundWindowParam(
+    const FunctionData_SetForegroundWindow *i_fd)
+    : m_fd(i_fd),
+      m_hwnd(NULL)
+  {
+  }
+};
+
+
+/// enum windows for SetForegroundWindow
+static BOOL CALLBACK enumWindowsForSetForegroundWindow(
+  HWND i_hwnd, LPARAM i_lParam)
+{
+  EnumWindowsForSetForegroundWindowParam &ep =
+    *reinterpret_cast<EnumWindowsForSetForegroundWindowParam *>(i_lParam);
+
+  _TCHAR name[GANA_MAX_ATOM_LENGTH];
+  if (!GetClassName(i_hwnd, name, NUMBER_OF(name)))
+    return TRUE;
+  tsmatch what;
+  if (!boost::regex_search(tstring(name), what, ep.m_fd->m_windowClassName))
+    if (ep.m_fd->m_logicalOp == LogicalOperatorType_and)
+      return TRUE;                             // match failed
+
+  if (ep.m_fd->m_logicalOp == LogicalOperatorType_and)
+  {
+    if (GetWindowText(i_hwnd, name, NUMBER_OF(name)) == 0)
+      name[0] = _T('\0');
+    if (!boost::regex_search(tstring(name), what,
+                            ep.m_fd->m_windowTitleName))
+      return TRUE;                             // match failed
+  }
+
+  ep.m_hwnd = i_hwnd;
+  return FALSE;
+}
+
+
+/// SetForegroundWindow
+void Engine::funcSetForegroundWindow(FunctionParam *i_param, const tregex &,
+                                    LogicalOperatorType , const tregex &)
+{
+  if (!i_param->m_isPressed)
+    return;
+  EnumWindowsForSetForegroundWindowParam
+    ep(static_cast<const FunctionData_SetForegroundWindow *>(
+      i_param->m_af->m_functionData));
+  EnumWindows(enumWindowsForSetForegroundWindow,
+             reinterpret_cast<LPARAM>(&ep));
+  if (ep.m_hwnd)
+    PostMessage(m_hwndAssocWindow,
+               WM_APP_engineNotify, EngineNotify_setForegroundWindow,
+               reinterpret_cast<LPARAM>(ep.m_hwnd));
+
+}
+
+
+// load setting
+void Engine::funcLoadSetting(FunctionParam *i_param, const StrExprArg &i_name)
+{
+  if (!i_param->m_isPressed)
+    return;
+  if (!i_name.eval().empty())
+  {
+    // set MAYU_REGISTRY_ROOT\.mayuIndex which name is same with i_name
+    Registry reg(MAYU_REGISTRY_ROOT);
+
+    tregex split(_T("^([^;]*);([^;]*);(.*)$"));
+    tstringi dot_mayu;
+    for (size_t i = 0; i < MAX_MAYU_REGISTRY_ENTRIES; ++ i)
+    {
+      _TCHAR buf[100];
+      _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), i);
+      if (!reg.read(buf, &dot_mayu))
+       break;
+      
+      tsmatch what;
+      if (boost::regex_match(dot_mayu, what, split) &&
+         what.str(1) == i_name.eval())
+      {        
+       reg.write(_T(".mayuIndex"), i);
+       goto success;
+      }
+    }
+
+    {
+      Acquire a(&m_log, 0);
+      m_log << _T("unknown setting name: ") << i_name;
+    }
+    return;
+    
+    success: ;
+  }
+  PostMessage(m_hwndAssocWindow,
+             WM_APP_engineNotify, EngineNotify_loadSetting, 0);
+}
+
+// virtual key
+void Engine::funcVK(FunctionParam *i_param, VKey i_vkey)
+{
+  long key = static_cast<long>(i_vkey);
+  BYTE vkey = static_cast<BYTE>(i_vkey);
+  bool isExtended = !!(key & VKey_extended);
+  bool isUp       = !i_param->m_isPressed && !!(key & VKey_released);
+  bool isDown     = i_param->m_isPressed && !!(key & VKey_pressed);
+  
+  if (vkey == VK_LBUTTON && isDown)
+    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
+  else if (vkey == VK_LBUTTON && isUp)
+    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
+  else if (vkey == VK_MBUTTON && isDown)
+    mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
+  else if (vkey == VK_MBUTTON && isUp)
+    mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
+  else if (vkey == VK_RBUTTON && isDown)
+    mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
+  else if (vkey == VK_RBUTTON && isUp)
+    mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
+#if(_WIN32_WINNT >= 0x0500)
+  else if (vkey == VK_XBUTTON1 && isDown)
+    mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON1, 0);
+  else if (vkey == VK_XBUTTON1 && isUp)
+    mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON1, 0);
+  else if (vkey == VK_XBUTTON2 && isDown)
+    mouse_event(MOUSEEVENTF_XDOWN, 0, 0, XBUTTON2, 0);
+  else if (vkey == VK_XBUTTON2 && isUp)
+    mouse_event(MOUSEEVENTF_XUP, 0, 0, XBUTTON2, 0);
+#endif /* _WIN32_WINNT >= 0x0500 */
+  else if (isUp || isDown)
+    keybd_event(vkey,
+               static_cast<BYTE>(MapVirtualKey(vkey, 0)),
+               (isExtended ? KEYEVENTF_EXTENDEDKEY : 0) |
+               (i_param->m_isPressed ? 0 : KEYEVENTF_KEYUP), 0);
+}
+
+// wait
+void Engine::funcWait(FunctionParam *i_param, int i_milliSecond)
+{
+  if (!i_param->m_isPressed)
+    return;
+  if (i_milliSecond < 0 || 5000 < i_milliSecond)       // too long wait
+    return;
+  
+  m_isSynchronizing = true;
+  m_cs.release();
+  Sleep(i_milliSecond);
+  m_cs.acquire();
+  m_isSynchronizing = false;
+}
+
+// investigate WM_COMMAND, WM_SYSCOMMAND
+void Engine::funcInvestigateCommand(FunctionParam *i_param)
+{
+  if (!i_param->m_isPressed)
+    return;
+  Acquire a(&m_log, 0);
+  g_hookData->m_doesNotifyCommand = !g_hookData->m_doesNotifyCommand;
+  if (g_hookData->m_doesNotifyCommand)
+    m_log << _T(" begin") << std::endl;
+  else
+    m_log << _T(" end") << std::endl;
+}
+
+// show mayu dialog box
+void Engine::funcMayuDialog(FunctionParam *i_param, MayuDialogType i_dialog,
+                           ShowCommandType i_showCommand)
+{
+  if (!i_param->m_isPressed)
+    return;
+  PostMessage(getAssociatedWndow(), WM_APP_engineNotify, EngineNotify_showDlg,
+             static_cast<LPARAM>(i_dialog) |
+             static_cast<LPARAM>(i_showCommand));
+}
+
+// describe bindings
+void Engine::funcDescribeBindings(FunctionParam *i_param)
+{
+  if (!i_param->m_isPressed)
+    return;
+  {
+    Acquire a(&m_log, 1);
+    m_log << std::endl;
+  }
+  describeBindings();
+}
+
+// show help message
+void Engine::funcHelpMessage(FunctionParam *i_param, const StrExprArg &i_title,
+                            const StrExprArg &i_message)
+{
+  if (!i_param->m_isPressed)
+    return;
+
+  m_helpTitle = i_title.eval();
+  m_helpMessage = i_message.eval();
+  bool doesShow = !(i_title.eval().size() == 0 && i_message.eval().size() == 0);
+  PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
+             EngineNotify_helpMessage, doesShow);
+}
+
+// show variable
+void Engine::funcHelpVariable(FunctionParam *i_param, const StrExprArg &i_title)
+{
+  if (!i_param->m_isPressed)
+    return;
+
+  _TCHAR buf[20];
+  _sntprintf(buf, NUMBER_OF(buf), _T("%d"), m_variable);
+
+  m_helpTitle = i_title.eval();
+  m_helpMessage = buf;
+  PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
+             EngineNotify_helpMessage, true);
+}
+
+// raise window
+void Engine::funcWindowRaise(FunctionParam *i_param,
+                            TargetWindowType i_twt)
+{
+  HWND hwnd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
+    return;
+  SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
+              SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
+}
+
+// lower window
+void Engine::funcWindowLower(FunctionParam *i_param, TargetWindowType i_twt)
+{
+  HWND hwnd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
+    return;
+  SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0,
+              SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
+}
+
+// minimize window
+void Engine::funcWindowMinimize(FunctionParam *i_param, TargetWindowType i_twt)
+{
+  HWND hwnd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
+    return;
+  PostMessage(hwnd, WM_SYSCOMMAND,
+             IsIconic(hwnd) ? SC_RESTORE : SC_MINIMIZE, 0);
+}
+
+// maximize window
+void Engine::funcWindowMaximize(FunctionParam *i_param, TargetWindowType i_twt)
+{
+  HWND hwnd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
+    return;
+  PostMessage(hwnd, WM_SYSCOMMAND,
+             IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, 0);
+}
+
+// maximize horizontally or virtically
+void Engine::funcWindowHVMaximize(FunctionParam *i_param,
+                                 BooleanType i_isHorizontal,
+                                 TargetWindowType i_twt)
+{
+  HWND hwnd;
+  RECT rc, rcd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
+    return;
+
+  // erase non window
+  while (true)
+  {
+    WindowPositions::iterator i = m_windowPositions.begin();
+    WindowPositions::iterator end = m_windowPositions.end();
+    for (; i != end; ++ i)
+      if (!IsWindow((*i).m_hwnd))
+       break;
+    if (i == end)
+      break;
+    m_windowPositions.erase(i);
+  }
+
+  // find target
+  WindowPositions::iterator i = m_windowPositions.begin();
+  WindowPositions::iterator end = m_windowPositions.end();
+  WindowPositions::iterator target = end;
+  for (; i != end; ++ i)
+    if ((*i).m_hwnd == hwnd)
+    {
+      target = i;
+      break;
+    }
+  
+  if (IsZoomed(hwnd))
+    PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
+  else
+  {
+    WindowPosition::Mode mode = WindowPosition::Mode_normal;
+    
+    if (target != end)
+    {
+      WindowPosition &wp = *target;
+      rc = wp.m_rc;
+      if (wp.m_mode == WindowPosition::Mode_HV)
+       mode = wp.m_mode =
+         i_isHorizontal ? WindowPosition::Mode_V : WindowPosition::Mode_H;
+      else if (( i_isHorizontal && wp.m_mode == WindowPosition::Mode_V) ||
+              (!i_isHorizontal && wp.m_mode == WindowPosition::Mode_H))
+       mode = wp.m_mode = WindowPosition::Mode_HV;
+      else
+       m_windowPositions.erase(target);
+    }
+    else
+    {
+      mode = i_isHorizontal ? WindowPosition::Mode_H : WindowPosition::Mode_V;
+      m_windowPositions.push_front(WindowPosition(hwnd, rc, mode));
+    }
+    
+    if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_H))
+      rc.left = rcd.left, rc.right = rcd.right;
+    if (static_cast<int>(mode) & static_cast<int>(WindowPosition::Mode_V))
+      rc.top = rcd.top, rc.bottom = rcd.bottom;
+    
+    asyncMoveWindow(hwnd, rc.left, rc.top, rcWidth(&rc), rcHeight(&rc));
+  }
+}
+
+// maximize window horizontally
+void Engine::funcWindowHMaximize(FunctionParam *i_param,
+                                TargetWindowType i_twt)
+{
+  funcWindowHVMaximize(i_param, BooleanType_true, i_twt);
+}
+
+// maximize window virtically
+void Engine::funcWindowVMaximize(FunctionParam *i_param,
+                                TargetWindowType i_twt)
+{
+  funcWindowHVMaximize(i_param, BooleanType_false, i_twt);
+}
+
+// move window
+void Engine::funcWindowMove(FunctionParam *i_param, int i_dx, int i_dy,
+                           TargetWindowType i_twt)
+{
+  funcWindowMoveTo(i_param, GravityType_C, i_dx, i_dy, i_twt);
+}
+
+// move window to ...
+void Engine::funcWindowMoveTo(FunctionParam *i_param,
+                             GravityType i_gravityType,
+                             int i_dx, int i_dy, TargetWindowType i_twt)
+{
+  HWND hwnd;
+  RECT rc, rcd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
+    return;
+  
+  int x = rc.left + i_dx;
+  int y = rc.top + i_dy;
+
+  if (i_gravityType & GravityType_N)
+    y = i_dy + rcd.top;
+  if (i_gravityType & GravityType_E)
+    x = i_dx + rcd.right - rcWidth(&rc);
+  if (i_gravityType & GravityType_W)
+    x = i_dx + rcd.left;
+  if (i_gravityType & GravityType_S)
+    y = i_dy + rcd.bottom - rcHeight(&rc);
+  asyncMoveWindow(hwnd, x, y);
+}
+
+
+// move window visibly
+void Engine::funcWindowMoveVisibly(FunctionParam *i_param,
+                                  TargetWindowType i_twt)
+{
+  HWND hwnd;
+  RECT rc, rcd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
+    return;
+
+  int x = rc.left;
+  int y = rc.top;
+  if (rc.left < rcd.left)
+    x = rcd.left;
+  else if (rcd.right < rc.right)
+    x = rcd.right - rcWidth(&rc);
+  if (rc.top < rcd.top)
+    y = rcd.top;
+  else if (rcd.bottom < rc.bottom)
+    y = rcd.bottom - rcHeight(&rc);
+  asyncMoveWindow(hwnd, x, y);
+}
+
+
+struct EnumDisplayMonitorsForWindowMonitorToParam
+{
+  std::vector<HMONITOR> m_monitors;
+  std::vector<MONITORINFO> m_monitorinfos;
+  int m_primaryMonitorIdx;
+  int m_currentMonitorIdx;
+
+  HMONITOR m_hmon;
+
+public:
+  EnumDisplayMonitorsForWindowMonitorToParam(HMONITOR i_hmon)
+    : m_hmon(i_hmon),
+      m_primaryMonitorIdx(-1), m_currentMonitorIdx(-1)
+  {
+  }
+};
+
+static BOOL CALLBACK enumDisplayMonitorsForWindowMonitorTo(
+  HMONITOR i_hmon, HDC i_hdc, LPRECT i_rcMonitor, LPARAM i_data)
+{
+  EnumDisplayMonitorsForWindowMonitorToParam &ep =
+    *reinterpret_cast<EnumDisplayMonitorsForWindowMonitorToParam *>(i_data);
+
+  ep.m_monitors.push_back(i_hmon);
+
+  MONITORINFO mi;
+  mi.cbSize = sizeof(mi);
+  getMonitorInfo(i_hmon, &mi);
+  ep.m_monitorinfos.push_back(mi);
+
+  if(mi.dwFlags & MONITORINFOF_PRIMARY)
+    ep.m_primaryMonitorIdx = ep.m_monitors.size() - 1;
+  if(i_hmon == ep.m_hmon)
+    ep.m_currentMonitorIdx = ep.m_monitors.size() - 1;
+
+  return TRUE;
+}
+
+/// move window to other monitor
+void Engine::funcWindowMonitorTo(
+    FunctionParam *i_param, WindowMonitorFromType i_fromType, int i_monitor,
+    BooleanType i_adjustPos, BooleanType i_adjustSize)
+{
+  HWND hwnd;
+  if(! getSuitableWindow(i_param, &hwnd))
+    return;
+
+  HMONITOR hmonCur;
+  hmonCur = monitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+
+  EnumDisplayMonitorsForWindowMonitorToParam ep(hmonCur);
+  enumDisplayMonitors(NULL, NULL, enumDisplayMonitorsForWindowMonitorTo,
+                      reinterpret_cast<LPARAM>(&ep));
+  if(ep.m_monitors.size() < 1 ||
+     ep.m_primaryMonitorIdx < 0 || ep.m_currentMonitorIdx < 0)
+    return;
+
+  int targetIdx;
+  switch(i_fromType) {
+  case WindowMonitorFromType_primary:
+    targetIdx = (ep.m_primaryMonitorIdx + i_monitor) % ep.m_monitors.size();
+    break;
+
+  case WindowMonitorFromType_current:
+    targetIdx = (ep.m_currentMonitorIdx + i_monitor) % ep.m_monitors.size();
+    break;
+  }
+  if(ep.m_currentMonitorIdx == targetIdx)
+    return;
+
+  RECT rcCur, rcTarget, rcWin;
+  rcCur = ep.m_monitorinfos[ep.m_currentMonitorIdx].rcWork;
+  rcTarget = ep.m_monitorinfos[targetIdx].rcWork;
+  GetWindowRect(hwnd, &rcWin);
+
+  int x = rcTarget.left + (rcWin.left - rcCur.left);
+  int y = rcTarget.top + (rcWin.top - rcCur.top);
+  int w = rcWidth(&rcWin);
+  int h = rcHeight(&rcWin);
+
+  if(i_adjustPos) {
+    if(x + w > rcTarget.right)
+      x = rcTarget.right - w;
+    if(x < rcTarget.left)
+      x = rcTarget.left;
+    if(w > rcWidth(&rcTarget)) {
+      x = rcTarget.left;
+      w = rcWidth(&rcTarget);
+    }
+
+    if(y + h > rcTarget.bottom)
+      y = rcTarget.bottom - h;
+    if(y < rcTarget.top)
+      y = rcTarget.top;
+    if(h > rcHeight(&rcTarget)) {
+      y = rcTarget.top;
+      h = rcHeight(&rcTarget);
+    }
+  }
+
+  if(i_adjustPos && i_adjustSize) {
+    if(IsZoomed(hwnd))
+      PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
+    asyncMoveWindow(hwnd, x, y, w, h);
+  } else {
+    asyncMoveWindow(hwnd, x, y);
+  }
+}
+
+/// move window to other monitor
+void Engine::funcWindowMonitor(
+    FunctionParam *i_param, int i_monitor,
+    BooleanType i_adjustPos, BooleanType i_adjustSize)
+{
+  funcWindowMonitorTo(i_param, WindowMonitorFromType_primary, i_monitor,
+                      i_adjustPos, i_adjustSize);
+}
+
+
+//
+void Engine::funcWindowClingToLeft(FunctionParam *i_param,
+                                  TargetWindowType i_twt)
+{
+  funcWindowMoveTo(i_param, GravityType_W, 0, 0, i_twt);
+}
+
+//
+void Engine::funcWindowClingToRight(FunctionParam *i_param,
+                                   TargetWindowType i_twt)
+{
+  funcWindowMoveTo(i_param, GravityType_E, 0, 0, i_twt);
+}
+
+//
+void Engine::funcWindowClingToTop(FunctionParam *i_param,
+                                 TargetWindowType i_twt)
+{
+  funcWindowMoveTo(i_param, GravityType_N, 0, 0, i_twt);
+}
+
+//
+void Engine::funcWindowClingToBottom(FunctionParam *i_param,
+                                    TargetWindowType i_twt)
+{
+  funcWindowMoveTo(i_param, GravityType_S, 0, 0, i_twt);
+}
+
+// close window
+void Engine::funcWindowClose(FunctionParam *i_param, TargetWindowType i_twt)
+{
+  HWND hwnd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt))
+    return;
+  PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
+}
+
+// toggle top-most flag of the window
+void Engine::funcWindowToggleTopMost(FunctionParam *i_param)
+{
+  HWND hwnd;
+  if (!getSuitableWindow(i_param, &hwnd))
+    return;
+  SetWindowPos(
+    hwnd,
+    (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) ?
+    HWND_NOTOPMOST : HWND_TOPMOST,
+    0, 0, 0, 0,
+    SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSIZE);
+}
+
+// identify the window
+void Engine::funcWindowIdentify(FunctionParam *i_param)
+{
+  if (!i_param->m_isPressed)
+    return;
+
+  _TCHAR className[GANA_MAX_ATOM_LENGTH];
+  bool ok = false;
+  if (GetClassName(i_param->m_hwnd, className, NUMBER_OF(className)))
+  {
+    if (_tcsicmp(className, _T("ConsoleWindowClass")) == 0)
+    {
+      _TCHAR titleName[1024];
+      if (GetWindowText(i_param->m_hwnd, titleName, NUMBER_OF(titleName)) == 0)
+       titleName[0] = _T('\0');
+      {
+       Acquire a(&m_log, 1);
+       m_log << _T("HWND:\t") << std::hex
+             << reinterpret_cast<int>(i_param->m_hwnd)
+             << std::dec << std::endl;
+      }
+      Acquire a(&m_log, 0);
+      m_log << _T("CLASS:\t") << className << std::endl;
+      m_log << _T("TITLE:\t") << titleName << std::endl;
+
+      HWND hwnd = getToplevelWindow(i_param->m_hwnd, NULL);
+      RECT rc;
+      GetWindowRect(hwnd, &rc);
+      m_log << _T("Toplevel Window Position/Size: (")
+           << rc.left << _T(", ") << rc.top << _T(") / (")
+           << rcWidth(&rc) << _T("x") << rcHeight(&rc)
+           << _T(")") << std::endl;
+      
+      SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
+      m_log << _T("Desktop Window Position/Size: (")
+           << rc.left << _T(", ") << rc.top << _T(") / (")
+           << rcWidth(&rc) << _T("x") << rcHeight(&rc)
+           << _T(")") << std::endl;
+
+      m_log << std::endl;
+      ok = true;
+    }
+  }
+  if (!ok)
+  {
+    UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
+               addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
+    CHECK_TRUE( PostMessage(i_param->m_hwnd, WM_MAYU_MESSAGE,
+                           MayuMessage_notifyName, 0) );
+  }
+}
+
+// set alpha blending parameter to the window
+void Engine::funcWindowSetAlpha(FunctionParam *i_param, int i_alpha)
+{
+#if defined(_WINNT)
+  HWND hwnd;
+  if (!getSuitableWindow(i_param, &hwnd))
+    return;
+  
+  if (i_alpha < 0)     // remove all alpha
+  {
+    for (WindowsWithAlpha::iterator i = m_windowsWithAlpha.begin(); 
+        i != m_windowsWithAlpha.end(); ++ i)
+    {
+      SetWindowLong(*i, GWL_EXSTYLE,
+                   GetWindowLong(*i, GWL_EXSTYLE) & ~WS_EX_LAYERED);
+      RedrawWindow(*i, NULL, NULL,
+                  RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+    }
+    m_windowsWithAlpha.clear();
+  }
+  else
+  {
+    LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+    if (exStyle & WS_EX_LAYERED)       // remove alpha
+    {
+      WindowsWithAlpha::iterator
+       i = std::find(m_windowsWithAlpha.begin(), m_windowsWithAlpha.end(),
+                     hwnd);
+      if (i == m_windowsWithAlpha.end())
+       return; // already layered by the application
+    
+      m_windowsWithAlpha.erase(i);
+    
+      SetWindowLong(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
+    }
+    else       // add alpha
+    {
+      SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
+      i_alpha %= 101;
+      if (!setLayeredWindowAttributes(hwnd, 0,
+                                     (BYTE)(255 * i_alpha / 100), LWA_ALPHA))
+      {
+       Acquire a(&m_log, 0);
+       m_log << _T("error: &WindowSetAlpha(") << i_alpha
+             << _T(") failed for HWND: ") << std::hex
+             << hwnd << std::dec << std::endl;
+       return;
+      }
+      m_windowsWithAlpha.push_front(hwnd);
+    }
+    RedrawWindow(hwnd, NULL, NULL,
+                RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+  }
+#endif // _WINNT
+}
+
+
+// redraw the window
+void Engine::funcWindowRedraw(FunctionParam *i_param)
+{
+  HWND hwnd;
+  if (!getSuitableWindow(i_param, &hwnd))
+    return;
+  RedrawWindow(hwnd, NULL, NULL,
+              RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
+}
+
+// resize window to
+void Engine::funcWindowResizeTo(FunctionParam *i_param, int i_width,
+                               int i_height, TargetWindowType i_twt)
+{
+  HWND hwnd;
+  RECT rc, rcd;
+  if (!getSuitableMdiWindow(i_param, &hwnd, &i_twt, &rc, &rcd))
+    return;
+  
+  if (i_width == 0)
+    i_width = rcWidth(&rc);
+  else if (i_width < 0)
+    i_width += rcWidth(&rcd);
+  
+  if (i_height == 0)
+    i_height = rcHeight(&rc);
+  else if (i_height < 0)
+    i_height += rcHeight(&rcd);
+  
+  asyncResize(hwnd, i_width, i_height);
+}
+
+// move the mouse cursor
+void Engine::funcMouseMove(FunctionParam *i_param, int i_dx, int i_dy)
+{
+  if (!i_param->m_isPressed)
+    return;
+  POINT pt;
+  GetCursorPos(&pt);
+  SetCursorPos(pt.x + i_dx, pt.y + i_dy);
+}
+
+// send a mouse-wheel-message to Windows
+void Engine::funcMouseWheel(FunctionParam *i_param, int i_delta)
+{
+  if (!i_param->m_isPressed)
+    return;
+  mouse_event(MOUSEEVENTF_WHEEL, 0, 0, i_delta, 0);
+}
+
+// convert the contents of the Clipboard to upper case
+void Engine::funcClipboardChangeCase(FunctionParam *i_param,
+                                    BooleanType i_doesConvertToUpperCase)
+{
+  if (!i_param->m_isPressed)
+    return;
+  
+  HGLOBAL hdata;
+  const _TCHAR *text = getTextFromClipboard(&hdata);
+  HGLOBAL hdataNew = NULL;
+  if (text)
+  {
+    int size = static_cast<int>(GlobalSize(hdata));
+    hdataNew = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
+    if (hdataNew)
+    {
+      if (_TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew)))
+      {
+       std::memcpy(dataNew, text, size);
+       _TCHAR *dataEnd = dataNew + size;
+       while (dataNew < dataEnd && *dataNew)
+       {
+         _TCHAR c = *dataNew;
+         if (_istlead(c))
+           dataNew += 2;
+         else
+           *dataNew++ =
+             i_doesConvertToUpperCase ? _totupper(c) : _totlower(c);
+       }
+       GlobalUnlock(hdataNew);
+      }
+    }
+  }
+  closeClipboard(hdata, hdataNew);
+}
+
+// convert the contents of the Clipboard to upper case
+void Engine::funcClipboardUpcaseWord(FunctionParam *i_param)
+{
+  funcClipboardChangeCase(i_param, BooleanType_true);
+}
+
+// convert the contents of the Clipboard to lower case
+void Engine::funcClipboardDowncaseWord(FunctionParam *i_param)
+{
+  funcClipboardChangeCase(i_param, BooleanType_false);
+}
+
+// set the contents of the Clipboard to the string
+void Engine::funcClipboardCopy(FunctionParam *i_param, const StrExprArg &i_text)
+{
+  if (!i_param->m_isPressed)
+    return;
+  if (!OpenClipboard(NULL))
+    return;
+  
+  HGLOBAL hdataNew =
+    GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
+               (i_text.eval().size() + 1) * sizeof(_TCHAR));
+  if (!hdataNew)
+    return;
+  _TCHAR *dataNew = reinterpret_cast<_TCHAR *>(GlobalLock(hdataNew));
+  _tcscpy(dataNew, i_text.eval().c_str());
+  GlobalUnlock(hdataNew);
+  closeClipboard(NULL, hdataNew);
+}
+
+//
+void Engine::funcEmacsEditKillLinePred(
+  FunctionParam *i_param, const KeySeq *i_keySeq1, const KeySeq *i_keySeq2)
+{
+  m_emacsEditKillLine.m_doForceReset = false;
+  if (!i_param->m_isPressed)
+    return;
+  
+  int r = m_emacsEditKillLine.pred();
+  const KeySeq *keySeq;
+  if (r == 1)
+    keySeq = i_keySeq1;
+  else if (r == 2)
+    keySeq = i_keySeq2;
+  else // r == 0
+    return;
+  ASSERT(keySeq);
+  generateKeySeqEvents(i_param->m_c, keySeq, Part_all);
+}
+
+//
+void Engine::funcEmacsEditKillLineFunc(FunctionParam *i_param)
+{
+  if (!i_param->m_isPressed)
+    return;
+  m_emacsEditKillLine.func();
+  m_emacsEditKillLine.m_doForceReset = false;
+}
+
+// clear log
+void Engine::funcLogClear(FunctionParam *i_param)
+{
+  if (!i_param->m_isPressed)
+    return;
+  PostMessage(getAssociatedWndow(), WM_APP_engineNotify,
+             EngineNotify_clearLog, 0);
+}
+
+// recenter
+void Engine::funcRecenter(FunctionParam *i_param)
+{
+  if (!i_param->m_isPressed)
+    return;
+  if (m_hwndFocus)
+  {
+    UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
+               addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
+    PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcRecenter, 0);
+  }
+}
+
+// set IME open status
+void Engine::funcSetImeStatus(FunctionParam *i_param, ToggleType i_toggle)
+{
+  if (!i_param->m_isPressed)
+    return;
+  if (m_hwndFocus)
+  {
+    UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
+               addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
+    int status = -1;
+    switch (i_toggle)
+    {
+      case ToggleType_toggle:
+       status = -1;
+       break;
+      case ToggleType_off:
+       status = 0;
+       break;
+      case ToggleType_on:
+       status = 1;
+       break;
+    }
+    PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeStatus, status);
+  }
+}
+
+// set IME open status
+void Engine::funcSetImeString(FunctionParam *i_param, const StrExprArg &i_data)
+{
+#if defined(_WINNT)
+  if (!i_param->m_isPressed)
+    return;
+  if (m_hwndFocus)
+  {
+    UINT WM_MAYU_MESSAGE = RegisterWindowMessage(
+               addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
+    PostMessage(m_hwndFocus, WM_MAYU_MESSAGE, MayuMessage_funcSetImeString, i_data.eval().size() * sizeof(_TCHAR));
+
+    DWORD len = 0;
+    DWORD error;
+    DisconnectNamedPipe(m_hookPipe);
+    ConnectNamedPipe(m_hookPipe, NULL);
+    error = WriteFile(m_hookPipe, i_data.eval().c_str(),
+                     i_data.eval().size() * sizeof(_TCHAR),
+                     &len, NULL);
+
+    //FlushFileBuffers(m_hookPipe);
+  }
+#else
+  Acquire a(&m_log);
+  m_log << _T("supported on only Windows NT/2000/XP") << std::endl;
+#endif
+}
+
+// Direct SSTP Server
+class DirectSSTPServer
+{
+public:
+  tstring m_path;
+  HWND m_hwnd;
+  tstring m_name;
+  tstring m_keroname;
+
+public:
+  DirectSSTPServer()
+    : m_hwnd(NULL)
+  {
+  }
+};
+
+
+class ParseDirectSSTPData
+{
+  typedef boost::match_results<boost::regex::const_iterator> MR;
+
+public:
+  typedef std::map<tstring, DirectSSTPServer> DirectSSTPServers;
+
+private:
+  DirectSSTPServers *m_directSSTPServers;
+  
+public:
+  // constructor
+  ParseDirectSSTPData(DirectSSTPServers *i_directSSTPServers)
+    : m_directSSTPServers(i_directSSTPServers)
+  {
+  }
+  
+  bool operator()(const MR& i_what)
+  {
+#ifdef _UNICODE
+    tstring id(to_wstring(std::string(i_what[1].first, i_what[1].second)));
+    tstring member(to_wstring(std::string(i_what[2].first, i_what[2].second)));
+    tstring value(to_wstring(std::string(i_what[3].first, i_what[3].second)));
+#else
+    tstring id(i_what[1].first, i_what[1].second);
+    tstring member(i_what[2].first, i_what[2].second);
+    tstring value(i_what[3].first, i_what[3].second);
+#endif
+
+    if (member == _T("path"))
+      (*m_directSSTPServers)[id].m_path = value;
+    else if (member == _T("hwnd"))
+      (*m_directSSTPServers)[id].m_hwnd =
+       reinterpret_cast<HWND>(_ttoi(value.c_str()));
+    else if (member == _T("name"))
+      (*m_directSSTPServers)[id].m_name = value;
+    else if (member == _T("keroname"))
+      (*m_directSSTPServers)[id].m_keroname = value;
+    return true; 
+  }
+};
+
+// Direct SSTP
+void Engine::funcDirectSSTP(FunctionParam *i_param,
+                           const tregex &i_name,
+                           const StrExprArg &i_protocol,
+                           const std::list<tstringq> &i_headers)
+{
+  if (!i_param->m_isPressed)
+    return;
+
+  // check Direct SSTP server exist ?
+  if (HANDLE hm = OpenMutex(MUTEX_ALL_ACCESS, FALSE, _T("sakura")))
+    CloseHandle(hm);
+  else
+  {
+    Acquire a(&m_log, 0);
+    m_log << _T(" Error(1): Direct SSTP server does not exist.");
+    return;
+  }
+
+  HANDLE hfm = OpenFileMapping(FILE_MAP_READ, FALSE, _T("Sakura"));
+  if (!hfm)
+  {
+    Acquire a(&m_log, 0);
+    m_log << _T(" Error(2): Direct SSTP server does not provide data.");
+    return;
+  }
+  
+  char *data =
+    reinterpret_cast<char *>(MapViewOfFile(hfm, FILE_MAP_READ, 0, 0, 0));
+  if (!data)
+  {
+    CloseHandle(hfm);
+    Acquire a(&m_log, 0);
+    m_log << _T(" Error(3): Direct SSTP server does not provide data.");
+    return;
+  }
+  
+  long length = *(long *)data;
+  const char *begin = data + 4;
+  const char *end = data + length;
+  boost::regex getSakura("([0-9a-fA-F]{32})\\.([^\x01]+)\x01(.*?)\r\n");
+  
+  ParseDirectSSTPData::DirectSSTPServers servers;
+  boost::regex_iterator<boost::regex::const_iterator>
+    it(begin, end, getSakura), last;
+  for (; it != last; ++it)
+    ((ParseDirectSSTPData)(&servers))(*it);
+
+  // make request
+  tstring request;
+  if (!i_protocol.eval().size())
+    request += _T("NOTIFY SSTP/1.1");
+  else
+    request += i_protocol.eval();
+  request += _T("\r\n");
+
+  bool hasSender = false;
+  for (std::list<tstringq>::const_iterator
+        i = i_headers.begin(); i != i_headers.end(); ++ i)
+  {
+    if (_tcsnicmp(_T("Charset"), i->c_str(), 7) == 0 ||
+       _tcsnicmp(_T("Hwnd"),    i->c_str(), 4) == 0)
+      continue;
+    if (_tcsnicmp(_T("Sender"), i->c_str(), 6) == 0)
+      hasSender = true;
+    request += i->c_str();
+    request += _T("\r\n");
+  }
+
+  if (!hasSender)
+  {
+    request += _T("Sender: ");
+    request += loadString(IDS_mayu);
+    request += _T("\r\n");
+  }
+  
+  _TCHAR buf[100];
+  _sntprintf(buf, NUMBER_OF(buf), _T("HWnd: %d\r\n"),
+            reinterpret_cast<int>(m_hwndAssocWindow));
+  request += buf;
+
+#ifdef _UNICODE
+  request += _T("Charset: UTF-8\r\n");
+#else
+  request += _T("Charset: Shift_JIS\r\n");
+#endif
+  request += _T("\r\n");
+
+#ifdef _UNICODE
+  std::string request_UTF_8 = to_UTF_8(request);
+#endif
+
+  // send request to Direct SSTP Server which matches i_name;
+  for (ParseDirectSSTPData::DirectSSTPServers::iterator
+        i = servers.begin(); i != servers.end(); ++ i)
+  {
+    tsmatch what;
+    if (boost::regex_match(i->second.m_name, what, i_name))
+    {
+      COPYDATASTRUCT cd;
+      cd.dwData = 9801;
+#ifdef _UNICODE
+      cd.cbData = request_UTF_8.size();
+      cd.lpData = (void *)request_UTF_8.c_str();
+#else
+      cd.cbData = request.size();
+      cd.lpData = (void *)request.c_str();
+#endif
+      DWORD result;
+      SendMessageTimeout(i->second.m_hwnd, WM_COPYDATA,
+                        reinterpret_cast<WPARAM>(m_hwndAssocWindow),
+                        reinterpret_cast<LPARAM>(&cd),
+                        SMTO_ABORTIFHUNG | SMTO_BLOCK, 5000, &result);
+    }
+  }
+  
+  UnmapViewOfFile(data);
+  CloseHandle(hfm);
+}
+
+
+namespace shu
+{
+  class PlugIn
+  {
+    enum Type
+    {
+      Type_A,
+      Type_W
+    };
+    
+  private:
+    HMODULE m_dll;
+    FARPROC m_func;
+    Type m_type;
+    tstringq m_funcParam;
+    
+  public:
+    PlugIn() : m_dll(NULL)
+    {
+    }
+    
+    ~PlugIn()
+    {
+      FreeLibrary(m_dll);
+    }
+
+    bool load(const tstringq &i_dllName, const tstringq &i_funcName,
+             const tstringq &i_funcParam, tomsgstream &i_log)
+    {
+      m_dll = LoadLibrary((_T("Plugins\\") + i_dllName).c_str());
+      if (!m_dll)
+      {
+       m_dll = LoadLibrary((_T("Plugin\\") + i_dllName).c_str());
+       if (!m_dll)
+       {
+         m_dll = LoadLibrary(i_dllName.c_str());
+         if (!m_dll)
+         {
+           Acquire a(&i_log);
+           i_log << std::endl;
+           i_log << _T("error: &PlugIn() failed to load ") << i_dllName << std::endl;
+           return false;
+         }
+       }
+      }
+
+      // get function
+#ifdef UNICODE
+#  define to_wstring
+#else
+#  define to_string
+#endif
+      m_type = Type_W;
+      m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("W")).c_str());
+      if (!m_func)
+      {
+       m_type = Type_A;
+       m_func
+         = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName + _T("A")).c_str());
+       if (!m_func)
+       {
+         m_func = GetProcAddress(m_dll, to_string(_T("mayu") + i_funcName).c_str());
+         if (!m_func)
+         {
+           m_func = GetProcAddress(m_dll, to_string(i_funcName).c_str());
+           if (!m_func)
+           {
+             Acquire a(&i_log);
+             i_log << std::endl;
+             i_log << _T("error: &PlugIn() failed to find function: ")
+                   << i_funcName << std::endl;
+             return false;
+           }
+         }
+       }
+      }
+      
+      m_funcParam = i_funcParam;
+      return true;
+    }
+
+    void exec()
+    {
+      ASSERT( m_dll );
+      ASSERT( m_func );
+      
+      typedef void (WINAPI * PLUGIN_FUNCTION_A)(const char *i_arg);
+      typedef void (WINAPI * PLUGIN_FUNCTION_W)(const wchar_t *i_arg);
+      switch (m_type)
+      {
+       case Type_A:
+         reinterpret_cast<PLUGIN_FUNCTION_A>(m_func)(to_string(m_funcParam).c_str());
+         break;
+       case Type_W:
+         reinterpret_cast<PLUGIN_FUNCTION_W>(m_func)(to_wstring(m_funcParam).c_str());
+         break;
+      }
+    }
+#undef to_string
+#undef to_wstring
+  };
+
+  static void plugInThread(void *i_plugin)
+  {
+    PlugIn *plugin = static_cast<PlugIn *>(i_plugin);
+    plugin->exec();
+    delete plugin;
+  }
+}
+
+void Engine::funcPlugIn(FunctionParam *i_param,
+                       const StrExprArg &i_dllName,
+                       const StrExprArg &i_funcName,
+                       const StrExprArg &i_funcParam,
+                       BooleanType i_doesCreateThread)
+{
+  if (!i_param->m_isPressed)
+    return;
+
+  shu::PlugIn *plugin = new shu::PlugIn();
+  if (!plugin->load(i_dllName.eval(), i_funcName.eval(), i_funcParam.eval(), m_log))
+  {
+    delete plugin;
+    return;
+  }
+  if (i_doesCreateThread)
+  {
+    if (_beginthread(shu::plugInThread, 0, plugin) == -1)
+    {
+      delete plugin;
+      Acquire a(&m_log);
+      m_log << std::endl;
+      m_log << _T("error: &PlugIn() failed to create thread.");
+    }
+    return;
+  }
+  else
+    plugin->exec();
+}
+
+
+void Engine::funcMouseHook(FunctionParam *i_param,
+                          MouseHookType i_hookType, int i_hookParam)
+{
+  GetCursorPos(&g_hookData->m_mousePos);
+  g_hookData->m_mouseHookType = i_hookType;
+  g_hookData->m_mouseHookParam = i_hookParam;
+
+  switch (i_hookType)
+  {
+    case MouseHookType_WindowMove:
+    {
+      // For this type, g_hookData->m_mouseHookParam means
+      // target window type to move.
+      HWND target;
+      bool isMDI;
+
+      // i_hooParam < 0 means target window to move is MDI.
+      if (i_hookParam < 0)
+       isMDI = true;
+      else
+       isMDI = false;
+
+      // abs(i_hookParam) == 2: target is window under mouse cursor
+      // otherwise: target is current focus window
+      if (i_hookParam == 2 || i_hookParam == -2)
+       target = WindowFromPoint(g_hookData->m_mousePos);
+      else
+       target = i_param->m_hwnd;
+
+      g_hookData->m_hwndMouseHookTarget =
+       getToplevelWindow(target, &isMDI);
+      break;
+    default:
+      g_hookData->m_hwndMouseHookTarget = NULL;
+      break;
+    }
+  }
+  return;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// StrExpr
+class StrExpr
+{
+private:
+  tstringq m_symbol;
+protected:
+  static const Engine *s_engine;
+public:
+  StrExpr(const tstringq &i_symbol) : m_symbol(i_symbol) {};
+
+  virtual ~StrExpr() {};
+
+  virtual StrExpr *clone() const
+  {
+    return new StrExpr(*this);
+  }
+
+  virtual tstringq eval() const
+  {
+    return m_symbol;
+  }
+
+  static void setEngine(const Engine *i_engine) { s_engine = i_engine; }
+};
+
+const Engine *StrExpr::s_engine = NULL;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// StrExprClipboard
+class StrExprClipboard : public StrExpr
+{
+public:
+  StrExprClipboard(const tstringq &i_symbol) : StrExpr(i_symbol) {};
+
+  ~StrExprClipboard() {};
+
+  StrExpr *clone() const
+  {
+    return new StrExprClipboard(*this);
+  }
+
+  tstringq eval() const
+  {
+    HGLOBAL g;
+    const _TCHAR *text = getTextFromClipboard(&g);
+    const tstring value(text == NULL ? _T("") : text);
+    closeClipboard(g);
+    return value;
+  }
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// StrExprWindowClassName
+class StrExprWindowClassName : public StrExpr
+{
+public:
+  StrExprWindowClassName(const tstringq &i_symbol) : StrExpr(i_symbol) {};
+
+  ~StrExprWindowClassName() {};
+
+  StrExpr *clone() const
+  {
+    return new StrExprWindowClassName(*this);
+  }
+
+  tstringq eval() const
+  {
+    return s_engine->getCurrentWindowClassName();
+  }
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// StrExprWindowTitleName
+class StrExprWindowTitleName : public StrExpr
+{
+public:
+  StrExprWindowTitleName(const tstringq &i_symbol) : StrExpr(i_symbol) {};
+
+  ~StrExprWindowTitleName() {};
+
+  StrExpr *clone() const
+  {
+    return new StrExprWindowTitleName(*this);
+  }
+
+  tstringq eval() const
+  {
+    return s_engine->getCurrentWindowTitleName();
+  }
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// StrExprArg
+
+
+// default constructor
+StrExprArg::StrExprArg()
+{
+  m_expr = new StrExpr(_T(""));
+}
+
+
+// copy contructor
+StrExprArg::StrExprArg(const StrExprArg &i_data)
+{
+  m_expr = i_data.m_expr->clone();
+}
+
+
+StrExprArg &StrExprArg::operator=(const StrExprArg &i_data)
+{
+  if (i_data.m_expr == m_expr)
+    return *this;
+
+  delete m_expr;
+  m_expr = i_data.m_expr->clone();
+
+  return *this;
+}
+
+
+// initializer
+StrExprArg::StrExprArg(const tstringq &i_symbol, Type i_type)
+{
+  switch (i_type)
+  {
+    case Literal:
+      m_expr = new StrExpr(i_symbol);
+      break;
+    case Builtin:
+      if (i_symbol == _T("Clipboard"))
+       m_expr = new StrExprClipboard(i_symbol);
+      else if (i_symbol == _T("WindowClassName"))
+       m_expr = new StrExprWindowClassName(i_symbol);
+      else if (i_symbol == _T("WindowTitleName"))
+       m_expr = new StrExprWindowTitleName(i_symbol);
+      break;
+    default:
+      break;
+  }
+}
+
+
+StrExprArg::~StrExprArg()
+{
+  delete m_expr;
+}
+
+
+tstringq StrExprArg::eval() const
+{
+  return m_expr->eval();
+}
+
+void StrExprArg::setEngine(const Engine *i_engine)
+{
+  StrExpr::setEngine(i_engine);
+}
+
+// stream output
+tostream &operator<<(tostream &i_ost, const StrExprArg &i_data)
+{
+  i_ost << i_data.eval();
+  return i_ost;
+}
diff --git a/function.h b/function.h
new file mode 100644 (file)
index 0000000..3fd7d7a
--- /dev/null
@@ -0,0 +1,264 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// keymap.h\r
+\r
+\r
+#ifndef _FUNCTION_H\r
+#  define _FUNCTION_H\r
+\r
+\r
+class SettingLoader;\r
+class Engine;\r
+class FunctionParam;\r
+\r
+///\r
+class FunctionData\r
+{\r
+public:\r
+  /// virtual destructor\r
+  virtual ~FunctionData() = 0;\r
+  ///\r
+  virtual void load(SettingLoader *i_sl) = 0;\r
+  ///\r
+  virtual void exec(Engine *i_engine, FunctionParam *i_param) const = 0;\r
+  ///\r
+  virtual const _TCHAR *getName() const = 0;\r
+  ///\r
+  virtual tostream &output(tostream &i_ost) const = 0;\r
+  ///\r
+  virtual FunctionData *clone() const = 0;\r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, const FunctionData *i_data);\r
+\r
+\r
+// create function\r
+extern FunctionData *createFunctionData(const tstring &i_name);\r
+\r
+///\r
+enum VKey\r
+{\r
+  VKey_extended = 0x100,                       ///\r
+  VKey_released = 0x200,                       ///\r
+  VKey_pressed  = 0x400,                       ///\r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, VKey i_data);\r
+\r
+\r
+///\r
+enum ToWindowType\r
+{\r
+  ToWindowType_toBegin            = -2,                ///\r
+  ToWindowType_toMainWindow       = -2,                ///\r
+  ToWindowType_toOverlappedWindow = -1,                ///\r
+  ToWindowType_toItself           = 0,         ///\r
+  ToWindowType_toParentWindow     = 1,         ///\r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, ToWindowType i_data);\r
+\r
+// get value of ToWindowType\r
+extern bool getTypeValue(ToWindowType *o_type, const tstring &i_name);\r
+\r
+\r
+///\r
+enum GravityType\r
+{\r
+  GravityType_C = 0,                           /// center\r
+  GravityType_N = 1 << 0,                      /// north\r
+  GravityType_E = 1 << 1,                      /// east\r
+  GravityType_W = 1 << 2,                      /// west\r
+  GravityType_S = 1 << 3,                      /// south\r
+  GravityType_NW = GravityType_N | GravityType_W, /// north west\r
+  GravityType_NE = GravityType_N | GravityType_E, /// north east\r
+  GravityType_SW = GravityType_S | GravityType_W, /// south west\r
+  GravityType_SE = GravityType_S | GravityType_E, /// south east\r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, GravityType i_data);\r
+\r
+/// get value of GravityType\r
+extern bool getTypeValue(GravityType *o_type, const tstring &i_name);\r
+\r
+\r
+/// enum MouseHookType is defined in hook.h\r
+extern enum MouseHookType;\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, MouseHookType i_data);\r
+\r
+/// get value of MouseHookType\r
+extern bool getTypeValue(MouseHookType *o_type, const tstring &i_name);\r
+\r
+\r
+///\r
+enum MayuDialogType\r
+{\r
+  MayuDialogType_investigate = 0x10000,                /// \r
+  MayuDialogType_log         = 0x20000,                /// \r
+  MayuDialogType_mask        = 0xffff0000,     /// \r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, MayuDialogType i_data);\r
+\r
+// get value of MayuDialogType\r
+bool getTypeValue(MayuDialogType *o_type, const tstring &i_name);\r
+\r
+  \r
+///\r
+enum ModifierLockType\r
+{\r
+  ModifierLockType_Lock0 = Modifier::Type_Lock0, /// \r
+  ModifierLockType_Lock1 = Modifier::Type_Lock1, /// \r
+  ModifierLockType_Lock2 = Modifier::Type_Lock2, /// \r
+  ModifierLockType_Lock3 = Modifier::Type_Lock3, /// \r
+  ModifierLockType_Lock4 = Modifier::Type_Lock4, /// \r
+  ModifierLockType_Lock5 = Modifier::Type_Lock5, /// \r
+  ModifierLockType_Lock6 = Modifier::Type_Lock6, /// \r
+  ModifierLockType_Lock7 = Modifier::Type_Lock7, /// \r
+  ModifierLockType_Lock8 = Modifier::Type_Lock8, /// \r
+  ModifierLockType_Lock9 = Modifier::Type_Lock9, /// \r
+};\r
+\r
+///\r
+enum ToggleType\r
+{\r
+  ToggleType_toggle    = -1, /// \r
+  ToggleType_off       = 0, /// \r
+  ToggleType_on                = 1, /// \r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, ToggleType i_data);\r
+  \r
+// get value of ShowCommandType\r
+extern bool getTypeValue(ToggleType *o_type, const tstring &i_name);\r
+\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, ModifierLockType i_data);\r
+\r
+// get value of ModifierLockType\r
+extern bool getTypeValue(ModifierLockType *o_type, const tstring &i_name);\r
+\r
+\r
+///\r
+enum ShowCommandType\r
+{\r
+  ShowCommandType_hide                 = SW_HIDE, /// \r
+  ShowCommandType_maximize             = SW_MAXIMIZE, /// \r
+  ShowCommandType_minimize             = SW_MINIMIZE, /// \r
+  ShowCommandType_restore              = SW_RESTORE, /// \r
+  ShowCommandType_show                 = SW_SHOW, /// \r
+  ShowCommandType_showDefault          = SW_SHOWDEFAULT, /// \r
+  ShowCommandType_showMaximized                = SW_SHOWMAXIMIZED, /// \r
+  ShowCommandType_showMinimized                = SW_SHOWMINIMIZED, /// \r
+  ShowCommandType_showMinNoActive      = SW_SHOWMINNOACTIVE, /// \r
+  ShowCommandType_showNA               = SW_SHOWNA, /// \r
+  ShowCommandType_showNoActivate       = SW_SHOWNOACTIVATE, /// \r
+  ShowCommandType_showNormal           = SW_SHOWNORMAL, /// \r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, ShowCommandType i_data);\r
+  \r
+// get value of ShowCommandType\r
+extern bool getTypeValue(ShowCommandType *o_type, const tstring &i_name);\r
+\r
+\r
+///\r
+enum TargetWindowType\r
+{\r
+  TargetWindowType_overlapped  = 0, /// \r
+  TargetWindowType_mdi         = 1, /// \r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, TargetWindowType i_data);\r
+  \r
+// get value of ShowCommandType\r
+extern bool getTypeValue(TargetWindowType *o_type, const tstring &i_name);\r
+\r
+\r
+///\r
+enum BooleanType\r
+{\r
+  BooleanType_false    = 0, /// \r
+  BooleanType_true     = 1, /// \r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, BooleanType i_data);\r
+  \r
+// get value of ShowCommandType\r
+extern bool getTypeValue(BooleanType *o_type, const tstring &i_name);\r
+\r
+\r
+///\r
+enum LogicalOperatorType\r
+{\r
+  LogicalOperatorType_or       = 0, /// \r
+  LogicalOperatorType_and      = 1, /// \r
+};\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost, LogicalOperatorType i_data);\r
+  \r
+// get value of LogicalOperatorType\r
+extern bool getTypeValue(LogicalOperatorType *o_type, const tstring &i_name);\r
+\r
+\r
+///\r
+enum WindowMonitorFromType\r
+{\r
+  WindowMonitorFromType_primary = 0, ///\r
+  WindowMonitorFromType_current = 1, ///\r
+};\r
+\r
+// stream output\r
+extern tostream &operator<<(tostream &i_ost, WindowMonitorFromType i_data);\r
+\r
+// get value of WindowMonitorFromType\r
+extern bool getTypeValue(WindowMonitorFromType *o_type, const tstring &i_name);\r
+\r
+\r
+/// stream output\r
+extern tostream &operator<<(tostream &i_ost,\r
+                           const std::list<tstringq> &i_data);\r
+\r
+\r
+/// string type expression\r
+class StrExpr;\r
+\r
+\r
+/// string type expression for function arguments\r
+class StrExprArg\r
+{\r
+private:\r
+  StrExpr *m_expr;\r
+public:\r
+  enum Type\r
+  {\r
+    Literal,\r
+    Builtin,\r
+  };\r
+  StrExprArg();\r
+  StrExprArg(const StrExprArg &i_data);\r
+  StrExprArg(const tstringq &i_symbol, Type i_type);\r
+  ~StrExprArg();\r
+  StrExprArg &operator=(const StrExprArg &i_data);\r
+  tstringq eval() const;\r
+  static void setEngine(const Engine *i_engine);\r
+};\r
+\r
+\r
+/// stream output\r
+tostream &operator<<(tostream &i_ost, const StrExprArg &i_data);\r
+\r
+\r
+#endif // !_FUNCTION_H\r
diff --git a/hook.cpp b/hook.cpp
new file mode 100644 (file)
index 0000000..6bda39d
--- /dev/null
+++ b/hook.cpp
@@ -0,0 +1,715 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// hook.cpp
+
+
+#define _HOOK_CPP
+
+#include "misc.h"
+
+#include "hook.h"
+#include "stringtool.h"
+
+#include <locale.h>
+#include <imm.h>
+#include <richedit.h>
+
+
+///
+#define HOOK_DATA_NAME _T("{08D6E55C-5103-4e00-8209-A1C4AB13BBEF}") _T(VERSION)
+
+// Some applications use different values for below messages
+// when double click of title bar.
+#define SC_MAXIMIZE2 (SC_MAXIMIZE + 2)
+#define SC_MINIMIZE2 (SC_MINIMIZE + 2)
+#define SC_RESTORE2 (SC_RESTORE + 2)
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Global Variables
+
+
+DllExport HookData *g_hookData;                        ///
+
+struct Globals
+{
+  HANDLE m_hHookData;                          ///
+  HWND m_hwndFocus;                            /// 
+  HINSTANCE m_hInstDLL;                                ///
+  bool m_isInMenu;                             ///
+  UINT m_WM_MAYU_MESSAGE;                      ///
+  bool m_isImeLock;                            ///
+  bool m_isImeCompositioning;                  ///
+};
+
+static Globals g;
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Prototypes
+
+
+static void notifyThreadDetach();
+static void notifyShow(NotifyShow::Show i_show, bool i_isMDI);
+static void notifyLog(_TCHAR *i_msg);
+static bool mapHookData();
+static void unmapHookData();
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Functions
+
+
+/// EntryPoint
+BOOL WINAPI DllMain(HINSTANCE i_hInstDLL, DWORD i_fdwReason,
+                   LPVOID /* i_lpvReserved */)
+{
+  switch (i_fdwReason)
+  {
+    case DLL_PROCESS_ATTACH:
+    {
+      if (!mapHookData())
+       return FALSE;
+      g.m_hInstDLL = i_hInstDLL;
+      _tsetlocale(LC_ALL, _T(""));
+      g.m_WM_MAYU_MESSAGE = RegisterWindowMessage(
+       addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
+      break;
+    }
+    case DLL_THREAD_ATTACH:
+      break;
+    case DLL_PROCESS_DETACH:
+      notifyThreadDetach();
+      unmapHookData();
+      break;
+    case DLL_THREAD_DETACH:
+      notifyThreadDetach();
+      break;
+    default:
+      break;
+  }
+  return TRUE;
+}
+
+
+/// map hook data
+static bool mapHookData()
+{
+  g.m_hHookData = CreateFileMapping((HANDLE)0xffffffff, NULL, PAGE_READWRITE,
+                                   0, sizeof(HookData),
+                                   addSessionId(HOOK_DATA_NAME).c_str());
+  if (!g.m_hHookData)
+    return false;
+  
+  g_hookData =
+    (HookData *)MapViewOfFile(g.m_hHookData, FILE_MAP_READ | FILE_MAP_WRITE,
+                             0, 0, sizeof(HookData));
+  if (!g_hookData)
+  {
+    unmapHookData();
+    return false;
+  }
+  return true;
+}
+
+
+/// unmap hook data
+static void unmapHookData()
+{
+  if (g_hookData)
+    if (!UnmapViewOfFile(g_hookData))
+      return;
+  g_hookData = NULL;
+  if (g.m_hHookData)
+    CloseHandle(g.m_hHookData);
+  g.m_hHookData = NULL;
+}
+
+
+/// notify
+DllExport bool notify(void *i_data, size_t i_dataSize)
+{
+  COPYDATASTRUCT cd;
+  DWORD result;
+
+  cd.dwData = reinterpret_cast<Notify *>(i_data)->m_type;
+  cd.cbData = i_dataSize;
+  cd.lpData = i_data;
+  if (g_hookData->m_hwndTaskTray == NULL)
+    return false;
+  if (!SendMessageTimeout(g_hookData->m_hwndTaskTray, WM_COPYDATA,
+                         NULL, reinterpret_cast<LPARAM>(&cd),
+                         SMTO_ABORTIFHUNG | SMTO_NORMAL, 5000, &result))
+    return false;
+  return true;
+}
+
+
+/// get class name and title name
+static void getClassNameTitleName(HWND i_hwnd, bool i_isInMenu, 
+                                 tstringi *o_className,
+                                 tstring *o_titleName)
+{
+  tstringi &className = *o_className;
+  tstring &titleName = *o_titleName;
+  
+  bool isTheFirstTime = true;
+  
+  if (i_isInMenu)
+  {
+    className = titleName = _T("MENU");
+    isTheFirstTime = false;
+  }
+
+  while (true)
+  {
+    _TCHAR buf[MAX(GANA_MAX_PATH, GANA_MAX_ATOM_LENGTH)];
+
+    // get class name
+    if (i_hwnd)
+      GetClassName(i_hwnd, buf, NUMBER_OF(buf));
+    else
+      GetModuleFileName(GetModuleHandle(NULL), buf, NUMBER_OF(buf));
+    buf[NUMBER_OF(buf) - 1] = _T('\0');
+    if (isTheFirstTime)
+      className = buf;
+    else
+      className = tstringi(buf) + _T(":") + className;
+    
+    // get title name
+    if (i_hwnd)
+    {
+      GetWindowText(i_hwnd, buf, NUMBER_OF(buf));
+      buf[NUMBER_OF(buf) - 1] = _T('\0');
+      for (_TCHAR *b = buf; *b; ++ b)
+       if (_istlead(*b) && b[1])
+         b ++;
+       else if (_istcntrl(*b))
+         *b = _T('?');
+    }
+    if (isTheFirstTime)
+      titleName = buf;
+    else
+      titleName = tstring(buf) + _T(":") + titleName;
+
+    // next loop or exit
+    if (!i_hwnd)
+      break;
+    i_hwnd = GetParent(i_hwnd);
+    isTheFirstTime = false;
+  }
+}
+
+
+/// update show
+static void updateShow(HWND i_hwnd, NotifyShow::Show i_show)
+{
+  bool isMDI = false;
+
+  if (!i_hwnd)
+    return;
+
+  LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+  if (!(style & WS_MAXIMIZEBOX) && !(style & WS_MAXIMIZEBOX))
+    return; // ignore window that has neither maximize or minimize button
+
+  if (style & WS_CHILD)
+  {
+    LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
+    if (exStyle & WS_EX_MDICHILD)
+    {
+      isMDI = true;
+    }
+    else
+      return; // ignore non-MDI child window case
+  }
+
+  notifyShow(i_show, isMDI);
+}
+
+
+/// notify WM_Targetted
+static void notifyName(HWND i_hwnd, Notify::Type i_type = Notify::Type_name)
+{
+  tstringi className;
+  tstring titleName;
+  getClassNameTitleName(i_hwnd, g.m_isInMenu, &className, &titleName);
+  
+  NotifySetFocus *nfc = new NotifySetFocus;
+  nfc->m_type = i_type;
+  nfc->m_threadId = GetCurrentThreadId();
+  nfc->m_hwnd = i_hwnd;
+  tcslcpy(nfc->m_className, className.c_str(), NUMBER_OF(nfc->m_className));
+  tcslcpy(nfc->m_titleName, titleName.c_str(), NUMBER_OF(nfc->m_titleName));
+
+  notify(nfc, sizeof(*nfc));
+  delete nfc;
+}
+
+
+/// notify WM_SETFOCUS
+static void notifySetFocus(bool i_doesForce = false)
+{
+  HWND hwnd = GetFocus();
+  if (i_doesForce || hwnd != g.m_hwndFocus)
+  {
+    g.m_hwndFocus = hwnd;
+    notifyName(hwnd, Notify::Type_setFocus);
+  }
+}
+
+
+/// notify sync
+static void notifySync()
+{
+  Notify n;
+  n.m_type = Notify::Type_sync;
+  notify(&n, sizeof(n));
+}
+
+
+/// notify DLL_THREAD_DETACH
+static void notifyThreadDetach()
+{
+  NotifyThreadDetach ntd;
+  ntd.m_type = Notify::Type_threadDetach;
+  ntd.m_threadId = GetCurrentThreadId();
+  notify(&ntd, sizeof(ntd));
+}
+
+
+/// notify WM_COMMAND, WM_SYSCOMMAND
+static void notifyCommand(
+  HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
+{
+  if (g_hookData->m_doesNotifyCommand)
+  {
+    NotifyCommand ntc;
+    ntc.m_type = Notify::Type_command;
+    ntc.m_hwnd = i_hwnd;
+    ntc.m_message = i_message;
+    ntc.m_wParam = i_wParam;
+    ntc.m_lParam = i_lParam;
+    notify(&ntc, sizeof(ntc));
+  }
+}
+
+
+/// notify show of current window
+static void notifyShow(NotifyShow::Show i_show, bool i_isMDI)
+{
+  NotifyShow ns;
+  ns.m_type = Notify::Type_show;
+  ns.m_show = i_show;
+  ns.m_isMDI = i_isMDI;
+  notify(&ns, sizeof(ns));
+}
+
+
+/// notify log
+static void notifyLog(_TCHAR *i_msg)
+{
+  NotifyLog nl;
+  nl.m_type = Notify::Type_log;
+  tcslcpy(nl.m_msg, i_msg, NUMBER_OF(nl.m_msg));
+  notify(&nl, sizeof(nl));
+}
+
+
+/// &Recenter
+static void funcRecenter(HWND i_hwnd)
+{
+  _TCHAR buf[MAX(GANA_MAX_PATH, GANA_MAX_ATOM_LENGTH)];
+  GetClassName(i_hwnd, buf, NUMBER_OF(buf));
+  bool isEdit;
+  if (_tcsicmp(buf, _T("Edit")) == 0)
+    isEdit = true;
+  else if (_tcsnicmp(buf, _T("RichEdit"), 8) == 0)
+    isEdit = false;
+  else
+    return;    // this function only works for Edit control
+
+  LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+  if (!(style & ES_MULTILINE))
+    return;    // this function only works for multi line Edit control
+
+  RECT rc;
+  GetClientRect(i_hwnd, &rc);
+  POINTL p = { (rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2 };
+  int line;
+  if (isEdit)
+  {
+    line = SendMessage(i_hwnd, EM_CHARFROMPOS, 0, MAKELPARAM(p.x, p.y));
+    line = HIWORD(line);
+  }
+  else
+  {
+    int ci = SendMessage(i_hwnd, EM_CHARFROMPOS, 0, (LPARAM)&p);
+    line = SendMessage(i_hwnd, EM_EXLINEFROMCHAR, 0, ci);
+  }
+  int caretLine = SendMessage(i_hwnd, EM_LINEFROMCHAR, -1, 0);
+  SendMessage(i_hwnd, EM_LINESCROLL, 0, caretLine - line);
+}
+
+
+// &SetImeStatus
+static void funcSetImeStatus(HWND i_hwnd, int i_status)
+{
+  HIMC hIMC;
+
+  hIMC = ImmGetContext(i_hwnd);
+  if (hIMC == INVALID_HANDLE_VALUE)
+    return;
+
+  if (i_status < 0)
+    i_status = !ImmGetOpenStatus(hIMC);
+
+  ImmSetOpenStatus(hIMC, i_status);
+  ImmReleaseContext(i_hwnd, hIMC);
+}
+
+
+// &SetImeString
+static void funcSetImeString(HWND i_hwnd, int i_size)
+{
+#if defined(_WINNT)
+  _TCHAR *buf = new _TCHAR(i_size);
+  DWORD len = 0;
+  _TCHAR ImeDesc[GANA_MAX_ATOM_LENGTH];
+  UINT ImeDescLen;
+  DWORD error;
+  DWORD denom = 1;
+  HANDLE hPipe
+    = CreateFile(addSessionId(HOOK_PIPE_NAME).c_str(), GENERIC_READ,
+                FILE_SHARE_READ, (SECURITY_ATTRIBUTES *)NULL,
+                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
+  error = ReadFile(hPipe, buf, i_size, &len, NULL);
+  CloseHandle(hPipe);
+
+  ImeDescLen = ImmGetDescription(GetKeyboardLayout(0),
+                                ImeDesc, sizeof(ImeDesc));
+  if (_tcsncmp(ImeDesc, _T("SKKIME"), ImeDescLen) > 0)
+    denom = sizeof(_TCHAR);
+
+  HIMC hIMC = ImmGetContext(i_hwnd);
+  if (hIMC == INVALID_HANDLE_VALUE)
+    return;
+
+  int status = ImmGetOpenStatus(hIMC);
+  ImmSetCompositionString(hIMC, SCS_SETSTR, buf, len / denom, NULL, 0);
+  delete buf;
+  ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+  if (!status)
+    ImmSetOpenStatus(hIMC, status);
+  ImmReleaseContext(i_hwnd, hIMC);
+#endif // _WINNT
+}
+
+/// notify lock state
+/*DllExport*/ void notifyLockState(int i_cause)
+{
+  NotifyLockState n;
+  n.m_type = Notify::Type_lockState;
+  n.m_isNumLockToggled = !!(GetKeyState(VK_NUMLOCK) & 1);
+  n.m_isCapsLockToggled = !!(GetKeyState(VK_CAPITAL) & 1);
+  n.m_isScrollLockToggled = !!(GetKeyState(VK_SCROLL) & 1);
+  n.m_isKanaLockToggled = !!(GetKeyState(VK_KANA) & 1);
+  n.m_isImeLockToggled = g.m_isImeLock;
+  n.m_isImeCompToggled = g.m_isImeCompositioning;
+  n.m_debugParam = i_cause;
+  notify(&n, sizeof(n));
+}
+
+DllExport void notifyLockState()
+{
+  notifyLockState(9);
+}
+
+
+/// hook of GetMessage
+LRESULT CALLBACK getMessageProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
+{
+  if (!g_hookData)
+    return 0;
+  
+  MSG &msg = (*(MSG *)i_lParam);
+
+  switch (msg.message)
+  {
+    case WM_COMMAND:
+    case WM_SYSCOMMAND:
+      notifyCommand(msg.hwnd, msg.message, msg.wParam, msg.lParam);
+      break;
+    case WM_KEYDOWN:
+    case WM_KEYUP:
+    case WM_SYSKEYDOWN:
+    case WM_SYSKEYUP:
+    {
+      if (HIMC hIMC = ImmGetContext(msg.hwnd))
+      {
+       bool prev = g.m_isImeLock;
+       g.m_isImeLock = !!ImmGetOpenStatus(hIMC);
+       ImmReleaseContext(msg.hwnd, hIMC);
+       if (prev != g.m_isImeLock) {
+         notifyLockState(1);
+       }
+      }
+      int nVirtKey = (int)msg.wParam;
+      // int repeatCount = (msg.lParam & 0xffff);
+      BYTE scanCode   = (BYTE)((msg.lParam >> 16) & 0xff);
+      bool isExtended = !!(msg.lParam & (1 << 24));
+      // bool isAltDown  = !!(msg.lParam & (1 << 29));
+      // bool isKeyup    = !!(msg.lParam & (1 << 31));
+      
+      if (nVirtKey == VK_CAPITAL ||
+         nVirtKey == VK_NUMLOCK ||
+         nVirtKey == VK_KANA ||
+         nVirtKey == VK_SCROLL)
+       notifyLockState(2);
+      else if (scanCode == g_hookData->m_syncKey &&
+              isExtended == g_hookData->m_syncKeyIsExtended)
+       notifySync();
+      break;
+    }
+    case WM_IME_STARTCOMPOSITION:
+      g.m_isImeCompositioning = true;
+      notifyLockState(3);
+      break;
+    case WM_IME_ENDCOMPOSITION:
+      g.m_isImeCompositioning = false;
+      notifyLockState(4);
+      break;
+    default:
+      if (i_wParam == PM_REMOVE && msg.message == g.m_WM_MAYU_MESSAGE)
+      {
+       switch (msg.wParam)
+       {
+         case MayuMessage_notifyName:
+           notifyName(msg.hwnd);
+           break;
+         case MayuMessage_funcRecenter:
+           funcRecenter(msg.hwnd);
+           break;
+         case MayuMessage_funcSetImeStatus:
+           funcSetImeStatus(msg.hwnd, msg.lParam);
+           break;
+         case MayuMessage_funcSetImeString:
+           funcSetImeString(msg.hwnd, msg.lParam);
+           break;
+       }
+      }
+      break;
+  }
+  return CallNextHookEx(g_hookData->m_hHookGetMessage,
+                       i_nCode, i_wParam, i_lParam);
+}
+
+
+/// hook of SendMessage
+LRESULT CALLBACK callWndProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
+{
+  if (!g_hookData)
+    return 0;
+  
+  CWPSTRUCT &cwps = *(CWPSTRUCT *)i_lParam;
+  
+  if (0 <= i_nCode)
+  {
+    switch (cwps.message)
+    {
+      case WM_ACTIVATEAPP:
+      case WM_NCACTIVATE:
+       if (i_wParam)
+         notifySetFocus();
+       break;
+      case WM_SYSCOMMAND:
+       switch (cwps.wParam)
+       {
+         case SC_MAXIMIZE:
+         case SC_MAXIMIZE2:
+           updateShow(cwps.hwnd, NotifyShow::Show_Maximized);
+           break;
+         case SC_MINIMIZE:
+         case SC_MINIMIZE2:
+           updateShow(cwps.hwnd, NotifyShow::Show_Minimized);
+           break;
+         case SC_RESTORE:
+         case SC_RESTORE2:
+           updateShow(cwps.hwnd, NotifyShow::Show_Normal);
+           break;
+         default:
+           break;
+       }
+       /* through below */
+      case WM_COMMAND:
+       notifyCommand(cwps.hwnd, cwps.message, cwps.wParam, cwps.lParam);
+       break;
+      case WM_SIZE:
+       switch (cwps.wParam)
+       {
+         case SIZE_MAXIMIZED:
+           updateShow(cwps.hwnd, NotifyShow::Show_Maximized);
+           break;
+         case SIZE_MINIMIZED:
+           updateShow(cwps.hwnd, NotifyShow::Show_Minimized);
+           break;
+         case SIZE_RESTORED:
+           updateShow(cwps.hwnd, NotifyShow::Show_Normal);
+           break;
+         default:
+           break;
+       }
+       break;
+      case WM_MOUSEACTIVATE:
+       notifySetFocus();
+       break;
+      case WM_ACTIVATE:
+       if (LOWORD(cwps.wParam) != WA_INACTIVE)
+       {
+         notifySetFocus();
+         if (HIWORD(cwps.wParam)) // check minimized flag
+         {
+           // minimized flag on
+           notifyShow(NotifyShow::Show_Minimized, false);
+           //notifyShow(NotifyShow::Show_Normal, true);
+         }
+       }
+       break;
+      case WM_ENTERMENULOOP:
+       g.m_isInMenu = true;
+       notifySetFocus(true);
+       break;
+      case WM_EXITMENULOOP:
+       g.m_isInMenu = false;
+       notifySetFocus(true);
+       break;
+      case WM_SETFOCUS:
+       g.m_isInMenu = false;
+       // for kana
+       if (g_hookData->m_correctKanaLockHandling) {
+         if (HIMC hIMC = ImmGetContext(cwps.hwnd)) {
+           bool status = !!ImmGetOpenStatus(hIMC);
+           // this code set the VK_KANA state correctly.
+           ImmSetOpenStatus(hIMC, !status);
+           ImmSetOpenStatus(hIMC, status);
+           ImmReleaseContext(cwps.hwnd, hIMC);
+         }
+       }
+       notifySetFocus();
+       notifyLockState(5);
+       break;
+      case WM_IME_STARTCOMPOSITION:
+       g.m_isImeCompositioning = true;
+       notifyLockState(6);
+       break;
+      case WM_IME_ENDCOMPOSITION:
+       g.m_isImeCompositioning = false;
+       notifyLockState(7);
+       break;
+      case WM_IME_NOTIFY:
+       if (cwps.wParam == IMN_SETOPENSTATUS)
+         if (HIMC hIMC = ImmGetContext(cwps.hwnd))
+         {
+           g.m_isImeLock = !!ImmGetOpenStatus(hIMC);
+           ImmReleaseContext(cwps.hwnd, hIMC);
+           notifyLockState(8);
+         }
+       break;
+    }
+  }
+  return CallNextHookEx(g_hookData->m_hHookCallWndProc, i_nCode,
+                       i_wParam, i_lParam);
+}
+
+
+static LRESULT CALLBACK lowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+  MSLLHOOKSTRUCT *pMsll = (MSLLHOOKSTRUCT*)lParam;
+  LONG dx = pMsll->pt.x - g_hookData->m_mousePos.x;
+  LONG dy = pMsll->pt.y - g_hookData->m_mousePos.y;
+  HWND target = g_hookData->m_hwndMouseHookTarget;
+
+  if (!g_hookData || nCode < 0 || wParam != WM_MOUSEMOVE)
+    goto through;
+
+  switch (g_hookData->m_mouseHookType)
+  {
+    case MouseHookType_Wheel:
+      // For this type, g_hookData->m_mouseHookParam means
+      // translate rate mouse move to wheel.
+      mouse_event(MOUSEEVENTF_WHEEL, 0, 0,
+                 g_hookData->m_mouseHookParam * dy, 0);
+      return 1;
+      break;
+    case MouseHookType_WindowMove:
+    {
+      RECT curRect;
+
+      if (!GetWindowRect(target, &curRect))
+       goto through;
+
+      // g_hookData->m_mouseHookParam < 0 means
+      // target window to move is MDI.
+      if (g_hookData->m_mouseHookParam < 0)
+      {
+       HWND parent = GetParent(target);
+       POINT p = {curRect.left, curRect.top};
+
+       if (parent == NULL || !ScreenToClient(parent, &p))
+         goto through;
+
+       curRect.left = p.x;
+       curRect.top = p.y;
+      }
+       
+      SetWindowPos(target, NULL,
+                  curRect.left + dx,
+                  curRect.top + dy,
+                  0, 0,
+                  SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE |
+                  SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
+      g_hookData->m_mousePos = pMsll->pt;
+      goto through;
+      break;
+    }
+    case MouseHookType_None:
+    default:
+      goto through;
+      break;
+  }
+    
+ through:
+  return CallNextHookEx(g_hookData->m_hHookMouseProc,
+                       nCode, wParam, lParam);
+}
+
+
+/// install hooks
+DllExport int installHooks()
+{
+  g_hookData->m_hwndTaskTray = NULL;
+  g_hookData->m_hHookGetMessage =
+    SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)getMessageProc,
+                    g.m_hInstDLL, 0);
+  g_hookData->m_hHookCallWndProc =
+    SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)callWndProc, g.m_hInstDLL, 0);
+  g_hookData->m_mouseHookType = MouseHookType_None;
+  g_hookData->m_hHookMouseProc =
+    SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)lowLevelMouseProc,
+                    g.m_hInstDLL, 0);
+  return 0;
+}
+
+
+/// uninstall hooks
+DllExport int uninstallHooks()
+{
+  if (g_hookData->m_hHookGetMessage)
+    UnhookWindowsHookEx(g_hookData->m_hHookGetMessage);
+  g_hookData->m_hHookGetMessage = NULL;
+  if (g_hookData->m_hHookCallWndProc)
+    UnhookWindowsHookEx(g_hookData->m_hHookCallWndProc);
+  g_hookData->m_hHookCallWndProc = NULL;
+  if (g_hookData->m_hHookMouseProc)
+    UnhookWindowsHookEx(g_hookData->m_hHookMouseProc);
+  g_hookData->m_hHookMouseProc = NULL;
+  return 0;
+}
diff --git a/hook.h b/hook.h
new file mode 100644 (file)
index 0000000..984b66e
--- /dev/null
+++ b/hook.h
@@ -0,0 +1,156 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// hook.h
+
+
+#ifndef _HOOK_H
+#  define _HOOK_H
+
+#  include "misc.h"
+#  include <tchar.h>
+
+///
+#  define HOOK_PIPE_NAME \
+ _T("\\\\.\\pipe\\GANAware\\mayu\\{4B22D464-7A4E-494b-982A-C2B2BBAAF9F3}") _T(VERSION)
+///
+#  define WM_MAYU_MESSAGE_NAME _T("GANAware\\mayu\\WM_MAYU_MESSAGE")
+
+///
+enum MayuMessage
+{
+  MayuMessage_notifyName,
+  MayuMessage_funcRecenter,
+  MayuMessage_funcSetImeStatus,
+  MayuMessage_funcSetImeString,
+};
+
+
+///
+struct Notify
+{
+  ///
+  enum Type
+  {
+    Type_setFocus,                             /// NotifySetFocus
+    Type_name,                                 /// NotifySetFocus
+    Type_lockState,                            /// NotifyLockState
+    Type_sync,                                 /// Notify
+    Type_threadDetach,                         /// NotifyThreadDetach
+    Type_command,                              /// NotifyThreadDetach
+    Type_show,                                 /// NotifyShow
+    Type_log,                                  /// NotifyLog
+  };
+  Type m_type;                                 ///
+  DWORD m_debugParam;                          /// (for debug)
+};
+
+
+///
+struct NotifySetFocus : public Notify
+{
+  DWORD m_threadId;                            ///
+  HWND m_hwnd;                                 ///
+  _TCHAR m_className[GANA_MAX_PATH];           ///
+  _TCHAR m_titleName[GANA_MAX_PATH];           ///
+};
+
+
+///
+struct NotifyLockState : public Notify
+{
+  bool m_isNumLockToggled;                     ///
+  bool m_isCapsLockToggled;                    ///
+  bool m_isScrollLockToggled;                  ///
+  bool m_isKanaLockToggled;                    ///
+  bool m_isImeLockToggled;                     ///
+  bool m_isImeCompToggled;                     ///
+};
+
+
+///
+struct NotifyThreadDetach : public Notify
+{
+  DWORD m_threadId;                            ///
+};
+
+
+///
+struct NotifyCommand : public Notify
+{
+  HWND m_hwnd;                                 ///
+  UINT m_message;                              ///
+  WPARAM m_wParam;                             ///
+  LPARAM m_lParam;                             ///
+};
+
+
+enum
+{
+  NOTIFY_MESSAGE_SIZE = sizeof(NotifySetFocus),        ///
+};
+
+
+///
+struct NotifyShow : public Notify
+{
+  ///
+  enum Show
+  {
+    Show_Normal,
+    Show_Maximized,
+    Show_Minimized,
+  };
+  Show m_show;                                 ///
+  bool m_isMDI;                                        ///
+};
+
+
+///
+struct NotifyLog : public Notify
+{
+  _TCHAR m_msg[GANA_MAX_PATH];                 ///
+};
+
+
+///
+enum MouseHookType
+{
+  MouseHookType_None = 0,                              /// none
+  MouseHookType_Wheel = 1 << 0,                        /// wheel
+  MouseHookType_WindowMove = 1 << 1,           /// window move
+};
+
+///
+class HookData
+{
+public:
+  HHOOK m_hHookGetMessage;                     ///
+  HHOOK m_hHookCallWndProc;                    ///
+  HHOOK m_hHookMouseProc;                      ///
+  USHORT m_syncKey;                            ///
+  bool m_syncKeyIsExtended;                    ///
+  bool m_doesNotifyCommand;                    ///
+  HWND m_hwndTaskTray;                         ///
+  bool m_correctKanaLockHandling;              /// does use KL- ?
+  MouseHookType m_mouseHookType;               ///
+  int m_mouseHookParam;                        ///
+  HWND m_hwndMouseHookTarget;          ///
+  POINT m_mousePos;                            ///
+};
+
+
+///
+#  define DllExport __declspec(dllexport)
+///
+#  define DllImport __declspec(dllimport)
+
+
+#  ifndef _HOOK_CPP
+extern DllImport HookData *g_hookData;
+extern DllImport int installHooks();
+extern DllImport int uninstallHooks();
+extern DllImport bool notify(void *data, size_t sizeof_data);
+extern DllImport void notifyLockState();
+#  endif // !_HOOK_CPP
+
+
+#endif // !_HOOK_H
diff --git a/keyboard.cpp b/keyboard.cpp
new file mode 100644 (file)
index 0000000..931f5a7
--- /dev/null
@@ -0,0 +1,370 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// setting.cpp
+
+
+#include "keyboard.h"
+
+#include <algorithm>
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Key
+
+
+// add a name or an alias of key
+void Key::addName(const tstringi &i_name)
+{
+  m_names.push_back(i_name);
+}
+
+
+// add a scan code
+void Key::addScanCode(const ScanCode &i_sc)
+{
+  ASSERT(m_scanCodesSize < MAX_SCAN_CODES_SIZE);
+  m_scanCodes[m_scanCodesSize ++] = i_sc;
+}
+
+
+// initializer
+Key &Key::initialize()
+{
+  m_names.clear();
+  m_isPressed = false;
+  m_isPressedOnWin32 = false;
+  m_isPressedByAssign = false;
+  m_scanCodesSize = 0;
+  return *this;
+}
+
+
+// equation by name
+bool Key::operator==(const tstringi &i_name) const
+{
+  return std::find(m_names.begin(), m_names.end(), i_name) != m_names.end();
+}
+
+  
+// is the scan code of this key ?
+bool Key::isSameScanCode(const Key &i_key) const
+{
+  if (m_scanCodesSize != i_key.m_scanCodesSize)
+    return false;
+  return isPrefixScanCode(i_key);
+}
+
+
+// is the key's scan code the prefix of this key's scan code ?
+bool Key::isPrefixScanCode(const Key &i_key) const
+{
+  for (size_t i = 0; i < i_key.m_scanCodesSize; ++ i)
+    if (m_scanCodes[i] != i_key.m_scanCodes[i])
+      return false;
+  return true;
+}
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, const Key &i_mk)
+{
+  return i_ost << i_mk.getName();
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Modifier
+
+
+Modifier::Modifier()
+  : m_modifiers(0),
+    m_dontcares(0)
+{
+  ASSERT(Type_end <= (sizeof(MODIFIERS) * 8));
+  static const Type defaultDontCare[] =
+  {
+    Type_Up, Type_Down, Type_Repeat,
+    Type_ImeLock, Type_ImeComp, Type_NumLock, Type_CapsLock, Type_ScrollLock,
+       Type_KanaLock,
+    Type_Maximized, Type_Minimized, Type_MdiMaximized, Type_MdiMinimized,
+    Type_Touchpad, Type_TouchpadSticky,
+    Type_Lock0, Type_Lock1, Type_Lock2, Type_Lock3, Type_Lock4,
+    Type_Lock5, Type_Lock6, Type_Lock7, Type_Lock8, Type_Lock9,
+  };
+  for (size_t i = 0; i < NUMBER_OF(defaultDontCare); ++ i)
+    dontcare(defaultDontCare[i]);
+}
+
+
+// add m's modifiers where this dontcare
+void Modifier::add(const Modifier &i_m)
+{
+  for (int i = 0; i < Type_end; ++ i)
+  {
+    if (isDontcare(static_cast<Modifier::Type>(i)))
+      if (!i_m.isDontcare(static_cast<Modifier::Type>(i)))
+       if (i_m.isPressed(static_cast<Modifier::Type>(i)))
+         press(static_cast<Modifier::Type>(i));
+       else
+         release(static_cast<Modifier::Type>(i));
+  }
+}
+
+// stream output
+tostream &operator<<(tostream &i_ost, const Modifier &i_m)
+{
+  struct Mods
+  {
+    Modifier::Type m_mt;
+    const _TCHAR *m_symbol;
+  };
+  
+  const static Mods mods[] =
+  {
+    { Modifier::Type_Up, _T("U-") }, { Modifier::Type_Down, _T("D-") },
+    { Modifier::Type_Shift, _T("S-") }, { Modifier::Type_Alt, _T("A-") },
+    { Modifier::Type_Control, _T("C-") }, { Modifier::Type_Windows, _T("W-") },
+    { Modifier::Type_Repeat, _T("R-") },
+    { Modifier::Type_ImeLock, _T("IL-") },
+    { Modifier::Type_ImeComp, _T("IC-") },
+    { Modifier::Type_ImeComp, _T("I-") },
+    { Modifier::Type_NumLock, _T("NL-") },
+    { Modifier::Type_CapsLock, _T("CL-") },
+    { Modifier::Type_ScrollLock, _T("SL-") },
+    { Modifier::Type_KanaLock, _T("KL-") },
+    { Modifier::Type_Maximized, _T("MAX-") },
+    { Modifier::Type_Minimized, _T("MIN-") },
+    { Modifier::Type_MdiMaximized, _T("MMAX-") },
+    { Modifier::Type_MdiMinimized, _T("MMIN-") },
+    { Modifier::Type_Touchpad, _T("T-") },
+    { Modifier::Type_TouchpadSticky, _T("TS-") },
+    { Modifier::Type_Mod0, _T("M0-") }, { Modifier::Type_Mod1, _T("M1-") },
+    { Modifier::Type_Mod2, _T("M2-") }, { Modifier::Type_Mod3, _T("M3-") },
+    { Modifier::Type_Mod4, _T("M4-") }, { Modifier::Type_Mod5, _T("M5-") },
+    { Modifier::Type_Mod6, _T("M6-") }, { Modifier::Type_Mod7, _T("M7-") },
+    { Modifier::Type_Mod8, _T("M8-") }, { Modifier::Type_Mod9, _T("M9-") },
+    { Modifier::Type_Lock0, _T("L0-") }, { Modifier::Type_Lock1, _T("L1-") },
+    { Modifier::Type_Lock2, _T("L2-") }, { Modifier::Type_Lock3, _T("L3-") },
+    { Modifier::Type_Lock4, _T("L4-") }, { Modifier::Type_Lock5, _T("L5-") },
+    { Modifier::Type_Lock6, _T("L6-") }, { Modifier::Type_Lock7, _T("L7-") },
+    { Modifier::Type_Lock8, _T("L8-") }, { Modifier::Type_Lock9, _T("L9-") },
+  };
+
+  for (size_t i = 0; i < NUMBER_OF(mods); ++ i)
+    if (!i_m.isDontcare(mods[i].m_mt) && i_m.isPressed(mods[i].m_mt))
+      i_ost << mods[i].m_symbol;
+#if 0
+    else if (!i_m.isDontcare(mods[i].m_mt) && i_m.isPressed(mods[i].m_mt))
+      i_ost << _T("~") << mods[i].m_symbol;
+    else
+      i_ost << _T("*") << mods[i].m_symbol;
+#endif
+
+  return i_ost;
+}
+
+
+/// stream output
+tostream &operator<<(tostream &i_ost, Modifier::Type i_type)
+{
+  const _TCHAR *modNames[] =
+  {
+    _T("Shift"), 
+    _T("Alt"), 
+    _T("Control"), 
+    _T("Windows"), 
+    _T("Up"), 
+    _T("Down"), 
+    _T("Repeat"), 
+    _T("ImeLock"), 
+    _T("ImeComp"), 
+    _T("NumLock"), 
+    _T("CapsLock"), 
+    _T("ScrollLock"), 
+    _T("KanaLock"), 
+    _T("Maximized"), 
+    _T("Minimized"), 
+    _T("MdiMaximized"), 
+    _T("MdiMinimized"), 
+    _T("Touchpad"), 
+    _T("TouchpadSticky"), 
+    _T("Mod0"), 
+    _T("Mod1"), 
+    _T("Mod2"), 
+    _T("Mod3"), 
+    _T("Mod4"), 
+    _T("Mod5"), 
+    _T("Mod6"), 
+    _T("Mod7"), 
+    _T("Mod8"), 
+    _T("Mod9"), 
+    _T("Lock0"), 
+    _T("Lock1"), 
+    _T("Lock2"), 
+    _T("Lock3"), 
+    _T("Lock4"), 
+    _T("Lock5"), 
+    _T("Lock6"), 
+    _T("Lock7"), 
+    _T("Lock8"), 
+    _T("Lock9"), 
+  };
+
+  int i = static_cast<int>(i_type);
+  if (0 <= i && i < NUMBER_OF(modNames))
+    i_ost << modNames[i];
+  
+  return i_ost;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ModifiedKey
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, const ModifiedKey &i_mk)
+{
+  if (i_mk.m_key)
+    i_ost << i_mk.m_modifier << *i_mk.m_key;
+  return i_ost;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Keyboard::KeyIterator
+
+
+Keyboard::KeyIterator::KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize)
+  : m_hashedKeys(i_hashedKeys),
+    m_hashedKeysSize(i_hashedKeysSize),
+    m_i((*m_hashedKeys).begin())
+{
+  if ((*m_hashedKeys).empty())
+    next();
+}
+
+
+void Keyboard::KeyIterator::next()
+{
+  if (m_hashedKeysSize == 0)
+    return;
+  ++ m_i;
+  if (m_i == (*m_hashedKeys).end())
+  {
+    do
+    {
+      -- m_hashedKeysSize;
+      ++ m_hashedKeys;
+    } while (0 < m_hashedKeysSize && (*m_hashedKeys).empty());
+    if (0 < m_hashedKeysSize)
+      m_i = (*m_hashedKeys).begin();
+  }
+}
+
+
+Key *Keyboard::KeyIterator::operator *()
+{
+  if (m_hashedKeysSize == 0)
+    return NULL;
+  return &*m_i;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Keyboard
+
+
+Keyboard::Keys &Keyboard::getKeys(const Key &i_key)
+{
+  ASSERT(1 <= i_key.getScanCodesSize());
+  return m_hashedKeys[i_key.getScanCodes()->m_scan % HASHED_KEYS_SIZE];
+}
+
+
+// add a key
+void Keyboard::addKey(const Key &i_key)
+{
+  getKeys(i_key).push_front(i_key);
+}
+
+
+// add a key name alias
+void Keyboard::addAlias(const tstringi &i_aliasName, Key *i_key)
+{
+  m_aliases.insert(Aliases::value_type(i_aliasName, i_key));
+}
+
+// add substitute
+void Keyboard::addSubstitute(const ModifiedKey &i_mkeyFrom,
+                            const ModifiedKey &i_mkeyTo)
+{
+  m_substitutes.push_front(Substitute(i_mkeyFrom, i_mkeyTo));
+}
+
+
+// add a modifier key
+void Keyboard::addModifier(Modifier::Type i_mt, Key *i_key)
+{
+  ASSERT((int)i_mt < (int)Modifier::Type_BASIC);
+  if (std::find(m_mods[i_mt].begin(), m_mods[i_mt].end(), i_key)
+      != m_mods[i_mt].end())
+    return; // already added
+  m_mods[i_mt].push_back(i_key);
+}
+
+
+// search a key
+Key *Keyboard::searchKey(const Key &i_key)
+{
+  Keys &keys = getKeys(i_key);
+  for (Keys::iterator i = keys.begin(); i != keys.end(); ++ i)
+    if ((*i).isSameScanCode(i_key))
+      return &*i;
+  return NULL;
+}
+
+
+// search a key (of which the key's scan code is the prefix)
+Key *Keyboard::searchPrefixKey(const Key &i_key)
+{
+  Keys &keys = getKeys(i_key);
+  for (Keys::iterator i = keys.begin(); i != keys.end(); ++ i)
+    if ((*i).isPrefixScanCode(i_key))
+      return &*i;
+  return NULL;
+}
+
+  
+// search a key by name
+Key *Keyboard::searchKey(const tstringi &i_name)
+{
+  Aliases::iterator i = m_aliases.find(i_name);
+  if (i != m_aliases.end())
+    return (*i).second;
+  return searchKeyByNonAliasName(i_name);
+}
+
+
+// search a key by non-alias name
+Key *Keyboard::searchKeyByNonAliasName(const tstringi &i_name)
+{
+  for (int j = 0; j < HASHED_KEYS_SIZE; ++ j)
+  {
+    Keys &keys = m_hashedKeys[j];
+    Keys::iterator i = std::find(keys.begin(), keys.end(), i_name);
+    if (i != keys.end())
+      return &*i;
+  }
+  return NULL;
+}
+
+/// search a substitute
+ModifiedKey Keyboard::searchSubstitute(const ModifiedKey &i_mkey)
+{
+  for (Substitutes::const_iterator
+        i = m_substitutes.begin(); i != m_substitutes.end(); ++ i)
+    if (i->m_mkeyFrom.m_key == i_mkey.m_key &&
+       i->m_mkeyFrom.m_modifier.doesMatch(i_mkey.m_modifier))
+      return i->m_mkeyTo;
+  return ModifiedKey();                                // not found (.m_mkey is NULL)
+}
diff --git a/keyboard.h b/keyboard.h
new file mode 100644 (file)
index 0000000..1d9111f
--- /dev/null
@@ -0,0 +1,415 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// keyboard.h
+
+
+#ifndef _KEYBOARD_H
+#  define _KEYBOARD_H
+
+#  include "misc.h"
+#  include "driver.h"
+#  include "stringtool.h"
+#  include <vector>
+#  include <list>
+#  include <map>
+
+
+/// a scan code with flags
+class ScanCode
+{
+public:
+  ///
+  enum
+  {
+    BREAK = KEYBOARD_INPUT_DATA::BREAK,                /// key release flag
+    E0    = KEYBOARD_INPUT_DATA::E0,           /// extended key flag
+    E1    = KEYBOARD_INPUT_DATA::E1,           /// extended key flag
+    E0E1  = KEYBOARD_INPUT_DATA::E0E1,         /// extended key flag
+  };
+
+public:
+  USHORT m_scan;                               ///
+  USHORT m_flags;                              ///
+
+public:
+  ///
+  ScanCode() : m_scan(0), m_flags(0) { }
+  ///
+  ScanCode(USHORT i_scan, USHORT i_flags)
+    : m_scan(i_scan), m_flags(i_flags) { }
+  ///
+  bool operator==(const ScanCode &i_sc) const
+  {
+    return (m_scan == i_sc.m_scan &&
+           (E0E1 & m_flags) == (E0E1 & i_sc.m_flags));
+  }
+  ///
+  bool operator!=(const ScanCode &i_sc) const { return !(*this == i_sc); }
+};
+
+
+/// a key
+class Key
+{
+public:
+  enum
+  {
+    ///
+    MAX_SCAN_CODES_SIZE = 4,
+  };
+
+private:
+  ///
+  typedef std::vector<tstringi> Names;
+
+public:
+  /// if this key pressed physically
+  bool m_isPressed;
+  /// if this key pressed on Win32
+  bool m_isPressedOnWin32;
+  /// if this key pressed by assign
+  bool m_isPressedByAssign;
+
+private:
+  /// key name
+  Names m_names;
+  /// key scan code length
+  size_t m_scanCodesSize;
+  /// key scan code
+  ScanCode m_scanCodes[MAX_SCAN_CODES_SIZE];
+
+public:
+  ///
+  Key()
+    : m_isPressed(false),
+      m_isPressedOnWin32(false),
+      m_isPressedByAssign(false),
+      m_scanCodesSize(0)
+  { }
+
+  /// for Event::* only
+  Key(const tstringi &i_name)
+    : m_isPressed(false),
+      m_isPressedOnWin32(false),
+      m_isPressedByAssign(false),
+      m_scanCodesSize(0)
+  {
+    addName(i_name);
+    addScanCode(ScanCode());
+  }
+
+  /// get key name (first name)
+  const tstringi &getName() const { return m_names.front(); }
+
+  /// get scan codes
+  const ScanCode *getScanCodes() const { return m_scanCodes; }
+  ///
+  size_t getScanCodesSize() const { return m_scanCodesSize; }
+  
+  /// add a name of key
+  void addName(const tstringi &i_name);
+  
+  /// add a scan code
+  void addScanCode(const ScanCode &i_sc);
+  
+  /// initializer
+  Key &initialize();
+  
+  /// equation by name
+  bool operator==(const tstringi &i_name) const;
+  ///
+  bool operator!=(const tstringi &i_name) const
+  { return !(*this == i_name); }
+  
+  /// is the scan code of this key ?
+  bool isSameScanCode(const Key &i_key) const;
+  
+  /// is the i_key's scan code the prefix of this key's scan code ?
+  bool isPrefixScanCode(const Key &i_key) const;
+  
+  /// stream output
+  friend tostream &operator<<(tostream &i_ost, const Key &i_key);
+  
+  /// < 
+  bool operator<(const Key &i_key) const
+  { return getName() < i_key.getName(); }
+};
+
+
+///
+class Modifier
+{
+  ///
+  typedef u_int64 MODIFIERS;
+  ///
+  MODIFIERS m_modifiers;
+  ///
+  MODIFIERS m_dontcares;
+  
+public:
+  ///
+  enum Type
+  {
+    Type_begin = 0,                            ///
+
+    Type_Shift = Type_begin,                   /// &lt;BASIC_MODIFIER&gt;
+    Type_Alt,                                  /// &lt;BASIC_MODIFIER&gt;
+    Type_Control,                              /// &lt;BASIC_MODIFIER&gt;
+    Type_Windows,                              /// &lt;BASIC_MODIFIER&gt;
+    Type_BASIC,                                        ///
+    
+    Type_Up = Type_BASIC,                      /// &lt;KEYSEQ_MODIFIER&gt;
+    Type_Down,                                 /// &lt;KEYSEQ_MODIFIER&gt;
+    Type_KEYSEQ,                               ///
+
+    Type_Repeat = Type_KEYSEQ,                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_ImeLock,                              /// &lt;ASSIGN_MODIFIER&gt;
+    Type_ImeComp,                              /// &lt;ASSIGN_MODIFIER&gt;
+    Type_NumLock,                              /// &lt;ASSIGN_MODIFIER&gt;
+    Type_CapsLock,                             /// &lt;ASSIGN_MODIFIER&gt;
+    Type_ScrollLock,                           /// &lt;ASSIGN_MODIFIER&gt;
+    Type_KanaLock,                             /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Maximized,                            /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Minimized,                            /// &lt;ASSIGN_MODIFIER&gt;
+    Type_MdiMaximized,                         /// &lt;ASSIGN_MODIFIER&gt;
+    Type_MdiMinimized,                         /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Touchpad,                             /// &lt;ASSIGN_MODIFIER&gt;
+    Type_TouchpadSticky,                       /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod0,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod1,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod2,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod3,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod4,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod5,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod6,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod7,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod8,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Mod9,                                 /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock0,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock1,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock2,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock3,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock4,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock5,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock6,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock7,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock8,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_Lock9,                                        /// &lt;ASSIGN_MODIFIER&gt;
+    Type_ASSIGN,                               ///
+
+    Type_end = Type_ASSIGN                     ///
+  };
+  
+public:
+  ///
+  Modifier();
+  ///
+  Modifier &on(Type i_type) { return press(i_type); }
+  ///
+  Modifier &off(Type i_type) { return release(i_type); }
+  ///
+  Modifier &press(Type i_type)
+  { m_modifiers |= ((MODIFIERS(1)) << i_type); return care(i_type); }
+  ///
+  Modifier &release(Type i_type)
+  { m_modifiers &= ~((MODIFIERS(1)) << i_type); return care(i_type); }
+  ///
+  Modifier &care(Type i_type)
+  { m_dontcares &= ~((MODIFIERS(1)) << i_type); return *this; }
+  ///
+  Modifier &dontcare(Type i_type)
+  { m_dontcares |= ((MODIFIERS(1)) << i_type); return *this; }
+  /// set all modifiers to dontcare
+  Modifier &dontcare() { m_dontcares = ~MODIFIERS(0); return *this; }
+
+  ///
+  Modifier &on(Type i_type, bool i_isOn) { return press(i_type, i_isOn); }
+  ///
+  Modifier &press(Type i_type, bool i_isPressed)
+  { return i_isPressed ? press(i_type) : release(i_type); }
+  ///
+  Modifier &care(Type i_type, bool i_doCare)
+  { return i_doCare ? care(i_type) : dontcare(i_type); }
+  
+  ///
+  bool operator==(const Modifier &i_m) const
+  { return m_modifiers == i_m.m_modifiers && m_dontcares == i_m.m_dontcares; }
+
+  /// add m's modifiers where this dontcare
+  void add(const Modifier &i_m);
+  //Modifier &operator+=(const Modifier &i_m);
+
+  /** does match. (except dontcare modifiers) (is the m included in the *this
+      set ?) */
+  bool doesMatch(const Modifier &i_m) const
+  { return ((m_modifiers | m_dontcares) == (i_m.m_modifiers | m_dontcares)); }
+  
+  ///
+  bool isOn(Type i_type) const { return isPressed(i_type); }
+  ///
+  bool isPressed(Type i_type) const
+  { return !!(m_modifiers & ((MODIFIERS(1)) << i_type)); }
+  ///
+  bool isDontcare(Type i_type) const
+  { return !!(m_dontcares & ((MODIFIERS(1)) << i_type)); }
+
+  /// stream output
+  friend tostream &operator<<(tostream &i_ost, const Modifier &i_m);
+  
+  /// < 
+  bool operator<(const Modifier &i_m) const
+  {
+    return m_modifiers < i_m.m_modifiers ||
+      (m_modifiers == i_m.m_modifiers && m_dontcares < i_m.m_dontcares);
+  }
+};
+
+
+/// stream output
+tostream &operator<<(tostream &i_ost, Modifier::Type i_type);
+
+
+///
+class ModifiedKey
+{
+public:
+  Modifier m_modifier; ///
+  Key *m_key;          ///
+  
+public:
+  ///
+  ModifiedKey() : m_key(NULL) { }
+  ///
+  ModifiedKey(Key *i_key) : m_key(i_key) { }
+  ///
+  ModifiedKey(const Modifier &i_modifier, Key *i_key)
+    : m_modifier(i_modifier), m_key(i_key) { }
+  ///
+  bool operator==(const ModifiedKey &i_mk) const
+  { return m_modifier == i_mk.m_modifier && m_key == i_mk.m_key; }
+  ///
+  bool operator!=(const ModifiedKey &i_mk) const
+  { return !operator==(i_mk); }
+  
+  /// stream output
+  friend tostream &operator<<(tostream &i_ost, const ModifiedKey &i_mk);
+
+  /// < 
+  bool operator<(const ModifiedKey &i_mk) const
+  {
+    return *m_key < *i_mk.m_key ||
+      (!(*i_mk.m_key < *m_key) && m_modifier < i_mk.m_modifier);
+  }
+};
+
+
+///
+class Keyboard
+{
+public:
+  /// keyboard modifiers (pointer into Keys)
+  typedef std::list<Key *> Mods;
+
+private:
+  /** keyboard keys (hashed by first scan code).
+      Keys must be *list* of Key.
+      Because *pointers* into Keys exist anywhere in this program, the address
+      of Key's elements must be fixed.  */
+  enum {
+    HASHED_KEYS_SIZE = 128,                    ///
+  };
+  typedef std::list<Key> Keys;                 ///
+  typedef std::map<tstringi, Key *> Aliases;   /// key name aliases
+  ///
+  class Substitute
+  {
+  public:
+    ModifiedKey m_mkeyFrom;
+    ModifiedKey m_mkeyTo;
+  public:
+    Substitute(const ModifiedKey &i_mkeyFrom,
+              const ModifiedKey &i_mkeyTo)
+      : m_mkeyFrom(i_mkeyFrom), m_mkeyTo(i_mkeyTo)
+    {
+    }
+  };
+  typedef std::list<Substitute> Substitutes;   /// substitutes
+
+private:
+  Keys m_hashedKeys[HASHED_KEYS_SIZE];         ///
+  Aliases m_aliases;                           ///
+  Substitutes m_substitutes;                   /// 
+  Key m_syncKey;                               /// key used to synchronize
+  
+private:
+  ///
+  Mods m_mods[Modifier::Type_BASIC];
+
+public:
+  ///
+  class KeyIterator
+  {
+    ///
+    Keys *m_hashedKeys;
+    ///
+    size_t m_hashedKeysSize;
+    ///
+    Keys::iterator m_i;
+    
+    ///
+    void next();
+    
+  public:
+    ///
+    KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize);
+    ///
+    Key *operator *();
+    ///
+    void operator++() { next(); }
+  };
+  
+private:
+  ///
+  Keys &getKeys(const Key &i_key);
+
+public:
+  /// add a key
+  void addKey(const Key &i_key);
+
+  /// add a key name alias
+  void addAlias(const tstringi &i_aliasName, Key *i_key);
+  
+  /// add substitute
+  void addSubstitute(const ModifiedKey &i_mkeyFrom,
+                    const ModifiedKey &i_mkeyTo);
+  
+  /// get a sync key
+  Key *getSyncKey() { return &m_syncKey; }
+  
+  /// add a modifier key
+  void addModifier(Modifier::Type i_mt, Key * i_key);
+  
+  /// search a key
+  Key *searchKey(const Key &i_key);
+  
+  /// search a key (of which the key's scan code is the prefix)
+  Key *searchPrefixKey(const Key &i_key);
+  
+  /// search a key by name
+  Key *searchKey(const tstringi &i_name);
+
+  /// search a key by non-alias name
+  Key *searchKeyByNonAliasName(const tstringi &i_name);
+
+  /// search a substitute
+  ModifiedKey searchSubstitute(const ModifiedKey &i_mkey);
+
+  /// get modifiers
+  Mods &getModifiers(Modifier::Type i_mt) { return m_mods[i_mt]; }
+
+  /// get key iterator
+  KeyIterator getKeyIterator()
+  { return KeyIterator(&m_hashedKeys[0], HASHED_KEYS_SIZE); }
+};
+
+
+#endif // !_KEYBOARD_H
diff --git a/keymap.cpp b/keymap.cpp
new file mode 100644 (file)
index 0000000..b692da8
--- /dev/null
@@ -0,0 +1,604 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// setting.cpp
+
+
+#include "keymap.h"
+#include "errormessage.h"
+#include "stringtool.h"
+#include "setting.h"
+#include <algorithm>
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Action
+
+//
+tostream &operator<<(tostream &i_ost, const Action &i_action)
+{
+  return i_action.output(i_ost);
+}
+
+
+//
+ActionKey::ActionKey(const ModifiedKey &i_mk)
+  : m_modifiedKey(i_mk)
+{
+}
+
+//
+Action::Type ActionKey::getType() const
+{
+  return Type_key;
+}
+
+// create clone
+Action *ActionKey::clone() const
+{
+  return new ActionKey(m_modifiedKey);
+}
+
+// stream output
+tostream &ActionKey::output(tostream &i_ost) const
+{
+  return i_ost << m_modifiedKey;
+}
+
+//
+ActionKeySeq::ActionKeySeq(KeySeq *i_keySeq)
+  : m_keySeq(i_keySeq)
+{
+}
+
+//
+Action::Type ActionKeySeq::getType() const
+{
+  return Type_keySeq;
+}
+
+// create clone
+Action *ActionKeySeq::clone() const
+{
+  return new ActionKeySeq(m_keySeq);
+}
+
+// stream output
+tostream &ActionKeySeq::output(tostream &i_ost) const
+{
+  return i_ost << _T("$") << m_keySeq->getName();
+}
+
+//
+ActionFunction::ActionFunction(FunctionData *i_functionData,
+                              Modifier i_modifier)
+  : m_functionData(i_functionData),
+    m_modifier(i_modifier)
+{
+}
+
+//
+ActionFunction::~ActionFunction()
+{
+  delete m_functionData;
+}
+
+//
+Action::Type ActionFunction::getType() const
+{
+  return Type_function;
+}
+
+// create clone
+Action *ActionFunction::clone() const
+{
+  return new ActionFunction(m_functionData->clone(), m_modifier);
+}
+
+// stream output
+tostream &ActionFunction::output(tostream &i_ost) const
+{
+  return i_ost << m_modifier << m_functionData;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// KeySeq
+
+
+void KeySeq::copy()
+{
+  for (Actions::iterator i = m_actions.begin(); i != m_actions.end(); ++ i)
+    (*i) = (*i)->clone();
+}
+
+
+void KeySeq::clear()
+{
+  for (Actions::iterator i = m_actions.begin(); i != m_actions.end(); ++ i)
+    delete (*i);
+}
+
+
+KeySeq::KeySeq(const tstringi &i_name)
+  : m_name(i_name),
+    m_mode(Modifier::Type_KEYSEQ)
+{
+}
+
+
+KeySeq::KeySeq(const KeySeq &i_ks)
+  : m_actions(i_ks.m_actions),
+    m_name(i_ks.m_name),
+    m_mode(i_ks.m_mode)
+{
+  copy();
+}
+
+
+KeySeq::~KeySeq()
+{
+  clear();
+}
+
+
+KeySeq &KeySeq::operator=(const KeySeq &i_ks)
+{
+  if (this != &i_ks)
+  {
+    clear();
+    m_actions = i_ks.m_actions;
+    m_mode = i_ks.m_mode;
+    copy();
+  }
+  return *this;
+}
+
+
+KeySeq &KeySeq::add(const Action &i_action)
+{
+  m_actions.push_back(i_action.clone());
+  return *this;
+}
+
+
+/// get the first modified key of this key sequence
+ModifiedKey KeySeq::getFirstModifiedKey() const
+{
+  if (0 < m_actions.size())
+  {
+    const Action *a = m_actions.front();
+    switch (a->getType())
+    {
+      case Action::Type_key:
+       return reinterpret_cast<const ActionKey *>(a)->m_modifiedKey;
+      case Action::Type_keySeq:
+       return reinterpret_cast<const ActionKeySeq *>(a)->
+         m_keySeq->getFirstModifiedKey();
+      default:
+       break;
+    }
+  }
+  return ModifiedKey();                                // failed
+}
+
+
+// stream output
+tostream &operator<<(tostream &i_ost, const KeySeq &i_ks)
+{
+  for (KeySeq::Actions::const_iterator
+        i = i_ks.m_actions.begin(); i != i_ks.m_actions.end(); ++ i)
+    i_ost << **i << _T(" ");
+  return i_ost;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Keymap
+
+
+Keymap::KeyAssignments &Keymap::getKeyAssignments(const ModifiedKey &i_mk)
+{
+  ASSERT(1 <= i_mk.m_key->getScanCodesSize());
+  return m_hashedKeyAssignments[i_mk.m_key->getScanCodes()->m_scan %
+                              HASHED_KEY_ASSIGNMENT_SIZE];
+}
+
+const Keymap::KeyAssignments &
+Keymap::getKeyAssignments(const ModifiedKey &i_mk) const
+{
+  ASSERT(1 <= i_mk.m_key->getScanCodesSize());
+  return m_hashedKeyAssignments[i_mk.m_key->getScanCodes()->m_scan %
+                              HASHED_KEY_ASSIGNMENT_SIZE];
+}
+
+
+Keymap::Keymap(Type i_type,
+              const tstringi &i_name,
+              const tstringi &i_windowClass,
+              const tstringi &i_windowTitle,
+              KeySeq *i_defaultKeySeq,
+              Keymap *i_parentKeymap)
+  : m_type(i_type),
+    m_name(i_name),
+    m_defaultKeySeq(i_defaultKeySeq),
+    m_parentKeymap(i_parentKeymap),
+    m_windowClass(_T(".*")),
+    m_windowTitle(_T(".*"))
+{
+  if (i_type == Type_windowAnd || i_type == Type_windowOr)
+    try
+    {
+      tregex::flag_type f = (tregex::normal | 
+                            tregex::icase |
+                            tregex::use_except);
+      if (!i_windowClass.empty())
+       m_windowClass.assign(i_windowClass, f);
+      if (!i_windowTitle.empty())
+       m_windowTitle.assign(i_windowTitle, f);
+    }
+    catch (boost::bad_expression &i_e)
+    {
+      throw ErrorMessage() << i_e.what();
+    }
+}
+
+
+// add a key assignment;
+void Keymap::addAssignment(const ModifiedKey &i_mk, KeySeq *i_keySeq)
+{
+  KeyAssignments &ka = getKeyAssignments(i_mk);
+  for (KeyAssignments::iterator i = ka.begin(); i != ka.end(); ++ i)
+    if ((*i).m_modifiedKey == i_mk)
+    {
+      (*i).m_keySeq = i_keySeq;
+      return;
+    }
+  ka.push_front(KeyAssignment(i_mk, i_keySeq));
+}
+
+
+// add modifier
+void Keymap::addModifier(Modifier::Type i_mt, AssignOperator i_ao,
+                        AssignMode i_am, Key *i_key)
+{
+  if (i_ao == AO_new)
+    m_modAssignments[i_mt].clear();
+  else
+  {
+    for (ModAssignments::iterator i = m_modAssignments[i_mt].begin();
+        i != m_modAssignments[i_mt].end(); ++ i)
+      if ((*i).m_key == i_key)
+      {
+       (*i).m_assignOperator = i_ao;
+       (*i).m_assignMode = i_am;
+       return;
+      }
+  }
+  ModAssignment ma;
+  ma.m_assignOperator = i_ao;
+  ma.m_assignMode = i_am;
+  ma.m_key = i_key;
+  m_modAssignments[i_mt].push_back(ma);
+}
+
+  
+// search
+const Keymap::KeyAssignment *
+Keymap::searchAssignment(const ModifiedKey &i_mk) const
+{
+  const KeyAssignments &ka = getKeyAssignments(i_mk);
+  for (KeyAssignments::const_iterator i = ka.begin(); i != ka.end(); ++ i)
+    if ((*i).m_modifiedKey.m_key == i_mk.m_key &&
+       (*i).m_modifiedKey.m_modifier.doesMatch(i_mk.m_modifier))
+      return &(*i);
+  return NULL;
+}
+
+
+// does same window
+bool Keymap::doesSameWindow(const tstringi i_className,
+                           const tstringi &i_titleName)
+{
+  if (m_type == Type_keymap)
+    return false;
+
+  tsmatch what;
+  if (boost::regex_search(i_className, what, m_windowClass))
+  {
+    if (m_type == Type_windowAnd)
+      return boost::regex_search(i_titleName, what, m_windowTitle);
+    else // type == Type_windowOr
+      return true;
+  }
+  else
+  {
+    if (m_type == Type_windowAnd)
+      return false;
+    else // type == Type_windowOr
+      return boost::regex_search(i_titleName, what, m_windowTitle);
+  }
+}
+
+
+// adjust modifier
+void Keymap::adjustModifier(Keyboard &i_keyboard)
+{
+  for (size_t i = 0; i < NUMBER_OF(m_modAssignments); ++ i)
+  {
+    ModAssignments mos;
+    if (m_parentKeymap)
+      mos = m_parentKeymap->m_modAssignments[i];
+    else
+    {
+      // set default modifiers
+      if (i < Modifier::Type_BASIC)
+      {
+       Keyboard::Mods mods =
+         i_keyboard.getModifiers(static_cast<Modifier::Type>(i));
+       for (Keyboard::Mods::iterator j = mods.begin(); j != mods.end(); ++ j)
+       {
+         ModAssignment ma;
+         ma.m_assignOperator = AO_add;
+         ma.m_assignMode = AM_normal;
+         ma.m_key = *j;
+         mos.push_back(ma);
+       }
+      }
+    }
+    
+    // mod adjust
+    for (ModAssignments::iterator mai = m_modAssignments[i].begin();
+        mai != m_modAssignments[i].end(); ++ mai)
+    {
+      ModAssignment ma = *mai;
+      ma.m_assignOperator = AO_new;
+      switch ((*mai).m_assignOperator)
+      {
+       case AO_new:
+       {
+         mos.clear();
+         mos.push_back(ma);
+         break;
+       }
+       case AO_add:
+       {
+         mos.push_back(ma);
+         break;
+       }
+       case AO_sub:
+       {
+         for (ModAssignments::iterator j = mos.begin();
+              j != mos.end(); ++ j)
+           if ((*j).m_key == ma.m_key)
+           {
+             mos.erase(j);
+             break;
+           }
+         break;
+       }
+       case AO_overwrite:
+       {
+         for (ModAssignments::iterator j = mos.begin();
+              j != mos.end(); ++ j)
+           (*j).m_assignMode = (*mai).m_assignMode;
+         break;
+       }
+      }
+    }
+
+    // erase redundant modifiers
+    for (ModAssignments::iterator j = mos.begin(); j != mos.end(); ++ j)
+    {
+      ModAssignments::iterator k;
+      for (k = j, ++ k; k != mos.end(); ++ k)
+       if ((*k).m_key == (*j).m_key)
+         break;
+      if (k != mos.end())
+      {
+       k = j;
+       ++ j;
+       mos.erase(k);
+       break;
+      }
+    }
+    
+    m_modAssignments[i] = mos;
+  }
+}
+
+
+// describe
+void Keymap::describe(tostream &i_ost, DescribeParam *i_dp) const
+{
+  // Is this keymap already described ?
+  {
+    DescribeParam::DescribedKeymap::iterator
+      i = std::find(i_dp->m_dkeymap.begin(), i_dp->m_dkeymap.end(), this);
+    if (i != i_dp->m_dkeymap.end())
+      return;                                  // yes!
+    i_dp->m_dkeymap.push_back(this);
+  }
+
+  switch (m_type)
+  {
+    case Type_keymap:
+      i_ost << _T("keymap ") << m_name;
+      break;
+    case Type_windowAnd:
+      i_ost << _T("window ") << m_name << _T(" ");
+      if (m_windowTitle.str() == _T(".*"))
+       i_ost << _T("/") << m_windowClass.str() << _T("/");
+      else
+       i_ost << _T("( /") << m_windowClass.str() << _T("/ && /")
+             << m_windowTitle.str() << _T("/ )");
+      break;
+    case Type_windowOr:
+      i_ost << _T("window ") << m_name << _T(" ( /")
+           << m_windowClass.str() << _T("/ || /") << m_windowTitle.str()
+           << _T("/ )");
+      break;
+  }
+  if (m_parentKeymap)
+    i_ost << _T(" : ") << m_parentKeymap->m_name;
+  i_ost << _T(" = ") << *m_defaultKeySeq << std::endl;
+
+  // describe modifiers
+  if (i_dp->m_doesDescribeModifiers)
+  {
+    for (int t = Modifier::Type_begin; t != Modifier::Type_end; ++ t)
+    {
+      Modifier::Type type = static_cast<Modifier::Type>(t);
+      const Keymap::ModAssignments &ma = getModAssignments(type);
+      if (ma.size())
+      {
+       i_ost << _T(" mod ") << type << _T("\t= ");
+       for (Keymap::ModAssignments::const_iterator
+              j = ma.begin(); j != ma.end(); ++ j)
+       {
+         switch (j->m_assignMode)
+         {
+           case Keymap::AM_true: i_ost << _T("!"); break;
+           case Keymap::AM_oneShot: i_ost << _T("!!"); break;
+           case Keymap::AM_oneShotRepeatable: i_ost << _T("!!!"); break;
+           default:
+             break;
+         }
+         i_ost << *j->m_key << _T(" ");
+       }
+       i_ost << std::endl;
+      }
+    }
+    i_dp->m_doesDescribeModifiers = false;
+  }
+  
+  typedef std::vector<KeyAssignment> SortedKeyAssignments;
+  SortedKeyAssignments ska;
+  for (size_t i = 0; i < HASHED_KEY_ASSIGNMENT_SIZE; ++ i)
+  {
+    const KeyAssignments &ka = m_hashedKeyAssignments[i];
+    for (KeyAssignments::const_iterator j = ka.begin(); j != ka.end(); ++ j)
+      ska.push_back(*j);
+  }
+  std::sort(ska.begin(), ska.end());
+  for (SortedKeyAssignments::iterator i = ska.begin(); i != ska.end(); ++ i)
+  {
+    // Is this key assignment already described ?
+    DescribeParam::DescribedKeys::iterator
+      j = std::find(i_dp->m_dk.begin(), i_dp->m_dk.end(), i->m_modifiedKey);
+    if (j != i_dp->m_dk.end())
+      continue;                                        // yes!
+
+    // check if the key is an event
+    Key **e;
+    for (e = Event::events; *e; ++ e)
+      if (i->m_modifiedKey.m_key == *e)
+       break;
+    if (*e)
+      i_ost << _T(" event ") << *i->m_modifiedKey.m_key;
+    else
+      i_ost << _T(" key ") << i->m_modifiedKey;
+    i_ost << _T("\t= ") << *i->m_keySeq << std::endl;
+    i_dp->m_dk.push_back(i->m_modifiedKey);
+  }
+
+  i_ost << std::endl;
+  
+  if (m_parentKeymap)
+    m_parentKeymap->describe(i_ost, i_dp);
+}
+
+// set default keySeq and parent keymap if default keySeq has not been set
+bool Keymap::setIfNotYet(KeySeq *i_keySeq, Keymap *i_parentKeymap)
+{
+  if (m_defaultKeySeq)
+    return false;
+  m_defaultKeySeq = i_keySeq;
+  m_parentKeymap = i_parentKeymap;
+  return true;
+}
+
+// stream output
+extern tostream &operator<<(tostream &i_ost, const Keymap *i_keymap)
+{
+  return i_ost << i_keymap->getName();
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Keymaps
+
+
+Keymaps::Keymaps()
+{
+}
+
+
+// search by name
+Keymap *Keymaps::searchByName(const tstringi &i_name)
+{
+  for (KeymapList::iterator
+        i = m_keymapList.begin(); i != m_keymapList.end(); ++ i)
+    if ((*i).getName() == i_name)
+      return &*i;
+  return NULL;
+}
+
+
+// search window
+void Keymaps::searchWindow(KeymapPtrList *o_keymapPtrList,
+                          const tstringi &i_className,
+                          const tstringi &i_titleName)
+{
+  o_keymapPtrList->clear();
+  for (KeymapList::iterator
+        i = m_keymapList.begin(); i != m_keymapList.end(); ++ i)
+    if ((*i).doesSameWindow(i_className, i_titleName))
+      o_keymapPtrList->push_back(&(*i));
+}
+
+
+// add keymap
+Keymap *Keymaps::add(const Keymap &i_keymap)
+{
+  if (Keymap *k = searchByName(i_keymap.getName()))
+    return k;
+  m_keymapList.push_front(i_keymap);
+  return &m_keymapList.front();
+}
+
+
+// adjust modifier
+void Keymaps::adjustModifier(Keyboard &i_keyboard)
+{
+  for (KeymapList::reverse_iterator i = m_keymapList.rbegin();
+       i != m_keymapList.rend(); ++ i)
+    (*i).adjustModifier(i_keyboard);
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// KeySeqs
+
+
+// add a named keyseq (name can be empty)
+KeySeq *KeySeqs::add(const KeySeq &i_keySeq)
+{
+  if (!i_keySeq.getName().empty())
+  {
+    KeySeq *ks = searchByName(i_keySeq.getName());
+    if (ks)
+      return &(*ks = i_keySeq);
+  }
+  m_keySeqList.push_front(i_keySeq);
+  return &m_keySeqList.front();
+}
+
+
+// search by name
+KeySeq *KeySeqs::searchByName(const tstringi &i_name)
+{
+  for (KeySeqList::iterator
+        i = m_keySeqList.begin(); i != m_keySeqList.end(); ++ i)
+    if ((*i).getName() == i_name)
+      return &(*i);
+  return NULL;
+}
diff --git a/keymap.h b/keymap.h
new file mode 100644 (file)
index 0000000..e5c5cd0
--- /dev/null
+++ b/keymap.h
@@ -0,0 +1,376 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// keymap.h
+
+
+#ifndef _KEYMAP_H
+#  define _KEYMAP_H
+
+#  include "keyboard.h"
+#  include "function.h"
+#  include <vector>
+
+
+///
+class Action
+{
+public:
+  ///
+  enum Type
+  {
+    Type_key,                                  ///
+    Type_keySeq,                               ///
+    Type_function,                             ///
+  };
+
+private:
+  Action(const Action &i_action);
+  
+public:
+  Action() { }
+  ///
+  virtual ~Action() { }
+  ///
+  virtual Type getType() const = 0;
+  /// create clone
+  virtual Action *clone() const = 0;
+  /// stream output
+  virtual tostream &output(tostream &i_ost) const = 0;
+};
+
+///
+tostream &operator<<(tostream &i_ost, const Action &i_action);
+
+///
+class ActionKey : public Action
+{
+public:
+  ///
+  const ModifiedKey m_modifiedKey;
+
+private:
+  ActionKey(const ActionKey &i_actionKey);
+  
+public:
+  ///
+  ActionKey(const ModifiedKey &i_mk);
+  ///
+  virtual Type getType() const;
+  /// create clone
+  virtual Action *clone() const;
+  /// stream output
+  virtual tostream &output(tostream &i_ost) const;
+};
+
+
+class KeySeq;
+///
+class ActionKeySeq : public Action
+{
+public:
+  KeySeq * const m_keySeq;                     ///
+
+private:
+  ActionKeySeq(const ActionKeySeq &i_actionKeySeq);
+  
+public:
+  ///
+  ActionKeySeq(KeySeq *i_keySeq);
+  ///
+  virtual Type getType() const;
+  /// create clone
+  virtual Action *clone() const;
+  /// stream output
+  virtual tostream &output(tostream &i_ost) const;
+};
+
+
+///
+class ActionFunction : public Action
+{
+public:
+  FunctionData * const m_functionData;         /// function data
+  const Modifier m_modifier;                   /// modifier for &Sync
+
+private:
+  ActionFunction(const ActionFunction &i_actionFunction);
+  
+public:
+  ///
+  ActionFunction(FunctionData *i_functionData,
+                Modifier i_modifier = Modifier());
+  ///
+  virtual ~ActionFunction();
+  ///
+  virtual Type getType() const;
+  /// create clone
+  virtual Action *clone() const;
+  /// stream output
+  virtual tostream &output(tostream &i_ost) const;
+};
+
+
+///
+class KeySeq
+{
+public:
+  typedef std::vector<Action *> Actions;       /// 
+
+private:
+  Actions m_actions;                           ///
+  tstringi m_name;                             ///
+  Modifier::Type m_mode;                       /** Either Modifier::Type_KEYSEQ
+                                                    or Modifier::Type_ASSIGN */
+
+private:
+  ///
+  void copy();
+  ///
+  void clear();
+  
+public:
+  ///
+  KeySeq(const tstringi &i_name);
+  ///
+  KeySeq(const KeySeq &i_ks);
+  ///
+  ~KeySeq();
+  
+  ///
+  const Actions &getActions() const { return m_actions; }
+  
+  ///
+  KeySeq &operator=(const KeySeq &i_ks);
+  
+  /// add
+  KeySeq &add(const Action &i_action);
+
+  /// get the first modified key of this key sequence
+  ModifiedKey getFirstModifiedKey() const;
+  
+  ///
+  const tstringi &getName() const { return m_name; }
+  
+  /// stream output
+  friend tostream &operator<<(tostream &i_ost, const KeySeq &i_ks);
+
+  ///
+  bool isCorrectMode(Modifier::Type i_mode) { return m_mode <= i_mode; }
+
+  ///
+  void setMode(Modifier::Type i_mode)
+  {
+    if (m_mode < i_mode)
+      m_mode = i_mode;
+    ASSERT( m_mode == Modifier::Type_KEYSEQ ||
+           m_mode == Modifier::Type_ASSIGN);
+  }
+
+  ///
+  Modifier::Type getMode() const { return m_mode; }
+};
+
+
+///
+class Keymap
+{
+public:
+  ///
+  enum Type
+  {
+    Type_keymap,                               /// this is keymap
+    Type_windowAnd,                            /// this is window &amp;&amp;
+    Type_windowOr,                             /// this is window ||
+  };
+  ///
+  enum AssignOperator
+  {
+    AO_new,                                    /// =
+    AO_add,                                    /// +=
+    AO_sub,                                    /// -=
+    AO_overwrite,                              /// !, !!
+  };
+  ///
+  enum AssignMode
+  {
+    AM_notModifier,                            ///    not modifier
+    AM_normal,                                 ///    normal modifier
+    AM_true,                                   /** !  true modifier(doesn't
+                                                    generate scan code) */
+    AM_oneShot,                                        /// !! one shot modifier
+    AM_oneShotRepeatable,                      /// !!! one shot modifier
+  };
+  
+  /// key assignment
+  class KeyAssignment
+  {
+  public:
+    ModifiedKey m_modifiedKey; ///
+    KeySeq *m_keySeq;          ///
+
+  public:
+    ///
+    KeyAssignment(const ModifiedKey &i_modifiedKey, KeySeq *i_keySeq)
+      : m_modifiedKey(i_modifiedKey), m_keySeq(i_keySeq) { }
+    ///
+    KeyAssignment(const KeyAssignment &i_o)
+      : m_modifiedKey(i_o.m_modifiedKey), m_keySeq(i_o.m_keySeq) { }
+    ///
+    bool operator<(const KeyAssignment &i_o) const
+    { return m_modifiedKey < i_o.m_modifiedKey; }
+  };
+
+  /// modifier assignments
+  class ModAssignment
+  {
+  public:
+    AssignOperator m_assignOperator;   ///
+    AssignMode m_assignMode;           ///
+    Key *m_key;                                ///
+  };
+  typedef std::list<ModAssignment> ModAssignments; ///
+
+  /// parameter for describe();
+  class DescribeParam
+  {
+  private:
+    typedef std::list<ModifiedKey> DescribedKeys;
+    typedef std::list<const Keymap *> DescribedKeymap;
+    friend class Keymap;
+
+  private:
+    DescribedKeys m_dk;
+    DescribedKeymap m_dkeymap;
+    bool m_doesDescribeModifiers;
+
+  public:
+    DescribeParam() : m_doesDescribeModifiers(true) { }
+  };
+  
+private:
+  /// key assignments (hashed by first scan code)
+  typedef std::list<KeyAssignment> KeyAssignments;
+  enum {
+    HASHED_KEY_ASSIGNMENT_SIZE = 32,   ///
+  };
+
+private:
+  KeyAssignments m_hashedKeyAssignments[HASHED_KEY_ASSIGNMENT_SIZE];   ///
+  
+  /// modifier assignments
+  ModAssignments m_modAssignments[Modifier::Type_ASSIGN];
+
+  Type m_type;                                 /// type
+  tstringi m_name;                             /// keymap name
+  tregex m_windowClass;                                /// window class name regexp
+  tregex m_windowTitle;                                /// window title name regexp
+
+  KeySeq *m_defaultKeySeq;                     /// default keySeq
+  Keymap *m_parentKeymap;                      /// parent keymap
+  
+private:
+  ///
+  KeyAssignments &getKeyAssignments(const ModifiedKey &i_mk);
+  ///
+  const KeyAssignments &getKeyAssignments(const ModifiedKey &i_mk) const;
+
+public:
+  ///
+  Keymap(Type i_type,
+        const tstringi &i_name,
+        const tstringi &i_windowClass,
+        const tstringi &i_windowTitle,
+        KeySeq *i_defaultKeySeq,
+        Keymap *i_parentKeymap);
+  
+  /// add a key assignment;
+  void addAssignment(const ModifiedKey &i_mk, KeySeq *i_keySeq);
+
+  /// add modifier
+  void addModifier(Modifier::Type i_mt, AssignOperator i_ao,
+                  AssignMode i_am, Key *i_key);
+  
+  /// search
+  const KeyAssignment *searchAssignment(const ModifiedKey &i_mk) const;
+
+  /// get
+  const KeySeq *getDefaultKeySeq() const { return m_defaultKeySeq; }
+  ///
+  Keymap *getParentKeymap() const { return m_parentKeymap; }
+  ///
+  const tstringi &getName() const { return m_name; }
+
+  /// does same window
+  bool doesSameWindow(const tstringi i_className,
+                     const tstringi &i_titleName);
+  
+  /// adjust modifier
+  void adjustModifier(Keyboard &i_keyboard);
+
+  /// get modAssignments
+  const ModAssignments &getModAssignments(Modifier::Type i_mt) const
+  { return m_modAssignments[i_mt]; }
+
+  /// describe
+  void describe(tostream &i_ost, DescribeParam *i_dp) const;
+  
+  /// set default keySeq and parent keymap if default keySeq has not been set
+  bool setIfNotYet(KeySeq *i_keySeq, Keymap *i_parentKeymap);
+};
+
+
+/// stream output
+extern tostream &operator<<(tostream &i_ost, const Keymap *i_keymap);
+
+
+///
+class Keymaps
+{
+public:
+  typedef std::list<Keymap *> KeymapPtrList;   /// 
+  
+private:
+  typedef std::list<Keymap> KeymapList;                /// 
+
+private:
+  KeymapList m_keymapList;                     /** pointer into keymaps may
+                                                    exist */
+  
+public:
+  ///
+  Keymaps();
+  
+  /// search by name
+  Keymap *searchByName(const tstringi &i_name);
+
+  /// search window
+  void searchWindow(KeymapPtrList *o_keymapPtrList,
+                   const tstringi &i_className,
+                   const tstringi &i_titleName);
+  
+  /// add keymap
+  Keymap *add(const Keymap &i_keymap);
+  
+  /// adjust modifier
+  void adjustModifier(Keyboard &i_keyboard);
+};
+
+
+///
+class KeySeqs
+{
+private:
+  typedef std::list<KeySeq> KeySeqList;                ///
+
+private:
+  KeySeqList m_keySeqList;                     ///
+  
+public:
+  /// add a named keyseq (name can be empty)
+  KeySeq *add(const KeySeq &i_keySeq);
+  
+  /// search by name
+  KeySeq *searchByName(const tstringi &i_name);
+};
+
+
+#endif // !_KEYMAP_H
diff --git a/layoutmanager.cpp b/layoutmanager.cpp
new file mode 100644 (file)
index 0000000..bea2737
--- /dev/null
@@ -0,0 +1,234 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// layoutmanager.cpp\r
+\r
+\r
+#include "layoutmanager.h"\r
+#include "windowstool.h"\r
+\r
+#include <windowsx.h>\r
+\r
+\r
+//\r
+LayoutManager::LayoutManager(HWND i_hwnd)\r
+  : m_hwnd(i_hwnd),\r
+    m_smallestRestriction(RESTRICT_NONE),\r
+    m_largestRestriction(RESTRICT_NONE)\r
+{\r
+}\r
+\r
+// restrict the smallest size of the window to the current size of it or\r
+// specified by i_size\r
+void LayoutManager::restrictSmallestSize(Restrict i_restrict, SIZE *i_size)\r
+{\r
+  m_smallestRestriction = i_restrict;\r
+  if (i_size)\r
+    m_smallestSize = *i_size;\r
+  else\r
+  {\r
+    RECT rc;\r
+    GetWindowRect(m_hwnd, &rc);\r
+    m_smallestSize.cx = rc.right - rc.left;\r
+    m_smallestSize.cy = rc.bottom - rc.top;\r
+  }\r
+}\r
+\r
+\r
+// restrict the largest size of the window to the current size of it or\r
+// specified by i_size\r
+void LayoutManager::restrictLargestSize(Restrict i_restrict, SIZE *i_size)\r
+{\r
+  m_largestRestriction = i_restrict;\r
+  if (i_size)\r
+    m_largestSize = *i_size;\r
+  else\r
+  {\r
+    RECT rc;\r
+    GetWindowRect(m_hwnd, &rc);\r
+    m_largestSize.cx = rc.right - rc.left;\r
+    m_largestSize.cy = rc.bottom - rc.top;\r
+  }\r
+}\r
+\r
+//\r
+bool LayoutManager::addItem(HWND i_hwnd, Origin i_originLeft,\r
+                           Origin i_originTop,\r
+                           Origin i_originRight, Origin i_originBottom)\r
+{\r
+  Item item;\r
+  if (!i_hwnd)\r
+    return false;\r
+  item.m_hwnd = i_hwnd;\r
+  if (!(GetWindowLong(i_hwnd, GWL_STYLE) & WS_CHILD))\r
+    return false;\r
+  item.m_hwndParent = GetParent(i_hwnd);\r
+  if (!item.m_hwndParent)\r
+    return false;\r
+  getChildWindowRect(item.m_hwnd, &item.m_rc);\r
+  GetWindowRect(item.m_hwndParent, &item.m_rcParent);\r
+  item.m_origin[0] = i_originLeft;\r
+  item.m_origin[1] = i_originTop;\r
+  item.m_origin[2] = i_originRight;\r
+  item.m_origin[3] = i_originBottom;\r
+    \r
+  m_items.push_back(item);\r
+  return true;\r
+}\r
+\r
+//\r
+void LayoutManager::adjust() const\r
+{\r
+  for (Items::const_iterator i = m_items.begin(); i != m_items.end(); ++ i)\r
+  {\r
+    RECT rc;\r
+    GetWindowRect(i->m_hwndParent, &rc);\r
+\r
+    struct { int m_width, m_pos; int m_curWidth; LONG *m_out; }\r
+    pos[4] =\r
+    {\r
+      { rcWidth(&i->m_rcParent), i->m_rc.left, rcWidth(&rc), &rc.left },\r
+      { rcHeight(&i->m_rcParent), i->m_rc.top, rcHeight(&rc), &rc.top },\r
+      { rcWidth(&i->m_rcParent), i->m_rc.right, rcWidth(&rc), &rc.right },\r
+      { rcHeight(&i->m_rcParent), i->m_rc.bottom, rcHeight(&rc), &rc.bottom }\r
+    };\r
+    for (int j = 0; j < 4; ++ j)\r
+    {\r
+      switch (i->m_origin[j])\r
+      {\r
+       case ORIGIN_LEFT_EDGE:\r
+         *pos[j].m_out = pos[j].m_pos;\r
+         break;\r
+       case ORIGIN_CENTER:\r
+         *pos[j].m_out = pos[j].m_curWidth / 2\r
+           - (pos[j].m_width / 2 - pos[j].m_pos);\r
+         break;\r
+       case ORIGIN_RIGHT_EDGE:\r
+         *pos[j].m_out = pos[j].m_curWidth\r
+           - (pos[j].m_width - pos[j].m_pos);\r
+         break;\r
+      }\r
+    }\r
+    MoveWindow(i->m_hwnd, rc.left, rc.top,\r
+              rcWidth(&rc), rcHeight(&rc), FALSE);\r
+  }\r
+}\r
+\r
+\r
+// draw size box\r
+BOOL LayoutManager::wmPaint()\r
+{\r
+  PAINTSTRUCT ps;\r
+  HDC hdc = BeginPaint(m_hwnd, &ps);\r
+  RECT rc;\r
+  GetClientRect(m_hwnd, &rc);\r
+  rc.left = rc.right - GetSystemMetrics(SM_CXHTHUMB);\r
+  rc.top = rc.bottom - GetSystemMetrics(SM_CYVTHUMB);\r
+  DrawFrameControl(hdc, &rc, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);\r
+  EndPaint(m_hwnd, &ps);\r
+  return TRUE;\r
+}\r
+\r
+\r
+// size restriction\r
+BOOL LayoutManager::wmSizing(int i_edge, RECT *io_rc)\r
+{\r
+  switch (i_edge)\r
+  {\r
+    case WMSZ_TOPLEFT:\r
+    case WMSZ_LEFT:\r
+    case WMSZ_BOTTOMLEFT:\r
+      if (m_smallestRestriction & RESTRICT_HORIZONTALLY)\r
+       if (io_rc->right - io_rc->left < m_smallestSize.cx)\r
+         io_rc->left = io_rc->right - m_smallestSize.cx;\r
+      if (m_largestRestriction & RESTRICT_HORIZONTALLY)\r
+       if (m_largestSize.cx < io_rc->right - io_rc->left)\r
+         io_rc->left = io_rc->right - m_largestSize.cx;\r
+      break;\r
+  }\r
+  switch (i_edge)\r
+  {\r
+    case WMSZ_TOPRIGHT:\r
+    case WMSZ_RIGHT:\r
+    case WMSZ_BOTTOMRIGHT:\r
+      if (m_smallestRestriction & RESTRICT_HORIZONTALLY)\r
+       if (io_rc->right - io_rc->left < m_smallestSize.cx)\r
+         io_rc->right = io_rc->left + m_smallestSize.cx;\r
+      if (m_largestRestriction & RESTRICT_HORIZONTALLY)\r
+       if (m_largestSize.cx < io_rc->right - io_rc->left)\r
+         io_rc->right = io_rc->left + m_largestSize.cx;\r
+      break;\r
+  }\r
+  switch (i_edge)\r
+  {\r
+    case WMSZ_TOP:\r
+    case WMSZ_TOPLEFT:\r
+    case WMSZ_TOPRIGHT:\r
+      if (m_smallestRestriction & RESTRICT_VERTICALLY)\r
+       if (io_rc->bottom - io_rc->top < m_smallestSize.cy)\r
+         io_rc->top = io_rc->bottom - m_smallestSize.cy;\r
+      if (m_largestRestriction & RESTRICT_VERTICALLY)\r
+       if (m_largestSize.cy < io_rc->bottom - io_rc->top)\r
+         io_rc->top = io_rc->bottom - m_largestSize.cy;\r
+      break;\r
+  }\r
+  switch (i_edge)\r
+  {\r
+    case WMSZ_BOTTOM:\r
+    case WMSZ_BOTTOMLEFT:\r
+    case WMSZ_BOTTOMRIGHT:\r
+      if (m_smallestRestriction & RESTRICT_VERTICALLY)\r
+       if (io_rc->bottom - io_rc->top < m_smallestSize.cy)\r
+         io_rc->bottom = io_rc->top + m_smallestSize.cy;\r
+      if (m_largestRestriction & RESTRICT_VERTICALLY)\r
+       if (m_largestSize.cy < io_rc->bottom - io_rc->top)\r
+         io_rc->bottom = io_rc->top + m_largestSize.cy;\r
+      break;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+\r
+// hittest for size box\r
+BOOL LayoutManager::wmNcHitTest(int i_x, int i_y)\r
+{\r
+  POINT p = { i_x, i_y };\r
+  ScreenToClient(m_hwnd, &p);\r
+  RECT rc;\r
+  GetClientRect(m_hwnd, &rc);\r
+  if (rc.right - GetSystemMetrics(SM_CXHTHUMB) <= p.x &&\r
+      rc.bottom - GetSystemMetrics(SM_CYVTHUMB) <= p.y)\r
+  {\r
+    SetWindowLong(m_hwnd, DWL_MSGRESULT, HTBOTTOMRIGHT);\r
+    return TRUE;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
+// WM_SIZE\r
+BOOL LayoutManager::wmSize(DWORD /* i_fwSizeType */, short /* i_nWidth */,\r
+                          short /* i_nHeight */)\r
+{\r
+  adjust();\r
+  RedrawWindow(m_hwnd, NULL, NULL,\r
+              RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);\r
+  return TRUE;\r
+}\r
+\r
+\r
+// forward message\r
+BOOL LayoutManager::defaultWMHandler(UINT i_message,\r
+                                    WPARAM i_wParam, LPARAM i_lParam)\r
+{\r
+  switch (i_message)\r
+  {\r
+    case WM_SIZE:\r
+      return wmSize(i_wParam, LOWORD(i_lParam), HIWORD(i_lParam));\r
+   case WM_PAINT:\r
+      return wmPaint();\r
+    case WM_SIZING:\r
+      return wmSizing(i_wParam, reinterpret_cast<RECT *>(i_lParam));\r
+    case WM_NCHITTEST:\r
+      return wmNcHitTest(GET_X_LPARAM(i_lParam), GET_Y_LPARAM(i_lParam));\r
+  }\r
+  return FALSE;\r
+}\r
diff --git a/layoutmanager.h b/layoutmanager.h
new file mode 100644 (file)
index 0000000..25ace7e
--- /dev/null
@@ -0,0 +1,113 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// layoutmanager.h
+
+
+#ifndef _LAYOUTMANAGER_H
+#  define _LAYOUTMANAGER_H
+
+#  include "misc.h"
+#  include <list>
+
+
+///
+class LayoutManager
+{
+public:
+  ///
+  enum Origin
+  {
+    ORIGIN_LEFT_EDGE,                          /// 
+    ORIGIN_TOP_EDGE = ORIGIN_LEFT_EDGE,                ///
+    ORIGIN_CENTER,                             /// 
+    ORIGIN_RIGHT_EDGE,                         /// 
+    ORIGIN_BOTTOM_EDGE = ORIGIN_RIGHT_EDGE,    /// 
+  };
+
+  ///
+  enum Restrict
+  {
+    RESTRICT_NONE = 0,                         /// 
+    RESTRICT_HORIZONTALLY = 1,                 /// 
+    RESTRICT_VERTICALLY = 2,                   /// 
+    RESTRICT_BOTH = RESTRICT_HORIZONTALLY | RESTRICT_VERTICALLY, /// 
+  };
+
+private:
+  ///
+  class Item
+  {
+  public:
+    HWND m_hwnd;                               /// 
+    HWND m_hwndParent;                         /// 
+    RECT m_rc;                                 /// 
+    RECT m_rcParent;                           /// 
+    Origin m_origin[4];                                /// 
+  };
+
+  ///
+  class SmallestSize
+  {
+  public:
+    HWND m_hwnd;                               /// 
+    SIZE m_size;                               /// 
+
+  public:
+    ///
+    SmallestSize() : m_hwnd(NULL) { }
+  };
+
+  typedef std::list<Item> Items;               /// 
+  
+protected:
+  HWND m_hwnd;                                 /// 
+
+private:
+  Items m_items;                               /// 
+  Restrict m_smallestRestriction;              /// 
+  SIZE m_smallestSize;                         /// 
+  Restrict m_largestRestriction;               /// 
+  SIZE m_largestSize;                          /// 
+  
+public:
+  ///
+  LayoutManager(HWND i_hwnd);
+  
+  /** restrict the smallest size of the window to the current size of it or
+      specified by i_size */
+  void restrictSmallestSize(Restrict i_restrict = RESTRICT_BOTH,
+                           SIZE *i_size = NULL);
+  
+  /** restrict the largest size of the window to the current size of it or
+      specified by i_size */
+  void restrictLargestSize(Restrict i_restrict = RESTRICT_BOTH,
+                          SIZE *i_size = NULL);
+  
+  ///
+  bool addItem(HWND i_hwnd,
+              Origin i_originLeft = ORIGIN_LEFT_EDGE,
+              Origin i_originTop = ORIGIN_TOP_EDGE,
+              Origin i_originRight = ORIGIN_LEFT_EDGE,
+              Origin i_originBottom = ORIGIN_TOP_EDGE);
+  ///
+  void adjust() const;
+
+  /// draw size box
+  virtual BOOL wmPaint();
+
+  /// size restriction
+  virtual BOOL wmSizing(int i_edge, RECT *io_rc);
+
+  /// hittest for size box
+  virtual BOOL wmNcHitTest(int i_x, int i_y);
+
+  /// WM_SIZE
+  virtual BOOL wmSize(DWORD /* i_fwSizeType */, short /* i_nWidth */,
+                     short /* i_nHeight */);
+  
+  /// forward message
+  virtual BOOL defaultWMHandler(UINT i_message, WPARAM i_wParam,
+                               LPARAM i_lParam);
+};
+
+
+#endif // !_LAYOUTMANAGER_H
diff --git a/mayu-common.mak b/mayu-common.mak
new file mode 100644 (file)
index 0000000..a57fefa
--- /dev/null
@@ -0,0 +1,272 @@
+############################################################## -*- Makefile -*-
+#
+# Makefile for mayu
+#
+###############################################################################
+
+
+!if "$(VERSION)" == ""
+#VERSION               = 3.31
+VERSION                = snapshot20050612
+!endif
+
+!if "$(TARGETOS)" == "WINNT"
+OS_SPECIFIC_DEFINES    =  -DUNICODE -D_UNICODE
+DISTRIB_OS     = xp
+!endif
+
+!if "$(TARGETOS)" == "WIN95"
+OS_SPECIFIC_DEFINES    =  -D_MBCS
+DISTRIB_OS     = 9x
+!endif
+
+!if "$(TARGETOS)" == "BOTH"
+!error You must specify TARGETOS=WINNT
+!endif
+
+
+COMMON_DEFINES = -DSTRICT -D_WIN32_IE=0x0500 $(OS_SPECIFIC_DEFINES)
+BOOST_DIR      = ../boost_$(BOOST_VER)_0
+
+
+# mayu.exe     ###############################################################
+
+TARGET_1       = $(OUT_DIR)\mayu.exe
+OBJS_1         =                                       \
+               $(OUT_DIR)\compiler_specific_func.obj   \
+               $(OUT_DIR)\dlgeditsetting.obj           \
+               $(OUT_DIR)\dlginvestigate.obj           \
+               $(OUT_DIR)\dlglog.obj                   \
+               $(OUT_DIR)\dlgsetting.obj               \
+               $(OUT_DIR)\dlgversion.obj               \
+               $(OUT_DIR)\engine.obj                   \
+               $(OUT_DIR)\focus.obj                    \
+               $(OUT_DIR)\function.obj                 \
+               $(OUT_DIR)\keyboard.obj                 \
+               $(OUT_DIR)\keymap.obj                   \
+               $(OUT_DIR)\layoutmanager.obj            \
+               $(OUT_DIR)\mayu.obj                     \
+               $(OUT_DIR)\parser.obj                   \
+               $(OUT_DIR)\registry.obj                 \
+               $(OUT_DIR)\setting.obj                  \
+               $(OUT_DIR)\stringtool.obj               \
+               $(OUT_DIR)\target.obj                   \
+               $(OUT_DIR)\vkeytable.obj                \
+               $(OUT_DIR)\windowstool.obj              \
+
+SRCS_1         =                               \
+               compiler_specific_func.cpp      \
+               dlgeditsetting.cpp              \
+               dlginvestigate.cpp              \
+               dlglog.cpp                      \
+               dlgsetting.cpp                  \
+               dlgversion.cpp                  \
+               engine.cpp                      \
+               focus.cpp                       \
+               function.cpp                    \
+               keyboard.cpp                    \
+               keymap.cpp                      \
+               layoutmanager.cpp               \
+               mayu.cpp                        \
+               parser.cpp                      \
+               registry.cpp                    \
+               setting.cpp                     \
+               stringtool.cpp                  \
+               target.cpp                      \
+               vkeytable.cpp                   \
+               windowstool.cpp                 \
+
+RES_1          = $(OUT_DIR)\mayu.res
+
+LIBS_1         =                       \
+               $(guixlibsmt)           \
+               shell32.lib             \
+               comctl32.lib            \
+               wtsapi32.lib            \
+               $(OUT_DIR)\mayu.lib     \
+
+EXTRADEP_1     = $(OUT_DIR)\mayu.lib
+
+# mayu.dll     ###############################################################
+
+TARGET_2       = $(OUT_DIR)\mayu.dll
+OBJS_2         = $(OUT_DIR)\hook.obj $(OUT_DIR)\stringtool.obj
+SRCS_2         = hook.cpp stringtool.cpp
+LIBS_2         = $(guixlibsmt) imm32.lib
+
+
+# mayu.lib     ###############################################################
+
+TARGET_3       = $(OUT_DIR)\mayu.lib
+DLL_3          = $(OUT_DIR)\mayu.dll
+
+
+# distribution ###############################################################
+
+DISTRIB_SETTINGS =                     \
+               104.mayu                \
+               104on109.mayu           \
+               109.mayu                \
+               109on104.mayu           \
+               default.mayu            \
+               emacsedit.mayu          \
+               dot.mayu                \
+
+DISTRIB_MANUAL =                               \
+               doc\banner-ja.gif               \
+               doc\CONTENTS-ja.html            \
+               doc\CUSTOMIZE-ja.html           \
+               doc\edit-setting-ja.png         \
+               doc\investigate-ja.png          \
+               doc\log-ja.png                  \
+               doc\MANUAL-ja.html              \
+               doc\menu-ja.png                 \
+               doc\pause-ja.png                \
+               doc\README-ja.html              \
+               doc\README.css                  \
+               doc\setting-ja.png              \
+               doc\syntax.txt                  \
+               doc\target.png                  \
+               doc\version-ja.png              \
+               mayu-mode.el                    \
+
+DISTRIB_CONTRIBS =                             \
+               contrib\109onAX.mayu            \
+               contrib\mayu-settings.txt       \
+               contrib\dvorak.mayu             \
+               contrib\dvorak109.mayu          \
+               contrib\keitai.mayu             \
+               contrib\ax.mayu                 \
+               contrib\98x1.mayu               \
+               contrib\DVORAKon109.mayu        \
+
+!if "$(TARGETOS)" == "WINNT"
+DISTRIB_DRIVER =                               \
+               d\i386\mayud.sys                \
+               d\rescue\i386\mayudrsc.sys      \
+               d\nt4\i386\mayudnt4.sys
+!endif
+!if "$(TARGETOS)" == "WIN95"
+DISTRIB_DRIVER = d_win9x\mayud.vxd
+!endif
+
+DISTRIB                =                       \
+               $(TARGET_1)             \
+               $(TARGET_2)             \
+               s\$(OUT_DIR)\setup.exe  \
+               $(DISTRIB_SETTINGS)     \
+               $(DISTRIB_MANUAL)       \
+               $(DISTRIB_CONTRIBS)     \
+               $(DISTRIB_DRIVER)       \
+
+
+# tools                ###############################################################
+
+IEXPRESS       = iexpress
+DOCXX          = doc++.exe
+MAKEDEPEND     = perl tools/makedepend -o.obj
+DOS2UNIX       = perl tools/dos2unix
+UNIX2DOS       = perl tools/unix2dos
+MAKEFUNC       = perl tools/makefunc
+GETCVSFILES    = perl tools/getcvsfiles
+GENIEXPRESS    = perl tools/geniexpress
+
+
+# rules                ###############################################################
+
+all:           boost $(OUT_DIR) $(TARGET_1) $(TARGET_2) $(TARGET_3)
+
+$(OUT_DIR):
+               if not exist "$(OUT_DIR)\\" $(MKDIR) $(OUT_DIR)
+
+functions.h:   engine.h tools/makefunc
+               $(MAKEFUNC) < engine.h > functions.h
+
+clean::
+               -$(RM) $(TARGET_1) $(TARGET_2) $(TARGET_3)
+               -$(RM) $(OUT_DIR)\*.obj
+               -$(RM) $(OUT_DIR)\*.res $(OUT_DIR)\*.exp
+               -$(RM) mayu.aps mayu.opt $(OUT_DIR)\*.pdb
+               -$(RM) *~ $(CLEAN)
+               -$(RMDIR) $(OUT_DIR)
+
+depend::
+               $(MAKEDEPEND) -fmayu-common.mak \
+               -- $(DEPENDFLAGS) -- $(SRCS_1) $(SRCS_2)
+
+distrib:
+               -@echo "we need cygwin tool"
+               -rm -f mayu-$(VERSION) 
+               -ln -s . mayu-$(VERSION)
+               -bash -c "tar cvjf mayu-$(VERSION)-src.tar.bz2 `$(GETCVSFILES) | sed 's/^./mayu-$(VERSION)/'`"
+               -rm -f mayu-$(VERSION) 
+               -$(GENIEXPRESS) \
+                       mayu-$(VERSION)-$(DISTRIB_OS).exe \
+                       "MADO TSUKAI NO YUUTSU $(VERSION) $(TARGETOS)" \
+                       setup.exe $(DISTRIB) > __mayu__.sed
+               -$(UNIX2DOS) $(DISTRIB_SETTINGS) $(DISTRIB_CONTRIBS)
+               -$(IEXPRESS) /N __mayu__.sed
+               -$(DOS2UNIX) $(DISTRIB_SETTINGS) $(DISTRIB_CONTRIBS)
+               -$(RM) __mayu__.sed
+
+srcdesc::
+               @$(ECHO) USE DOC++ 3.4.4 OR HIGHER
+               $(DOCXX) *.h
+
+# DO NOT DELETE
+
+$(OUT_DIR)\compiler_specific_func.obj: compiler_specific.h \
+ compiler_specific_func.h misc.h stringtool.h
+$(OUT_DIR)\dlgeditsetting.obj: compiler_specific.h dlgeditsetting.h \
+ layoutmanager.h mayurc.h misc.h stringtool.h windowstool.h
+$(OUT_DIR)\dlginvestigate.obj: compiler_specific.h d\ioctl.h \
+ dlginvestigate.h driver.h engine.h focus.h function.h functions.h hook.h \
+ keyboard.h keymap.h mayurc.h misc.h msgstream.h multithread.h parser.h \
+ setting.h stringtool.h target.h vkeytable.h windowstool.h
+$(OUT_DIR)\dlglog.obj: compiler_specific.h dlglog.h layoutmanager.h mayu.h \
+ mayurc.h misc.h msgstream.h multithread.h registry.h stringtool.h \
+ windowstool.h
+$(OUT_DIR)\dlgsetting.obj: compiler_specific.h d\ioctl.h dlgeditsetting.h \
+ driver.h function.h functions.h keyboard.h keymap.h layoutmanager.h mayu.h \
+ mayurc.h misc.h multithread.h parser.h registry.h setting.h stringtool.h \
+ windowstool.h
+$(OUT_DIR)\dlgversion.obj: compiler_specific.h compiler_specific_func.h \
+ layoutmanager.h mayu.h mayurc.h misc.h stringtool.h windowstool.h
+$(OUT_DIR)\engine.obj: compiler_specific.h d\ioctl.h driver.h engine.h \
+ errormessage.h function.h functions.h hook.h keyboard.h keymap.h mayurc.h \
+ misc.h msgstream.h multithread.h parser.h setting.h stringtool.h \
+ windowstool.h
+$(OUT_DIR)\focus.obj: compiler_specific.h focus.h misc.h stringtool.h \
+ windowstool.h
+$(OUT_DIR)\function.obj: compiler_specific.h d\ioctl.h driver.h engine.h \
+ function.h functions.h hook.h keyboard.h keymap.h mayu.h mayurc.h misc.h \
+ msgstream.h multithread.h parser.h registry.h setting.h stringtool.h \
+ vkeytable.h windowstool.h
+$(OUT_DIR)\keyboard.obj: compiler_specific.h d\ioctl.h driver.h keyboard.h \
+ misc.h stringtool.h
+$(OUT_DIR)\keymap.obj: compiler_specific.h d\ioctl.h driver.h \
+ errormessage.h function.h functions.h keyboard.h keymap.h misc.h \
+ multithread.h parser.h setting.h stringtool.h
+$(OUT_DIR)\layoutmanager.obj: compiler_specific.h layoutmanager.h misc.h \
+ stringtool.h windowstool.h
+$(OUT_DIR)\mayu.obj: compiler_specific.h compiler_specific_func.h d\ioctl.h \
+ dlginvestigate.h dlglog.h dlgsetting.h dlgversion.h driver.h engine.h \
+ errormessage.h focus.h function.h functions.h hook.h keyboard.h keymap.h \
+ mayu.h mayuipc.h mayurc.h misc.h msgstream.h multithread.h parser.h \
+ registry.h setting.h stringtool.h target.h windowstool.h
+$(OUT_DIR)\parser.obj: compiler_specific.h errormessage.h misc.h parser.h \
+ stringtool.h
+$(OUT_DIR)\registry.obj: array.h compiler_specific.h misc.h registry.h \
+ stringtool.h
+$(OUT_DIR)\setting.obj: array.h compiler_specific.h d\ioctl.h dlgsetting.h \
+ driver.h errormessage.h function.h functions.h keyboard.h keymap.h mayu.h \
+ mayurc.h misc.h multithread.h parser.h registry.h setting.h stringtool.h \
+ vkeytable.h windowstool.h
+$(OUT_DIR)\stringtool.obj: array.h compiler_specific.h misc.h stringtool.h
+$(OUT_DIR)\target.obj: compiler_specific.h mayurc.h misc.h stringtool.h \
+ target.h windowstool.h
+$(OUT_DIR)\vkeytable.obj: compiler_specific.h misc.h vkeytable.h
+$(OUT_DIR)\windowstool.obj: array.h compiler_specific.h misc.h stringtool.h \
+ windowstool.h
+$(OUT_DIR)\hook.obj: compiler_specific.h hook.h misc.h stringtool.h
+$(OUT_DIR)\stringtool.obj: array.h compiler_specific.h misc.h stringtool.h
diff --git a/mayu-mode.el b/mayu-mode.el
new file mode 100644 (file)
index 0000000..54b1724
--- /dev/null
@@ -0,0 +1,180 @@
+;;; mayu-mode.el --- mayu setting editing commands for Emacs
+
+;;; Copyright (C) 2000-2005 TAGA Nayuta <nayuta@ganaware.org>
+
+;; Author: TAGA Nayuta <nayuta@ganaware.org>
+;; Maintainer: TAGA Nayuta <nayuta@ganaware.org>
+;; Keywords: languages, faces
+
+(require 'font-lock)
+
+(defvar
+  mayu-font-lock-keywords
+  (let* ((warning-face 
+         (if (boundp 'font-lock-warning-face)
+             font-lock-warning-face
+           font-lock-function-name-face))
+        (preprocessor-face 
+         (if (boundp 'font-lock-builtin-face)
+             font-lock-builtin-face
+           font-lock-preprocessor-face))
+        (function-name-face 
+         (if (boundp 'font-lock-builtin-face)
+             font-lock-builtin-face
+           font-lock-function-name-face)))
+    `((,(concat
+        "\\<\\("
+        "[AMCWS]-"
+        "\\|IC-"
+        ;;"\\|I-"
+        "\\|[INCSK]L-"
+        "\\|M[0-9]-"
+        "\\|L[0-9]-"
+        "\\|U-"
+        "\\|D-"
+        "\\|R-"
+        "\\|E[01]-"
+        "\\|MAX-"
+        "\\|MIN-"
+        "\\|MMAX-"
+        "\\|MMIN-"
+        "\\)"
+        ) . font-lock-keyword-face)
+      ("#.*$" . font-lock-comment-face)
+      ("/[^/\n]*/" . font-lock-string-face)
+      ("\\\\$" . ,warning-face)
+      (,(concat
+        "^\\s *\\<\\("
+        "key"
+        "\\|event\\s +\\(prefixed\\|after-key-up\\|before-key-down\\)"
+        "\\|keyseq"
+        "\\|def\\s +\\(key\\|alias\\|mod\\|sync\\|subst\\|option\\)"
+        "\\|mod"
+        "\\|keymap"
+        "\\|keymap2"
+        "\\|window"
+        "\\|include"
+        "\\|if"
+        "\\|define"
+        "\\|else"
+        "\\|elseif"
+        "\\|elsif"
+        "\\|endif"
+        "\\)\\>"
+        ) . ,preprocessor-face)
+      (,(concat
+        "&\\("
+        "Default"
+        "\\|KeymapParent"
+        "\\|KeymapWindow"
+        "\\|KeymapPrevPrefix"
+        "\\|OtherWindowClass"
+        "\\|Prefix"
+        "\\|Keymap"
+        "\\|Sync"
+        "\\|Toggle"
+        "\\|EditNextModifier"
+        "\\|Variable"
+        "\\|Repeat"
+        "\\|Undefined"
+        "\\|Ignore"
+        "\\|PostMessage"
+        "\\|ShellExecute"
+        "\\|SetForegroundWindow"
+        "\\|LoadSetting"
+        "\\|VK"
+        "\\|Wait"
+        "\\|InvestigateCommand"
+        "\\|MayuDialog"
+        "\\|DescribeBindings"
+        "\\|HelpMessage"
+        "\\|HelpVariable"
+        "\\|WindowRaise"
+        "\\|WindowLower"
+        "\\|WindowMinimize"
+        "\\|WindowMaximize"
+        "\\|WindowHMaximize"
+        "\\|WindowVMaximize"
+        "\\|WindowHVMaximize"
+        "\\|WindowMove"
+        "\\|WindowMoveTo"
+        "\\|WindowMoveVisibly"
+        "\\|WindowClingToLeft"
+        "\\|WindowClingToRight"
+        "\\|WindowClingToTop"
+        "\\|WindowClingToBottom"
+        "\\|WindowClose"
+        "\\|WindowToggleTopMost"
+        "\\|WindowIdentify"
+        "\\|WindowSetAlpha"
+        "\\|WindowRedraw"
+        "\\|WindowResizeTo"
+        "\\|WindowMonitor"
+        "\\|WindowMonitorTo"
+        "\\|MouseMove"
+        "\\|MouseWheel"
+        "\\|ClipboardChangeCase"
+        "\\|ClipboardUpcaseWord"
+        "\\|ClipboardDowncaseWord"
+        "\\|ClipboardCopy"
+        "\\|EmacsEditKillLinePred"
+        "\\|EmacsEditKillLineFunc"
+        "\\|LogClear"
+        "\\|DirectSSTP"
+        "\\|PlugIn"
+        "\\|Recenter"
+        "\\|SetImeStatus"
+        "\\|SetImeString"
+        "\\)\\>"
+        ) . ,function-name-face)
+      "Default font-lock-keywords for mayu mode.")))
+
+(defvar mayu-mode-syntax-table nil
+  "syntax table used in mayu mode")
+(setq mayu-mode-syntax-table (make-syntax-table))
+(modify-syntax-entry ?# "<\n" mayu-mode-syntax-table)
+(modify-syntax-entry ?\n ">#" mayu-mode-syntax-table)
+
+(defvar mayu-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-c\C-c" 'comment-region)
+    map))
+
+;;;###autoload
+(defun mayu-mode ()
+  "A major mode to edit mayu setting files."
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map mayu-mode-map)
+
+  (make-local-variable 'comment-start)
+  (setq comment-start "# ")
+  (make-local-variable 'comment-start-skip)
+  (setq comment-start-skip "\\(^\\|\\s-\\);?#+ *")
+  (make-local-variable 'comment-indent-function)
+  (setq comment-indent-function 'mayu-comment-indent)
+  (make-local-variable 'parse-sexp-ignore-comments)
+  (setq parse-sexp-ignore-comments t)
+
+  (make-local-variable 'font-lock-defaults)
+  (setq major-mode 'mayu-mode
+       mode-name "mayu"
+       font-lock-defaults '(mayu-font-lock-keywords nil)
+       )
+  (set-syntax-table mayu-mode-syntax-table)
+  (run-hooks 'mayu-mode-hook))
+
+;;; derived from perl-mode.el
+(defun mayu-comment-indent ()
+  (if (and (bolp) (not (eolp)))
+      0                                        ;Existing comment at bol stays there.
+    (save-excursion
+      (skip-chars-backward " \t")
+      (max (if (bolp)                  ;Else indent at comment column
+              0                        ; except leave at least one space if
+            (1+ (current-column)))     ; not at beginning of line.
+          comment-column))))
+
+(provide 'mayu-mode)
+
+;;; mayu-mode.el ends here
diff --git a/mayu-vc.mak b/mayu-vc.mak
new file mode 100644 (file)
index 0000000..65f3f6b
--- /dev/null
@@ -0,0 +1,87 @@
+############################################################## -*- Makefile -*-
+#
+# Makefile for mayu (Visual C++)
+#
+#      make release version: nmake nodebug=1
+#      make debug version: nmake
+#
+###############################################################################
+
+!if "$(BOOST_VER)" == ""
+BOOST_VER      = 1_32
+!endif
+INCLUDES       = -I$(BOOST_DIR)        # why here ?
+DEPENDIGNORE   = --ignore=$(BOOST_DIR)
+
+!if "$(MAYU_VC)" == ""
+MAYU_VC        = vc6
+!endif
+
+!if ( "$(MAYU_VC)" == "vct" )
+MAYU_REGEX_VC  = vc71
+!else
+MAYU_REGEX_VC  = $(MAYU_VC)
+!endif
+
+!include <vc.mak>
+!include <mayu-common.mak>
+
+DEFINES                = $(COMMON_DEFINES) -DVERSION=""""$(VERSION)"""" \
+               -DLOGNAME=""""$(LOGNAME)"""" \
+               -DCOMPUTERNAME=""""$(COMPUTERNAME)""""
+# INCLUDES     = -I$(BOOST_DIR)        # make -f mayu-vc.mak depend fails ...
+
+LDFLAGS_1      =                                               \
+               $(guilflags)                                    \
+               /PDB:$(TARGET_1).pdb                            \
+               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC) \
+
+LDFLAGS_2      =                                               \
+               $(dlllflags)                                    \
+               /PDB:$(TARGET_2).pdb                            \
+               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC) \
+
+$(TARGET_1):   $(OBJS_1) $(RES_1) $(EXTRADEP_1)
+       $(link) -out:$@ $(ldebug) $(LDFLAGS_1) $(OBJS_1) $(LIBS_1) $(RES_1)
+
+$(TARGET_2):   $(OBJS_2) $(RES_2) $(EXTRADEP_2)
+       $(link) -out:$@ $(ldebug) $(LDFLAGS_2) $(OBJS_2) $(LIBS_2) $(RES_2)
+
+$(TARGET_3):   $(DLL_3)
+
+REGEXPP_XCFLAGS        = $(REGEXPP_XCFLAGS) XCFLAGS=-D_WCTYPE_INLINE_DEFINED
+
+clean::
+               -$(RM) mayu.aps mayu.opt *.pdb
+
+boost:
+               cd $(BOOST_DIR)/libs/regex/build/
+               $(MAKE) -f $(MAYU_REGEX_VC).mak $(REGEXPP_XCFLAGS) main_dir libboost_regex-$(MAYU_REGEX_VC)-mt-s-$(BOOST_VER)_dir ./$(MAYU_REGEX_VC)/libboost_regex-$(MAYU_REGEX_VC)-mt-s-$(BOOST_VER).lib
+               cd ../../../../mayu
+
+distclean::    clean
+               cd $(BOOST_DIR)/libs/regex/build/
+               -$(MAKE) -k -f $(MAYU_REGEX_VC).mak clean
+               cd ../../../../mayu
+
+batch:
+!if "$(MAYU_VC)" != "vct"
+               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT
+!endif
+               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1
+               cd s
+               -$(MAKE) -k -f setup-vc.mak MAYU_VC=$(MAYU_VC) batch
+               cd ..
+
+batch_clean:
+               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1 clean
+               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT clean
+               cd s
+               -$(MAKE) -k -f setup-vc.mak MAYU_VC=$(MAYU_VC) batch_clean
+               cd ..
+
+batch_distclean: batch_clean
+               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT distclean
+
+batch_distrib: batch
+               -$(MAKE) -k -f mayu-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1 distrib
diff --git a/mayu.cpp b/mayu.cpp
new file mode 100644 (file)
index 0000000..36cc3d3
--- /dev/null
+++ b/mayu.cpp
@@ -0,0 +1,979 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// mayu.cpp
+
+
+#define APSTUDIO_INVOKED
+
+#include "misc.h"
+#include "compiler_specific_func.h"
+#include "dlginvestigate.h"
+#include "dlglog.h"
+#include "dlgsetting.h"
+#include "dlgversion.h"
+#include "engine.h"
+#include "errormessage.h"
+#include "focus.h"
+#include "function.h"
+#include "hook.h"
+#include "mayu.h"
+#include "mayuipc.h"
+#include "mayurc.h"
+#include "msgstream.h"
+#include "multithread.h"
+#include "registry.h"
+#include "setting.h"
+#include "target.h"
+#include "windowstool.h"
+#include <process.h>
+#include <time.h>
+#include <commctrl.h>
+#include <wtsapi32.h>
+
+
+///
+#define ID_MENUITEM_reloadBegin _APS_NEXT_COMMAND_VALUE
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Mayu
+
+
+///
+class Mayu
+{
+  HWND m_hwndTaskTray;                         /// tasktray window
+  HWND m_hwndLog;                              /// log dialog
+  HWND m_hwndInvestigate;                      /// investigate dialog
+  HWND m_hwndVersion;                          /// version dialog
+  
+  UINT m_WM_TaskbarRestart;                    /** window message sent when
+                                                    taskber restarts */
+  UINT m_WM_MayuIPC;                           /** IPC message sent from
+                                                   other applications */
+  NOTIFYICONDATA m_ni;                         /// taskbar icon data
+  HICON m_tasktrayIcon[2];                     /// taskbar icon
+  bool m_canUseTasktrayBaloon;                 /// 
+
+  tomsgstream m_log;                           /** log stream (output to log
+                                                   dialog's edit) */
+
+  HMENU m_hMenuTaskTray;                       /// tasktray menu
+  
+  Setting *m_setting;                          /// current setting
+  bool m_isSettingDialogOpened;                        /// is setting dialog opened ?
+  
+  Engine m_engine;                             /// engine
+
+  bool m_usingSN;                 /// using WTSRegisterSessionNotification() ?
+  time_t m_startTime;                          /// mayu started at ...
+
+  enum
+  { 
+    WM_APP_taskTrayNotify = WM_APP + 101,      ///
+    WM_APP_msgStreamNotify = WM_APP + 102,     ///
+    ID_TaskTrayIcon = 1,                       ///
+  };
+
+private:
+  /// register class for tasktray
+  ATOM Register_tasktray()
+  {
+    WNDCLASS wc;
+    wc.style         = 0;
+    wc.lpfnWndProc   = tasktray_wndProc;
+    wc.cbClsExtra    = 0;
+    wc.cbWndExtra    = sizeof(Mayu *);
+    wc.hInstance     = g_hInst;
+    wc.hIcon         = NULL;
+    wc.hCursor       = NULL;
+    wc.hbrBackground = NULL;
+    wc.lpszMenuName  = NULL;
+    wc.lpszClassName = _T("mayuTasktray");
+    return RegisterClass(&wc);
+  }
+
+  /// notify handler
+  BOOL notifyHandler(COPYDATASTRUCT *cd)
+  {
+      switch (cd->dwData)
+      {
+       case Notify::Type_setFocus:
+       case Notify::Type_name:
+       {
+         NotifySetFocus *n = (NotifySetFocus *)cd->lpData;
+         n->m_className[NUMBER_OF(n->m_className) - 1] = _T('\0');
+         n->m_titleName[NUMBER_OF(n->m_titleName) - 1] = _T('\0');
+         
+         if (n->m_type == Notify::Type_setFocus)
+           m_engine.setFocus(n->m_hwnd, n->m_threadId,
+                             n->m_className, n->m_titleName, false);
+
+         {
+           Acquire a(&m_log, 1);
+           m_log << _T("HWND:\t") << std::hex
+                 << reinterpret_cast<int>(n->m_hwnd)
+                 << std::dec << std::endl;
+           m_log << _T("THREADID:") << static_cast<int>(n->m_threadId)
+                 << std::endl;
+         }
+         Acquire a(&m_log, (n->m_type == Notify::Type_name) ? 0 : 1);
+         m_log << _T("CLASS:\t") << n->m_className << std::endl;
+         m_log << _T("TITLE:\t") << n->m_titleName << std::endl;
+         
+         bool isMDI = true;
+         HWND hwnd = getToplevelWindow(n->m_hwnd, &isMDI);
+         RECT rc;
+         if (isMDI)
+         {
+           getChildWindowRect(hwnd, &rc);
+           m_log << _T("MDI Window Position/Size: (")
+                 << rc.left << _T(", ") << rc.top << _T(") / (")
+                 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
+                 << std::endl;
+           hwnd = getToplevelWindow(n->m_hwnd, NULL);
+         }
+         
+         GetWindowRect(hwnd, &rc);
+         m_log << _T("Toplevel Window Position/Size: (")
+               << rc.left << _T(", ") << rc.top << _T(") / (")
+               << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
+               << std::endl;
+
+         SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
+         m_log << _T("Desktop Window Position/Size: (")
+               << rc.left << _T(", ") << rc.top << _T(") / (")
+               << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
+               << std::endl;
+         
+         m_log << std::endl;
+         break;
+       }
+       
+       case Notify::Type_lockState:
+       {
+         NotifyLockState *n = (NotifyLockState *)cd->lpData;
+         m_engine.setLockState(n->m_isNumLockToggled,
+                               n->m_isCapsLockToggled,
+                               n->m_isScrollLockToggled,
+                               n->m_isKanaLockToggled,
+                               n->m_isImeLockToggled,
+                               n->m_isImeCompToggled);
+#if 0
+         Acquire a(&m_log, 0);
+         if (n->m_isKanaLockToggled) {
+           m_log << _T("Notify::Type_lockState Kana on  : ");
+         } else {
+           m_log << _T("Notify::Type_lockState Kana off : ");
+         }
+         m_log << n->m_debugParam << ", "
+               << g_hookData->m_correctKanaLockHandling << std::endl;
+#endif
+         break;
+       }
+
+       case Notify::Type_sync:
+       {
+         m_engine.syncNotify();
+         break;
+       }
+
+       case Notify::Type_threadDetach:
+       {
+         NotifyThreadDetach *n = (NotifyThreadDetach *)cd->lpData;
+         m_engine.threadDetachNotify(n->m_threadId);
+         break;
+       }
+
+       case Notify::Type_command:
+       {
+         NotifyCommand *n = (NotifyCommand *)cd->lpData;
+         m_engine.commandNotify(n->m_hwnd, n->m_message,
+                                n->m_wParam, n->m_lParam);
+         break;
+       }
+
+       case Notify::Type_show:
+       {
+         NotifyShow *n = (NotifyShow *)cd->lpData;
+         switch (n->m_show)
+         {
+           case NotifyShow::Show_Maximized:
+             m_engine.setShow(true, false, n->m_isMDI);
+             break;
+           case NotifyShow::Show_Minimized:
+             m_engine.setShow(false, true, n->m_isMDI);
+             break;
+           case NotifyShow::Show_Normal:
+           default:
+             m_engine.setShow(false, false, n->m_isMDI);
+             break;
+         }       
+         break;
+       }
+
+       case Notify::Type_log:
+       {
+         Acquire a(&m_log, 1);
+         NotifyLog *n = (NotifyLog *)cd->lpData;
+         m_log << _T("hook log: ") << n->m_msg << std::endl;
+         break;
+       }
+      }
+      return true;
+  }
+
+  /// window procedure for tasktray
+  static LRESULT CALLBACK
+  tasktray_wndProc(HWND i_hwnd, UINT i_message,
+                  WPARAM i_wParam, LPARAM i_lParam)
+  {
+    Mayu *This = reinterpret_cast<Mayu *>(GetWindowLong(i_hwnd, 0));
+
+    if (!This)
+      switch (i_message)
+      {
+       case WM_CREATE:
+         This = reinterpret_cast<Mayu *>(
+           reinterpret_cast<CREATESTRUCT *>(i_lParam)->lpCreateParams);
+         SetWindowLong(i_hwnd, 0, (long)This);
+         return 0;
+      }
+    else
+      switch (i_message)
+      {
+        case WM_COPYDATA:
+       {
+         COPYDATASTRUCT *cd;
+         cd = reinterpret_cast<COPYDATASTRUCT *>(i_lParam);
+         return This->notifyHandler(cd);
+       }
+        case WM_QUERYENDSESSION:
+         This->m_engine.prepairQuit();
+         PostQuitMessage(0);
+         return TRUE;
+
+#ifndef WM_WTSSESSION_CHANGE                   // WinUser.h
+#  define WM_WTSSESSION_CHANGE            0x02B1
+#endif
+       case WM_WTSSESSION_CHANGE:
+       {
+         const char *m = "";
+         switch (i_wParam)
+         {
+#ifndef WTS_CONSOLE_CONNECT                    // WinUser.h
+#  define WTS_CONSOLE_CONNECT                0x1
+#  define WTS_CONSOLE_DISCONNECT             0x2
+#  define WTS_REMOTE_CONNECT                 0x3
+#  define WTS_REMOTE_DISCONNECT              0x4
+#  define WTS_SESSION_LOGON                  0x5
+#  define WTS_SESSION_LOGOFF                 0x6
+#  define WTS_SESSION_LOCK                   0x7
+#  define WTS_SESSION_UNLOCK                 0x8
+#endif
+           case WTS_CONSOLE_CONNECT:
+             m = "WTS_CONSOLE_CONNECT";
+             if (!This->m_engine.resume()) {
+               This->m_engine.prepairQuit();
+               PostQuitMessage(0);
+             }
+             break;
+           case WTS_CONSOLE_DISCONNECT:
+             m = "WTS_CONSOLE_DISCONNECT";
+             This->m_engine.pause();
+             break;
+           case WTS_REMOTE_CONNECT: m = "WTS_REMOTE_CONNECT"; break;
+           case WTS_REMOTE_DISCONNECT: m = "WTS_REMOTE_DISCONNECT"; break;
+           case WTS_SESSION_LOGON:  m = "WTS_SESSION_LOGON"; break;
+           case WTS_SESSION_LOGOFF: m = "WTS_SESSION_LOGOFF"; break;
+           case WTS_SESSION_LOCK: m = "WTS_SESSION_LOCK"; break;
+           case WTS_SESSION_UNLOCK: m = "WTS_SESSION_UNLOCK"; break;
+             //case WTS_SESSION_REMOTE_CONTROL: m = "WTS_SESSION_REMOTE_CONTROL"; break;
+         }
+         This->m_log << _T("WM_WTSESSION_CHANGE(")
+                     << i_wParam << ", " << i_lParam << "): "
+                     << m << std::endl;
+         return TRUE;
+       }
+       case WM_APP_msgStreamNotify:
+       {
+         tomsgstream::StreamBuf *log =
+           reinterpret_cast<tomsgstream::StreamBuf *>(i_lParam);
+         const tstring &str = log->acquireString();
+         editInsertTextAtLast(GetDlgItem(This->m_hwndLog, IDC_EDIT_log),
+                              str, 65000);
+         log->releaseString();
+         return 0;
+       }
+       
+       case WM_APP_taskTrayNotify:
+       {
+         if (i_wParam == ID_TaskTrayIcon)
+           switch (i_lParam)
+           {
+             case WM_RBUTTONUP:
+             {
+               POINT p;
+               CHECK_TRUE( GetCursorPos(&p) );
+               SetForegroundWindow(i_hwnd);
+               HMENU hMenuSub = GetSubMenu(This->m_hMenuTaskTray, 0);
+               if (This->m_engine.getIsEnabled())
+                 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
+                               MF_UNCHECKED | MF_BYCOMMAND);
+               else
+                 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
+                               MF_CHECKED | MF_BYCOMMAND);
+               CHECK_TRUE( SetMenuDefaultItem(hMenuSub,
+                                         ID_MENUITEM_investigate, FALSE) );
+
+               // create reload menu
+               HMENU hMenuSubSub = GetSubMenu(hMenuSub, 1);
+               Registry reg(MAYU_REGISTRY_ROOT);
+               int mayuIndex;
+               reg.read(_T(".mayuIndex"), &mayuIndex, 0);
+               while (DeleteMenu(hMenuSubSub, 0, MF_BYPOSITION))
+                 ;
+               tregex getName(_T("^([^;]*);"));
+               for (int index = 0; ; index ++)
+               {
+                 _TCHAR buf[100];
+                 _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
+                 tstringi dot_mayu;
+                 if (!reg.read(buf, &dot_mayu))
+                   break;
+                 tsmatch what;
+                 if (boost::regex_search(dot_mayu, what, getName))
+                 {
+                   MENUITEMINFO mii;
+                   std::memset(&mii, 0, sizeof(mii));
+                   mii.cbSize = sizeof(mii);
+                   mii.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE;
+                   mii.fType = MFT_STRING;
+                   mii.fState =
+                     MFS_ENABLED | ((mayuIndex == index) ? MFS_CHECKED : 0);
+                   mii.wID = ID_MENUITEM_reloadBegin + index;
+                   tstringi name(what.str(1));
+                   mii.dwTypeData = const_cast<_TCHAR *>(name.c_str());
+                   mii.cch = name.size();
+                   
+                   InsertMenuItem(hMenuSubSub, index, TRUE, &mii);
+                 }
+               }
+
+               // show popup menu
+               TrackPopupMenu(hMenuSub, TPM_LEFTALIGN,
+                              p.x, p.y, 0, i_hwnd, NULL);
+               // TrackPopupMenu may fail (ERROR_POPUP_ALREADY_ACTIVE)
+               break;
+             }
+             
+             case WM_LBUTTONDBLCLK:
+               SendMessage(i_hwnd, WM_COMMAND,
+                           MAKELONG(ID_MENUITEM_investigate, 0), 0);
+               break;
+           }
+         return 0;
+       }
+      
+       case WM_COMMAND:
+       {
+         int notify_code = HIWORD(i_wParam);
+         int id = LOWORD(i_wParam);
+         if (notify_code == 0) // menu
+           switch (id)
+           {
+             default:
+               if (ID_MENUITEM_reloadBegin <= id)
+               {
+                 Registry reg(MAYU_REGISTRY_ROOT);
+                 reg.write(_T(".mayuIndex"), id - ID_MENUITEM_reloadBegin);
+                 This->load();
+               }
+               break;
+             case ID_MENUITEM_reload:
+               This->load();
+               break;
+             case ID_MENUITEM_investigate:
+             {
+               ShowWindow(This->m_hwndLog, SW_SHOW);
+               ShowWindow(This->m_hwndInvestigate, SW_SHOW);
+               
+               RECT rc1, rc2;
+               GetWindowRect(This->m_hwndInvestigate, &rc1);
+               GetWindowRect(This->m_hwndLog, &rc2);
+
+               MoveWindow(This->m_hwndLog, rc1.left, rc1.bottom,
+                          rcWidth(&rc1), rcHeight(&rc2), TRUE);
+               
+               SetForegroundWindow(This->m_hwndLog);
+               SetForegroundWindow(This->m_hwndInvestigate);
+               break;
+             }
+             case ID_MENUITEM_setting:
+               if (!This->m_isSettingDialogOpened)
+               {
+                 This->m_isSettingDialogOpened = true;
+                 if (DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_setting),
+                               NULL, dlgSetting_dlgProc))
+                   This->load();
+                 This->m_isSettingDialogOpened = false;
+               }
+               break;
+             case ID_MENUITEM_log:
+               ShowWindow(This->m_hwndLog, SW_SHOW);
+               SetForegroundWindow(This->m_hwndLog);
+               break;
+             case ID_MENUITEM_version:
+               ShowWindow(This->m_hwndVersion, SW_SHOW);
+               SetForegroundWindow(This->m_hwndVersion);
+               break;
+             case ID_MENUITEM_help:
+             {
+               _TCHAR buf[GANA_MAX_PATH];
+               CHECK_TRUE( GetModuleFileName(g_hInst, buf, NUMBER_OF(buf)) );
+               tstringi helpFilename = pathRemoveFileSpec(buf);
+               helpFilename += _T("\\");
+               helpFilename += loadString(IDS_helpFilename);
+               ShellExecute(NULL, _T("open"), helpFilename.c_str(),
+                            NULL, NULL, SW_SHOWNORMAL);
+               break;
+             }
+             case ID_MENUITEM_disable:
+               This->m_engine.enable(!This->m_engine.getIsEnabled());
+               This->showTasktrayIcon();
+               break;
+             case ID_MENUITEM_quit:
+               This->m_engine.prepairQuit();
+               PostQuitMessage(0);
+               break;
+           }
+         return 0;
+       }
+
+       case WM_APP_engineNotify:
+       {
+         switch (i_wParam)
+         {
+           case EngineNotify_shellExecute:
+             This->m_engine.shellExecute();
+             break;
+           case EngineNotify_loadSetting:
+             This->load();
+             break;
+           case EngineNotify_helpMessage:
+             This->showHelpMessage(false);
+             if (i_lParam)
+               This->showHelpMessage(true);
+             break;
+           case EngineNotify_showDlg:
+           {
+             // show investigate/log window
+             int sw = (i_lParam & ~MayuDialogType_mask);
+             HWND hwnd = NULL;
+             switch (static_cast<MayuDialogType>(
+               i_lParam & MayuDialogType_mask))
+             {
+               case MayuDialogType_investigate:
+                 hwnd = This->m_hwndInvestigate;
+                 break;
+               case MayuDialogType_log:
+                 hwnd = This->m_hwndLog;
+                 break;
+             }
+             if (hwnd)
+             {
+               ShowWindow(hwnd, sw);
+               switch (sw)
+               {
+                 case SW_SHOWNORMAL:
+                 case SW_SHOWMAXIMIZED:
+                 case SW_SHOW:
+                 case SW_RESTORE:
+                 case SW_SHOWDEFAULT:
+                   SetForegroundWindow(hwnd);
+                   break;
+               }
+             }
+             break;
+           }
+           case EngineNotify_setForegroundWindow:
+             // FIXME: completely useless. why ?
+             setForegroundWindow(reinterpret_cast<HWND>(i_lParam));
+             {
+               Acquire a(&This->m_log, 1);
+               This->m_log << _T("setForegroundWindow(0x")
+                           << std::hex << i_lParam << std::dec << _T(")")
+                           << std::endl;
+             }
+             break;
+           case EngineNotify_clearLog:
+             SendMessage(This->m_hwndLog, WM_COMMAND,
+                         MAKELONG(IDC_BUTTON_clearLog, 0), 0);
+             break;
+           default:
+             break;
+         }
+         return 0;
+       }
+       
+       case WM_APP_dlglogNotify:
+       {
+         switch (i_wParam)
+         {
+           case DlgLogNotify_logCleared:
+             This->showBanner(true);
+             break;
+           default:
+             break;
+         }
+         return 0;
+       }
+
+       case WM_DESTROY:
+         if (This->m_usingSN)
+         {
+           wtsUnRegisterSessionNotification(i_hwnd);
+           This->m_usingSN = false;
+         }
+         return 0;
+       
+       default:
+         if (i_message == This->m_WM_TaskbarRestart)
+         {
+           if (This->showTasktrayIcon(true))
+           {
+             Acquire a(&This->m_log, 0);
+             This->m_log << _T("Tasktray icon is updated.") << std::endl;
+           }
+           else
+           {
+             Acquire a(&This->m_log, 1);
+             This->m_log << _T("Tasktray icon already exists.") << std::endl;
+           }
+           return 0;
+         }
+         else if (i_message == This->m_WM_MayuIPC)
+         {
+           switch (static_cast<MayuIPCCommand>(i_wParam))
+           {
+             case MayuIPCCommand_Enable:
+               This->m_engine.enable(!!i_lParam);
+               This->showTasktrayIcon();
+               if (i_lParam)
+               {
+                 Acquire a(&This->m_log, 1);
+                 This->m_log << _T("Enabled by another application.")
+                             << std::endl;
+               }
+               else
+               {
+                 Acquire a(&This->m_log, 1);
+                 This->m_log << _T("Disabled by another application.")
+                             << std::endl;
+               }
+               break;
+           }
+         }
+      }
+    return DefWindowProc(i_hwnd, i_message, i_wParam, i_lParam);
+  }
+
+  /// load setting
+  void load()
+  {
+    Setting *newSetting = new Setting;
+
+    // set symbol
+    for (int i = 1; i < __argc; ++ i)
+    {
+      if (__targv[i][0] == _T('-') && __targv[i][1] == _T('D'))
+       newSetting->m_symbols.insert(__targv[i] + 2);
+    }
+
+    if (!SettingLoader(&m_log, &m_log).load(newSetting))
+    {
+      ShowWindow(m_hwndLog, SW_SHOW);
+      SetForegroundWindow(m_hwndLog);
+      delete newSetting;
+      Acquire a(&m_log, 0);
+      m_log << _T("error: failed to load.") << std::endl;
+      return;
+    }
+    m_log << _T("successfully loaded.") << std::endl;
+    while (!m_engine.setSetting(newSetting))
+      Sleep(1000);
+    delete m_setting;
+    m_setting = newSetting;
+  }
+
+  // show message (a baloon from the task tray icon)
+  void showHelpMessage(bool i_doesShow = true)
+  {
+    if (m_canUseTasktrayBaloon)
+    {
+      if (i_doesShow)
+      {
+       tstring helpMessage, helpTitle;
+       m_engine.getHelpMessages(&helpMessage, &helpTitle);
+       tcslcpy(m_ni.szInfo, helpMessage.c_str(), NUMBER_OF(m_ni.szInfo));
+       tcslcpy(m_ni.szInfoTitle, helpTitle.c_str(),
+               NUMBER_OF(m_ni.szInfoTitle));
+       m_ni.dwInfoFlags = NIIF_INFO;
+      }
+      else
+       m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
+      CHECK_TRUE( Shell_NotifyIcon(NIM_MODIFY, &m_ni) );
+    }
+  }
+  
+  // change the task tray icon
+  bool showTasktrayIcon(bool i_doesAdd = false)
+  {
+    m_ni.hIcon  = m_tasktrayIcon[m_engine.getIsEnabled() ? 1 : 0];
+    m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
+    if (i_doesAdd) {
+      // http://support.microsoft.com/kb/418138/JA/
+      int guard = 60;
+      for (; !Shell_NotifyIcon(NIM_ADD, &m_ni) && 0 < guard; -- guard) {
+       if (Shell_NotifyIcon(NIM_MODIFY, &m_ni)) {
+         return true;
+       }
+       Sleep(1000);                            // 1sec
+      }
+      return 0 < guard;
+    } else {
+      return !!Shell_NotifyIcon(NIM_MODIFY, &m_ni);
+    }
+  }
+
+  void showBanner(bool i_isCleared)
+  {
+    time_t now;
+    time(&now);
+      
+    _TCHAR starttimebuf[1024];
+    _TCHAR timebuf[1024];
+
+#ifdef __BORLANDC__
+#pragma message("\t\t****\tAfter std::ostream() is called,  ")
+#pragma message("\t\t****\tstrftime(... \"%%#c\" ...) fails.")
+#pragma message("\t\t****\tWhy ? Bug of Borland C++ 5.5.1 ? ")
+#pragma message("\t\t****\t                         - nayuta")
+    _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%Y/%m/%d %H:%M:%S"),
+             localtime(&now));
+    _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%Y/%m/%d %H:%M:%S"),
+             localtime(&m_startTime));
+#else
+    _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%#c"), localtime(&now));
+    _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%#c"),
+             localtime(&m_startTime));
+#endif
+      
+    Acquire a(&m_log, 0);
+    m_log << _T("------------------------------------------------------------") << std::endl;
+    m_log << loadString(IDS_mayu) << _T(" ") _T(VERSION);
+#ifndef NDEBUG
+    m_log << _T(" (DEBUG)");
+#endif
+#ifdef _UNICODE
+    m_log << _T(" (UNICODE)");
+#endif
+    m_log << std::endl;
+    m_log << _T("  built by ")
+         << _T(LOGNAME) << _T("@") << toLower(_T(COMPUTERNAME))
+         << _T(" (") << _T(__DATE__) <<  _T(" ")
+         << _T(__TIME__) << _T(", ")
+         << getCompilerVersionString() << _T(")") << std::endl;
+    _TCHAR modulebuf[1024];
+    CHECK_TRUE( GetModuleFileName(g_hInst, modulebuf,
+                                 NUMBER_OF(modulebuf)) );
+    m_log << _T("started at ") << starttimebuf << std::endl;
+    m_log << modulebuf << std::endl;
+    m_log << _T("------------------------------------------------------------") << std::endl;
+
+    if (i_isCleared) {
+      m_log << _T("log was cleared at ") << timebuf << std::endl;
+    } else {
+      m_log << _T("log begins at ") << timebuf << std::endl;
+    }
+  }
+
+public:
+  ///
+  Mayu()
+    : m_hwndTaskTray(NULL),
+      m_hwndLog(NULL),
+      m_WM_TaskbarRestart(RegisterWindowMessage(_T("TaskbarCreated"))),
+      m_WM_MayuIPC(RegisterWindowMessage(WM_MayuIPC_NAME)),
+      m_canUseTasktrayBaloon(
+       PACKVERSION(5, 0) <= getDllVersion(_T("shlwapi.dll"))),
+      m_log(WM_APP_msgStreamNotify),
+      m_setting(NULL),
+      m_isSettingDialogOpened(false),
+      m_engine(m_log)
+  {
+    time(&m_startTime);
+
+    CHECK_TRUE( Register_focus() );
+    CHECK_TRUE( Register_target() );
+    CHECK_TRUE( Register_tasktray() );
+
+    // change dir
+#if 0
+    HomeDirectories pathes;
+    getHomeDirectories(&pathes);
+    for (HomeDirectories::iterator i = pathes.begin(); i != pathes.end(); ++ i)
+      if (SetCurrentDirectory(i->c_str()))
+       break;
+#endif
+    
+    // create windows, dialogs
+    tstringi title = loadString(IDS_mayu);
+    m_hwndTaskTray = CreateWindow(_T("mayuTasktray"), title.c_str(),
+                                 WS_OVERLAPPEDWINDOW,
+                                 CW_USEDEFAULT, CW_USEDEFAULT, 
+                                 CW_USEDEFAULT, CW_USEDEFAULT, 
+                                 NULL, NULL, g_hInst, this);
+    CHECK_TRUE( m_hwndTaskTray );
+    
+    // set window handle of tasktray to hooks
+    g_hookData->m_hwndTaskTray = m_hwndTaskTray;
+    m_usingSN = wtsRegisterSessionNotification(m_hwndTaskTray,
+                                              NOTIFY_FOR_THIS_SESSION);
+
+    DlgLogData dld;
+    dld.m_log = &m_log;
+    dld.m_hwndTaskTray = m_hwndTaskTray;
+    m_hwndLog =
+      CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_log), NULL,
+                       dlgLog_dlgProc, (LPARAM)&dld);
+    CHECK_TRUE( m_hwndLog );
+
+    DlgInvestigateData did;
+    did.m_engine = &m_engine;
+    did.m_hwndLog = m_hwndLog;
+    m_hwndInvestigate =
+      CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_investigate), NULL,
+                       dlgInvestigate_dlgProc, (LPARAM)&did);
+    CHECK_TRUE( m_hwndInvestigate );
+
+    m_hwndVersion =
+      CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_version),
+                       NULL, dlgVersion_dlgProc,
+                       (LPARAM)m_engine.getMayudVersion().c_str());
+    CHECK_TRUE( m_hwndVersion );
+
+    // attach log
+    SendMessage(GetDlgItem(m_hwndLog, IDC_EDIT_log), EM_SETLIMITTEXT, 0, 0);
+    m_log.attach(m_hwndTaskTray);
+
+    // start keyboard handler thread
+    m_engine.setAssociatedWndow(m_hwndTaskTray);
+    m_engine.start();
+    
+    // show tasktray icon
+    m_tasktrayIcon[0] = loadSmallIcon(IDI_ICON_mayu_disabled);
+    m_tasktrayIcon[1] = loadSmallIcon(IDI_ICON_mayu);
+    std::memset(&m_ni, 0, sizeof(m_ni));
+    m_ni.uID    = ID_TaskTrayIcon;
+    m_ni.hWnd   = m_hwndTaskTray;
+    m_ni.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+    m_ni.hIcon  = m_tasktrayIcon[1];
+    m_ni.uCallbackMessage = WM_APP_taskTrayNotify;
+    tstring tip = loadString(IDS_mayu);
+    tcslcpy(m_ni.szTip, tip.c_str(), NUMBER_OF(m_ni.szTip));
+    if (m_canUseTasktrayBaloon)
+    {
+      m_ni.cbSize = sizeof(m_ni);
+      m_ni.uFlags |= NIF_INFO;
+    }
+    else
+      m_ni.cbSize = NOTIFYICONDATA_V1_SIZE;
+    showTasktrayIcon(true);
+
+    // create menu
+    m_hMenuTaskTray = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU_tasktray));
+    ASSERT(m_hMenuTaskTray);
+    
+    // set initial lock state
+    notifyLockState();
+  }
+
+  ///
+  ~Mayu()
+  {
+    // first, detach log from edit control to avoid deadlock
+    m_log.detach();
+   
+    // stop notify from mayu.dll
+    g_hookData->m_hwndTaskTray = NULL;
+    
+    // destroy windows
+    CHECK_TRUE( DestroyWindow(m_hwndVersion) );
+    CHECK_TRUE( DestroyWindow(m_hwndInvestigate) );
+    CHECK_TRUE( DestroyWindow(m_hwndLog) );
+    CHECK_TRUE( DestroyWindow(m_hwndTaskTray) );
+    
+    // destroy menu
+    DestroyMenu(m_hMenuTaskTray);
+    
+    // delete tasktray icon
+    CHECK_TRUE( Shell_NotifyIcon(NIM_DELETE, &m_ni) );
+    CHECK_TRUE( DestroyIcon(m_tasktrayIcon[1]) );
+    CHECK_TRUE( DestroyIcon(m_tasktrayIcon[0]) );
+
+    // stop keyboard handler thread
+    m_engine.stop();
+    
+    // remove setting;
+    delete m_setting;
+  }
+
+  /// message loop
+  WPARAM messageLoop()
+  {
+    showBanner(false);
+    load();
+    
+    MSG msg;
+    while (0 < GetMessage(&msg, NULL, 0, 0))
+    {
+      if (IsDialogMessage(m_hwndLog, &msg))
+       continue;
+      if (IsDialogMessage(m_hwndInvestigate, &msg))
+       continue;
+      if (IsDialogMessage(m_hwndVersion, &msg))
+       continue;
+      TranslateMessage(&msg);
+      DispatchMessage(&msg);
+    }
+    return msg.wParam;
+  }  
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Functions
+
+
+/// convert registry
+void convertRegistry()
+{
+  Registry reg(MAYU_REGISTRY_ROOT);
+  tstringi dot_mayu;
+  bool doesAdd = false;
+  DWORD index;
+  if (reg.read(_T(".mayu"), &dot_mayu))
+  {
+    reg.write(_T(".mayu0"), _T(";") + dot_mayu + _T(";"));
+    reg.remove(_T(".mayu"));
+    doesAdd = true;
+    index = 0;
+  }
+  else if (!reg.read(_T(".mayu0"), &dot_mayu))
+  {
+    reg.write(_T(".mayu0"), loadString(IDS_readFromHomeDirectory) + _T(";;"));
+    doesAdd = true;
+    index = 1;
+  }
+  if (doesAdd)
+  {
+    Registry commonreg(HKEY_LOCAL_MACHINE, _T("Software\\GANAware\\mayu"));
+    tstringi dir, layout;
+    if (commonreg.read(_T("dir"), &dir) &&
+       commonreg.read(_T("layout"), &layout))
+    {
+      tstringi tmp = _T(";") + dir + _T("\\dot.mayu");
+      if (layout == _T("109"))
+      {
+       reg.write(_T(".mayu1"), loadString(IDS_109Emacs) + tmp
+                 + _T(";-DUSE109") _T(";-DUSEdefault"));
+       reg.write(_T(".mayu2"), loadString(IDS_104on109Emacs) + tmp
+                 + _T(";-DUSE109") _T(";-DUSEdefault") _T(";-DUSE104on109"));
+       reg.write(_T(".mayu3"), loadString(IDS_109) + tmp
+                 + _T(";-DUSE109"));
+       reg.write(_T(".mayu4"), loadString(IDS_104on109) + tmp
+                 + _T(";-DUSE109") _T(";-DUSE104on109"));
+      }
+      else
+      {
+       reg.write(_T(".mayu1"), loadString(IDS_104Emacs) + tmp
+                 + _T(";-DUSE104") _T(";-DUSEdefault"));
+       reg.write(_T(".mayu2"), loadString(IDS_109on104Emacs) + tmp
+                 + _T(";-DUSE104") _T(";-DUSEdefault") _T(";-DUSE109on104"));
+       reg.write(_T(".mayu3"), loadString(IDS_104) + tmp
+                 + _T(";-DUSE104"));
+       reg.write(_T(".mayu4"), loadString(IDS_109on104) + tmp
+                 + _T(";-DUSE104") _T(";-DUSE109on104"));
+      }
+      reg.write(_T(".mayuIndex"), index);
+    }
+  }
+}
+
+
+/// main
+int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
+                    LPTSTR /* i_lpszCmdLine */, int /* i_nCmdShow */)
+{
+  g_hInst = i_hInstance;
+
+  // set locale
+  CHECK_TRUE( _tsetlocale(LC_ALL, _T("")) );
+
+  // common controls
+#if defined(_WIN95)
+  InitCommonControls();
+#else
+  INITCOMMONCONTROLSEX icc;
+  icc.dwSize = sizeof(icc);
+  icc.dwICC = ICC_LISTVIEW_CLASSES;
+  CHECK_TRUE( InitCommonControlsEx(&icc) );
+#endif
+
+  // convert old registry to new registry
+  convertRegistry();
+  
+  // is another mayu running ?
+  HANDLE mutex = CreateMutex(
+      (SECURITY_ATTRIBUTES *)NULL, TRUE,
+      addSessionId(MUTEX_MAYU_EXCLUSIVE_RUNNING).c_str());
+  if (GetLastError() == ERROR_ALREADY_EXISTS)
+  {
+    // another mayu already running
+    tstring text = loadString(IDS_mayuAlreadyExists);
+    tstring title = loadString(IDS_mayu);
+    if (g_hookData) {
+       UINT WM_TaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated"));
+       PostMessage(g_hookData->m_hwndTaskTray, WM_TaskbarRestart, 0, 0);
+    }
+    MessageBox((HWND)NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONSTOP);
+    return 1;
+  }
+
+  // check remote desktop
+  DWORD sessionId;
+  if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId) ||
+      wtsGetActiveConsoleSessionId() != sessionId)
+  {
+    tstring text = loadString(IDS_executedInRemoteDesktop);
+    tstring title = loadString(IDS_mayu);
+    MessageBox((HWND)NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONSTOP);
+    return 1;
+  }
+  
+  CHECK_FALSE( installHooks() );
+  try
+  {
+    Mayu().messageLoop();
+  }
+  catch (ErrorMessage &i_e)
+  {
+    tstring title = loadString(IDS_mayu);
+    MessageBox((HWND)NULL, i_e.getMessage().c_str(), title.c_str(),
+              MB_OK | MB_ICONSTOP);
+  }
+  CHECK_FALSE( uninstallHooks() );
+  
+  CHECK_TRUE( CloseHandle(mutex) );
+  return 0;
+}
diff --git a/mayu.h b/mayu.h
new file mode 100644 (file)
index 0000000..ff6ea99
--- /dev/null
+++ b/mayu.h
@@ -0,0 +1,20 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// mayu.h
+
+
+#ifndef _MAYU_H
+#  define _MAYU_H
+
+
+///
+#  define MAYU_REGISTRY_ROOT HKEY_CURRENT_USER, _T("Software\\GANAware\\mayu")
+
+///
+#  define MUTEX_MAYU_EXCLUSIVE_RUNNING         \
+_T("{46269F4D-D560-40f9-B38B-DB5E280FEF47}")
+
+///
+#  define MAX_MAYU_REGISTRY_ENTRIES 256
+
+
+#endif // _MAYU_H
diff --git a/mayu.rc b/mayu.rc
new file mode 100644 (file)
index 0000000..edade0d
--- /dev/null
+++ b/mayu.rc
@@ -0,0 +1,521 @@
+//Microsoft Developer Studio generated resource script.\r
+//\r
+#include "mayurc.h"\r
+\r
+#define APSTUDIO_READONLY_SYMBOLS\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 2 resource.\r
+//\r
+#include "winresrc.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#undef APSTUDIO_READONLY_SYMBOLS\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// \93ú\96{\8cê resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT\r
+#pragma code_page(932)\r
+#endif //_WIN32\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Dialog\r
+//\r
+\r
+IDD_DIALOG_investigate DIALOGEX 0, 0, 298, 51\r
+STYLE DS_MODALFRAME | DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "\92²\8d¸ - \91\8b\8eg\82¢\82Ì\97J\9fT"\r
+FONT 9, "MS UI Gothic"\r
+BEGIN\r
+    CONTROL         "scancode",IDC_CUSTOM_scancode,"mayuFocus",WS_TABSTOP,88,\r
+                    18,20,20,WS_EX_CLIENTEDGE\r
+    LTEXT           "\81©\82±\82Ì\92\86\82Å\92²\82×\82½\82¢\83L\81[\82ð\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢",IDC_STATIC,\r
+                    112,16,44,27\r
+    GROUPBOX        "\89¼\91z\83L\81[\82Ì\92²\8d¸(&V)",IDC_STATIC,164,4,76,44\r
+    CONTROL         "vkey",IDC_CUSTOM_vkey,"mayuFocus",WS_TABSTOP,168,18,20,\r
+                    20,WS_EX_CLIENTEDGE\r
+    LTEXT           "\81©\82±\82Ì\92\86\82Å\92²\82×\82½\82¢\83L\81[\82ð\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢",IDC_STATIC,\r
+                    192,16,44,27\r
+    DEFPUSHBUTTON   "\95Â\82\82é",IDOK,244,32,50,14\r
+    GROUPBOX        "\83E\83B\83\93\83h\83E\82Ì\92²\8d¸(&W)",IDC_STATIC,4,4,76,44\r
+    CONTROL         "",IDC_CUSTOM_target,"mayuTarget",0x0,8,18,20,20,\r
+                    WS_EX_CLIENTEDGE\r
+    LTEXT           "\81©\82ð\92²\82×\82½\82¢\83E\83B\83\93\83h\83E\82Ü\82Å\83h\83\89\83b\83O\82µ\82Ä\82­\82¾\82³\82¢",\r
+                    IDC_STATIC,32,17,44,27\r
+    GROUPBOX        "\83X\83L\83\83\83\93\83R\81[\83h\82Ì\92²\8d¸(&S)",IDC_STATIC,84,4,76,44\r
+END\r
+\r
+IDD_DIALOG_setting DIALOGEX 0, 0, 302, 135\r
+STYLE DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME\r
+CAPTION "\90Ý\92è - \91\8b\8eg\82¢\82Ì\97J\9fT"\r
+FONT 9, "MS UI Gothic"\r
+BEGIN\r
+    GROUPBOX        "\90Ý\92è\83t\83@\83C\83\8b\96¼\83\8a\83X\83g(&L)",IDC_STATIC_mayuPaths,4,4,296,\r
+                    108\r
+    CONTROL         "List1",IDC_LIST_mayuPaths,"SysListView32",LVS_REPORT | \r
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | \r
+                    WS_BORDER | WS_TABSTOP,8,16,268,72\r
+    PUSHBUTTON      "\81ª",IDC_BUTTON_up,280,36,14,14\r
+    PUSHBUTTON      "\81«",IDC_BUTTON_down,280,52,14,14\r
+    PUSHBUTTON      "\92Ç\89Á(&A)",IDC_BUTTON_add,66,92,50,14\r
+    PUSHBUTTON      "\95Ò\8fW(&E)",IDC_BUTTON_edit,126,92,50,14\r
+    PUSHBUTTON      "\8dí\8f\9c(&D)",IDC_BUTTON_delete,186,92,50,14\r
+    PUSHBUTTON      "\83L\83\83\83\93\83Z\83\8b",IDCANCEL,156,116,50,14\r
+    DEFPUSHBUTTON   "OK",IDOK,96,116,50,14\r
+END\r
+\r
+IDD_DIALOG_log DIALOGEX 0, 0, 250, 62\r
+STYLE DS_CENTERMOUSE | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | \r
+    WS_THICKFRAME\r
+CAPTION "\83\8d\83O - \91\8b\8eg\82¢\82Ì\97J\9fT"\r
+FONT 9, "MS UI Gothic"\r
+BEGIN\r
+    DEFPUSHBUTTON   "\95Â\82\82é(&C)",IDOK,192,44,50,15\r
+    EDITTEXT        IDC_EDIT_log,0,0,250,40,ES_MULTILINE | ES_AUTOVSCROLL | \r
+                    ES_AUTOHSCROLL | ES_NOHIDESEL | ES_READONLY | \r
+                    ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL\r
+    PUSHBUTTON      "\83\8d\83O\82Ì\83N\83\8a\83A(&L)",IDC_BUTTON_clearLog,4,44,69,15,0,\r
+                    WS_EX_CLIENTEDGE\r
+    PUSHBUTTON      "\83t\83H\83\93\83g\82Ì\95Ï\8dX(&F)...",IDC_BUTTON_changeFont,76,44,69,\r
+                    15,0,WS_EX_CLIENTEDGE\r
+    CONTROL         "\8fÚ\8d×(&D)",IDC_CHECK_detail,"Button",BS_AUTOCHECKBOX | \r
+                    WS_TABSTOP,149,47,39,10\r
+END\r
+\r
+IDD_DIALOG_version DIALOG DISCARDABLE  0, 0, 204, 140\r
+STYLE DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME\r
+CAPTION "\83o\81[\83W\83\87\83\93\8fî\95ñ - \91\8b\8eg\82¢\82Ì\97J\9fT"\r
+FONT 9, "MS UI Gothic"\r
+BEGIN\r
+    DEFPUSHBUTTON   "\95Â\82\82é",IDOK,136,120,50,14\r
+    PUSHBUTTON      "\8dÅ\90V\83o\81[\83W\83\87\83\93\82Ì\83_\83E\83\93\83\8d\81[\83h(&D)",IDC_BUTTON_download,\r
+                    32,120,100,14\r
+    ICON            IDI_ICON_mayu,IDC_STATIC_mayuIcon,8,20,20,20\r
+    EDITTEXT        IDC_EDIT_builtBy,32,8,164,104,ES_MULTILINE | \r
+                    ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER\r
+END\r
+\r
+IDD_DIALOG_editSetting DIALOG DISCARDABLE  0, 0, 254, 75\r
+STYLE DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME\r
+CAPTION "\90Ý\92è\82Ì\95Ò\8fW - \91\8b\8eg\82¢\82Ì\97J\9fT"\r
+FONT 9, "MS UI Gothic"\r
+BEGIN\r
+    LTEXT           "\96¼\91O(&N)",IDC_STATIC_mayuPathName,8,7,36,8\r
+    EDITTEXT        IDC_EDIT_mayuPathName,44,4,152,14,ES_AUTOHSCROLL\r
+    LTEXT           "(\83Z\83~\83R\83\8d\83\93\95s\89Â)",IDC_STATIC_mayuPathNameComment,200,6,\r
+                    44,8\r
+    LTEXT           "\83t\83@\83C\83\8b\96¼(&F)",IDC_STATIC_mayuPath,8,22,36,8\r
+    EDITTEXT        IDC_EDIT_mayuPath,44,20,152,14,ES_AUTOHSCROLL\r
+    PUSHBUTTON      "\8eQ\8fÆ(&B)",IDC_BUTTON_browse,200,20,50,14\r
+    LTEXT           "\83V\83\93\83{\83\8b(&S)",IDC_STATIC_symbols,8,38,36,8\r
+    EDITTEXT        IDC_EDIT_symbols,44,36,152,14,ES_AUTOHSCROLL\r
+    LTEXT           "(-D \82ð\95t\82¯\81A\83Z\83~\83R\83\8d\83\93\82Å\8bæ\90Ø\82é)",\r
+                    IDC_STATIC_symbolsComment,200,38,48,22\r
+    DEFPUSHBUTTON   "OK",IDOK,76,56,50,14\r
+    PUSHBUTTON      "\83L\83\83\83\93\83Z\83\8b",IDCANCEL,132,56,50,14\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// DESIGNINFO\r
+//\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+GUIDELINES DESIGNINFO DISCARDABLE \r
+BEGIN\r
+    IDD_DIALOG_investigate, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 291\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 44\r
+    END\r
+\r
+    IDD_DIALOG_setting, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 295\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 128\r
+    END\r
+\r
+    IDD_DIALOG_log, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 236\r
+        TOPMARGIN, 7\r
+    END\r
+\r
+    IDD_DIALOG_version, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 195\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 124\r
+    END\r
+\r
+    IDD_DIALOG_editSetting, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 247\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 68\r
+    END\r
+END\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Menu\r
+//\r
+\r
+IDR_MENU_tasktray MENU DISCARDABLE \r
+BEGIN\r
+    POPUP "\83^\83X\83N\83g\83\8c\83C"\r
+    BEGIN\r
+        MENUITEM "\8dÄ\93Ç\82Ý\8d\9e\82Ý(&R)",              ID_MENUITEM_reload\r
+        POPUP "\91I\91ð(&C)"\r
+        BEGIN\r
+            MENUITEM "(\83z\81[\83\80\83f\83B\83\8c\83N\83g\83\8a\82©\82ç)",    ID_MENUITEM_reload\r
+        END\r
+        MENUITEM "\90Ý\92è(&S)...",                 ID_MENUITEM_setting\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "\88ê\8e\9e\92â\8e~(&T)",                ID_MENUITEM_disable\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "\92²\8d¸(&I)...",                 ID_MENUITEM_investigate\r
+        MENUITEM "\83\8d\83O(&L)...",                 ID_MENUITEM_log\r
+        MENUITEM "\83o\81[\83W\83\87\83\93(&V)...",           ID_MENUITEM_version\r
+        MENUITEM "\83w\83\8b\83v(&H)...",               ID_MENUITEM_help\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "\8fI\97¹(&X)",                    ID_MENUITEM_quit\r
+    END\r
+END\r
+\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// TEXTINCLUDE\r
+//\r
+\r
+1 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "mayurc.h\0"\r
+END\r
+\r
+2 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "#include ""winresrc.h""\r\n"\r
+    "\0"\r
+END\r
+\r
+3 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "\r\n"\r
+    "\0"\r
+END\r
+\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// String Table\r
+//\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_mayu                "\91\8b\8eg\82¢\82Ì\97J\9fT"\r
+    IDS_mayuAlreadyExists   "\8aù\82É\91\8b\8eg\82¢\82Ì\97J\9fT\82Í\93®\8dì\92\86\82Å\82·"\r
+    IDS_cannotOpenDevice    "\91\8b\8eg\82¢\82Ì\97J\9fT\83f\83o\83C\83X\83h\83\89\83C\83o\82ª\97\98\97p\82Å\82«\82Ü\82¹\82ñ"\r
+    IDS_driverNotInstalled  "\91\8b\8eg\82¢\82Ì\97J\9fT\83f\83o\83C\83X\83h\83\89\83C\83o\82ª\90³\82µ\82­\83C\83\93\83X\83g\81[\83\8b\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ"\r
+    IDS_executedInRemoteDesktop  "\91\8b\8eg\82¢\82Ì\97J\9fT\82Í\82è\83\82\81[\83g\83f\83X\83N\83g\83b\83v\8fã\82Å\82Í\8eÀ\8ds\82Å\82«\82Ü\82¹\82ñ"\r
+    IDS_openMayu            "\90Ý\92è\83t\83@\83C\83\8b\82ð\92T\82· - \91\8b\8eg\82¢\82Ì\97J\9fT"\r
+    IDS_openMayuFilter      "\91\8b\8eg\82¢\82Ì\97J\9fT\83t\83@\83C\83\8b (*.mayu) |*.mayu|\91S\82Ä\82Ì\83t\83@\83C\83\8b|*|"\r
+    IDS_helpFilename        "doc\\README-ja.html"\r
+    IDS_mayuFile            "\91\8b\8eg\82¢\82Ì\97J\9fT\83t\83@\83C\83\8b"\r
+    IDS_mayuShellOpen       "notepad.exe ""%1"""\r
+    IDS_readFromHomeDirectory "(\83z\81[\83\80\83f\83B\83\8c\83N\83g\83\8a\82©\82ç)"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_logFont             "-13,0,0,0,400,0,0,0,128,1,2,1,1,Terminal"\r
+    IDS_109Emacs            "\93ú\96{\8cê 109 \83L\81[\83{\81[\83h (Emacs \95\97)"\r
+    IDS_104on109Emacs       "\93ú\96{\8cê 109 \83L\81[\83{\81[\83h (104 \95\97, Emacs \95\97)"\r
+    IDS_109                 "\93ú\96{\8cê 109 \83L\81[\83{\81[\83h"\r
+    IDS_104on109            "\93ú\96{\8cê 109 \83L\81[\83{\81[\83h (104 \95\97)"\r
+    IDS_104Emacs            "\89p\8cê 104 \83L\81[\83{\81[\83h (Emacs \95\97)"\r
+    IDS_109on104Emacs       "\89p\8cê 104 \83L\81[\83{\81[\83h (109 \95\97, Emacs \95\97)"\r
+    IDS_104                 "\89p\8cê 104 \83L\81[\83{\81[\83h"\r
+    IDS_109on104            "\89p\8cê 104 \83L\81[\83{\81[\83h (109 \95\97)"\r
+    IDS_mayuPathName        "\96¼\91O"\r
+    IDS_mayuPath            "\90Ý\92è\83t\83@\83C\83\8b\96¼"\r
+    IDS_mayuSymbols         "\83V\83\93\83{\83\8b"\r
+    IDS_version             "\91\8b\8eg\82¢\82Ì\97J\9fT %s\r\n(mayud: %s)\r\n  %s\r\n\r\nCopyright (C) 1999-2005,\r\n  TAGA Nayuta <nayuta@users.sourceforge.net>\r\n\r\nbuilt by %s\r\n  %s\r\n  %s\r\n\r\n  %s\r\n"\r
+    IDS_homepage            "http://mayu.sourceforge.net"\r
+END\r
+\r
+#endif    // \93ú\96{\8cê resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// \89p\8cê (±Òض) resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+#pragma code_page(1252)\r
+#endif //_WIN32\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Dialog\r
+//\r
+\r
+IDD_DIALOG_investigate DIALOGEX 0, 0, 298, 51\r
+STYLE DS_MODALFRAME | DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Investigation - MADO TSUKAI NO YUUTSU"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    CONTROL         "scancode",IDC_CUSTOM_scancode,"mayuFocus",WS_TABSTOP,88,\r
+                    18,20,20,WS_EX_CLIENTEDGE\r
+    LTEXT           "<= input any key in this box.",IDC_STATIC,112,16,44,27\r
+    GROUPBOX        "&Virtual Key",IDC_STATIC,164,4,76,44\r
+    CONTROL         "vkey",IDC_CUSTOM_vkey,"mayuFocus",WS_TABSTOP,168,18,20,\r
+                    20,WS_EX_CLIENTEDGE\r
+    LTEXT           "<= input any key in this box.",IDC_STATIC,192,16,44,27\r
+    DEFPUSHBUTTON   "&Close",IDOK,244,32,50,14\r
+    GROUPBOX        "&Window",IDC_STATIC,4,4,76,44\r
+    CONTROL         "",IDC_CUSTOM_target,"mayuTarget",0x0,8,18,20,20,\r
+                    WS_EX_CLIENTEDGE\r
+    LTEXT           "<= drag this to any window.",IDC_STATIC,32,17,44,27\r
+    GROUPBOX        "&Scan Code",IDC_STATIC,84,4,76,44\r
+END\r
+\r
+IDD_DIALOG_setting DIALOGEX 0, 0, 304, 135\r
+STYLE DS_CENTERMOUSE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | \r
+    WS_CAPTION | WS_SYSMENU | WS_THICKFRAME\r
+CAPTION "Setting - MADO TSUKAI NO YUUTSU"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    GROUPBOX        "Setting File &List",IDC_STATIC_mayuPaths,4,4,296,108\r
+    CONTROL         "List1",IDC_LIST_mayuPaths,"SysListView32",LVS_REPORT | \r
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOLABELWRAP | \r
+                    WS_BORDER | WS_TABSTOP,8,16,268,72\r
+    PUSHBUTTON      "&Up",IDC_BUTTON_up,280,36,14,14\r
+    PUSHBUTTON      "&Dn",IDC_BUTTON_down,280,52,14,14\r
+    PUSHBUTTON      "&Add",IDC_BUTTON_add,66,92,50,14\r
+    PUSHBUTTON      "&Edit",IDC_BUTTON_edit,126,92,50,14\r
+    PUSHBUTTON      "&Delete",IDC_BUTTON_delete,186,92,50,14\r
+    PUSHBUTTON      "&Cancel",IDCANCEL,156,116,50,14\r
+    DEFPUSHBUTTON   "&OK",IDOK,96,116,50,14\r
+END\r
+\r
+IDD_DIALOG_log DIALOGEX 0, 0, 243, 162\r
+STYLE DS_CENTERMOUSE | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | \r
+    WS_THICKFRAME\r
+CAPTION "Log - MADO TSUKAI NO YUUTSU"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    DEFPUSHBUTTON   "&Close",IDOK,192,144,50,15\r
+    EDITTEXT        IDC_EDIT_log,0,0,244,140,ES_MULTILINE | ES_AUTOVSCROLL | \r
+                    ES_AUTOHSCROLL | ES_NOHIDESEL | ES_READONLY | \r
+                    ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL\r
+    PUSHBUTTON      "Clear &Log",IDC_BUTTON_clearLog,4,144,69,15,0,\r
+                    WS_EX_CLIENTEDGE\r
+    PUSHBUTTON      "Choose &Font...",IDC_BUTTON_changeFont,76,144,69,15,0,\r
+                    WS_EX_CLIENTEDGE\r
+    CONTROL         "&Details",IDC_CHECK_detail,"Button",BS_AUTOCHECKBOX | \r
+                    WS_TABSTOP,149,147,39,10\r
+END\r
+\r
+IDD_DIALOG_version DIALOG DISCARDABLE  0, 0, 204, 140\r
+STYLE DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME\r
+CAPTION "Version - MADO TSUKAI NO YUUTSU"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    DEFPUSHBUTTON   "&Close",IDOK,136,120,50,14\r
+    PUSHBUTTON      "&Download The Latest Version",IDC_BUTTON_download,32,\r
+                    120,100,14\r
+    ICON            IDI_ICON_mayu,IDC_STATIC_mayuIcon,8,20,20,20\r
+    EDITTEXT        IDC_EDIT_builtBy,32,8,164,104,ES_MULTILINE | \r
+                    ES_AUTOVSCROLL | ES_READONLY | NOT WS_BORDER\r
+END\r
+\r
+IDD_DIALOG_editSetting DIALOG DISCARDABLE  0, 0, 256, 76\r
+STYLE DS_CENTERMOUSE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME\r
+CAPTION "Edit Settings - MADO TSUKAI NO YUUTSU"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    LTEXT           "&Name",IDC_STATIC,8,7,36,8\r
+    EDITTEXT        IDC_EDIT_mayuPathName,44,4,152,14,ES_AUTOHSCROLL\r
+    LTEXT           "(don't use "";"")",IDC_STATIC,200,6,44,8\r
+    LTEXT           "&Filename",IDC_STATIC,8,22,36,8\r
+    EDITTEXT        IDC_EDIT_mayuPath,44,20,152,14,ES_AUTOHSCROLL\r
+    PUSHBUTTON      "&Browse",IDC_BUTTON_browse,200,20,50,14\r
+    LTEXT           "&Symbols",IDC_STATIC,8,38,36,8\r
+    EDITTEXT        IDC_EDIT_symbols,44,36,152,14,ES_AUTOHSCROLL\r
+    LTEXT           "(separate by "";"" with -D)",IDC_STATIC,200,38,48,22\r
+    DEFPUSHBUTTON   "&OK",IDOK,76,56,50,14\r
+    PUSHBUTTON      "&Cancel",IDCANCEL,132,56,50,14\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// DESIGNINFO\r
+//\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+GUIDELINES DESIGNINFO DISCARDABLE \r
+BEGIN\r
+    IDD_DIALOG_investigate, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 291\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 44\r
+    END\r
+\r
+    IDD_DIALOG_setting, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 297\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 128\r
+    END\r
+\r
+    IDD_DIALOG_log, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 236\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 155\r
+    END\r
+\r
+    IDD_DIALOG_version, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 196\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 73\r
+    END\r
+\r
+    IDD_DIALOG_editSetting, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 249\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 69\r
+    END\r
+END\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Menu\r
+//\r
+\r
+IDR_MENU_tasktray MENU DISCARDABLE \r
+BEGIN\r
+    POPUP "TASK TRAY"\r
+    BEGIN\r
+        MENUITEM "&Reload",                     ID_MENUITEM_reload\r
+        POPUP "&Change Setting"\r
+        BEGIN\r
+            MENUITEM "(from home directory)",       ID_MENUITEM_reload\r
+        END\r
+        MENUITEM "&Setting...",                 ID_MENUITEM_setting\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "S&top",                       ID_MENUITEM_disable\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "&Investigation...",           ID_MENUITEM_investigate\r
+        MENUITEM "&Log...",                     ID_MENUITEM_log\r
+        MENUITEM "&Version...",                 ID_MENUITEM_version\r
+        MENUITEM "&Help...",                    ID_MENUITEM_help\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "E&xit",                       ID_MENUITEM_quit\r
+    END\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Icon\r
+//\r
+\r
+// Icon with lowest ID value placed first to ensure application icon\r
+// remains consistent on all systems.\r
+IDI_ICON_mayu           ICON    DISCARDABLE     "r\\mayu.ico"\r
+IDI_ICON_mayu_file      ICON    DISCARDABLE     "r\\mayufile.ico"\r
+IDI_ICON_mayu_disabled  ICON    DISCARDABLE     "r\\mayudisabled.ico"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Cursor\r
+//\r
+\r
+IDC_CURSOR_target       CURSOR  DISCARDABLE     "r\\target.cur"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// String Table\r
+//\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_mayu                "MADO TSUKAI NO YUUTSU"\r
+    IDS_mayuAlreadyExists   "Already MADO TSUKAI NO YUUTSU is running."\r
+    IDS_cannotOpenDevice    "MADO TSUKAI NO YUUTSU driver is not available."\r
+    IDS_driverNotInstalled  "MADO TSUKAI NO YUUTSU is not installed correctly."\r
+    IDS_executedInRemoteDesktop  "MADO TSUKAI NO YUUTSU cannot be executed in the Remote Desktop."\r
+    IDS_openMayu            "Find Setting File - MADO TSUKAI NO YUUTSU"\r
+    IDS_openMayuFilter      "MADO TSUKAI NO YUUTSU file (*.mayu) |*.mayu|All Files|*|"\r
+    IDS_helpFilename        "doc\\README-ja.html"\r
+    IDS_mayuFile            "MADO TSUKAI NO YUUTSU file"\r
+    IDS_mayuShellOpen       "notepad.exe ""%1"""\r
+    IDS_readFromHomeDirectory "(from home directory)"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_logFont             "-13,0,0,0,400,0,0,0,128,1,2,1,1,Terminal"\r
+    IDS_109Emacs            "Japanese 109 Keyboard (Emacs Like)"\r
+    IDS_104on109Emacs       "Japanese 109 Keyboard (104 Like, Emacs Like)"\r
+    IDS_109                 "Japanese 109 Keyboard"\r
+    IDS_104on109            "Japanese 109 Keyboard (104 Like)"\r
+    IDS_104Emacs            "English 104 Keyboard (Emacs Like)"\r
+    IDS_109on104Emacs       "English 104 Keyboard (109 Like, Emacs Like)"\r
+    IDS_104                 "English 104 Keyboard"\r
+    IDS_109on104            "English 104 Keyboard (109 Like, Emacs Like)"\r
+    IDS_mayuPathName        "Name"\r
+    IDS_mayuPath            "Setting Filename"\r
+    IDS_mayuSymbols         "Symbols"\r
+    IDS_version             "MADO TSUKAI NO YUUTSU %s\r\n(mayud: %s)\r\n  %s\r\n\r\nCopyright (C) 1999-2005,\r\n  TAGA Nayuta <nayuta@users.sourceforge.net>\r\n\r\nbuilt by %s\r\n  %s\r\n  %s\r\n\r\n  %s\r\n"\r
+    IDS_homepage            "http://mayu.sourceforge.net"\r
+END\r
+\r
+#endif    // \89p\8cê (±Òض) resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+#ifndef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 3 resource.\r
+//\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#endif    // not APSTUDIO_INVOKED\r
+\r
diff --git a/mayuipc.h b/mayuipc.h
new file mode 100644 (file)
index 0000000..4fc28d6
--- /dev/null
+++ b/mayuipc.h
@@ -0,0 +1,60 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// mayuipc.h - mayu inter process communication
+
+#ifndef _MAYUIPC_H
+#  define _MAYUIPC_H
+
+#  include <windows.h>
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif // __cplusplus
+
+/// 
+#  define WM_MayuIPC_NAME _T("MayuIPC{46269F4D-D560-40f9-B38B-DB5E280FEF47}")
+
+enum MayuIPCCommand
+{
+       // enable or disable Mayu
+       MayuIPCCommand_Enable = 1,
+};
+
+BOOL MayuIPC_PostMessage(MayuIPCCommand i_wParam, LPARAM i_lParam);
+BOOL MayuIPC_Enable(BOOL i_isEnabled);
+
+#  ifdef _MAYUIPC_H_DEFINE_FUNCTIONS
+
+BOOL MayuIPC_PostMessage(MayuIPCCommand i_command, LPARAM i_lParam)
+{
+       static UINT WM_MayuIPC;
+       HWND hwnd;
+       
+       if (WM_MayuIPC == 0)
+       {
+               WM_MayuIPC = RegisterWindowMessage(WM_MayuIPC_NAME);
+               if (WM_MayuIPC == 0)
+               {
+                       return FALSE;
+               }
+       }
+       
+       hwnd = FindWindow(_T("mayuTasktray"), NULL);
+       if (hwnd == NULL)
+       {
+               return FALSE;
+       }
+       PostMessage(hwnd, WM_MayuIPC, i_command, i_lParam);
+       return TRUE;
+}
+
+BOOL MayuIPC_Enable(BOOL i_isEnabled)
+{
+       return MayuIPC_PostMessage(MayuIPCCommand_Enable, i_isEnabled);
+}
+
+#  endif // _MAYUIPC_H_DEFINE_FUNCTIONS
+
+#  ifdef __cplusplus
+}
+#  endif // __cplusplus
+#endif // !_MAYUIPC_H
diff --git a/mayurc.h b/mayurc.h
new file mode 100644 (file)
index 0000000..d3f4ed8
--- /dev/null
+++ b/mayurc.h
@@ -0,0 +1,87 @@
+//{{NO_DEPENDENCIES}}\r
+// Microsoft Developer Studio generated include file.\r
+// Used by mayu.rc\r
+//\r
+#define IDS_mayu                        1\r
+#define IDS_mayuAlreadyExists           2\r
+#define IDS_cannotOpenDevice            3\r
+#define IDS_driverNotInstalled          4\r
+#define IDS_executedInRemoteDesktop     5\r
+#define IDS_openMayu                    10\r
+#define IDS_openMayuFilter              11\r
+#define IDS_helpFilename                12\r
+#define IDS_mayuFile                    13\r
+#define IDS_mayuShellOpen               14\r
+#define IDS_readFromHomeDirectory       15\r
+#define IDS_logFont                     16\r
+#define IDS_109Emacs                    17\r
+#define IDS_104on109Emacs               18\r
+#define IDS_109                         19\r
+#define IDS_104on109                    20\r
+#define IDS_104Emacs                    21\r
+#define IDS_109on104Emacs               22\r
+#define IDS_104                         23\r
+#define IDS_109on104                    24\r
+#define IDS_mayuPathName                25\r
+#define IDS_mayuPath                    26\r
+#define IDS_mayuSymbols                 27\r
+#define IDS_version                     28\r
+#define IDS_homepage                    29\r
+#define IDC_CURSOR_target               101\r
+#define IDD_DIALOG_editSetting          102\r
+#define IDD_DIALOG_investigate          103\r
+#define IDD_DIALOG_log                  104\r
+#define IDD_DIALOG_setting              105\r
+#define IDD_DIALOG_version              106\r
+#define IDI_ICON_mayu                   107\r
+#define IDI_ICON_mayu_file              108\r
+#define IDI_ICON_mayu_disabled          109\r
+#define IDR_MENU_tasktray               110\r
+#define IDC_BUTTON_add                  1001\r
+#define IDC_BUTTON_browse               1002\r
+#define IDC_BUTTON_changeFont           1003\r
+#define IDC_BUTTON_clearLog             1004\r
+#define IDC_BUTTON_delete               1005\r
+#define IDC_BUTTON_down                 1006\r
+#define IDC_BUTTON_download             1007\r
+#define IDC_BUTTON_edit                 1008\r
+#define IDC_BUTTON_up                   1009\r
+#define IDC_CHECK_detail                1010\r
+#define IDC_CUSTOM_scancode             1011\r
+#define IDC_CUSTOM_target               1012\r
+#define IDC_CUSTOM_vkey                 1013\r
+#define IDC_EDIT_log                    1014\r
+#define IDC_EDIT_mayuPath               1015\r
+#define IDC_EDIT_mayuPathName           1016\r
+#define IDC_EDIT_symbols                1017\r
+#define IDC_LIST_mayuPaths              1018\r
+#define IDC_STATIC_mayuPath             1019\r
+#define IDC_STATIC_mayuPathName         1020\r
+#define IDC_STATIC_mayuPathNameComment  1021\r
+#define IDC_STATIC_mayuPaths            1022\r
+#define IDC_STATIC_symbols              1023\r
+#define IDC_STATIC_symbolsComment       1024\r
+#define IDC_STATIC_url                  1025\r
+#define IDC_STATIC_version              1026\r
+#define IDC_EDIT_builtBy                1027\r
+#define IDC_STATIC_mayuIcon             1028\r
+#define ID_MENUITEM_quit                40001\r
+#define ID_MENUITEM_reload              40002\r
+#define ID_MENUITEM_setting             40003\r
+#define ID_MENUITEM_investigate         40004\r
+#define ID_MENUITEM_version             40005\r
+#define ID_MENUITEM_help                40006\r
+#define ID_MENUITEM_disable             40007\r
+#define ID_MENUITEM_log                 40008\r
+#define IDC_STATIC                      -1\r
+\r
+// Next default values for new objects\r
+// \r
+#ifdef APSTUDIO_INVOKED\r
+#ifndef APSTUDIO_READONLY_SYMBOLS\r
+#define _APS_NEXT_RESOURCE_VALUE        103\r
+#define _APS_NEXT_COMMAND_VALUE         40012\r
+#define _APS_NEXT_CONTROL_VALUE         1029\r
+#define _APS_NEXT_SYMED_VALUE           101\r
+#endif\r
+#endif\r
diff --git a/misc.h b/misc.h
new file mode 100644 (file)
index 0000000..9322f96
--- /dev/null
+++ b/misc.h
@@ -0,0 +1,67 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// misc.h
+
+
+#ifndef _MISC_H
+#  define _MISC_H
+
+#  include "compiler_specific.h"
+#  include <windows.h>
+#  include <cassert>
+
+
+typedef unsigned char u_char;                  /// unsigned char
+typedef unsigned short u_short;                        /// unsigned short
+typedef unsigned long u_long;                  /// unsigned long
+
+typedef char int8;                             /// signed 8bit
+typedef short int16;                           /// signed 16bit
+typedef long int32;                            /// signed 32bit
+typedef unsigned char u_int8;                  /// unsigned 8bit
+typedef unsigned short u_int16;                        /// unsigned 16bit
+typedef unsigned long u_int32;                 /// unsigned 32bit
+#if defined(__BORLANDC__)
+typedef unsigned __int64 u_int64;                      /// unsigned 64bit
+#elif _MSC_VER <= 1300
+typedef unsigned _int64 u_int64;                       /// unsigned 64bit
+#else
+typedef unsigned long long u_int64;                    /// unsigned 64bit
+#endif
+
+
+#  ifdef NDEBUG
+#    define ASSERT(i_exp)
+#    define CHECK(i_cond, i_exp)       i_exp
+#    define CHECK_TRUE(i_exp)          i_exp
+#    define CHECK_FALSE(i_exp)         i_exp
+#  else // NDEBUG
+/// assertion. i_exp is evaluated only in debug build
+#    define ASSERT(i_exp)              assert(i_exp)
+/// assertion, but i_exp is always evaluated
+#    define CHECK(i_cond, i_exp)       assert(i_cond (i_exp))
+/// identical to CHECK(!!, i_exp)
+#    define CHECK_TRUE(i_exp)          assert(!!(i_exp))
+/// identical to CHECK(!, i_exp)
+#    define CHECK_FALSE(i_exp)         assert(!(i_exp))
+#  endif // NDEBUG
+
+
+/// get number of array elements
+#  define NUMBER_OF(i_array) (sizeof(i_array) / sizeof((i_array)[0]))
+
+/// max path length
+#  define GANA_MAX_PATH                (MAX_PATH * 4)
+
+/// max length of global atom
+#  define GANA_MAX_ATOM_LENGTH 256
+
+#  undef MAX
+/// redefine MAX macro
+#  define MAX(a, b)    (((b) < (a)) ? (a) : (b))
+
+#  undef MIN
+/// redefine MIN macro
+#  define MIN(a, b)    (((a) < (b)) ? (a) : (b))
+
+
+#endif // !_MISC_H
diff --git a/msgstream.h b/msgstream.h
new file mode 100644 (file)
index 0000000..d720d32
--- /dev/null
@@ -0,0 +1,297 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// msgstream.h
+
+
+#ifndef _MSGSTREAM_H
+#  define _MSGSTREAM_H
+
+#  include "misc.h"
+#  include "stringtool.h"
+#  include "multithread.h"
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// msgstream
+
+/** msgstream.
+
+    <p>Before writing to omsgstream, you must acquire lock by calling
+    <code>acquire()</code>.  Then after completion of writing, you
+    must call <code>release()</code>.</p>
+    
+    <p>Omsgbuf calls <code>PostMessage(hwnd, messageid, 0,
+    (LPARAM)omsgbuf)</code> to notify that string is ready to get.
+    When the window (<code>hwnd</code>) get the message, you can get
+    the string containd in the omsgbuf by calling
+    <code>acquireString()</code>.  After calling
+    <code>acquireString()</code>, you must / call releaseString().</p>
+
+*/
+
+template<class T, size_t SIZE = 1024,
+  class TR = std::char_traits<T>, class A = std::allocator<T> >
+class basic_msgbuf : public std::basic_streambuf<T, TR>, public SyncObject
+{
+public:
+  typedef std::basic_string<T, TR, A> String;  /// 
+  typedef std::basic_streambuf<T, TR> Super;   ///
+  
+private:
+  HWND m_hwnd;                                 /** window handle for
+                                                   notification */
+  UINT m_messageId;                            /// messageid for notification
+  T *m_buf;                                    /// for streambuf
+  String m_str;                                        /// for notification
+  CriticalSection m_cs;                                /// lock
+  A m_allocator;                               /// allocator
+  
+  /** debug level.
+      if ( m_msgDebugLevel &lt;= m_debugLevel ), message is displayed
+  */
+  int m_debugLevel;
+  int m_msgDebugLevel;                         ///
+
+private:
+  basic_msgbuf(const basic_msgbuf &);          /// disable copy constructor
+
+public:
+  ///
+  basic_msgbuf(UINT i_messageId, HWND i_hwnd = 0)
+    : m_hwnd(i_hwnd),
+      m_messageId(i_messageId),
+      m_buf(m_allocator.allocate(SIZE, 0)),
+      m_debugLevel(0),
+      m_msgDebugLevel(0)
+  {
+    ASSERT(m_buf);
+    setp(m_buf, m_buf + SIZE);
+  }
+  
+  ///
+  ~basic_msgbuf()
+  {
+    sync();
+    m_allocator.deallocate(m_buf, SIZE);
+  }
+  
+  /// attach/detach a window
+  basic_msgbuf* attach(HWND i_hwnd)
+  {
+    Acquire a(&m_cs);
+    ASSERT( !m_hwnd && i_hwnd );
+    m_hwnd = i_hwnd;
+    if (!m_str.empty())
+      PostMessage(m_hwnd, m_messageId, 0, (LPARAM)this);
+    return this;
+  }
+  
+  ///
+  basic_msgbuf* detach()
+  {
+    Acquire a(&m_cs);
+    sync();
+    m_hwnd = 0;
+    return this;
+  }
+  
+  /// get window handle
+  HWND getHwnd() const { return m_hwnd; }
+  
+  /// is a window attached ?
+  int is_open() const { return !!m_hwnd; }
+  
+  /// acquire string and release the string
+  const String &acquireString()
+  {
+    m_cs.acquire();
+    return m_str;
+  }
+  
+  ///
+  void releaseString()
+  {
+    m_str.resize(0);
+    m_cs.release();
+  }
+
+  /// set debug level
+  void setDebugLevel(int i_debugLevel)
+  {
+    m_debugLevel = i_debugLevel;
+  }
+  
+  ///
+  int getDebugLevel() const { return m_debugLevel; }
+  
+  // for stream
+  typename Super::int_type overflow(typename Super::int_type i_c = TR::eof())
+  {
+    if (sync() == TR::eof()) // sync before new buffer created below
+      return TR::eof();
+    
+    if (i_c != TR::eof())
+    {
+      *pptr() = TR::to_char_type(i_c);
+      pbump(1);
+      sync();
+    }
+    return TR::not_eof(i_c); // return something other than EOF if successful
+  }
+  
+  // for stream
+  int sync()
+  {
+    T *begin = pbase();
+    T *end = pptr();
+    T *i;
+    for (i = begin; i < end; ++ i)
+      if (_istlead(*i))
+       ++ i;
+    if (i == end)
+    {
+      if (m_msgDebugLevel <= m_debugLevel)
+       m_str += String(begin, end - begin);
+      setp(m_buf, m_buf + SIZE);
+    }
+    else // end < i
+    {
+      if (m_msgDebugLevel <= m_debugLevel)
+       m_str += String(begin, end - begin - 1);
+      m_buf[0] = end[-1];
+      setp(m_buf, m_buf + SIZE);
+      pbump(1);
+    }
+    return TR::not_eof(0);
+  }
+
+  // sync object
+  
+  /// begin writing
+  virtual void acquire()
+  {
+    m_cs.acquire();
+  }
+
+  /// begin writing
+  virtual void acquire(int i_msgDebugLevel)
+  {
+    m_cs.acquire();
+    m_msgDebugLevel = i_msgDebugLevel;
+  }
+  
+  /// end writing
+  virtual void release()
+  {
+    if (!m_str.empty())
+      PostMessage(m_hwnd, m_messageId, 0, reinterpret_cast<LPARAM>(this));
+    m_msgDebugLevel = m_debugLevel;
+    m_cs.release();
+  }
+};
+
+
+///
+template<class T, size_t SIZE = 1024,
+  class TR = std::char_traits<T>, class A = std::allocator<T> >
+class basic_omsgstream : public std::basic_ostream<T, TR>, public SyncObject
+{
+public:
+  typedef std::basic_ostream<T, TR> Super;     /// 
+  typedef basic_msgbuf<T, SIZE, TR, A> StreamBuf; /// 
+  typedef std::basic_string<T, TR, A> String;  /// 
+  
+private:
+  StreamBuf m_streamBuf;                       /// 
+
+public:
+  ///
+  explicit basic_omsgstream(UINT i_messageId, HWND i_hwnd = 0)
+    : Super(&m_streamBuf), m_streamBuf(i_messageId, i_hwnd)
+  {
+  }
+  
+  ///
+  virtual ~basic_omsgstream()
+  {
+  }
+  
+  ///
+  StreamBuf *rdbuf() const
+  {
+    return const_cast<StreamBuf *>(&m_streamBuf);
+  }
+
+  /// attach a msg control
+  void attach(HWND i_hwnd)
+  {
+    m_streamBuf.attach(i_hwnd);
+  }
+
+  /// detach a msg control
+  void detach()
+  {
+    m_streamBuf.detach();
+  }
+
+  /// get window handle of the msg control
+  HWND getHwnd() const
+  {
+    return m_streamBuf.getHwnd();
+  }
+
+  /// is the msg control attached ?
+  int is_open() const
+  {
+    return m_streamBuf.is_open();
+  }
+
+  /// set debug level
+  void setDebugLevel(int i_debugLevel)
+  {
+    m_streamBuf.setDebugLevel(i_debugLevel);
+  }
+  
+  ///
+  int getDebugLevel() const
+  {
+    return m_streamBuf.getDebugLevel();
+  }
+
+  /// acquire string and release the string
+  const String &acquireString()
+  {
+    return m_streamBuf.acquireString();
+  }
+  
+  ///
+  void releaseString()
+  {
+    m_streamBuf->releaseString();
+  }
+
+  // sync object
+  
+  /// begin writing
+  virtual void acquire()
+  {
+    m_streamBuf.acquire();
+  }
+  
+  /// begin writing
+  virtual void acquire(int i_msgDebugLevel)
+  {
+    m_streamBuf.acquire(i_msgDebugLevel);
+  }
+  
+  /// end writing
+  virtual void release()
+  {
+    m_streamBuf.release();
+  }
+};
+
+///
+typedef basic_omsgstream<_TCHAR> tomsgstream;
+
+
+#endif // !_MSGSTREAM_H
diff --git a/multithread.h b/multithread.h
new file mode 100644 (file)
index 0000000..ffefe5d
--- /dev/null
@@ -0,0 +1,56 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// multithread.h
+
+
+#ifndef _MULTITHREAD_H
+#  define _MULTITHREAD_H
+
+#  include <windows.h>
+
+
+///
+class SyncObject
+{
+public:
+  ///
+  virtual void acquire() = 0;
+  ///
+  virtual void acquire(int ) { acquire(); }
+  ///
+  virtual void release() = 0;
+};
+
+
+///
+class CriticalSection : public SyncObject
+{
+  CRITICAL_SECTION m_cs;                       ///
+
+public:
+  ///
+  CriticalSection() { InitializeCriticalSection(&m_cs); }
+  ///
+  ~CriticalSection() { DeleteCriticalSection(&m_cs); }
+  ///
+  void acquire() { EnterCriticalSection(&m_cs); }
+  ///
+  void release() { LeaveCriticalSection(&m_cs); }
+};
+
+
+///
+class Acquire
+{
+  SyncObject *m_so;    ///
+  
+public:
+  ///
+  Acquire(SyncObject *i_so) : m_so(i_so) { m_so->acquire(); }
+  ///
+  Acquire(SyncObject *i_so, int i_n) : m_so(i_so) { m_so->acquire(i_n); }
+  ///
+  ~Acquire() { m_so->release(); }
+};
+
+
+#endif // !_MULTITHREAD_H
diff --git a/parser.cpp b/parser.cpp
new file mode 100644 (file)
index 0000000..f9fa927
--- /dev/null
@@ -0,0 +1,376 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// parser.cpp
+
+
+#include "misc.h"
+
+#include "errormessage.h"
+#include "parser.h"
+#include <cassert>
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Token
+
+
+Token::Token(const Token &i_token)
+  : m_type(i_token.m_type),
+    m_isValueQuoted(i_token.m_isValueQuoted),
+    m_numericValue(i_token.m_numericValue),
+    m_stringValue(i_token.m_stringValue),
+    m_data(i_token.m_data)
+{
+}
+
+Token::Token(int i_value, const tstringi &i_display)
+  : m_type(Type_number),
+    m_isValueQuoted(false),
+    m_numericValue(i_value),
+    m_stringValue(i_display),
+    m_data(NULL)
+{
+}
+
+Token::Token(const tstringi &i_value, bool i_isValueQuoted, bool i_isRegexp)
+  : m_type(i_isRegexp ? Type_regexp : Type_string),
+    m_isValueQuoted(i_isValueQuoted),
+    m_numericValue(0),
+    m_stringValue(i_value),
+    m_data(NULL)
+{
+}
+
+Token::Token(Type i_m_type)
+  : m_type(i_m_type),
+    m_isValueQuoted(false),
+    m_numericValue(0),
+    m_stringValue(_T("")),
+    m_data(NULL)
+{
+  ASSERT(m_type == Type_openParen || m_type == Type_closeParen ||
+        m_type == Type_comma);
+}
+
+// get numeric value
+int Token::getNumber() const
+{
+  if (m_type == Type_number)
+    return m_numericValue;
+  if (m_stringValue.empty())
+    return 0;
+  else
+    throw ErrorMessage() << _T("`") << *this << _T("' is not a Type_number.");
+}
+
+// get string value
+tstringi Token::getString() const
+{
+  if (m_type == Type_string)
+    return m_stringValue;
+  throw ErrorMessage() << _T("`") << *this << _T("' is not a string.");
+}
+
+// get regexp value
+tstringi Token::getRegexp() const
+{
+  if (m_type == Type_regexp)
+    return m_stringValue;
+  throw ErrorMessage() << _T("`") << *this << _T("' is not a regexp.");
+}
+
+// case insensitive equal
+bool Token::operator==(const _TCHAR *i_str) const
+{
+  if (m_type == Type_string)
+    return m_stringValue == i_str;
+  return false;
+}
+
+// paren equal
+bool Token::operator==(const _TCHAR i_c) const
+{
+  if (i_c == _T('(')) return m_type == Type_openParen;
+  if (i_c == _T(')')) return m_type == Type_openParen;
+  return false;
+}
+
+// add string
+void Token::add(const tstringi &i_str)
+{
+  m_stringValue += i_str;
+}
+
+// stream output
+tostream &operator<<(tostream &i_ost, const Token &i_token)
+{
+  switch (i_token.m_type)
+  {
+    case Token::Type_string: i_ost << i_token.m_stringValue; break;
+    case Token::Type_number: i_ost << i_token.m_stringValue; break;
+    case Token::Type_regexp: i_ost << i_token.m_stringValue; break;
+    case Token::Type_openParen: i_ost << _T("("); break;
+    case Token::Type_closeParen: i_ost << _T(")"); break;
+    case Token::Type_comma: i_ost << _T(", "); break;
+  }
+  return i_ost;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Parser
+
+
+Parser::Parser(const _TCHAR *i_str, size_t i_length)
+  : m_lineNumber(1),
+    m_prefixes(NULL),
+    m_internalLineNumber(1),
+    m_ptr(i_str),
+    m_end(i_str + i_length)
+{
+}
+
+// set string that may be prefix of a token.
+// prefix_ is not copied, so it must be preserved after setPrefix()
+void Parser::setPrefixes(const Prefixes *i_prefixes)
+{
+  m_prefixes = i_prefixes;
+}
+
+// get a line
+bool Parser::getLine(tstringi *o_line)
+{
+  o_line->resize(0);
+
+  if (m_ptr == m_end)
+    return false;
+  
+  const _TCHAR *begin = m_ptr;
+  const _TCHAR *end = m_end;
+  
+  // lines are separated by: "\r\n", "\n", "\x2028" (Unicode Line Separator)
+  while (m_ptr != m_end)
+    switch (*m_ptr)
+    {
+      case _T('\n'):
+#ifdef UNICODE
+      case 0x2028:
+       //case _T('\x2028'):    //  (U+2028)
+#endif
+       end = m_ptr;
+       ++ m_ptr;
+       goto got_line_end;
+      case _T('\r'):
+       if (m_ptr + 1 != m_end && m_ptr[1] == _T('\n'))
+       {
+         end = m_ptr;
+         m_ptr += 2;
+         goto got_line_end;
+       }
+       // fall through
+      default:
+       ++ m_ptr;
+       break;
+    }
+  got_line_end:
+  ++ m_internalLineNumber;
+  // o_line->assign(begin, end);               // why bcc cannot link this ?
+  o_line->assign(begin, end - begin);          // workarond for bcc
+  return true;
+}
+
+// symbol test
+static bool isSymbolChar(_TCHAR i_c)
+{
+  if (i_c == _T('\0'))
+    return false;
+  if (_istlead(i_c) ||
+      _istalpha(i_c) ||
+      _istdigit(i_c) ||
+      _istlead(i_c))
+    return true;
+
+#ifdef UNICODE
+  if (0x80 <= i_c && _istgraph(i_c))
+    return true;
+#endif // UNICODE
+
+  if (_istpunct(i_c))
+    return !!_tcschr(_T("-+/?_\\"), i_c);
+
+#ifdef UNICODE
+  // check arrows
+  if (_tcschr(_T("\x2190\x2191\x2192\x2193"), i_c)) {
+    return true;
+  }
+#endif // UNICODE
+  return _istgraph(i_c);
+}
+
+
+// get a parsed line.
+// if no more lines exist, returns false
+bool Parser::getLine(std::vector<Token> *o_tokens)
+{
+  o_tokens->clear();
+  m_lineNumber = m_internalLineNumber;
+
+  tstringi line;
+  bool isTokenExist = false;
+  continue_getLineLoop:
+  while (getLine(&line))
+  {
+    const _TCHAR *t = line.c_str();
+
+    continue_getTokenLoop:
+    while (true)
+    {
+      // skip white space
+      while (*t != _T('\0') && _istspace(*t))
+       t ++;
+      if (*t == _T('\0') || *t == _T('#'))
+       goto break_getTokenLoop; // no more tokens exist
+      if (*t == _T('\\') && *(t + 1) == _T('\0'))
+       goto continue_getLineLoop; // continue to next line
+      
+      const _TCHAR *tokenStart = t;
+      
+      // comma or empty token
+      if (*t == _T(','))
+      {
+       if (!isTokenExist)
+         o_tokens->push_back(Token(_T(""), false));
+       isTokenExist = false;
+       o_tokens->push_back(Token(Token::Type_comma));
+       t ++;
+       goto continue_getTokenLoop;
+      }
+
+      // paren
+      if (*t == _T('('))
+      {
+       o_tokens->push_back(Token(Token::Type_openParen));
+       isTokenExist = false;
+       t ++;
+       goto continue_getTokenLoop;
+      }
+      if (*t == _T(')'))
+      {
+       if (!isTokenExist)
+         o_tokens->push_back(Token(_T(""), false));
+       isTokenExist = true;
+       o_tokens->push_back(Token(Token::Type_closeParen));
+       t ++;
+       goto continue_getTokenLoop;
+      }
+
+      isTokenExist = true;
+      
+      // prefix
+      if (m_prefixes)
+       for (size_t i = 0; i < m_prefixes->size(); i ++)
+         if (_tcsnicmp(tokenStart, m_prefixes->at(i).c_str(),
+                       m_prefixes->at(i).size()) == 0)
+         {
+           o_tokens->push_back(Token(m_prefixes->at(i), false));
+           t += m_prefixes->at(i).size();
+           goto continue_getTokenLoop;
+         }
+
+      // quoted or regexp
+      if (*t == _T('"') || *t == _T('\'') ||
+         *t == _T('/') || (*t == _T('\\') && *(t + 1) == _T('m') &&
+                           *(t + 2) != _T('\0')))
+      {
+       bool isRegexp = !(*t == _T('"') || *t == _T('\''));
+       _TCHAR q[2] = { *t++, _T('\0') }; // quote character
+       if (q[0] == _T('\\'))
+       {
+         t++;
+         q[0] = *t++;
+       }
+       tokenStart = t;
+       
+       while (*t != _T('\0') && *t != q[0])
+       {
+         if (*t == _T('\\') && *(t + 1))
+           t ++;
+         if (_istlead(*t) && *(t + 1))
+           t ++;
+         t ++;
+       }
+       
+       tstring str =
+         interpretMetaCharacters(tokenStart, t - tokenStart, q, isRegexp);
+#ifdef _MBCS
+       if (isRegexp)
+         str = guardRegexpFromMbcs(str.c_str());
+#endif
+       // concatinate continuous string
+       if (!isRegexp &&
+           0 < o_tokens->size() && o_tokens->back().isString() &&
+           o_tokens->back().isQuoted())
+         o_tokens->back().add(str);
+       else
+         o_tokens->push_back(Token(str, true, isRegexp));
+       if (*t != _T('\0'))
+         t ++;
+       goto continue_getTokenLoop;
+      }
+
+      // not quoted
+      {
+       while (isSymbolChar(*t))
+       {
+         if (*t == _T('\\'))
+           if (*(t + 1))
+             t ++;
+           else
+             break;
+         if (_istlead(*t) && *(t + 1))
+           t ++;
+         t ++;
+       }
+       if (t == tokenStart)
+       {
+         ErrorMessage e;
+         e << _T("invalid character ");
+#ifdef UNICODE
+         e << _T("U+");
+         e << std::hex; // << std::setw(4) << std::setfill(_T('0'));
+         e << (int)(wchar_t)*t;
+#else
+         e << _T("\\x");
+         e << std::hex; // << std::setw(2) << std::setfill(_T('0'));
+         e << (int)(u_char)*t;
+#endif
+         e << std::dec;
+         if (_istprint(*t))
+           e << _T("(") << *t << _T(")");
+         throw e;
+       }
+       
+       _TCHAR *numEnd = NULL;
+       long value = _tcstol(tokenStart, &numEnd, 0);
+       if (tokenStart == numEnd)
+       {
+         tstring str = interpretMetaCharacters(tokenStart, t - tokenStart);
+         o_tokens->push_back(Token(str, false));
+       }
+       else
+       {
+         o_tokens->push_back(
+           Token(value, tstringi(tokenStart, numEnd - tokenStart)));
+         t = numEnd;
+       }
+       goto continue_getTokenLoop;
+      }
+    }
+    break_getTokenLoop:
+    if (0 < o_tokens->size())
+      break;
+    m_lineNumber = m_internalLineNumber;
+    isTokenExist = false;
+  }
+  
+  return 0 < o_tokens->size();
+}
diff --git a/parser.h b/parser.h
new file mode 100644 (file)
index 0000000..a662867
--- /dev/null
+++ b/parser.h
@@ -0,0 +1,144 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// parser.h
+
+
+#ifndef _PARSER_H
+#  define _PARSER_H
+
+#  include "misc.h"
+#  include "stringtool.h"
+#  include <vector>
+
+
+///
+class Token
+{
+public:
+  ///
+  enum Type
+  {
+    Type_string,                               ///
+    Type_number,                               ///
+    Type_regexp,                               ///
+    Type_openParen,                            ///
+    Type_closeParen,                           ///
+    Type_comma,                                        ///
+  };
+  
+private:
+  u_char m_type;                               ///
+  bool m_isValueQuoted;                                ///
+  int m_numericValue;                          ///
+  tstringi m_stringValue;                      ///
+  long m_data;                                 ///
+  
+public:
+  ///
+  Token(const Token &i_token);
+  ///
+  Token(int i_value, const tstringi &i_display);
+  ///
+  Token(const tstringi &i_value, bool i_isValueQuoted,
+       bool i_isRegexp = false);
+  ///
+  Token(Type i_type);
+  
+  /// is the value quoted ?
+  bool isQuoted() const { return m_isValueQuoted; }
+
+  /// value type
+  Type getType() const { return static_cast<Type>(m_type); }
+  ///
+  bool isString() const { return m_type == Type_string; }
+  ///
+  bool isNumber() const { return m_type == Type_number; }
+  ///
+  bool isRegexp() const { return m_type == Type_regexp; }
+  ///
+  bool isOpenParen() const { return m_type == Type_openParen; }
+  ///
+  bool isCloseParen() const { return m_type == Type_closeParen; }
+  ///
+  bool isComma() const { return m_type == Type_comma; }
+  
+  /// get numeric value
+  int getNumber() const;
+  
+  /// get string value
+  tstringi getString() const;
+  
+  /// get regexp value
+  tstringi getRegexp() const;
+
+  /// get data
+  long getData() const { return m_data; }
+  ///
+  void setData(long i_data) { m_data = i_data; }
+  
+  /// case insensitive equal
+  bool operator==(const tstringi &i_str) const
+  { return *this == i_str.c_str(); }
+  ///
+  bool operator==(const _TCHAR *i_str) const;
+  ///
+  bool operator!=(const tstringi &i_str) const
+  { return *this != i_str.c_str(); }
+  ///
+  bool operator!=(const _TCHAR *i_str) const { return !(*this == i_str); }
+  
+  /** paren equal
+      @param i_c '<code>(</code>' or '<code>)</code>' */
+  bool operator==(const _TCHAR i_c) const;
+  /** paren equal
+      @param i_c '<code>(</code>' or '<code>)</code>' */
+  bool operator!=(const _TCHAR i_c) const { return !(*this == i_c); }
+
+  /// add string
+  void add(const tstringi &i_str);
+
+  /// stream output
+  friend tostream &operator<<(tostream &i_ost, const Token &i_token);
+};
+
+
+///
+class Parser
+{
+public:
+  ///
+  typedef std::vector<Token> Tokens;
+  
+private:
+  ///
+  typedef std::vector<tstringi> Prefixes;
+  
+private:
+  size_t m_lineNumber;                         /// current line number
+  const Prefixes *m_prefixes;                  /** string that may be prefix
+                                                    of a token */
+  
+  size_t m_internalLineNumber;                 /// next line number
+  const _TCHAR *m_ptr;                         /// read pointer
+  const _TCHAR *m_end;                         /// end pointer
+
+private:
+  /// get a line
+  bool getLine(tstringi *o_line);
+  
+public:
+  ///
+  Parser(const _TCHAR *i_str, size_t i_length);
+
+  /** get a parsed line.  if no more lines exist, returns false */
+  bool getLine(Tokens *o_tokens);
+  
+  /// get current line number
+  size_t getLineNumber() const { return m_lineNumber; }
+  
+  /** set string that may be prefix of a token.  prefix_ is not
+      copied, so it must be preserved after setPrefix() */
+  void setPrefixes(const Prefixes *m_prefixes);
+};
+
+
+#endif // !_PARSER_H
diff --git a/r/mayu.ico b/r/mayu.ico
new file mode 100644 (file)
index 0000000..7e7e8f7
Binary files /dev/null and b/r/mayu.ico differ
diff --git a/r/mayudisabled.ico b/r/mayudisabled.ico
new file mode 100644 (file)
index 0000000..6e142f7
Binary files /dev/null and b/r/mayudisabled.ico differ
diff --git a/r/mayufile.ico b/r/mayufile.ico
new file mode 100644 (file)
index 0000000..f6943c8
Binary files /dev/null and b/r/mayufile.ico differ
diff --git a/r/target.cur b/r/target.cur
new file mode 100644 (file)
index 0000000..49437ac
Binary files /dev/null and b/r/target.cur differ
diff --git a/registry.cpp b/registry.cpp
new file mode 100644 (file)
index 0000000..d2f8d40
--- /dev/null
@@ -0,0 +1,302 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// registry.cpp
+
+
+#include "registry.h"
+#include "stringtool.h"
+#include "array.h"
+#include <malloc.h>
+
+
+// remove
+bool Registry::remove(HKEY i_root, const tstring &i_path,
+                     const tstring &i_name)
+{
+  if (i_name.empty())
+    return RegDeleteKey(i_root, i_path.c_str()) == ERROR_SUCCESS;
+  HKEY hkey;
+  if (ERROR_SUCCESS !=
+      RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_SET_VALUE, &hkey))
+    return false;
+  LONG r = RegDeleteValue(hkey, i_name.c_str());
+  RegCloseKey(hkey);
+  return r == ERROR_SUCCESS;
+}
+
+
+// does exist the key ?
+bool Registry::doesExist(HKEY i_root, const tstring &i_path)
+{
+  HKEY hkey;
+  if (ERROR_SUCCESS !=
+      RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
+    return false;
+  RegCloseKey(hkey);
+  return true;
+}
+
+
+// read DWORD
+bool Registry::read(HKEY i_root, const tstring &i_path,
+                   const tstring &i_name, int *o_value, int i_defaultValue)
+{
+  HKEY hkey;
+  if (ERROR_SUCCESS ==
+      RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
+  {
+    DWORD type = REG_DWORD;
+    DWORD size = sizeof(*o_value);
+    LONG r = RegQueryValueEx(hkey, i_name.c_str(), NULL,
+                            &type, (BYTE *)o_value, &size);
+    RegCloseKey(hkey);
+    if (r == ERROR_SUCCESS)
+      return true;
+  }
+  *o_value = i_defaultValue;
+  return false;
+}
+
+
+// write DWORD
+bool Registry::write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                    int i_value)
+{
+  HKEY hkey;
+  DWORD disposition;
+  if (ERROR_SUCCESS !=
+      RegCreateKeyEx(i_root, i_path.c_str(), 0, _T(""),
+                    REG_OPTION_NON_VOLATILE,
+                    KEY_ALL_ACCESS, NULL, &hkey, &disposition))
+    return false;
+  LONG r = RegSetValueEx(hkey, i_name.c_str(), NULL, REG_DWORD,
+                        (BYTE *)&i_value, sizeof(i_value));
+  RegCloseKey(hkey);
+  return r == ERROR_SUCCESS;
+}
+
+
+// read string
+bool Registry::read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   tstring *o_value, const tstring &i_defaultValue)
+{
+  HKEY hkey;
+  if (ERROR_SUCCESS ==
+      RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
+  {
+    DWORD type = REG_SZ;
+    DWORD size = 0;
+    BYTE dummy;
+    if (ERROR_MORE_DATA ==
+       RegQueryValueEx(hkey, i_name.c_str(), NULL, &type, &dummy, &size))
+    {
+      if (0 < size)
+      {
+       Array<BYTE> buf(size);
+       if (ERROR_SUCCESS == RegQueryValueEx(hkey, i_name.c_str(),
+                                            NULL, &type, buf.get(), &size))
+       {
+         buf.back() = 0;
+         *o_value = reinterpret_cast<_TCHAR *>(buf.get());
+         RegCloseKey(hkey);
+         return true;
+       }
+      }
+    }
+    RegCloseKey(hkey);
+  }
+  if (!i_defaultValue.empty())
+    *o_value = i_defaultValue;
+  return false;
+}
+
+
+// write string
+bool Registry::write(HKEY i_root, const tstring &i_path,
+                    const tstring &i_name, const tstring &i_value)
+{
+  HKEY hkey;
+  DWORD disposition;
+  if (ERROR_SUCCESS !=
+      RegCreateKeyEx(i_root, i_path.c_str(), 0, _T(""),
+                    REG_OPTION_NON_VOLATILE,
+                    KEY_ALL_ACCESS, NULL, &hkey, &disposition))
+    return false;
+  RegSetValueEx(hkey, i_name.c_str(), NULL, REG_SZ,
+               (BYTE *)i_value.c_str(),
+               (i_value.size() + 1) * sizeof(tstring::value_type));
+  RegCloseKey(hkey);
+  return true;
+}
+
+
+// read list of string
+bool Registry::read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   tstrings *o_value, const tstrings &i_defaultValue)
+{
+  HKEY hkey;
+  if (ERROR_SUCCESS ==
+      RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
+  {
+    DWORD type = REG_MULTI_SZ;
+    DWORD size = 0;
+    BYTE dummy;
+    if (ERROR_MORE_DATA ==
+       RegQueryValueEx(hkey, i_name.c_str(), NULL, &type, &dummy, &size))
+    {
+      if (0 < size)
+      {
+       Array<BYTE> buf(size);
+       if (ERROR_SUCCESS == RegQueryValueEx(hkey, i_name.c_str(),
+                                            NULL, &type, buf.get(), &size))
+       {
+         buf.back() = 0;
+         o_value->clear();
+         const _TCHAR *p = reinterpret_cast<_TCHAR *>(buf.get());
+         const _TCHAR *end = reinterpret_cast<_TCHAR *>(buf.end());
+         while (p < end && *p)
+         {
+           o_value->push_back(p);
+           p += o_value->back().length() + 1;
+         }
+         RegCloseKey(hkey);
+         return true;
+       }
+      }
+    }
+    RegCloseKey(hkey);
+  }
+  if (!i_defaultValue.empty())
+    *o_value = i_defaultValue;
+  return false;
+}
+
+
+// write list of string
+bool Registry::write(HKEY i_root, const tstring &i_path,
+                    const tstring &i_name, const tstrings &i_value)
+{
+  HKEY hkey;
+  DWORD disposition;
+  if (ERROR_SUCCESS !=
+      RegCreateKeyEx(i_root, i_path.c_str(), 0, _T(""),
+                    REG_OPTION_NON_VOLATILE,
+                    KEY_ALL_ACCESS, NULL, &hkey, &disposition))
+    return false;
+  tstring value;
+  for (tstrings::const_iterator i = i_value.begin(); i != i_value.end(); ++ i)
+  {
+    value += *i;
+    value += _T('\0');
+  }
+  RegSetValueEx(hkey, i_name.c_str(), NULL, REG_MULTI_SZ,
+               (BYTE *)value.c_str(),
+               (value.size() + 1) * sizeof(tstring::value_type));
+  RegCloseKey(hkey);
+  return true;
+}
+
+
+// read binary
+bool Registry::read(HKEY i_root, const tstring &i_path,
+                   const tstring &i_name, BYTE *o_value, DWORD i_valueSize,
+                   const BYTE *i_defaultValue, DWORD i_defaultValueSize)
+{
+  if (o_value && 0 < i_valueSize)
+  {
+    HKEY hkey;
+    if (ERROR_SUCCESS ==
+       RegOpenKeyEx(i_root, i_path.c_str(), 0, KEY_READ, &hkey))
+    {
+      DWORD type = REG_BINARY;
+      LONG r = RegQueryValueEx(hkey, i_name.c_str(), NULL, &type,
+                              (BYTE *)o_value, &i_valueSize);
+      RegCloseKey(hkey);
+      if (r == ERROR_SUCCESS)
+       return true;
+    }
+  }
+  if (i_defaultValue)
+    CopyMemory(o_value, i_defaultValue,
+              MIN(i_defaultValueSize, i_valueSize));
+  return false;
+}
+
+
+// write binary
+bool Registry::write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                    const BYTE *i_value, DWORD i_valueSize)
+{
+  if (!i_value)
+    return false;
+  HKEY hkey;
+  DWORD disposition;
+  if (ERROR_SUCCESS !=
+      RegCreateKeyEx(i_root, i_path.c_str(), 0, _T(""),
+                    REG_OPTION_NON_VOLATILE,
+                    KEY_ALL_ACCESS, NULL, &hkey, &disposition))
+    return false;
+  RegSetValueEx(hkey, i_name.c_str(), NULL, REG_BINARY, i_value, i_valueSize);
+  RegCloseKey(hkey);
+  return true;
+}
+
+
+//
+static bool string2logfont(LOGFONT *o_lf, const tstring &i_strlf)
+{
+  // -13,0,0,0,400,0,0,0,128,1,2,1,1,Terminal
+  tregex lf(_T("^(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+),")
+           _T("(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+),")
+           _T("(-?\\d+),(-?\\d+),(-?\\d+),(.+)$"));
+  tsmatch what;
+
+  if (!boost::regex_match(i_strlf, what, lf))
+    return false;
+  o_lf->lfHeight         =       _ttoi(what.str(1).c_str());
+  o_lf->lfWidth          =       _ttoi(what.str(2).c_str());
+  o_lf->lfEscapement     =       _ttoi(what.str(3).c_str());
+  o_lf->lfOrientation    =       _ttoi(what.str(4).c_str());
+  o_lf->lfWeight         =       _ttoi(what.str(5).c_str());
+  o_lf->lfItalic         = (BYTE)_ttoi(what.str(6).c_str());
+  o_lf->lfUnderline      = (BYTE)_ttoi(what.str(7).c_str());
+  o_lf->lfStrikeOut      = (BYTE)_ttoi(what.str(8).c_str());
+  o_lf->lfCharSet        = (BYTE)_ttoi(what.str(9).c_str());
+  o_lf->lfOutPrecision   = (BYTE)_ttoi(what.str(10).c_str());
+  o_lf->lfClipPrecision  = (BYTE)_ttoi(what.str(11).c_str());
+  o_lf->lfQuality        = (BYTE)_ttoi(what.str(12).c_str());
+  o_lf->lfPitchAndFamily = (BYTE)_ttoi(what.str(13).c_str());
+  tcslcpy(o_lf->lfFaceName, what.str(14).c_str(), NUMBER_OF(o_lf->lfFaceName));
+  return true;
+}
+
+
+// read LOGFONT
+bool Registry::read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   LOGFONT *o_value, const tstring &i_defaultStringValue)
+{
+  tstring buf;
+  if (!read(i_root, i_path, i_name, &buf) || !string2logfont(o_value, buf))
+  {
+    if (!i_defaultStringValue.empty())
+      string2logfont(o_value, i_defaultStringValue);
+    return false;
+  }
+  return true;
+}
+
+
+// write LOGFONT
+bool Registry::write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                    const LOGFONT &i_value)
+{
+  _TCHAR buf[1024];
+  _sntprintf(buf, NUMBER_OF(buf),
+            _T("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%s"),
+            i_value.lfHeight, i_value.lfWidth, i_value.lfEscapement,
+            i_value.lfOrientation, i_value.lfWeight, i_value.lfItalic,
+            i_value.lfUnderline, i_value.lfStrikeOut, i_value.lfCharSet,
+            i_value.lfOutPrecision, i_value.lfClipPrecision,
+            i_value.lfQuality,
+            i_value.lfPitchAndFamily, i_value.lfFaceName);
+  return Registry::write(i_root, i_path, i_name, buf);
+}
diff --git a/registry.h b/registry.h
new file mode 100644 (file)
index 0000000..8a7a1c5
--- /dev/null
@@ -0,0 +1,120 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// registry.h
+
+
+#ifndef _REGISTRY_H
+#  define _REGISTRY_H
+
+#  include "stringtool.h"
+#  include <list>
+
+
+/// registry access class
+class Registry
+{
+  HKEY m_root;                                 /// registry root
+  tstring m_path;                              /// path from registry root
+
+public:
+  typedef std::list<tstring> tstrings;
+  
+public:
+  ///
+  Registry() : m_root(NULL) { }
+  ///
+  Registry(HKEY i_root, const tstring &i_path)
+    : m_root(i_root), m_path(i_path) { }
+  
+  /// set registry root and path
+  void setRoot(HKEY i_root, const tstring &i_path)
+  { m_root = i_root; m_path = i_path; }
+  
+  /// remvoe
+  bool remove(const tstring &i_name = _T("")) const
+  { return remove(m_root, m_path, i_name); }
+  
+  /// does exist the key ?
+  bool doesExist() const { return doesExist(m_root, m_path); }
+
+  /// read DWORD
+  bool read(const tstring &i_name, int *o_value, int i_defaultValue = 0)
+    const
+  { return read(m_root, m_path, i_name, o_value, i_defaultValue); }
+  /// write DWORD
+  bool write(const tstring &i_name, int i_value) const
+  { return write(m_root, m_path, i_name, i_value); }
+  /// read tstring
+  bool read(const tstring &i_name, tstring *o_value, 
+           const tstring &i_defaultValue = _T("")) const
+  { return read(m_root, m_path, i_name, o_value, i_defaultValue); }
+  /// write tstring
+  bool write(const tstring &i_name, const tstring &i_value) const
+  { return write(m_root, m_path, i_name, i_value); }
+
+  /// read list of tstring
+  bool read(const tstring &i_name, tstrings *o_value, 
+           const tstrings &i_defaultValue = tstrings()) const
+  { return read(m_root, m_path, i_name, o_value, i_defaultValue); }
+  /// write list of tstring
+  bool write(const tstring &i_name, const tstrings &i_value) const
+  { return write(m_root, m_path, i_name, i_value); }
+
+  /// read binary data
+  bool read(const tstring &i_name, BYTE *o_value, DWORD i_valueSize,
+           const BYTE *i_defaultValue = NULL, DWORD i_defaultValueSize = 0)
+    const
+  { return read(m_root, m_path, i_name, o_value, i_valueSize, i_defaultValue,
+               i_defaultValueSize); }
+  /// write binary data
+  bool write(const tstring &i_name, const BYTE *i_value,
+            DWORD i_valueSize) const
+  { return write(m_root, m_path, i_name, i_value, i_valueSize); }
+
+public:
+  /// remove
+  static bool remove(HKEY i_root, const tstring &i_path,
+                    const tstring &i_name = _T(""));
+  
+  /// does exist the key ?
+  static bool doesExist(HKEY i_root, const tstring &i_path);
+  
+  /// read DWORD
+  static bool read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                  int *o_value, int i_defaultValue = 0);
+  /// write DWORD
+  static bool write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   int i_value);
+
+  /// read tstring
+  static bool read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                  tstring *o_value, const tstring &i_defaultValue = _T(""));
+  /// write tstring
+  static bool write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   const tstring &i_value);
+  
+  /// read list of tstring
+  static bool read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                  tstrings *o_value, const tstrings &i_defaultValue = tstrings());
+  /// write list of tstring
+  static bool write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   const tstrings &i_value);
+  
+  /// read binary data
+  static bool read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                  BYTE *o_value, DWORD i_valueSize,
+                  const BYTE *i_defaultValue = NULL,
+                  DWORD i_defaultValueSize = 0);
+  /// write binary data
+  static bool write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   const BYTE *i_value, DWORD i_valueSize);
+  /// read LOGFONT
+  static bool read(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                  LOGFONT *o_value, const tstring &i_defaultStringValue);
+  /// write LOGFONT
+  static bool write(HKEY i_root, const tstring &i_path, const tstring &i_name,
+                   const LOGFONT &i_value);
+};
+
+
+#endif // !_REGISTRY_H
diff --git a/s/.cvsignore b/s/.cvsignore
new file mode 100644 (file)
index 0000000..3634777
--- /dev/null
@@ -0,0 +1,9 @@
+strres.h
+*.aps
+*.opt
+*.tgz
+*.pdb
+outvc6_*
+outvc7_*
+outvc71_*
+outbcc_*
diff --git a/s/Makefile b/s/Makefile
new file mode 100644 (file)
index 0000000..d766531
--- /dev/null
@@ -0,0 +1,23 @@
+############################################################## -*- Makefile -*-
+#
+# Makefile for setup
+#
+###############################################################################
+
+F      =       setup-vc.mak
+
+all:
+       @echo "============================================================================="
+       @echo "Visual C++ 6.0: nmake"
+       @echo "Borland C++ 5.5: make F=setup-bcc.mak (NOT IMPREMENTED YET)"
+       @echo "============================================================================="
+       $(MAKE) -f $(F) $(MAKEFLAGS) batch
+
+clean:
+       $(MAKE) -f $(F) $(MAKEFLAGS) batch_clean
+
+distrib:
+       $(MAKE) -f $(F) $(MAKEFLAGS) batch_distrib
+
+depend:
+       $(MAKE) -f $(F) $(MAKEFLAGS) TARGETOS=WINNT depend
diff --git a/s/afxres.h b/s/afxres.h
new file mode 100644 (file)
index 0000000..8a6a91b
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef MAYU_AFXRES_H
+#  define MAYU_AFXRES_H
+
+#  include "windows.h"
+#  define IDC_STATIC -1
+
+#endif // !MAYU_AFXRES_H
diff --git a/s/installer.cpp b/s/installer.cpp
new file mode 100644 (file)
index 0000000..d9145c8
--- /dev/null
@@ -0,0 +1,652 @@
+///////////////////////////////////////////////////////////////////////////////
+// setup.cpp
+
+
+#include "../misc.h"
+#include "../registry.h"
+#include "../stringtool.h"
+#include "../windowstool.h"
+#include "installer.h"
+
+#include <shlobj.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+namespace Installer
+{
+  using namespace std;
+  
+  
+  /////////////////////////////////////////////////////////////////////////////
+  // Utility Functions
+
+  /** createLink
+               uses the shell's IShellLink and IPersistFile interfaces to
+               create and store a shortcut to the specified object.
+      @return
+               the result of calling the member functions of the interfaces.
+      @param i_pathObj
+               address of a buffer containing the path of the object.
+      @param i_pathLink
+               address of a buffer containing the path where the
+               shell link is to be stored.
+      @param i_desc
+               address of a buffer containing the description of the
+               shell link.
+  */
+  HRESULT createLink(LPCTSTR i_pathObj, LPCTSTR i_pathLink, LPCTSTR i_desc,
+                    LPCTSTR i_workingDirectory)
+  { 
+    // Get a pointer to the IShellLink interface. 
+    IShellLink* psl;
+    HRESULT hres =
+      CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+                      IID_IShellLink, (void **)&psl);
+    if (SUCCEEDED(hres))
+    { 
+      // Set the path to the shortcut target and add the description. 
+      psl->SetPath(i_pathObj);
+      psl->SetDescription(i_desc);
+      if (i_workingDirectory)
+       psl->SetWorkingDirectory(i_workingDirectory);
+      // Query IShellLink for the IPersistFile interface for saving the 
+      // shortcut in persistent storage. 
+      IPersistFile* ppf; 
+      hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
+      if (SUCCEEDED(hres))
+      {
+#ifdef UNICODE
+       // Save the link by calling IPersistFile::Save. 
+       hres = ppf->Save(i_pathLink, TRUE); 
+#else
+       wchar_t wsz[MAX_PATH];
+       // Ensure that the string is ANSI. 
+       MultiByteToWideChar(CP_ACP, 0, i_pathLink, -1, wsz, MAX_PATH);
+       // Save the link by calling IPersistFile::Save. 
+       hres = ppf->Save(wsz, TRUE); 
+#endif
+       ppf->Release();
+      }
+      psl->Release();
+    } 
+    return hres; 
+  }
+
+
+  // create file extension information
+  void createFileExtension(const tstringi &i_ext, const tstring &i_contentType,
+                          const tstringi &i_fileType,
+                          const tstring &i_fileTypeName,
+                          const tstringi &i_iconPath,
+                          const tstring &i_command)
+  {
+    tstring dummy;
+
+    Registry regExt(HKEY_CLASSES_ROOT, i_ext);
+    if (!         regExt.read (_T(""), &dummy))
+      CHECK_TRUE( regExt.write(_T(""), i_fileType) );
+    if (!         regExt.read (_T("Content Type"), &dummy))
+      CHECK_TRUE( regExt.write(_T("Content Type"), i_contentType) );
+
+    Registry      regFileType(HKEY_CLASSES_ROOT, i_fileType);
+    if (!         regFileType.read (_T(""), &dummy))
+      CHECK_TRUE( regFileType.write(_T(""), i_fileTypeName) );
+
+    Registry      regFileTypeIcon(HKEY_CLASSES_ROOT,
+                                 i_fileType + _T("\\DefaultIcon"));
+    if (!         regFileTypeIcon.read (_T(""), &dummy))
+      CHECK_TRUE( regFileTypeIcon.write(_T(""), i_iconPath) );
+
+    Registry      regFileTypeComand(HKEY_CLASSES_ROOT,
+                                   i_fileType + _T("\\shell\\open\\command"));
+    if (!         regFileTypeComand.read (_T(""), &dummy))
+      CHECK_TRUE( regFileTypeComand.write(_T(""), i_command) );
+  }
+
+
+  // remove file extension information
+  void removeFileExtension(const tstringi &i_ext, const tstringi &i_fileType)
+  {
+    Registry::remove(HKEY_CLASSES_ROOT, i_ext);
+    Registry::remove(HKEY_CLASSES_ROOT,
+                    i_fileType + _T("\\shell\\open\\command"));
+    Registry::remove(HKEY_CLASSES_ROOT, i_fileType + _T("\\shell\\open"));
+    Registry::remove(HKEY_CLASSES_ROOT, i_fileType + _T("\\shell"));
+    Registry::remove(HKEY_CLASSES_ROOT, i_fileType);
+  }
+
+  
+  // create uninstallation information
+  void createUninstallInformation(const tstringi &i_name,
+                                 const tstring &i_displayName,
+                                 const tstring &i_commandLine)
+  {
+    Registry reg(
+      HKEY_LOCAL_MACHINE,
+      _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\")
+      + i_name);
+
+    CHECK_TRUE( reg.write(_T("DisplayName"), i_displayName) );
+    CHECK_TRUE( reg.write(_T("UninstallString"), i_commandLine) );
+  }
+
+  
+  // remove uninstallation information
+  void removeUninstallInformation(const tstringi &i_name)
+  {
+    Registry::
+      remove(HKEY_LOCAL_MACHINE,
+            _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\")
+            + i_name);
+  }
+  
+  
+  // normalize path
+  tstringi normalizePath(tstringi i_path)
+  {
+    tregex regSlash(_T("^(.*)/(.*)$"));
+    tsmatch what;
+    while (boost::regex_search(i_path, what, regSlash))
+      i_path = what.str(1) + _T("\\") + what.str(2);
+
+    tregex regTailBackSlash(_T("^(.*)\\\\$"));
+    while (boost::regex_search(i_path, what, regTailBackSlash))
+      i_path = what.str(1);
+    
+    return i_path;
+  }
+  
+  
+  // create deep directory
+  bool createDirectories(const _TCHAR *i_folder)
+  {
+    const _TCHAR *s = _tcschr(i_folder, _T('\\')); // TODO: '/'
+    if (s && s - i_folder == 2 && i_folder[1] == _T(':'))
+      s = _tcschr(s + 1, _T('\\'));
+    
+    struct _stat sbuf;
+    while (s)
+    {
+      tstringi f(i_folder, 0, s - i_folder);
+      if (_tstat(f.c_str(), &sbuf) < 0)
+       if (!CreateDirectory(f.c_str(), NULL))
+         return false;
+      s = _tcschr(s + 1, _T('\\'));
+    }
+    if (_tstat(i_folder, &sbuf) < 0)
+      if (!CreateDirectory(i_folder, NULL))
+       return false;
+    return true;
+  }
+
+
+  // get driver directory
+  tstringi getDriverDirectory()
+  {
+    _TCHAR buf[GANA_MAX_PATH];
+    CHECK_TRUE( GetSystemDirectory(buf, NUMBER_OF(buf)) );
+    return tstringi(buf) + _T("\\drivers");
+  }
+
+  
+  // get current directory
+  tstringi getModuleDirectory()
+  {
+    _TCHAR buf[GANA_MAX_PATH];
+    CHECK_TRUE( GetModuleFileName(g_hInst, buf, NUMBER_OF(buf)) );
+    tregex reg(_T("^(.*)\\\\[^\\\\]*$"));
+    tsmatch what;
+    tstringi path(buf);
+    if (boost::regex_search(path, what, reg))
+      return what.str(1);
+    else
+      return path;
+  }
+
+
+  // get start menu name
+  tstringi getStartMenuName(const tstringi &i_shortcutName)
+  {
+#if 0
+    char programDir[GANA_MAX_PATH];
+    if (SUCCEEDED(SHGetSpecialFolderPath(NULL, programDir,
+                                        CSIDL_COMMON_PROGRAMS, FALSE)))
+      return tstringi(programDir) + "\\" + shortcutName + ".lnk";
+#else
+    tstringi programDir;
+    if (Registry::read(HKEY_LOCAL_MACHINE,
+                      _T("Software\\Microsoft\\Windows\\CurrentVersion\\")
+                      _T("Explorer\\Shell Folders"), _T("Common Programs"),
+                      &programDir))
+      return programDir + _T("\\") + i_shortcutName + _T(".lnk");
+#endif
+    return _T("");
+  }
+
+
+  // get start up name
+  tstringi getStartUpName(const tstringi &i_shortcutName)
+  {
+    tstringi startupDir;
+    if (Registry::read(HKEY_CURRENT_USER,
+                      _T("Software\\Microsoft\\Windows\\CurrentVersion\\")
+                      _T("Explorer\\Shell Folders"), _T("Startup"),
+                      &startupDir))
+      return startupDir + _T("\\") + i_shortcutName + _T(".lnk");
+    return _T("");
+  }
+
+
+#if defined(_WINNT)
+
+#  define MAYUD_FILTER_KEY _T("System\\CurrentControlSet\\Control\\Class\\{4D36E96B-E325-11CE-BFC1-08002BE10318}")
+
+  // create driver service
+  DWORD createDriverService(const tstringi &i_serviceName,
+                           const tstring &i_serviceDescription,
+                           const tstringi &i_driverPath,
+                           const _TCHAR *i_preloadedGroups,
+                           bool forUsb)
+  {
+    SC_HANDLE hscm =
+      OpenSCManager(NULL, NULL,
+                   SC_MANAGER_CREATE_SERVICE | SC_MANAGER_CONNECT);
+    if (!hscm)
+      return false;
+
+    SC_HANDLE hs =
+      CreateService(hscm, i_serviceName.c_str(), i_serviceDescription.c_str(),
+                   SERVICE_START | SERVICE_STOP, SERVICE_KERNEL_DRIVER,
+                   forUsb == true ? SERVICE_DEMAND_START : SERVICE_AUTO_START,
+                   SERVICE_ERROR_IGNORE,
+                   i_driverPath.c_str(), NULL, NULL,
+                   i_preloadedGroups, NULL, NULL);
+    DWORD err = GetLastError();
+    if (hs == NULL)
+    {
+      switch (err)
+      {
+       case ERROR_SERVICE_EXISTS:
+       {
+#if 0
+         hs = OpenService(hscm, i_serviceName.c_str(), SERVICE_CHANGE_CONFIG);
+         if (hs == NULL) {
+           CloseServiceHandle(hscm);
+           return GetLastError();
+         }
+         if (!ChangeServiceConfig(
+               hscm, SERVICE_KERNEL_DRIVER,
+               forUsb == true ? SERVICE_DEMAND_START : SERVICE_AUTO_START,
+               SERVICE_ERROR_IGNORE,
+               i_driverPath.c_str(), NULL, NULL,
+               i_preloadedGroups, NULL, NULL,
+               i_serviceDescription.c_str())) {
+           CloseServiceHandle(hs);
+           CloseServiceHandle(hscm);
+           return GetLastError();              // ERROR_IO_PENDING!
+           // this code always reaches here. why?
+         }
+#else
+         Registry reg(HKEY_LOCAL_MACHINE,
+                      _T("SYSTEM\\CurrentControlSet\\Services\\mayud"));
+         reg.write(_T("Start"),
+                   forUsb ? SERVICE_DEMAND_START : SERVICE_AUTO_START);
+#endif
+         break;
+       }
+       default:
+       {
+         CloseServiceHandle(hscm);
+         return err;
+       }
+      }
+    }
+    CloseServiceHandle(hs);
+    CloseServiceHandle(hscm);
+
+    if (forUsb == true) {
+      Registry reg(HKEY_LOCAL_MACHINE, MAYUD_FILTER_KEY);
+      typedef std::list<tstring> Filters;
+      Filters filters;
+      if (!reg.read(_T("UpperFilters"), &filters))
+       return false;
+      for (Filters::iterator i = filters.begin(); i != filters.end(); ) {
+         Filters::iterator next = i;
+         ++ next;
+         if (*i == _T("mayud")) {
+             filters.erase(i);
+         }
+         i = next;
+      }
+      filters.push_back(_T("mayud"));
+      if (!reg.write(_T("UpperFilters"), filters))
+       return false;
+    }
+
+    return ERROR_SUCCESS;
+  }
+#endif // _WINNT
+
+
+#if defined(_WINNT)
+  // remove driver service
+  DWORD removeDriverService(const tstringi &i_serviceName)
+  {
+    DWORD err = ERROR_SUCCESS;
+    
+    Registry reg(HKEY_LOCAL_MACHINE, MAYUD_FILTER_KEY);
+    std::list<tstring> filters;
+    if (reg.read(_T("UpperFilters"), &filters))
+    {
+      filters.remove(_T("mayud"));
+      reg.write(_T("UpperFilters"), filters);
+    }
+
+    SC_HANDLE hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+    SC_HANDLE hs =
+      OpenService(hscm, i_serviceName.c_str(),
+                 SERVICE_START | SERVICE_STOP | DELETE);
+    if (!hs)
+    {
+      err = GetLastError();
+      goto error;
+    }
+
+    SERVICE_STATUS ss;
+    ControlService(hs, SERVICE_CONTROL_STOP, &ss);
+  
+    if (!DeleteService(hs))
+    {
+      err = GetLastError();
+      goto error;
+    }
+    error:
+    CloseServiceHandle(hs);
+    CloseServiceHandle(hscm);
+    return err;
+  }
+#endif // _WINNT
+
+
+  // check operating system
+  bool checkOs(SetupFile::OS os)
+  {
+    OSVERSIONINFO ver;
+    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    GetVersionEx(&ver);
+    
+    switch (os)
+    {
+      default:
+      case SetupFile::ALL:
+       return true;
+      case SetupFile::W9x:
+       return (ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
+               4 <= ver.dwMajorVersion);
+      case SetupFile::NT :
+       return (ver.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+               4 <= ver.dwMajorVersion);
+      case SetupFile::NT4:
+       return (ver.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+               ver.dwMajorVersion == 4);
+      case SetupFile::W2k:                     // W2k, XP, ...
+       return (ver.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+               5 <= ver.dwMajorVersion);
+    }
+  }
+
+  
+  // install files
+  bool installFiles(const SetupFile::Data *i_setupFiles,
+                   size_t i_setupFilesSize, u_int32 i_flags,
+                   const tstringi &i_srcDir, const tstringi &i_destDir)
+  {
+    tstringi to, from;
+    tstringi destDriverDir = getDriverDirectory();
+
+    for (size_t i = 0; i < i_setupFilesSize; ++ i)
+    {
+      const SetupFile::Data &s = i_setupFiles[i];
+      const tstringi &fromDir = i_srcDir;
+      const tstringi &toDir =
+       (s.m_destination == SetupFile::ToDriver) ? destDriverDir : i_destDir;
+
+      if (!s.m_from)
+       continue;                               // remove only
+
+      if (fromDir == toDir)
+       continue;                               // same directory
+
+      if (!checkOs(s.m_os))                    // check operating system
+       continue;
+
+      if ((s.m_flags & i_flags) != i_flags)    // check flags
+       continue;
+      
+      // type
+      switch (s.m_kind)
+      {
+       case SetupFile::Dll:
+       {
+         // rename driver
+         tstringi from_ = toDir + _T("\\") + s.m_to;
+         tstringi to_ = toDir + _T("\\deleted.") + s.m_to;
+         DeleteFile(to_.c_str());
+         MoveFile(from_.c_str(), to_.c_str());
+         DeleteFile(to_.c_str());
+       }
+       // fall through
+       default:
+       case SetupFile::File:
+       {
+         from += fromDir + _T('\\') + s.m_from + _T('\0');
+         to   += toDir   + _T('\\') + s.m_to   + _T('\0');
+         break;
+       }
+       case SetupFile::Dir:
+       {
+         createDirectories((toDir + _T('\\') + s.m_to).c_str());
+         break;
+       }
+      }
+    }
+#if 0
+    {
+      tstringi to_(to), from_(from);
+      for (size_t i = 0; i < to_.size(); ++ i)
+       if (!to_[i])
+         to_[i] = ' ';
+      for (size_t i = 0; i < from_.size(); ++ i)
+       if (!from_[i])
+         from_[i] = ' ';
+      MessageBox(NULL, to_.c_str(), from_.c_str(), MB_OK);
+    }
+#endif
+
+    SHFILEOPSTRUCT fo;
+    ::ZeroMemory(&fo, sizeof(fo));
+    fo.wFunc = FO_COPY;
+    fo.fFlags = FOF_MULTIDESTFILES;
+    fo.pFrom = from.c_str();
+    fo.pTo   = to.c_str();
+    if (SHFileOperation(&fo) || fo.fAnyOperationsAborted)
+      return false;
+    return true;
+  }
+  
+
+  // remove files from src
+  bool removeSrcFiles(const SetupFile::Data *i_setupFiles, 
+                     size_t i_setupFilesSize, u_int32 i_flags,
+                     const tstringi &i_srcDir)
+  {
+    tstringi destDriverDir = getDriverDirectory();
+
+    for (size_t i = 0; i < i_setupFilesSize; ++ i)
+    {
+      const SetupFile::Data &s = i_setupFiles[i_setupFilesSize - i - 1];
+      const tstringi &fromDir = i_srcDir;
+      
+      if (!s.m_from)
+       continue;       // remove only
+
+      if (!checkOs(s.m_os))    // check operating system
+       continue;
+      
+      if ((s.m_flags & i_flags) != i_flags)    // check flags
+       continue;
+
+      // type
+      switch (s.m_kind)
+      {
+       default:
+       case SetupFile::Dll:
+       case SetupFile::File:
+         DeleteFile((fromDir + _T('\\') + s.m_from).c_str());
+         break;
+       case SetupFile::Dir:
+         RemoveDirectory((fromDir + _T('\\') + s.m_from).c_str());
+         break;
+      }
+    }
+    RemoveDirectory(i_srcDir.c_str());
+    return true;
+  }
+
+  
+  // remove files
+  void removeFiles(const SetupFile::Data *i_setupFiles,
+                  size_t i_setupFilesSize, u_int32 i_flags,
+                  const tstringi &i_destDir)
+  {
+    tstringi destDriverDir = getDriverDirectory();
+
+    for (size_t i = 0; i < i_setupFilesSize; ++ i)
+    {
+      const SetupFile::Data &s = i_setupFiles[i_setupFilesSize - i - 1];
+      const tstringi &toDir =
+       (s.m_destination == SetupFile::ToDriver) ? destDriverDir : i_destDir;
+
+      if (!checkOs(s.m_os))    // check operating system
+       continue;
+
+      if ((s.m_flags & i_flags) != i_flags)    // check flags
+       continue;
+      
+      // type
+      switch (s.m_kind)
+      {
+       case SetupFile::Dll:
+         DeleteFile((toDir + _T("\\deleted.") + s.m_to).c_str());
+         // fall through
+       default:
+       case SetupFile::File:
+         DeleteFile((toDir + _T('\\') + s.m_to).c_str());
+         break;
+       case SetupFile::Dir:
+         RemoveDirectory((toDir + _T('\\') + s.m_to).c_str());
+         break;
+      }
+    }
+    RemoveDirectory(i_destDir.c_str());
+  }
+  
+  
+  // uninstall step1
+  int uninstallStep1(const _TCHAR *i_uninstallOption)
+  {
+    // copy this EXEcutable image into the user's temp directory
+    _TCHAR setup_exe[GANA_MAX_PATH], tmp_setup_exe[GANA_MAX_PATH];
+    GetModuleFileName(NULL, setup_exe, NUMBER_OF(setup_exe));
+    GetTempPath(NUMBER_OF(tmp_setup_exe), tmp_setup_exe);
+    GetTempFileName(tmp_setup_exe, _T("del"), 0, tmp_setup_exe);
+    CopyFile(setup_exe, tmp_setup_exe, FALSE);
+    
+    // open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE
+    HANDLE hfile = CreateFile(tmp_setup_exe, 0, FILE_SHARE_READ, NULL,
+                             OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+    
+    // spawn the clone EXE passing it our EXE's process handle
+    // and the full path name to the original EXE file.
+    _TCHAR commandLine[512];
+    HANDLE hProcessOrig =
+      OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());
+    _sntprintf(commandLine, NUMBER_OF(commandLine), _T("%s %s %d"),
+              tmp_setup_exe, i_uninstallOption, hProcessOrig);
+    STARTUPINFO si;
+    ::ZeroMemory(&si, sizeof(si));
+    si.cb = sizeof(si);
+    PROCESS_INFORMATION pi;
+    CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si,&pi);
+    Sleep(2000); // important
+    CloseHandle(hProcessOrig);
+    CloseHandle(hfile);
+    
+    return 0;
+  }
+
+  // uninstall step2
+  // (after this function, we cannot use any resource)
+  void uninstallStep2(const _TCHAR *argByStep1)
+  {
+    // clone EXE: When original EXE terminates, delete it
+    HANDLE hProcessOrig = (HANDLE)_ttoi(argByStep1);
+    WaitForSingleObject(hProcessOrig, INFINITE);
+    CloseHandle(hProcessOrig);
+  }
+  
+  
+  /////////////////////////////////////////////////////////////////////////////
+  // Locale / StringResource
+
+
+  // constructor
+  Resource::Resource(const StringResource *i_stringResources)
+    : m_stringResources(i_stringResources),
+      m_locale(LOCALE_C)
+  {
+    struct LocaleInformaton
+    {
+      const _TCHAR *m_localeString;
+      Locale m_locale;
+    };
+
+    // set locale information
+    const _TCHAR *localeString = ::_tsetlocale(LC_ALL, _T(""));
+    
+    static const LocaleInformaton locales[] =
+    {
+      { _T("Japanese_Japan.932"), LOCALE_Japanese_Japan_932 },
+    };
+
+    for (size_t i = 0; i < NUMBER_OF(locales); ++ i)
+      if (_tcsicmp(localeString, locales[i].m_localeString) == 0)
+      {
+       m_locale = locales[i].m_locale;
+       break;
+      }
+  }
+  
+  
+  // get resource string
+  const _TCHAR *Resource::loadString(UINT i_id)
+  {
+    int n = static_cast<int>(m_locale);
+    int index = -1;
+    for (int i = 0; m_stringResources[i].m_str; ++ i)
+      if (m_stringResources[i].m_id == i_id)
+      {
+       if (n == 0)
+         return m_stringResources[i].m_str;
+       index = i;
+       n --;
+      }
+    if (0 <= index)
+      return m_stringResources[index].m_str;
+    else
+      return _T("");
+  }
+}
diff --git a/s/installer.h b/s/installer.h
new file mode 100644 (file)
index 0000000..753c2fe
--- /dev/null
@@ -0,0 +1,170 @@
+///////////////////////////////////////////////////////////////////////////////
+// installer.h
+
+
+#ifndef _INSTALLER_H
+#  define _INSTALLER_H
+
+
+namespace Installer
+{
+  /////////////////////////////////////////////////////////////////////////////
+  // SetupFile
+  
+  // files to copy
+  namespace SetupFile
+  {
+    enum Kind
+    {
+      File,
+      Dir,
+      Dll,
+    };
+    
+    enum OS
+    {
+      ALL,
+      W9x, // W95, W98,
+      NT,  NT4, W2k,                           // W2k includes XP
+    };
+    
+    enum Destination
+    {
+      ToDest,
+      ToDriver,
+    };
+
+    enum Flag
+    {
+      Normal = 1,
+    };
+    
+    struct Data
+    {
+      Kind m_kind;
+      OS m_os;
+      u_int32 m_flags;                         /// user defined flags
+      const _TCHAR *m_from;
+      Destination m_destination;
+      const _TCHAR *m_to;
+    };
+  }
+
+  
+  /////////////////////////////////////////////////////////////////////////////
+  // Locale / StringResource
+  
+  enum Locale
+  {
+    LOCALE_Japanese_Japan_932 = 0,
+    LOCALE_C = 1,
+  };
+
+  struct StringResource
+  {
+    UINT m_id;
+    _TCHAR *m_str;
+  };
+
+  class Resource
+  {
+    const StringResource *m_stringResources;
+    
+    Locale m_locale;
+    
+  public:
+    // constructor
+    Resource(const StringResource *i_stringResources);
+    Resource(const StringResource *i_stringResources, Locale i_locale)
+      : m_stringResources(i_stringResources), m_locale(i_locale) { }
+    
+    // get resource string
+    const _TCHAR *loadString(UINT i_id);
+
+    // locale
+    Locale getLocale() const { return m_locale; }
+  };
+
+  
+  /////////////////////////////////////////////////////////////////////////////
+  // Utility Functions
+
+  // createLink - uses the shell's IShellLink and IPersistFile interfaces 
+  //   to create and store a shortcut to the specified object. 
+  HRESULT createLink(LPCTSTR i_pathObj, LPCTSTR i_pathLink, LPCTSTR i_desc,
+                    LPCTSTR i_workingDirectory = NULL);
+  
+  // create file extension information
+  void createFileExtension(const tstringi &i_ext, const tstring &i_contentType,
+                          const tstringi &i_fileType,
+                          const tstring &i_fileTypeName,
+                          const tstringi &i_iconPath,
+                          const tstring &i_command);
+  
+  // remove file extension information
+  void removeFileExtension(const tstringi &i_ext, const tstringi &i_fileType);
+  
+  // create uninstallation information
+  void createUninstallInformation(const tstringi &i_name,
+                                 const tstring &i_displayName,
+                                 const tstring &i_commandLine);
+  
+  // remove uninstallation information
+  void removeUninstallInformation(const tstringi &i_name);
+
+  // normalize path
+  tstringi normalizePath(tstringi i_path);
+  
+  // create deep directory
+  bool createDirectories(const _TCHAR *i_folder);
+
+  // get driver directory
+  tstringi getDriverDirectory();
+
+  // get current directory
+  tstringi getModuleDirectory();
+
+  // get start menu name
+  tstringi getStartMenuName(const tstringi &i_shortcutName);
+
+  // get start up name
+  tstringi getStartUpName(const tstringi &i_shortcutName);
+
+  // create driver service
+  DWORD createDriverService(const tstringi &i_serviceName,
+                           const tstring &i_serviceDescription,
+                           const tstringi &i_driverPath,
+                           const _TCHAR *i_preloadedGroups,
+                           bool forUsb);
+
+  // remove driver service
+  DWORD removeDriverService(const tstringi &i_serviceName);
+
+  // check operating system
+  bool checkOs(SetupFile::OS i_os);
+  
+  // install files
+  bool installFiles(const SetupFile::Data *i_setupFiles,
+                   size_t i_setupFilesSize, u_int32 i_flags,
+                   const tstringi &i_srcDir, const tstringi &i_destDir);
+  
+  // remove files from src
+  bool removeSrcFiles(const SetupFile::Data *i_setupFiles,
+                     size_t i_setupFilesSize, u_int32 i_flags,
+                     const tstringi &i_srcDir);
+  
+  // remove files
+  void removeFiles(const SetupFile::Data *i_setupFiles,
+                  size_t i_setupFilesSize, u_int32 i_flags,
+                  const tstringi &i_destDir);
+  
+  // uninstall step1
+  int uninstallStep1(const _TCHAR *i_uninstallOption);
+  
+  // uninstall step2
+  // (after this function, we cannot use any resource)
+  void uninstallStep2(const _TCHAR *i_argByStep1);
+}
+
+
+#endif // _INSTALLER_H
diff --git a/s/setup-common.mak b/s/setup-common.mak
new file mode 100644 (file)
index 0000000..466864e
--- /dev/null
@@ -0,0 +1,86 @@
+############################################################## -*- Makefile -*-\r
+#\r
+# Makefile for setup\r
+#\r
+###############################################################################\r
+\r
+\r
+!if "$(TARGETOS)" == "WINNT"\r
+OS_SPECIFIC_DEFINES    =  -DUNICODE -D_UNICODE\r
+DISTRIB_OS     = nt\r
+!endif\r
+\r
+!if "$(TARGETOS)" == "WIN95"\r
+OS_SPECIFIC_DEFINES    =  -D_MBCS\r
+DISTRIB_OS     = 9x\r
+!endif\r
+\r
+!if "$(TARGETOS)" == "BOTH"\r
+!error Must specify TARGETOS=WIN95 or TARGETOS=WINNT\r
+!endif\r
+\r
+\r
+DEFINES                = -DSTRICT -D_WIN32_IE=0x0400 $(OS_SPECIFIC_DEFINES) \\r
+                 $(DEBUGDEFINES)\r
+BOOST_DIR      = ../../boost_$(BOOST_VER)_0\r
+\r
+\r
+# setup.exe    ###############################################################\r
+\r
+TARGET_1       = $(OUT_DIR)\setup.exe\r
+OBJS_1         =                               \\r
+               $(OUT_DIR)\setup.obj            \\r
+               $(OUT_DIR)\installer.obj        \\r
+               ..\$(OUT_DIR)\registry.obj      \\r
+               ..\$(OUT_DIR)\stringtool.obj    \\r
+               ..\$(OUT_DIR)\windowstool.obj   \\r
+\r
+SRCS_1         =                       \\r
+               setup.cpp               \\r
+               installer.cpp           \\r
+               ..\registry.cpp         \\r
+               ..\stringtool.cpp       \\r
+               ..\windowstool.cpp      \\r
+\r
+RES_1          = $(OUT_DIR)\setup.res\r
+\r
+LIBS_1         = $(guixlibsmt) shell32.lib ole32.lib uuid.lib\r
+\r
+\r
+# tools                ###############################################################\r
+\r
+MAKEDEPEND     = perl ../tools/makedepend -o.obj\r
+\r
+\r
+# rules                ###############################################################\r
+\r
+all:           $(OUT_DIR) $(TARGET_1)\r
+\r
+$(OUT_DIR):\r
+               if not exist "$(OUT_DIR)\\" $(MKDIR) $(OUT_DIR)\r
+\r
+setup.cpp:     strres.h\r
+\r
+clean:\r
+               -$(RM) $(TARGET_1) strres.h\r
+               -$(RM) $(OUT_DIR)\*.obj $(OUT_DIR)\*.res $(OUT_DIR)\*.pdb *.pdb\r
+               -$(RM) *~ $(CLEAN)\r
+               -$(RMDIR) $(OUT_DIR)\r
+\r
+depend::\r
+               $(MAKEDEPEND) -fsetup-common.mak \\r
+               -- $(DEPENDFLAGS) -- $(SRCS_1)\r
+\r
+# DO NOT DELETE\r
+\r
+$(OUT_DIR)\setup.obj: ../compiler_specific.h ../mayu.h ../misc.h \\r
+ ../registry.h ../stringtool.h ../windowstool.h installer.h setuprc.h \\r
+ strres.h\r
+$(OUT_DIR)\installer.obj: ../compiler_specific.h ../misc.h ../registry.h \\r
+ ../stringtool.h ../windowstool.h installer.h\r
+$(OUT_DIR)\..\registry.obj: ../compiler_specific.h ../misc.h \\r
+ ../registry.cpp ../registry.h ../stringtool.h\r
+$(OUT_DIR)\..\stringtool.obj: ../compiler_specific.h ../misc.h \\r
+ ../stringtool.cpp ../stringtool.h\r
+$(OUT_DIR)\..\windowstool.obj: ../compiler_specific.h ../misc.h \\r
+ ../stringtool.h ../windowstool.cpp ../windowstool.h\r
diff --git a/s/setup-vc.mak b/s/setup-vc.mak
new file mode 100644 (file)
index 0000000..16fbe44
--- /dev/null
@@ -0,0 +1,51 @@
+############################################################## -*- Makefile -*-
+#
+# Makefile for setup (Visual C++)
+#
+#      make release version: nmake nodebug=1
+#      make debug version: nmake
+#
+###############################################################################
+
+
+!if "$(BOOST_VER)" == ""
+BOOST_VER      = 1_32
+!endif
+INCLUDES       = -I$(BOOST_DIR)        # why here ?
+DEPENDIGNORE   = --ignore=$(BOOST_DIR)
+
+!if "$(MAYU_VC)" == ""
+MAYU_VC        = vc6
+!endif
+
+!if ( "$(MAYU_VC)" == "vct" )
+MAYU_REGEX_VC  = vc71
+!else
+MAYU_REGEX_VC  = $(MAYU_VC)
+!endif
+
+!include <..\vc.mak>
+!include <setup-common.mak>
+
+LDFLAGS_1      =                                               \
+               $(guilflags)                                    \
+               /PDB:$(TARGET_1).pdb                            \
+               /LIBPATH:$(BOOST_DIR)/libs/regex/build/$(MAYU_REGEX_VC) \
+
+$(TARGET_1):   $(OBJS_1) $(RES_1) $(EXTRADEP_1)
+       $(link) -out:$@ $(ldebug) $(LDFLAGS_1) $(OBJS_1) $(LIBS_1) $(RES_1)
+
+strres.h:      setup.rc
+       grep IDS setup.rc | \
+       sed "s/\(IDS[a-zA-Z0-9_]*\)[^""]*\("".*\)$$/\1, _T(\2),/" | \
+       sed "s/""""/"") _T(""/g" > strres.h
+
+batch:
+!if "$(MAYU_VC)" != "vct"
+               -$(MAKE) -k -f setup-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT
+!endif
+               -$(MAKE) -k -f setup-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1
+
+batch_clean:
+               -$(MAKE) -k -f setup-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT nodebug=1 clean
+               -$(MAKE) -k -f setup-vc.mak MAYU_VC=$(MAYU_VC) TARGETOS=WINNT clean
diff --git a/s/setup.cpp b/s/setup.cpp
new file mode 100644 (file)
index 0000000..53b4838
--- /dev/null
@@ -0,0 +1,587 @@
+///////////////////////////////////////////////////////////////////////////////
+// setup.cpp
+
+
+#include "../misc.h"
+#include "../registry.h"
+#include "../stringtool.h"
+#include "../windowstool.h"
+#include "../mayu.h"
+#include "setuprc.h"
+#include "installer.h"
+
+#include <windowsx.h>
+#include <shlobj.h>
+
+
+using namespace Installer;
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Registry
+
+
+#define DIR_REGISTRY_ROOT                      \
+       HKEY_LOCAL_MACHINE,                     \
+       _T("Software\\GANAware\\mayu")
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Globals
+
+
+enum
+{
+  Flag_Usb = 1 << 1,
+};
+u_int32 g_flags = SetupFile::Normal;
+
+
+using namespace SetupFile;
+const SetupFile::Data g_setupFiles[] =
+{
+  // same name
+#define SN(i_kind, i_os, i_from, i_destination)                        \
+  { i_kind, i_os, Normal|Flag_Usb, _T(i_from), i_destination, _T(i_from) }
+  // different name
+#define DN(i_kind, i_os, i_from, i_destination, i_to)  \
+  { i_kind, i_os, Normal|Flag_Usb, _T(i_from), i_destination, _T(i_to) }
+  
+  // executables
+  SN(Dll , ALL, "mayu.dll"          , ToDest),
+  SN(File, ALL, "mayu.exe"          , ToDest),
+  SN(File, ALL, "setup.exe"         , ToDest),
+                                   
+  // drivers
+#if defined(_WINNT)
+  SN(File, NT , "mayud.sys"         , ToDest),
+  SN(File, NT , "mayudnt4.sys"      , ToDest),
+  SN(File, W2k, "mayudrsc.sys"    , ToDest),
+  SN(File, W2k, "mayud.sys"         , ToDriver),
+  DN(File, NT4, "mayudnt4.sys"      , ToDriver, "mayud.sys"),
+  SN(File, W2k, "mayudrsc.sys"    , ToDriver),
+#elif defined(_WIN95)
+  SN(File, W9x, "mayud.vxd"         , ToDest),
+#else
+#  error
+#endif
+
+  // setting files                 
+  SN(File, ALL, "104.mayu"          , ToDest),
+  SN(File, ALL, "104on109.mayu"             , ToDest),
+  SN(File, ALL, "109.mayu"          , ToDest),
+  SN(File, ALL, "109on104.mayu"             , ToDest),
+  SN(File, ALL, "default.mayu"      , ToDest),
+  SN(File, ALL, "dot.mayu"          , ToDest),
+  SN(File, ALL, "emacsedit.mayu"     , ToDest),
+                                   
+  // documents                             
+  SN(Dir , ALL, "doc"               , ToDest), // mkdir
+  DN(File, ALL, "banner-ja.gif"             , ToDest, "doc\\banner-ja.gif"      ),
+  DN(File, ALL, "edit-setting-ja.png", ToDest, "doc\\edit-setting-ja.png"),
+  DN(File, ALL, "investigate-ja.png" , ToDest, "doc\\investigate-ja.png" ),
+  DN(File, ALL, "log-ja.png"        , ToDest, "doc\\log-ja.png"         ),
+  DN(File, ALL, "menu-ja.png"       , ToDest, "doc\\menu-ja.png"        ),
+  DN(File, ALL, "pause-ja.png"      , ToDest, "doc\\pause-ja.png"       ),
+  DN(File, ALL, "setting-ja.png"     , ToDest, "doc\\setting-ja.png"    ),
+  DN(File, ALL, "target.png"        , ToDest, "doc\\target.png"         ),
+  DN(File, ALL, "version-ja.png"     , ToDest, "doc\\version-ja.png"    ),
+  DN(File, ALL, "CONTENTS-ja.html"   , ToDest, "doc\\CONTENTS-ja.html"  ),
+  DN(File, ALL, "CUSTOMIZE-ja.html"  , ToDest, "doc\\CUSTOMIZE-ja.html"         ),
+  DN(File, ALL, "MANUAL-ja.html"     , ToDest, "doc\\MANUAL-ja.html"    ),
+  DN(File, ALL, "README-ja.html"     , ToDest, "doc\\README-ja.html"    ),
+  DN(File, ALL, "README.css"        , ToDest, "doc\\README.css"         ),
+  DN(File, ALL, "syntax.txt"        , ToDest, "doc\\syntax.txt"         ),
+  
+  SN(File, ALL, "mayu-mode.el"      , ToDest),
+                                   
+  SN(Dir , ALL, "contrib"           , ToDest), // mkdir
+  DN(File, ALL, "mayu-settings.txt"  , ToDest, "contrib\\mayu-settings.txt"),
+  DN(File, ALL, "dvorak.mayu"       , ToDest, "contrib\\dvorak.mayu"      ),
+  DN(File, ALL, "DVORAKon109.mayu"   , ToDest, "contrib\\DVORAKon109.mayu" ),
+  DN(File, ALL, "keitai.mayu"       , ToDest, "contrib\\keitai.mayu"      ),
+  DN(File, ALL, "ax.mayu"           , ToDest, "contrib\\ax.mayu"          ),
+  DN(File, ALL, "98x1.mayu"         , ToDest, "contrib\\98x1.mayu"        ),
+  DN(File, ALL, "109onAX.mayu"      , ToDest, "contrib\\109onAX.mayu"     ),
+
+  SN(Dir , ALL, "Plugins"           , ToDest), // mkdir
+};
+
+
+enum KeyboardKind
+{
+  KEYBOARD_KIND_109,
+  KEYBOARD_KIND_104,
+} g_keyboardKind;
+
+
+static const StringResource g_strres[] =
+{
+#include "strres.h"
+};
+
+
+bool g_wasExecutedBySFX = false;       // Was setup executed by cab32 SFX ?
+Resource *g_resource;                  // resource information
+tstringi g_destDir;                    // destination directory
+
+
+///////////////////////////////////////////////////////////////////////////////
+// functions
+
+
+// show message
+int message(int i_id, int i_flag, HWND i_hwnd = NULL)
+{
+  return MessageBox(i_hwnd, g_resource->loadString(i_id),
+                   g_resource->loadString(IDS_mayuSetup), i_flag);
+}
+
+
+// driver service error
+void driverServiceError(DWORD i_err)
+{
+  switch (i_err)
+  {
+    case ERROR_ACCESS_DENIED:
+      message(IDS_notAdministrator, MB_OK | MB_ICONSTOP);
+      break;
+    case ERROR_SERVICE_MARKED_FOR_DELETE:
+      message(IDS_alreadyUninstalled, MB_OK | MB_ICONSTOP);
+      break;
+    default:
+    {
+      TCHAR *errmsg;
+      int err = int(i_err);
+      if (err < 0) {
+       i_err = -err;
+      }
+      if (FormatMessage(
+           FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+           NULL, i_err, 0, (LPTSTR)&errmsg, 0, NULL)) {
+       TCHAR buf[1024];
+       _sntprintf(buf, NUMBER_OF(buf), _T("%s: %d: %s\n"),
+                  g_resource->loadString(IDS_error),
+                  err, errmsg);
+       LocalFree(errmsg);
+       MessageBox(NULL, buf, g_resource->loadString(IDS_mayuSetup),
+                  MB_OK | MB_ICONSTOP);
+      } else {
+       message(IDS_error, MB_OK | MB_ICONSTOP);
+      }
+      break;
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// dialogue
+
+
+// dialog box
+class DlgMain
+{
+  HWND m_hwnd;
+  bool m_doRegisterToStartMenu;        // if register to the start menu
+  bool m_doRegisterToStartUp;  // if register to the start up
+
+private:
+  // install
+  int install()
+  {
+    Registry reg(DIR_REGISTRY_ROOT);
+    CHECK_TRUE( reg.write(_T("dir"), g_destDir) );
+    tstringi srcDir = getModuleDirectory();
+
+    if (!installFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, srcDir,
+                     g_destDir))
+    {
+      removeFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, g_destDir);
+      if (g_wasExecutedBySFX)
+       removeSrcFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, srcDir);
+      return 1;
+    }
+    if (g_wasExecutedBySFX)
+      removeSrcFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, srcDir);
+
+#if defined(_WINNT)
+    DWORD err =
+      createDriverService(_T("mayud"),
+                         g_resource->loadString(IDS_mayud),
+                         getDriverDirectory() + _T("\\mayud.sys"),
+                         _T("+Keyboard Class\0"),
+                         g_flags & Flag_Usb ? true : false);
+
+    if (err != ERROR_SUCCESS)
+    {
+      driverServiceError(err);
+      removeFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, g_destDir);
+      return 1;
+    }
+
+    if (g_flags == Flag_Usb)
+      CHECK_TRUE( reg.write(_T("isUsbDriver"), DWORD(1)) );
+#endif // _WINNT
+    
+    // create shortcut
+    if (m_doRegisterToStartMenu)
+    {
+      tstringi shortcut = getStartMenuName(loadString(IDS_shortcutName));
+      if (!shortcut.empty())
+       createLink((g_destDir + _T("\\mayu.exe")).c_str(), shortcut.c_str(),
+                  g_resource->loadString(IDS_shortcutName),
+                  g_destDir.c_str());
+    }
+    if (m_doRegisterToStartUp)
+    {
+      tstringi shortcut = getStartUpName(loadString(IDS_shortcutName));
+      if (!shortcut.empty())
+       createLink((g_destDir + _T("\\mayu.exe")).c_str(), shortcut.c_str(),
+                  g_resource->loadString(IDS_shortcutName),
+                  g_destDir.c_str());
+    }
+
+    // set registry
+    reg.write(_T("layout"),
+             (g_keyboardKind == KEYBOARD_KIND_109) ? _T("109") : _T("104"));
+
+    // file extension
+    createFileExtension(_T(".mayu"), _T("text/plain"),
+                       _T("mayu file"), g_resource->loadString(IDS_mayuFile),
+                       g_destDir + _T("\\mayu.exe,1"),
+                       g_resource->loadString(IDS_mayuShellOpen));
+    
+    // uninstall
+    createUninstallInformation(_T("mayu"), g_resource->loadString(IDS_mayu),
+                              g_destDir + _T("\\setup.exe -u"));
+
+    if (g_flags == Flag_Usb)
+    {
+      if (message(IDS_copyFinishUsb, MB_YESNO | MB_ICONQUESTION, m_hwnd)
+         == IDYES)
+      {
+       // reboot ...
+       HANDLE hToken; 
+       // Get a token for this process. 
+       if (!OpenProcessToken(GetCurrentProcess(), 
+                             TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+       {
+         message(IDS_failedToReboot, MB_OK | MB_ICONSTOP);
+         return 0;
+       }
+       // Get the LUID for the shutdown privilege.
+       TOKEN_PRIVILEGES tkp;
+       LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
+       tkp.PrivilegeCount = 1;  // one privilege to set
+       tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+       // Get the shutdown privilege for this process. 
+       AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
+                             (PTOKEN_PRIVILEGES)NULL, 0);
+       // Cannot test the return value of AdjustTokenPrivileges. 
+       if (GetLastError() != ERROR_SUCCESS)
+       {
+         message(IDS_failedToReboot, MB_OK | MB_ICONSTOP);
+         return 0;
+       }
+       // Shut down the system and force all applications to close. 
+       if (!ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
+       {
+         message(IDS_failedToReboot, MB_OK | MB_ICONSTOP);
+         return 0;
+       }
+      }
+    }
+    else
+    {
+      if (message(IDS_copyFinish, MB_YESNO | MB_ICONQUESTION, m_hwnd)
+         == IDYES)
+       ExitWindows(0, 0);                      // logoff
+    }
+    return 0;
+  }
+  
+private:
+  // WM_INITDIALOG
+  BOOL wmInitDialog(HWND /* focus */, LPARAM /* lParam */)
+  {
+    setSmallIcon(m_hwnd, IDI_ICON_mayu);
+    setBigIcon(m_hwnd, IDI_ICON_mayu);
+    Edit_SetText(GetDlgItem(m_hwnd, IDC_EDIT_path), g_destDir.c_str());
+    HWND hwndCombo = GetDlgItem(m_hwnd, IDC_COMBO_keyboard);
+#if 0
+    if (checkOs(SetupFile::W2k))
+#endif
+    {
+      ComboBox_AddString(hwndCombo,
+                        g_resource->loadString(IDS_keyboard109usb));
+      ComboBox_AddString(hwndCombo,
+                        g_resource->loadString(IDS_keyboard104usb));
+    }
+#if 0
+    ComboBox_AddString(hwndCombo, g_resource->loadString(IDS_keyboard109));
+    ComboBox_AddString(hwndCombo, g_resource->loadString(IDS_keyboard104));
+#endif
+    ComboBox_SetCurSel(hwndCombo,
+                      (g_keyboardKind == KEYBOARD_KIND_109) ? 0 : 1);
+    tstring note;
+    for (int i = IDS_note01; i <= IDS_note13; ++ i) {
+      note += g_resource->loadString(i);
+    }
+    Edit_SetText(GetDlgItem(m_hwnd, IDC_EDIT_note), note.c_str());
+    return TRUE;
+  }
+  
+  // WM_CLOSE
+  BOOL wmClose()
+  {
+    EndDialog(m_hwnd, 0);
+    return TRUE;
+  }
+  
+  // WM_COMMAND
+  BOOL wmCommand(int /* notify_code */, int i_id, HWND /* hwnd_control */)
+  {
+    switch (i_id)
+    {
+      case IDC_BUTTON_browse:
+      {
+       _TCHAR folder[GANA_MAX_PATH];
+       
+       BROWSEINFO bi;
+       ZeroMemory(&bi, sizeof(bi));
+       bi.hwndOwner      = m_hwnd;
+       bi.pidlRoot       = NULL;
+       bi.pszDisplayName = folder;
+       bi.lpszTitle      = g_resource->loadString(IDS_selectDir);
+       ITEMIDLIST *browse = SHBrowseForFolder(&bi);
+       if (browse != NULL)
+       {
+         if (SHGetPathFromIDList(browse, folder))
+         {
+           if (createDirectories(folder))
+             Edit_SetText(GetDlgItem(m_hwnd, IDC_EDIT_path), folder);
+         }
+         IMalloc *imalloc = NULL;
+         if (SHGetMalloc(&imalloc) == NOERROR)
+           imalloc->Free((void *)browse);
+       }
+       return TRUE;
+      }
+      
+      case IDOK:
+      {
+       _TCHAR buf[GANA_MAX_PATH];
+       Edit_GetText(GetDlgItem(m_hwnd, IDC_EDIT_path), buf, NUMBER_OF(buf));
+       if (buf[0])
+       {
+         g_destDir = normalizePath(buf);
+         m_doRegisterToStartMenu =
+           (IsDlgButtonChecked(m_hwnd, IDC_CHECK_registerStartMenu) ==
+            BST_CHECKED);
+         m_doRegisterToStartUp =
+           (IsDlgButtonChecked(m_hwnd, IDC_CHECK_registerStartUp) ==
+            BST_CHECKED);
+
+         int curSel =
+           ComboBox_GetCurSel(GetDlgItem(m_hwnd, IDC_COMBO_keyboard));
+         g_flags = SetupFile::Normal;
+#if 0
+         if (checkOs(SetupFile::W2k))
+#endif
+         {
+           switch (curSel)
+           {
+             case 0:
+               g_keyboardKind = KEYBOARD_KIND_109;
+               g_flags = Flag_Usb;
+               break;
+             case 1:
+               g_keyboardKind = KEYBOARD_KIND_104;
+               g_flags = Flag_Usb;
+               break;
+#if 0
+             case 2: g_keyboardKind = KEYBOARD_KIND_109; break;
+             case 3: g_keyboardKind = KEYBOARD_KIND_104; break;
+#endif
+           };
+         }
+#if 0
+         else
+         {
+           switch (curSel)
+           {
+             case 0: g_keyboardKind = KEYBOARD_KIND_109; break;
+             case 1: g_keyboardKind = KEYBOARD_KIND_104; break;
+           };
+         }
+#endif
+
+#if 0
+         if (g_flags == Flag_Usb)
+           if (message(IDS_usbWarning, MB_OKCANCEL | MB_ICONWARNING, m_hwnd)
+               == IDCANCEL)
+             return TRUE;
+#endif
+         
+         if (createDirectories(g_destDir.c_str()))
+           EndDialog(m_hwnd, install());
+         else
+           message(IDS_invalidDirectory, MB_OK | MB_ICONSTOP, m_hwnd);
+       }
+       else
+         message(IDS_mayuEmpty, MB_OK, m_hwnd);
+       return TRUE;
+      }
+      
+      case IDCANCEL:
+      {
+       CHECK_TRUE( EndDialog(m_hwnd, 0) );
+       return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+public:
+  DlgMain(HWND i_hwnd)
+    : m_hwnd(i_hwnd),
+      m_doRegisterToStartMenu(false),
+      m_doRegisterToStartUp(false)
+  {
+  }
+
+  static BOOL CALLBACK dlgProc(HWND i_hwnd, UINT i_message,
+                              WPARAM i_wParam, LPARAM i_lParam)
+  {
+    DlgMain *wc;
+    getUserData(i_hwnd, &wc);
+    if (!wc)
+      switch (i_message)
+      {
+       case WM_INITDIALOG:
+         wc = setUserData(i_hwnd, new DlgMain(i_hwnd));
+         return wc->wmInitDialog(reinterpret_cast<HWND>(i_wParam), i_lParam);
+      }
+    else
+      switch (i_message)
+      {
+       case WM_COMMAND:
+         return wc->wmCommand(HIWORD(i_wParam), LOWORD(i_wParam),
+                              reinterpret_cast<HWND>(i_lParam));
+       case WM_CLOSE:
+         return wc->wmClose();
+       case WM_NCDESTROY:
+         delete wc;
+         return TRUE;
+      }
+    return FALSE;
+  }
+};
+
+
+// uninstall
+// (in this function, we cannot use any resource, so we use strres[])
+int uninstall()
+{
+  if (IDYES != message(IDS_removeOk, MB_YESNO | MB_ICONQUESTION))
+    return 1;
+
+#if defined(_WINNT)
+  DWORD err = removeDriverService(_T("mayud"));
+  if (err != ERROR_SUCCESS)
+  {
+    driverServiceError(err);
+    return 1;
+  }
+#endif // _WINNT
+
+  DeleteFile(getStartMenuName(
+    g_resource->loadString(IDS_shortcutName)).c_str());
+  DeleteFile(getStartUpName(
+    g_resource->loadString(IDS_shortcutName)).c_str());
+
+  removeFiles(g_setupFiles, NUMBER_OF(g_setupFiles), g_flags, g_destDir);
+  removeFileExtension(_T(".mayu"), _T("mayu file"));
+  removeUninstallInformation(_T("mayu"));
+  
+  Registry::remove(DIR_REGISTRY_ROOT);
+  Registry::remove(HKEY_CURRENT_USER, _T("Software\\GANAware\\mayu"));
+  
+  message(IDS_removeFinish, MB_OK | MB_ICONINFORMATION);
+  return 0;
+}
+
+
+int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* hPrevInstance */,
+                    LPTSTR /* lpszCmdLine */, int /* nCmdShow */)
+{
+  CoInitialize(NULL);
+  
+  g_hInst = i_hInstance;
+  Resource resource(g_strres);
+  g_resource = &resource;
+
+  // check OS
+  if (
+#if defined(_WINNT)
+      !checkOs(SetupFile::NT)
+#elif defined(_WIN95)
+      !checkOs(SetupFile::W9x)
+#else
+#  error
+#endif
+    )
+  {
+    message(IDS_invalidOS, MB_OK | MB_ICONSTOP);
+    return 1;
+  }
+
+  // keyboard kind
+  g_keyboardKind =
+    (resource.getLocale() == LOCALE_Japanese_Japan_932) ?
+    KEYBOARD_KIND_109 : KEYBOARD_KIND_104;
+
+  // read registry
+  tstringi programFiles;                       // "Program Files" directory
+  Registry::read(HKEY_LOCAL_MACHINE,
+                _T("Software\\Microsoft\\Windows\\CurrentVersion"),
+                _T("ProgramFilesDir"), &programFiles);
+  Registry::read(DIR_REGISTRY_ROOT, _T("dir"), &g_destDir,
+                programFiles + _T("\\mayu"));
+
+  int retval = 1;
+  
+  if (__argc == 2 && _tcsicmp(__targv[1], _T("-u")) == 0)
+    retval = uninstallStep1(_T("-u"));
+  else
+  {
+    HANDLE mutexPrevVer = CreateMutex(
+      (SECURITY_ATTRIBUTES *)NULL, TRUE,
+      MUTEX_MAYU_EXCLUSIVE_RUNNING);
+    if (GetLastError() == ERROR_ALREADY_EXISTS) { // mayu is running
+      message(IDS_mayuRunning, MB_OK | MB_ICONSTOP);
+    } else {
+      // is mayu running ?
+      HANDLE mutex = CreateMutex(
+       (SECURITY_ATTRIBUTES *)NULL, TRUE,
+       addSessionId(MUTEX_MAYU_EXCLUSIVE_RUNNING).c_str());
+      if (GetLastError() == ERROR_ALREADY_EXISTS) { // mayu is running
+       message(IDS_mayuRunning, MB_OK | MB_ICONSTOP);
+      } else if (__argc == 3 && _tcsicmp(__targv[1], _T("-u")) == 0) {
+       uninstallStep2(__targv[2]);
+       retval = uninstall();
+      } else if (__argc == 2 && _tcsicmp(__targv[1], _T("-s")) == 0) {
+       g_wasExecutedBySFX = true;
+       retval = DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_main), NULL,
+                          DlgMain::dlgProc);
+      } else if (__argc == 1) {
+       retval = DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_main), NULL,
+                          DlgMain::dlgProc);
+      }
+      CloseHandle(mutex);
+    }
+    CloseHandle(mutexPrevVer);
+  }
+  
+  return retval;
+}
diff --git a/s/setup.rc b/s/setup.rc
new file mode 100644 (file)
index 0000000..0e54d5a
--- /dev/null
@@ -0,0 +1,289 @@
+//Microsoft Developer Studio generated resource script.\r
+//\r
+#include "setuprc.h"\r
+\r
+#define APSTUDIO_READONLY_SYMBOLS\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 2 resource.\r
+//\r
+#include "afxres.h"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#undef APSTUDIO_READONLY_SYMBOLS\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// \93ú\96{\8cê resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT\r
+#pragma code_page(932)\r
+#endif //_WIN32\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// TEXTINCLUDE\r
+//\r
+\r
+1 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "setuprc.h\0"\r
+END\r
+\r
+2 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "#include ""afxres.h""\r\n"\r
+    "\0"\r
+END\r
+\r
+3 TEXTINCLUDE DISCARDABLE \r
+BEGIN\r
+    "\r\n"\r
+    "\0"\r
+END\r
+\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Dialog\r
+//\r
+\r
+IDD_DIALOG_main DIALOG DISCARDABLE  0, 0, 263, 309\r
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "\91\8b\8eg\82¢\82Ì\97J\9fT\83Z\83b\83g\83A\83b\83v"\r
+FONT 9, "MS UI Gothic"\r
+BEGIN\r
+    RTEXT           "\83C\83\93\83X\83g\81[\83\8b\90æ(&D):",IDC_STATIC,0,217,52,8\r
+    EDITTEXT        IDC_EDIT_path,56,214,152,14,ES_AUTOHSCROLL\r
+    PUSHBUTTON      "\8eQ\8fÆ(&B)...",IDC_BUTTON_browse,212,214,44,14\r
+    ICON            IDI_ICON_mayu,IDC_STATIC,8,250,20,20\r
+    GROUPBOX        "",IDC_STATIC,35,230,192,56\r
+    CONTROL         "All Users \82Ì\83X\83^\81[\83g\83\81\83j\83\85\81[\82É\93o\98^(&A)",\r
+                    IDC_CHECK_registerStartMenu,"Button",BS_AUTOCHECKBOX | \r
+                    WS_TABSTOP,44,240,176,10\r
+    CONTROL         "\8cÂ\90l\82Ì\83X\83^\81[\83g\83A\83b\83v\82É\93o\98^(&S)",\r
+                    IDC_CHECK_registerStartUp,"Button",BS_AUTOCHECKBOX | \r
+                    WS_TABSTOP,44,252,176,10\r
+    RTEXT           "\83L\81[\83{\81[\83h\82Ì\8eí\97Þ(&K):",IDC_STATIC,36,268,64,8\r
+    COMBOBOX        IDC_COMBO_keyboard,104,266,116,64,CBS_DROPDOWNLIST | \r
+                    WS_VSCROLL | WS_TABSTOP\r
+    DEFPUSHBUTTON   "OK",IDOK,76,290,50,14\r
+    PUSHBUTTON      "\83L\83\83\83\93\83Z\83\8b",IDCANCEL,132,290,50,14\r
+    GROUPBOX        "\92\8d\88Ó(&N)",IDC_STATIC,25,4,212,206\r
+    EDITTEXT        IDC_EDIT_note,31,14,200,192,ES_MULTILINE | ES_AUTOVSCROLL | \r
+                    ES_READONLY | NOT WS_BORDER\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// DESIGNINFO\r
+//\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+GUIDELINES DESIGNINFO DISCARDABLE \r
+BEGIN\r
+    IDD_DIALOG_main, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 256\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 172\r
+    END\r
+END\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// String Table\r
+//\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_mayuSetup           "\91\8b\8eg\82¢\82Ì\97J\9fT\83Z\83b\83g\83A\83b\83v"\r
+    IDS_mayuRunning         "\91\8b\8eg\82¢\82Ì\97J\9fT\82ª\93®\8dì\92\86\82Å\82·\81B\8fI\97¹\82µ\82Ä\82©\82ç\83Z\83b\83g\83A\83b\83v\82ð\82à\82¤\88ê\93x\8eÀ\8ds\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+    IDS_mayuEmpty           "\83C\83\93\83X\83g\81[\83\8b\90æ\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+    IDS_selectDir           "\83C\83\93\83X\83g\81[\83\8b\90æ\82ð\8ew\92è\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+    IDS_invalidDirectory    "\95s\90³\82È\83f\83B\83\8c\83N\83g\83\8a\82Å\82·\81B"\r
+    IDS_removeOk            "\91\8b\8eg\82¢\82Ì\97J\9fT\82ð\83A\83\93\83C\83\93\83X\83g\81[\83\8b\82µ\82Ä\82æ\82ë\82µ\82¢\82Å\82·\82©\81H"\r
+    IDS_removeFinish        "\91\8b\8eg\82¢\82Ì\97J\9fT\82Í\83A\83\93\83C\83\93\83X\83g\81[\83\8b\82³\82ê\82Ü\82µ\82½\81B"\r
+    IDS_copyFinish          "\83C\83\93\83X\83g\81[\83\8b\82ª\8fI\97¹\82µ\82Ü\82µ\82½\81B\n\88ê\93x\83\8d\83O\83I\83t\82·\82é\95K\97v\82ª\82 \82è\82Ü\82·\81B\n\8d¡\82·\82®\83\8d\83O\83I\83t\82µ\82Ü\82·\82©?"\r
+    IDS_error               "\83C\83\93\83X\83g\81[\83\8b\92\86\82É\83G\83\89\81[\82ª\8bN\82±\82è\82Ü\82µ\82½\81B"\r
+    IDS_alreadyUninstalled  "\91\8b\8eg\82¢\82Ì\97J\9fT\82Ì\83A\83\93\83C\83\93\83X\83g\81[\83\8b\82ª\8aù\82É\8eÀ\8ds\82³\82ê\82Ä\82¢\82Ü\82·\81B\n\8dÄ\8bN\93®\82µ\82Ä\82©\82ç\83C\83\93\83X\83g\81[\83\8b\82µ\82È\82¨\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+    IDS_notAdministrator    "Administrator \82Å\8eÀ\8ds\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+    IDS_invalidOS           "\82±\82Ì OS \82Å\82Í\93®\8dì\82µ\82Ü\82¹\82ñ\81B"\r
+    IDS_mayuFile            "\91\8b\8eg\82¢\82Ì\97J\9fT\83t\83@\83C\83\8b"\r
+    IDS_mayuShellOpen       "notepad.exe ""%1"""\r
+    IDS_mayu                "\91\8b\8eg\82¢\82Ì\97J\9fT"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_mayud               "\91\8b\8eg\82¢\82Ì\97J\9fT\83h\83\89\83C\83o"\r
+    IDS_shortcutName        "\91\8b\8eg\82¢\82Ì\97J\9fT"\r
+    IDS_keyboard109usb      "\93ú\96{\8cê 109 (106) \83L\81[\83{\81[\83h"\r
+    IDS_keyboard104usb      "\89p\8cê 104 (101) \83L\81[\83{\81[\83h"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_note01              "\81\9f\81u\91\8b\8eg\82¢\82Ì\97J\9fT\81v\82ð\83C\83\93\83X\83g\81[\83\8b\82µ\82½\82ç\82º\82Ð\83\81\81[\83\8a\83\93\83O\83\8a\83X\83g\82É\8eQ\89Á\82µ\82Ä\82­\82¾\82³\82¢\81B\8eQ\89Á\95û\96@\82Í README.html \82É\8f\91\82©\82ê\82Ä\82¢\82Ü\82·\81B\r\n\r\n"\r
+    IDS_note02              "\81\9f\95W\8f\80\82Å\82È\82¢\83L\81[\83{\81[\83h\83h\83\89\83C\83o\82ð\97\98\97p\82µ\82Ä\82¢\82é\82Æ Windows \82ª\90Â\89æ\96Ê\82É\82È\82Á\82Ä\8fI\97¹\82µ\82Ä\82µ\82Ü\82¤\82±\82Æ\82ª\82 \82è\82Ü\82·\81B"\r
+    IDS_note03              "\82»\82Ì\82æ\82¤\82È\8fê\8d\87\82Í\81A\95W\8f\80\82Å\82È\82¢\83h\83\89\83C\83o\82ð\83A\83\93\83C\83\93\83X\83g\81[\83\8b\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+    IDS_note04              "\95W\8f\80\82Å\82È\82¢\83h\83\89\83C\83o\82Æ\82Í\81A\83\8d\83W\83e\83b\83N\83}\83E\83X\82É\95t\91®\82Ì\83h\83\89\83C\83o\82â AltIME \82Ì\83h\83\89\83C\83o\82È\82Ç\82Å\82·\81B\r\n\r\n"\r
+    IDS_note05             "\81\9f\81u\91\8b\8eg\82¢\82Ì\97J\9fT\81v\82Í\81A\90ê\97p\82Ì\83f\83o\83C\83X\83h\83\89\83C\83o\82ð\83C\83\93\83X\83g\81[\83\8b\82µ\82Ü\82·\81B\82±\82Ì\83h\83\89\83C\83o\82Í Windows \82Ì\8bN\93®\8e\9e\82É\8eÀ\8ds\8aJ\8en\82³\82ê\82Ü\82·\81B"\r
+    IDS_note06             "\82±\82Ì\82½\82ß\81A\83h\83\89\83C\83o\82Ì\95s\8bï\8d\87\82É\82æ\82Á\82Ä Windows \82Ö\83\8d\83O\83C\83\93\82³\82¦\82Å\82«\82È\82­\82È\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B"\r
+    IDS_note07             "\82»\82Ì\8fê\8d\87\82Å\82à\89º\8bL\82Ì\8eè\8f\87\82É\82æ\82Á\82Ä\83\8d\83O\83C\83\93\89Â\94\\82É\82·\82é\82±\82Æ\82ª\82Å\82«\82é\8fê\8d\87\82ª\82 \82è\82Ü\82·\81B\r\n\r\n"\r
+    IDS_note08             "\81y1\81z\93d\8c¹\83{\83^\83\93\82Ì\92·\89\9f\82µ\93\99\82É\82æ\82Á\82Ä\88ê\92U\81A\8b­\90§\93I\82É\93d\8c¹\82ð\97\8e\82µ\82½\82 \82Æ\89ñ\95\9c\83R\83\93\83\\81[\83\8b\82ð\8bN\93®\82µ\82Ü\82·\81B"\r
+    IDS_note09             "\8f®\81A\89ñ\95\9c\83R\83\93\83\\81[\83\8b\82Å\82Ì\8bN\93®\82ª\82Å\82«\82é\82±\82Æ\82ð\81u\91\8b\8eg\82¢\82Ì\97J\9fT\81v\82Ì\83C\83\93\83X\83g\81[\83\8b\91O\82É\8am\94F\82µ\82Ä\82¨\82­\82±\82Æ\82ð\82¨\8a©\82ß\82µ\82Ü\82·\81B"\r
+    IDS_note10              "(\8eQ\8dl: http://support.microsoft.com/default.aspx?scid=kb;ja;314058 )\r\n"\r
+    IDS_note11              "\81y2\81z%WINDIR%\\system32\\drivers\\ \93à\82Ì mayudrsc.sys \82ð mayud.sys \82Ì\96¼\91O\82Å copy \82µ\82Ü\82· (\91¦\82¿ mayud.sys \82ð mayudrsc.sys \82Å\92u\82«\8a·\82¦\82Ü\82·)\81B\r\n"\r
+    IDS_note12              "\81y3\81z\8dÄ\8bN\93®\82µ\82Ü\82·\81B\r\n"\r
+    IDS_note13              "\81y4\81z\83R\83\93\83g\83\8d\81[\83\8b\83p\83l\83\8b\82©\82ç\81u\91\8b\8eg\82¢\82Ì\97J\9fT\81v\82ð\83A\83\93\83C\83\93\83X\83g\81[\83\8b\82µ\82Ü\82·\81B\r\n"\r
+    IDS_copyFinishUsb       "\83C\83\93\83X\83g\81[\83\8b\82ª\8fI\97¹\82µ\82Ü\82µ\82½\81B\n\83R\83\93\83s\83\85\81[\83^\82ð\8dÄ\8bN\93®\82·\82é\95K\97v\82ª\82 \82è\82Ü\82·\81B\n\8d¡\82·\82®\8dÄ\8bN\93®\82µ\82Ü\82·\82©?"\r
+    IDS_failedToReboot      "\8dÄ\8bN\93®\82É\8e¸\94s\82µ\82Ü\82µ\82½\81B\91\8b\8eg\82¢\82Ì\97J\9fT\82ð\8eÀ\8ds\82·\82é\91O\82É\95K\82¸\8dÄ\8bN\93®\82µ\82Ä\82­\82¾\82³\82¢\81B"\r
+END\r
+\r
+#endif    // \93ú\96{\8cê resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// \89p\8cê (±Òض) resources\r
+\r
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r
+#ifdef _WIN32\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+#pragma code_page(1252)\r
+#endif //_WIN32\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Dialog\r
+//\r
+\r
+IDD_DIALOG_main DIALOG DISCARDABLE  0, 0, 263, 179\r
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "MADO TSUKAI NO YUUTSU Setup"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    RTEXT           "&Destination:",IDC_STATIC,0,87,52,8\r
+    EDITTEXT        IDC_EDIT_path,56,84,152,14,ES_AUTOHSCROLL\r
+    PUSHBUTTON      "&Browse...",IDC_BUTTON_browse,212,84,44,14\r
+    ICON            IDI_ICON_mayu,IDC_STATIC,8,120,18,21\r
+    GROUPBOX        "",IDC_STATIC,35,100,192,56\r
+    CONTROL         "Create shortcut in the Start Menu of &All Users.",\r
+                    IDC_CHECK_registerStartMenu,"Button",BS_AUTOCHECKBOX | \r
+                    WS_TABSTOP,44,110,176,10\r
+    CONTROL         "Create shortcut in your &Startup Menu.",\r
+                    IDC_CHECK_registerStartUp,"Button",BS_AUTOCHECKBOX | \r
+                    WS_TABSTOP,44,122,176,10\r
+    RTEXT           "&Keyboard:",IDC_STATIC,36,138,64,8\r
+    COMBOBOX        IDC_COMBO_keyboard,104,136,116,50,CBS_DROPDOWNLIST | \r
+                    WS_VSCROLL | WS_TABSTOP\r
+    DEFPUSHBUTTON   "OK",IDOK,76,160,50,14\r
+    PUSHBUTTON      "&Cancel",IDCANCEL,132,160,50,14\r
+    GROUPBOX        "&NOTE",IDC_STATIC,25,4,212,76\r
+    EDITTEXT        IDC_EDIT_note,31,14,200,62,ES_MULTILINE | ES_AUTOVSCROLL | \r
+                    ES_READONLY | NOT WS_BORDER\r
+END\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// DESIGNINFO\r
+//\r
+\r
+#ifdef APSTUDIO_INVOKED\r
+GUIDELINES DESIGNINFO DISCARDABLE \r
+BEGIN\r
+    IDD_DIALOG_main, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 255\r
+        TOPMARGIN, 7\r
+    END\r
+END\r
+#endif    // APSTUDIO_INVOKED\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Icon\r
+//\r
+\r
+// Icon with lowest ID value placed first to ensure application icon\r
+// remains consistent on all systems.\r
+IDI_ICON_mayu           ICON    DISCARDABLE     "..\\r\\mayu.ico"\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// String Table\r
+//\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_mayuSetup           "MADO TSUKAI NO YUUTSU Setup"\r
+    IDS_mayuRunning         "MADO TSUKAI NO YUUTSU is running. Please quit it, then run this program again."\r
+    IDS_mayuEmpty           "Select destination directory."\r
+    IDS_selectDir           "Select destination directory."\r
+    IDS_invalidDirectory    "Invalid directory."\r
+    IDS_removeOk            "Are you sure to uninstall MADO TSUKAI NO YUUTSU ?"\r
+    IDS_removeFinish        "MADO TSUKAI NO YUUTSU is uninstalled."\r
+    IDS_copyFinish          "Install complete."\r
+    IDS_error               "An error happened !"\r
+    IDS_alreadyUninstalled  "MADO TSUKAI NO YUUTSU has been uninstalled.\nPlease reboot Windows, then run this program again."\r
+    IDS_notAdministrator    "Only Administrator can complete install."\r
+    IDS_invalidOS           "Only for WindowsNT4.0/2000"\r
+    IDS_mayuFile            "MADO TSUKAI NO YUTSU file"\r
+    IDS_mayuShellOpen       "notepad.exe ""%1"""\r
+    IDS_mayu                "MADO TSUKAI NO YUUTSU"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_mayud               "MADO TSUKAI NO YUUTSU driver"\r
+    IDS_shortcutName        "MADO TSUKAI NO YUUTSU"\r
+    IDS_keyboard109usb      "Japanese 109 (106) Keybaord"\r
+    IDS_keyboard104usb      "Standard 104 (101) Keyboard"\r
+END\r
+\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+    IDS_note01              "* After installing MADO TSUKAI NO YUUTSU, please subscribe MADO TSUKAI NO YUUTSU mailing list.  Details are written in README.html.\r\n"\r
+    IDS_note02              "* Windows may hang up, if you are using a non-standard keybaord driver. "\r
+    IDS_note03              "In that case, please uninstall the non-standard keybaord driver.\r\n"\r
+    IDS_note04              "* Non-standrd keybaord drivers are such as that of Logitech Mouse, and that of AltIME.\r\n"\r
+    IDS_note05             "\81u\91\8b\8eg\82¢\82Ì\97J\9fT\81v\82Í\81A\90ê\97p\82Ì\83f\83o\83C\83X\83h\83\89\83C\83o\82ð\83C\83\93\83X\83g\81[\83\8b\82µ\82Ü\82·\81B\82±\82Ì\83h\83\89\83C\83o\82Í Windows \82Ì\8bN\93®\8e\9e\82É\8eÀ\8ds\8aJ\8en\82³\82ê\82Ü\82·\81B"\r
+    IDS_note06             "\82±\82Ì\82½\82ß\81A\83h\83\89\83C\83o\82Ì\95s\8bï\8d\87\82É\82æ\82Á\82Ä Windows \82Ö\83\8d\83O\83C\83\93\82³\82¦\82Å\82«\82È\82­\82È\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B"\r
+    IDS_note07             "\82»\82Ì\8fê\8d\87\82Å\82à\89º\8bL\82Ì\8eè\8f\87\82É\82æ\82Á\82Ä\83\8d\83O\83C\83\93\89Â\94\\82É\82·\82é\82±\82Æ\82ª\82Å\82«\82é\8fê\8d\87\82ª\82 \82è\82Ü\82·\81B\r\n\r\n"\r
+    IDS_note08             "1. \93d\8c¹\83{\83^\83\93\82Ì\92·\89\9f\82µ\93\99\82É\82æ\82Á\82Ä\88ê\92U\81A\8b­\90§\93I\82É\93d\8c¹\82ð\97\8e\82µ\82½\82 \82Æ\89ñ\95\9c\83R\83\93\83\\81[\83\8b\82ð\8bN\93®\82µ\82Ü\82·\81B"\r
+    IDS_note09             "\8f®\81A\89ñ\95\9c\83R\83\93\83\\81[\83\8b\82Å\82Ì\8bN\93®\82ª\82Å\82«\82é\82±\82Æ\82ð\81u\91\8b\8eg\82¢\82Ì\97J\9fT\81v\82Ì\83C\83\93\83X\83g\81[\83\8b\91O\82É\8am\94F\82µ\82Ä\82¨\82­\82±\82Æ\82ð\82¨\8a©\82ß\82µ\82Ü\82·\81B"\r
+    IDS_note10              "(\8eQ\8dl: http://support.microsoft.com/default.aspx?scid=kb;ja;314058 )\r\n"\r
+    IDS_note11              "2. %WINDIR%\\system32\\drivers\\ \93à\82Ì mayudrsc.sys \82ð mayud.sys \82Ì\96¼\91O\82Å copy \82µ\82Ü\82· (\91¦\82¿ mayud.sys \82ð mayudrsc.sys \82Å\92u\82«\8a·\82¦\82Ü\82·)\81B\r\n"\r
+    IDS_note12              "3. \8dÄ\8bN\93®\82µ\82Ü\82·\81B\r\n"\r
+    IDS_note13              "4. \83R\83\93\83g\83\8d\81[\83\8b\83p\83l\83\8b\82©\82ç\81u\91\8b\8eg\82¢\82Ì\97J\9fT\81v\82ð\83A\83\93\83C\83\93\83X\83g\81[\83\8b\82µ\82Ü\82·\81B\r\n"\r
+    IDS_copyFinishUsb       "Install complete.  Do you want to reboot now?"\r
+    IDS_failedToReboot      "Failed to reboot."\r
+END\r
+\r
+#endif    // \89p\8cê (±Òض) resources\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+\r
+#ifndef APSTUDIO_INVOKED\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+// Generated from the TEXTINCLUDE 3 resource.\r
+//\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+#endif    // not APSTUDIO_INVOKED\r
+\r
diff --git a/s/setuprc.h b/s/setuprc.h
new file mode 100644 (file)
index 0000000..8273554
--- /dev/null
@@ -0,0 +1,59 @@
+//{{NO_DEPENDENCIES}}\r
+// Microsoft Developer Studio generated include file.\r
+// Used by setup.rc\r
+//\r
+#define IDS_mayuSetup                   1\r
+#define IDS_mayuRunning                 2\r
+#define IDS_mayuEmpty                   3\r
+#define IDS_selectDir                   4\r
+#define IDS_invalidDirectory            5\r
+#define IDS_removeOk                    6\r
+#define IDS_removeFinish                7\r
+#define IDS_copyFinish                  8\r
+#define IDS_error                       9\r
+#define IDS_alreadyUninstalled          10\r
+#define IDS_notAdministrator            11\r
+#define IDS_invalidOS                   12\r
+#define IDS_mayuFile                    13\r
+#define IDS_mayuShellOpen               14\r
+#define IDS_mayu                        15\r
+#define IDS_mayud                       16\r
+#define IDS_shortcutName                17\r
+#define IDS_keyboard109usb              20\r
+#define IDS_keyboard104usb              21\r
+#define IDS_readFromHomeDirectory       22\r
+#define IDS_note01                      30\r
+#define IDS_note02                      31\r
+#define IDS_note03                      32\r
+#define IDS_note04                      33\r
+#define IDS_note05                      34\r
+#define IDS_note06                      35\r
+#define IDS_note07                      36\r
+#define IDS_note08                      37\r
+#define IDS_note09                      38\r
+#define IDS_note10                      39\r
+#define IDS_note11                      40\r
+#define IDS_note12                      41\r
+#define IDS_note13                      42\r
+#define IDS_copyFinishUsb               43\r
+#define IDS_failedToReboot              44\r
+#define IDD_DIALOG_main                 101\r
+#define IDI_ICON_mayu                   102\r
+#define IDC_EDIT_path                   1000\r
+#define IDC_BUTTON_browse               1001\r
+#define IDC_CHECK_registerStartMenu     1002\r
+#define IDC_CHECK_registerStartUp       1003\r
+#define IDC_COMBO_keyboard              1004\r
+#define IDC_EDIT_note                   1005\r
+\r
+// Next default values for new objects\r
+// \r
+#ifdef APSTUDIO_INVOKED\r
+#ifndef APSTUDIO_READONLY_SYMBOLS\r
+#define _APS_NO_MFC                     1\r
+#define _APS_NEXT_RESOURCE_VALUE        103\r
+#define _APS_NEXT_COMMAND_VALUE         40001\r
+#define _APS_NEXT_CONTROL_VALUE         1006\r
+#define _APS_NEXT_SYMED_VALUE           101\r
+#endif\r
+#endif\r
diff --git a/s/stub/afxres.h b/s/stub/afxres.h
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/setting.cpp b/setting.cpp
new file mode 100644 (file)
index 0000000..6d36976
--- /dev/null
@@ -0,0 +1,1754 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// setting.cpp
+
+
+#include "misc.h"
+
+#include "dlgsetting.h"
+#include "errormessage.h"
+#include "mayu.h"
+#include "mayurc.h"
+#include "registry.h"
+#include "setting.h"
+#include "windowstool.h"
+#include "vkeytable.h"
+#include "array.h"
+
+#include <algorithm>
+#include <fstream>
+#include <iomanip>
+#include <sys/stat.h>
+
+
+namespace Event
+{
+  Key prefixed(_T("prefixed"));
+  Key before_key_down(_T("before-key-down"));
+  Key after_key_up(_T("after-key-up"));
+  Key *events[] =
+  {
+    &prefixed,
+    &before_key_down,
+    &after_key_up,
+    NULL,
+  };
+}
+
+
+// get mayu filename
+static bool getFilenameFromRegistry(
+  tstringi *o_name, tstringi *o_filename, Setting::Symbols *o_symbols)
+{
+  Registry reg(MAYU_REGISTRY_ROOT);
+  int index;
+  reg.read(_T(".mayuIndex"), &index, 0);
+  _TCHAR buf[100];
+  _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
+
+  tstringi entry;
+  if (!reg.read(buf, &entry))
+    return false;
+  
+  tregex getFilename(_T("^([^;]*);([^;]*);(.*)$"));
+  tsmatch getFilenameResult;
+  if (!boost::regex_match(entry, getFilenameResult, getFilename))
+    return false;
+  
+  if (o_name)
+    *o_name = getFilenameResult.str(1);
+  if (o_filename)
+    *o_filename = getFilenameResult.str(2);
+  if (o_symbols)
+  {
+    tstringi symbols = getFilenameResult.str(3);
+    tregex symbol(_T("-D([^;]*)(.*)$"));
+    tsmatch symbolResult;
+    while (boost::regex_search(symbols, symbolResult, symbol))
+    {
+      o_symbols->insert(symbolResult.str(1));
+      symbols = symbolResult.str(2);
+    }
+  }
+  return true;
+}
+
+
+// get home directory path
+void getHomeDirectories(HomeDirectories *o_pathes)
+{
+  tstringi filename;
+  if (getFilenameFromRegistry(NULL, &filename, NULL) &&
+      !filename.empty())
+  {
+    tregex getPath(_T("^(.*[/\\\\])[^/\\\\]*$"));
+    tsmatch getPathResult;
+    if (boost::regex_match(filename, getPathResult, getPath))
+      o_pathes->push_back(getPathResult.str(1));
+  }
+  
+  const _TCHAR *home = _tgetenv(_T("HOME"));
+  if (home)
+    o_pathes->push_back(home);
+
+  const _TCHAR *homedrive = _tgetenv(_T("HOMEDRIVE"));
+  const _TCHAR *homepath = _tgetenv(_T("HOMEPATH"));
+  if (homedrive && homepath)
+    o_pathes->push_back(tstringi(homedrive) + homepath);
+  
+  const _TCHAR *userprofile = _tgetenv(_T("USERPROFILE"));
+  if (userprofile)
+    o_pathes->push_back(userprofile);
+  
+  _TCHAR buf[GANA_MAX_PATH];
+  DWORD len = GetCurrentDirectory(NUMBER_OF(buf), buf);
+  if (0 < len && len < NUMBER_OF(buf))
+    o_pathes->push_back(buf);
+
+  if (GetModuleFileName(GetModuleHandle(NULL), buf, NUMBER_OF(buf)))
+    o_pathes->push_back(pathRemoveFileSpec(buf));
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// SettingLoader
+
+
+// is there no more tokens ?
+bool SettingLoader::isEOL()
+{
+  return m_ti == m_tokens.end();
+}
+
+
+// get next token
+Token *SettingLoader::getToken()
+{
+  if (isEOL())
+    throw ErrorMessage() << _T("too few words.");
+  return &*(m_ti ++);
+}
+
+  
+// look next token
+Token *SettingLoader::lookToken()
+{
+  if (isEOL())
+    throw ErrorMessage() << _T("too few words.");
+  return &*m_ti;
+}
+
+
+// argument "("
+bool SettingLoader::getOpenParen(bool i_doesThrow, const _TCHAR *i_name)
+{
+  if (!isEOL() && lookToken()->isOpenParen())
+  {
+    getToken();
+    return true;
+  }
+  if (i_doesThrow)
+    throw ErrorMessage() << _T("there must be `(' after `&")
+                        << i_name << _T("'.");
+  return false;
+}
+
+
+// argument ")"
+bool SettingLoader::getCloseParen(bool i_doesThrow, const _TCHAR *i_name)
+{
+  if (!isEOL() && lookToken()->isCloseParen())
+  {
+    getToken();
+    return true;
+  }
+  if (i_doesThrow)
+    throw ErrorMessage() << _T("`&")  << i_name
+                        << _T("': too many arguments.");
+  return false;
+}
+
+
+// argument ","
+bool SettingLoader::getComma(bool i_doesThrow, const _TCHAR *i_name)
+{
+  if (!isEOL() && lookToken()->isComma())
+  {
+    getToken();
+    return true;
+  }
+  if (i_doesThrow)
+    throw ErrorMessage() << _T("`&")  << i_name
+                        << _T("': comma expected.");
+  return false;
+}
+
+
+// <INCLUDE>
+void SettingLoader::load_INCLUDE()
+{
+  SettingLoader loader(m_soLog, m_log);
+  loader.m_defaultAssignModifier = m_defaultAssignModifier;
+  loader.m_defaultKeySeqModifier = m_defaultKeySeqModifier;
+  if (!loader.load(m_setting, (*getToken()).getString()))
+    m_isThereAnyError = true;
+}
+
+
+// <SCAN_CODES>
+void SettingLoader::load_SCAN_CODES(Key *o_key)
+{
+  for (int j = 0; j < Key::MAX_SCAN_CODES_SIZE && !isEOL(); ++ j)
+  {
+    ScanCode sc;
+    sc.m_flags = 0;
+    while (true)
+    {
+      Token *t = getToken();
+      if (t->isNumber())
+      {
+       sc.m_scan = (u_char)t->getNumber();
+       o_key->addScanCode(sc);
+       break;
+      }
+      if      (*t == _T("E0-")) sc.m_flags |= ScanCode::E0;
+      else if (*t == _T("E1-")) sc.m_flags |= ScanCode::E1;
+      else  throw ErrorMessage() << _T("`") << *t
+                                << _T("': invalid modifier.");
+    }
+  }
+}
+
+
+// <DEFINE_KEY>
+void SettingLoader::load_DEFINE_KEY()
+{
+  Token *t = getToken();
+  Key key;
+      
+  // <KEY_NAMES>
+  if (*t == _T('('))
+  {
+    key.addName(getToken()->getString());
+    while (t = getToken(), *t != _T(')'))
+      key.addName(t->getString());
+    if (*getToken() != _T("="))
+      throw ErrorMessage() << _T("there must be `=' after `)'.");
+  }
+  else
+  {
+    key.addName(t->getString());
+    while (t = getToken(), *t != _T("="))
+      key.addName(t->getString());
+  }
+
+  load_SCAN_CODES(&key);
+  m_setting->m_keyboard.addKey(key);
+}
+
+
+// <DEFINE_MODIFIER>
+void SettingLoader::load_DEFINE_MODIFIER()
+{
+  Token *t = getToken();
+  Modifier::Type mt;
+  if      (*t == _T("shift")  ) mt = Modifier::Type_Shift;
+  else if (*t == _T("alt")     ||
+          *t == _T("meta")    ||
+          *t == _T("menu")   ) mt = Modifier::Type_Alt;
+  else if (*t == _T("control") ||
+          *t == _T("ctrl")   ) mt = Modifier::Type_Control;
+  else if (*t == _T("windows") ||
+          *t == _T("win")    ) mt = Modifier::Type_Windows;
+  else throw ErrorMessage() << _T("`") << *t
+                           << _T("': invalid modifier name.");
+    
+  if (*getToken() != _T("="))
+    throw ErrorMessage() << _T("there must be `=' after modifier name.");
+    
+  while (!isEOL())
+  {
+    t = getToken();
+    Key *key =
+      m_setting->m_keyboard.searchKeyByNonAliasName(t->getString());
+    if (!key)
+      throw ErrorMessage() << _T("`") << *t << _T("': invalid key name.");
+    m_setting->m_keyboard.addModifier(mt, key);
+  }
+}
+
+
+// <DEFINE_SYNC_KEY>
+void SettingLoader::load_DEFINE_SYNC_KEY()
+{
+  Key *key = m_setting->m_keyboard.getSyncKey();
+  key->initialize();
+  key->addName(_T("sync"));
+  
+  if (*getToken() != _T("="))
+    throw ErrorMessage() << _T("there must be `=' after `sync'.");
+  
+  load_SCAN_CODES(key);
+}
+
+
+// <DEFINE_ALIAS>
+void SettingLoader::load_DEFINE_ALIAS()
+{
+  Token *name = getToken();
+  
+  if (*getToken() != _T("="))
+    throw ErrorMessage() << _T("there must be `=' after `alias'.");
+
+  Token *t = getToken();
+  Key *key = m_setting->m_keyboard.searchKeyByNonAliasName(t->getString());
+  if (!key)
+    throw ErrorMessage() << _T("`") << *t << _T("': invalid key name.");
+  m_setting->m_keyboard.addAlias(name->getString(), key);
+}
+
+
+// <DEFINE_SUBSTITUTE>
+void SettingLoader::load_DEFINE_SUBSTITUTE()
+{
+  typedef std::list<ModifiedKey> AssignedKeys;
+  AssignedKeys assignedKeys;
+  do
+  {
+    ModifiedKey mkey;
+    mkey.m_modifier =
+      load_MODIFIER(Modifier::Type_ASSIGN, m_defaultAssignModifier);
+    mkey.m_key = load_KEY_NAME();
+    assignedKeys.push_back(mkey);
+  } while (!(*lookToken() == _T("=>") || *lookToken() == _T("=")));
+  getToken();
+  
+  KeySeq *keySeq = load_KEY_SEQUENCE(_T(""), false, Modifier::Type_ASSIGN);
+  ModifiedKey mkey = keySeq->getFirstModifiedKey();
+  if (!mkey.m_key)
+    throw ErrorMessage() << _T("no key is specified for substitute.");
+  
+  for (AssignedKeys::iterator i = assignedKeys.begin();
+       i != assignedKeys.end(); ++ i)
+    m_setting->m_keyboard.addSubstitute(*i, mkey);
+}
+
+
+// <DEFINE_OPTION>
+void SettingLoader::load_DEFINE_OPTION()
+{
+  Token *t = getToken();
+  if (*t == _T("KL-")) {
+    if (*getToken() != _T("=")) {
+      throw ErrorMessage() << _T("there must be `=' after `def option KL-'.");
+    }
+
+    load_ARGUMENT(&m_setting->m_correctKanaLockHandling);
+    
+  } else if (*t == _T("delay-of")) {
+    if (*getToken() != _T("!!!")) {
+      throw ErrorMessage()
+       << _T("there must be `!!!' after `def option delay-of'.");
+    }
+    
+    if (*getToken() != _T("=")) {
+      throw ErrorMessage()
+       << _T("there must be `=' after `def option delay-of !!!'.");
+    }
+    
+    load_ARGUMENT(&m_setting->m_oneShotRepeatableDelay);
+    
+  } else if (*t == _T("sts4mayu")) {
+    if (*getToken() != _T("=")) {
+      throw ErrorMessage()
+       << _T("there must be `=' after `def option sts4mayu'.");
+    }
+    
+    load_ARGUMENT(&m_setting->m_sts4mayu);
+    
+  } else if (*t == _T("cts4mayu")) {
+    if (*getToken() != _T("=")) {
+      throw ErrorMessage()
+       << _T("there must be `=' after `def option cts4mayu'.");
+    }
+    
+    load_ARGUMENT(&m_setting->m_cts4mayu);
+    
+  } else {
+    throw ErrorMessage() << _T("syntax error `def option ") << *t << _T("'.");
+  }
+}
+
+
+
+// <KEYBOARD_DEFINITION>
+void SettingLoader::load_KEYBOARD_DEFINITION()
+{
+  Token *t = getToken();
+    
+  // <DEFINE_KEY>
+  if (*t == _T("key")) load_DEFINE_KEY();
+
+  // <DEFINE_MODIFIER>
+  else if (*t == _T("mod")) load_DEFINE_MODIFIER();
+  
+  // <DEFINE_SYNC_KEY>
+  else if (*t == _T("sync")) load_DEFINE_SYNC_KEY();
+  
+  // <DEFINE_ALIAS>
+  else if (*t == _T("alias")) load_DEFINE_ALIAS();
+  
+  // <DEFINE_SUBSTITUTE>
+  else if (*t == _T("subst")) load_DEFINE_SUBSTITUTE();
+
+  // <DEFINE_OPTION>
+  else if (*t == _T("option")) load_DEFINE_OPTION();
+  
+  //
+  else throw ErrorMessage() << _T("syntax error `") << *t << _T("'.");
+}
+
+
+// <..._MODIFIER>
+Modifier SettingLoader::load_MODIFIER(
+  Modifier::Type i_mode, Modifier i_modifier, Modifier::Type *o_mode)
+{
+  if (o_mode)
+    *o_mode = Modifier::Type_begin;
+  
+  Modifier isModifierSpecified;
+  enum { PRESS, RELEASE, DONTCARE } flag = PRESS;
+
+  int i;
+  for (i = i_mode; i < Modifier::Type_ASSIGN; ++ i)
+  {
+    i_modifier.dontcare(Modifier::Type(i));
+    isModifierSpecified.on(Modifier::Type(i));
+  }
+  
+  Token *t = NULL;
+  
+  continue_loop:
+  while (!isEOL())
+  {
+    t = lookToken();
+
+    const static struct { const _TCHAR *m_s; Modifier::Type m_mt; } map[] =
+    {
+      // <BASIC_MODIFIER>
+      { _T("S-"),  Modifier::Type_Shift },
+      { _T("A-"),  Modifier::Type_Alt },
+      { _T("M-"),  Modifier::Type_Alt },
+      { _T("C-"),  Modifier::Type_Control },
+      { _T("W-"),  Modifier::Type_Windows },
+      // <KEYSEQ_MODIFIER>
+      { _T("U-"),  Modifier::Type_Up },
+      { _T("D-"),  Modifier::Type_Down },
+      // <ASSIGN_MODIFIER>
+      { _T("R-"),  Modifier::Type_Repeat },
+      { _T("IL-"), Modifier::Type_ImeLock },
+      { _T("IC-"), Modifier::Type_ImeComp },
+      { _T("I-"),  Modifier::Type_ImeComp },
+      { _T("NL-"), Modifier::Type_NumLock },
+      { _T("CL-"), Modifier::Type_CapsLock },
+      { _T("SL-"), Modifier::Type_ScrollLock },
+      { _T("KL-"), Modifier::Type_KanaLock },
+      { _T("MAX-"), Modifier::Type_Maximized },
+      { _T("MIN-"), Modifier::Type_Minimized },
+      { _T("MMAX-"), Modifier::Type_MdiMaximized },
+      { _T("MMIN-"), Modifier::Type_MdiMinimized },
+      { _T("T-"), Modifier::Type_Touchpad },
+      { _T("TS-"), Modifier::Type_TouchpadSticky },
+      { _T("M0-"), Modifier::Type_Mod0 },
+      { _T("M1-"), Modifier::Type_Mod1 },
+      { _T("M2-"), Modifier::Type_Mod2 },
+      { _T("M3-"), Modifier::Type_Mod3 },
+      { _T("M4-"), Modifier::Type_Mod4 },
+      { _T("M5-"), Modifier::Type_Mod5 },
+      { _T("M6-"), Modifier::Type_Mod6 },
+      { _T("M7-"), Modifier::Type_Mod7 },
+      { _T("M8-"), Modifier::Type_Mod8 },
+      { _T("M9-"), Modifier::Type_Mod9 },
+      { _T("L0-"), Modifier::Type_Lock0 },
+      { _T("L1-"), Modifier::Type_Lock1 },
+      { _T("L2-"), Modifier::Type_Lock2 },
+      { _T("L3-"), Modifier::Type_Lock3 },
+      { _T("L4-"), Modifier::Type_Lock4 },
+      { _T("L5-"), Modifier::Type_Lock5 },
+      { _T("L6-"), Modifier::Type_Lock6 },
+      { _T("L7-"), Modifier::Type_Lock7 },
+      { _T("L8-"), Modifier::Type_Lock8 },
+      { _T("L9-"), Modifier::Type_Lock9 },
+    };
+
+    for (int i = 0; i < NUMBER_OF(map); ++ i)
+      if (*t == map[i].m_s)
+      {
+       getToken();
+       Modifier::Type mt = map[i].m_mt;
+       if (static_cast<int>(i_mode) <= static_cast<int>(mt))
+         throw ErrorMessage() << _T("`") << *t
+                              << _T("': invalid modifier at this context.");
+       switch (flag)
+       {
+         case PRESS: i_modifier.press(mt); break;
+         case RELEASE: i_modifier.release(mt); break;
+         case DONTCARE: i_modifier.dontcare(mt); break;
+       }
+       isModifierSpecified.on(mt);
+       flag = PRESS;
+       
+       if (o_mode && *o_mode < mt)
+       {
+         if (mt < Modifier::Type_BASIC)
+           *o_mode = Modifier::Type_BASIC;
+         else if (mt < Modifier::Type_KEYSEQ)
+           *o_mode = Modifier::Type_KEYSEQ;
+         else if (mt < Modifier::Type_ASSIGN)
+           *o_mode = Modifier::Type_ASSIGN;
+       }
+       goto continue_loop;
+      }
+      
+    if (*t == _T("*"))
+    {
+      getToken();
+      flag = DONTCARE;
+      continue;
+    }
+      
+    if (*t == _T("~"))
+    {
+      getToken();
+      flag = RELEASE;
+      continue;
+    }
+
+    break;
+  }
+  
+  for (i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)
+    if (!isModifierSpecified.isOn(Modifier::Type(i)))
+      switch (flag)
+      {
+       case PRESS: break;
+       case RELEASE: i_modifier.release(Modifier::Type(i)); break;
+       case DONTCARE: i_modifier.dontcare(Modifier::Type(i)); break;
+      }
+
+  // fix up and down
+  bool isDontcareUp   = i_modifier.isDontcare(Modifier::Type_Up);
+  bool isDontcareDown = i_modifier.isDontcare(Modifier::Type_Down);
+  bool isOnUp         = i_modifier.isOn(Modifier::Type_Up);
+  bool isOnDown       = i_modifier.isOn(Modifier::Type_Down);
+  if (isDontcareUp && isDontcareDown)
+    ;
+  else if (isDontcareUp)
+    i_modifier.on(Modifier::Type_Up, !isOnDown);
+  else if (isDontcareDown)
+    i_modifier.on(Modifier::Type_Down, !isOnUp);
+  else if (isOnUp == isOnDown)
+  {
+    i_modifier.dontcare(Modifier::Type_Up);
+    i_modifier.dontcare(Modifier::Type_Down);
+  }
+
+  // fix repeat
+  if (!isModifierSpecified.isOn(Modifier::Type_Repeat))
+    i_modifier.dontcare(Modifier::Type_Repeat);
+  return i_modifier;
+}
+
+
+// <KEY_NAME>
+Key *SettingLoader::load_KEY_NAME()
+{
+  Token *t = getToken();
+  Key *key = m_setting->m_keyboard.searchKey(t->getString());
+  if (!key)
+    throw ErrorMessage() << _T("`") << *t << _T("': invalid key name.");
+  return key;
+}
+
+
+// <KEYMAP_DEFINITION>
+void SettingLoader::load_KEYMAP_DEFINITION(const Token *i_which)
+{
+  Keymap::Type type = Keymap::Type_keymap;
+  Token *name = getToken();    // <KEYMAP_NAME>
+  tstringi windowClassName;
+  tstringi windowTitleName;
+  KeySeq *keySeq = NULL;
+  Keymap *parentKeymap = NULL;
+  bool isKeymap2 = false;
+  bool doesLoadDefaultKeySeq = false;
+
+  if (!isEOL())
+  {
+    Token *t = lookToken();
+    if (*i_which == _T("window"))      // <WINDOW>
+    {
+      if (t->isOpenParen())
+       // "(" <WINDOW_CLASS_NAME> "&&" <WINDOW_TITLE_NAME> ")"
+       // "(" <WINDOW_CLASS_NAME> "||" <WINDOW_TITLE_NAME> ")"
+      {
+       getToken();
+       windowClassName = getToken()->getRegexp();
+       t = getToken();
+       if (*t == _T("&&"))
+         type = Keymap::Type_windowAnd;
+       else if (*t == _T("||"))
+         type = Keymap::Type_windowOr;
+       else
+         throw ErrorMessage() << _T("`") << *t << _T("': unknown operator.");
+       windowTitleName = getToken()->getRegexp();
+       if (!getToken()->isCloseParen())
+         throw ErrorMessage() << _T("there must be `)'.");
+      }
+      else if (t->isRegexp())  // <WINDOW_CLASS_NAME>
+      {
+       getToken();
+       type = Keymap::Type_windowAnd;
+       windowClassName = t->getRegexp();
+      }
+    }
+    else if (*i_which == _T("keymap"))
+      ;
+    else if (*i_which == _T("keymap2"))
+      isKeymap2 = true;
+    else
+      ASSERT(false);
+    
+    if (!isEOL())
+      doesLoadDefaultKeySeq = true;
+  }
+
+  m_currentKeymap = m_setting->m_keymaps.add(
+    Keymap(type, name->getString(), windowClassName, windowTitleName,
+          NULL, NULL));
+
+  if (doesLoadDefaultKeySeq)
+  {
+    Token *t = lookToken();
+    // <KEYMAP_PARENT>
+    if (*t == _T(":"))
+    {
+      getToken();
+      t = getToken();
+      parentKeymap = m_setting->m_keymaps.searchByName(t->getString());
+      if (!parentKeymap)
+       throw ErrorMessage() << _T("`") << *t
+                            << _T("': unknown keymap name.");
+    }
+    if (!isEOL())
+    {
+      t = getToken();
+      if (!(*t == _T("=>") || *t == _T("=")))
+       throw ErrorMessage() << _T("`") << *t << _T("': syntax error.");
+      keySeq = SettingLoader::load_KEY_SEQUENCE();
+    }
+  }
+  if (keySeq == NULL)
+  {
+    FunctionData *fd;
+    if (type == Keymap::Type_keymap && !isKeymap2)
+      fd = createFunctionData(_T("KeymapParent"));
+    else if (type == Keymap::Type_keymap && !isKeymap2)
+      fd = createFunctionData(_T("Undefined"));
+    else // (type == Keymap::Type_windowAnd || type == Keymap::Type_windowOr)
+      fd = createFunctionData(_T("KeymapParent"));
+    ASSERT( fd );
+    keySeq = m_setting->m_keySeqs.add(
+      KeySeq(name->getString()).add(ActionFunction(fd)));
+  }
+
+  m_currentKeymap->setIfNotYet(keySeq, parentKeymap);
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(bool *o_arg)
+{
+  *o_arg = !(*getToken() == _T("false"));
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(int *o_arg)
+{
+  *o_arg = getToken()->getNumber();
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(unsigned int *o_arg)
+{
+  *o_arg = getToken()->getNumber();
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(long *o_arg)
+{
+  *o_arg = getToken()->getNumber();
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(tstringq *o_arg)
+{
+  *o_arg = getToken()->getString();
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(std::list<tstringq> *o_arg)
+{
+  while (true)
+  {
+    if (!lookToken()->isString())
+      return;
+    o_arg->push_back(getToken()->getString());
+    
+    if (!lookToken()->isComma())
+      return;
+    getToken();
+  }
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(tregex *o_arg)
+{
+  *o_arg = getToken()->getRegexp();
+}
+
+
+// &lt;ARGUMENT_VK&gt;
+void SettingLoader::load_ARGUMENT(VKey *o_arg)
+{
+  Token *t = getToken();
+  int vkey = 0;
+  while (true)
+  {
+    if (t->isNumber()) { vkey |= static_cast<BYTE>(t->getNumber()); break; }
+    else if (*t == _T("E-")) vkey |= VKey_extended;
+    else if (*t == _T("U-")) vkey |= VKey_released;
+    else if (*t == _T("D-")) vkey |= VKey_pressed;
+    else
+    {
+      const VKeyTable *vkt;
+      for (vkt = g_vkeyTable; vkt->m_name; ++ vkt)
+       if (*t == vkt->m_name)
+         break;
+      if (!vkt->m_name)
+       throw ErrorMessage() << _T("`") << *t
+                            << _T("': unknown virtual key name.");
+      vkey |= vkt->m_code;
+      break;
+    }
+    t = getToken();
+  }
+  if (!(vkey & VKey_released) && !(vkey & VKey_pressed))
+    vkey |= VKey_released | VKey_pressed;
+  *o_arg = static_cast<VKey>(vkey);
+}
+
+
+// &lt;ARGUMENT_WINDOW&gt;
+void SettingLoader::load_ARGUMENT(ToWindowType *o_arg)
+{
+  Token *t = getToken();
+  if (t->isNumber())
+  {
+    if (ToWindowType_toBegin <= t->getNumber())
+    {
+      *o_arg = static_cast<ToWindowType>(t->getNumber());
+      return;
+    }
+  }
+  else if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': invalid target window.");
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(GravityType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': unknown gravity symbol.");
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(MouseHookType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': unknown MouseHookType symbol.");
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(MayuDialogType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': unknown dialog box.");
+}
+
+
+// &lt;ARGUMENT_LOCK&gt;
+void SettingLoader::load_ARGUMENT(ModifierLockType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': unknown lock name.");
+}
+
+
+// &lt;ARGUMENT_LOCK&gt;
+void SettingLoader::load_ARGUMENT(ToggleType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': unknown toggle name.");
+}
+
+
+// &lt;ARGUMENT_SHOW_WINDOW&gt;
+void SettingLoader::load_ARGUMENT(ShowCommandType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': unknown show command.");
+}
+
+
+// &lt;ARGUMENT_TARGET_WINDOW&gt;
+void SettingLoader::load_ARGUMENT(TargetWindowType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t
+                      << _T("': unknown target window type.");
+}
+
+
+// &lt;bool&gt;
+void SettingLoader::load_ARGUMENT(BooleanType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': must be true or false.");
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(LogicalOperatorType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t << _T("': must be 'or' or 'and'.");
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(Modifier *o_arg)
+{
+  Modifier modifier;
+  for (int i = Modifier::Type_begin; i != Modifier::Type_end; ++ i)
+    modifier.dontcare(static_cast<Modifier::Type>(i));
+  *o_arg = load_MODIFIER(Modifier::Type_ASSIGN, modifier);
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(const Keymap **o_arg)
+{
+  Token *t = getToken();
+  const Keymap *&keymap = *o_arg;
+  keymap = m_setting->m_keymaps.searchByName(t->getString());
+  if (!keymap)
+    throw ErrorMessage() << _T("`") << *t << _T("': unknown keymap name.");
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(const KeySeq **o_arg)
+{
+  Token *t = getToken();
+  const KeySeq *&keySeq = *o_arg;
+  if (t->isOpenParen())
+  {
+    keySeq = load_KEY_SEQUENCE(_T(""), true);
+    getToken(); // close paren
+  }
+  else if (*t == _T("$"))
+  {
+    t = getToken();
+    keySeq = m_setting->m_keySeqs.searchByName(t->getString());
+    if (!keySeq)
+      throw ErrorMessage() << _T("`$") << *t << _T("': unknown keyseq name.");
+  }
+  else
+    throw ErrorMessage() << _T("`") << *t << _T("': it is not keyseq.");
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(StrExprArg *o_arg)
+{
+  Token *t = getToken();
+  StrExprArg::Type type = StrExprArg::Literal;
+  if (*t == _T("$") && t->isQuoted() == false
+      && lookToken()->getType() == Token::Type_string)
+  {
+    type = StrExprArg::Builtin;
+    t = getToken();
+  }
+  *o_arg = StrExprArg(t->getString(), type);
+}
+
+
+// &lt;ARGUMENT&gt;
+void SettingLoader::load_ARGUMENT(WindowMonitorFromType *o_arg)
+{
+  Token *t = getToken();
+  if (getTypeValue(o_arg, t->getString()))
+    return;
+  throw ErrorMessage() << _T("`") << *t
+                      << _T("': unknown monitor from type.");
+}
+
+
+// <KEY_SEQUENCE>
+KeySeq *SettingLoader::load_KEY_SEQUENCE(
+  const tstringi &i_name, bool i_isInParen, Modifier::Type i_mode)
+{
+  KeySeq keySeq(i_name);
+  while (!isEOL())
+  {
+    Modifier::Type mode;
+    Modifier modifier = load_MODIFIER(i_mode, m_defaultKeySeqModifier, &mode);
+    keySeq.setMode(mode);
+    Token *t = lookToken();
+    if (t->isCloseParen() && i_isInParen)
+      break;
+    else if (t->isOpenParen())
+    {
+      getToken(); // open paren
+      KeySeq *ks = load_KEY_SEQUENCE(_T(""), true, i_mode);
+      getToken(); // close paren
+      keySeq.add(ActionKeySeq(ks));
+    }
+    else if (*t == _T("$")) // <KEYSEQ_NAME>
+    {
+      getToken();
+      t = getToken();
+      KeySeq *ks = m_setting->m_keySeqs.searchByName(t->getString());
+      if (ks == NULL)
+       throw ErrorMessage() << _T("`$") << *t
+                            << _T("': unknown keyseq name.");
+      if (!ks->isCorrectMode(i_mode))
+       throw ErrorMessage()
+         << _T("`$") << *t
+         << _T("': Some of R-, IL-, IC-, NL-, CL-, SL-, KL-, MAX-, MIN-, MMAX-, MMIN-, T-, TS-, M0...M9- and L0...L9- are used in the keyseq.  They are prohibited in this context.");
+      keySeq.setMode(ks->getMode());
+      keySeq.add(ActionKeySeq(ks));
+    }
+    else if (*t == _T("&")) // <FUNCTION_NAME>
+    {
+      getToken();
+      t = getToken();
+      
+      // search function
+      ActionFunction af(createFunctionData(t->getString()), modifier);
+      if (af.m_functionData == NULL)
+       throw ErrorMessage() << _T("`&") << *t
+                            << _T("': unknown function name.");
+      af.m_functionData->load(this);
+      keySeq.add(af);
+    }
+    else // <KEYSEQ_MODIFIED_KEY_NAME>
+    {
+      ModifiedKey mkey;
+      mkey.m_modifier = modifier;
+      mkey.m_key = load_KEY_NAME();
+      keySeq.add(ActionKey(mkey));
+    }
+  }
+  return m_setting->m_keySeqs.add(keySeq);
+}
+
+
+// <KEY_ASSIGN>
+void SettingLoader::load_KEY_ASSIGN()
+{
+  typedef std::list<ModifiedKey> AssignedKeys;
+  AssignedKeys assignedKeys;
+  
+  ModifiedKey mkey;
+  mkey.m_modifier =
+    load_MODIFIER(Modifier::Type_ASSIGN, m_defaultAssignModifier);
+  if (*lookToken() == _T("="))
+  {
+    getToken();
+    m_defaultKeySeqModifier = load_MODIFIER(Modifier::Type_KEYSEQ,
+                                           m_defaultKeySeqModifier);
+    m_defaultAssignModifier = mkey.m_modifier;
+    return;
+  }
+  
+  while (true)
+  {
+    mkey.m_key = load_KEY_NAME();
+    assignedKeys.push_back(mkey);
+    if (*lookToken() == _T("=>") || *lookToken() == _T("="))
+      break;
+    mkey.m_modifier =
+      load_MODIFIER(Modifier::Type_ASSIGN, m_defaultAssignModifier);
+  }
+  getToken();
+
+  ASSERT(m_currentKeymap);
+  KeySeq *keySeq = load_KEY_SEQUENCE();
+  for (AssignedKeys::iterator i = assignedKeys.begin();
+       i != assignedKeys.end(); ++ i)
+    m_currentKeymap->addAssignment(*i, keySeq);
+}
+
+
+// <EVENT_ASSIGN>
+void SettingLoader::load_EVENT_ASSIGN()
+{
+  std::list<ModifiedKey> assignedKeys;
+
+  ModifiedKey mkey;
+  mkey.m_modifier.dontcare();                  //set all modifiers to dontcare
+  
+  Token *t = getToken();
+  Key **e;
+  for (e = Event::events; *e; ++ e)
+    if (*t == (*e)->getName())
+    {
+      mkey.m_key = *e;
+      break;
+    }
+  if (!*e)
+    throw ErrorMessage() << _T("`") << *t << _T("': invalid event name.");
+
+  t = getToken();
+  if (!(*t == _T("=>") || *t == _T("=")))
+    throw ErrorMessage() << _T("`=' is expected.");
+
+  ASSERT(m_currentKeymap);
+  KeySeq *keySeq = load_KEY_SEQUENCE();
+  m_currentKeymap->addAssignment(mkey, keySeq);
+}
+
+
+// <MODIFIER_ASSIGNMENT>
+void SettingLoader::load_MODIFIER_ASSIGNMENT()
+{
+  // <MODIFIER_NAME>
+  Token *t = getToken();
+  Modifier::Type mt;
+
+  while (true)
+  {
+    Keymap::AssignMode am = Keymap::AM_notModifier;
+    if      (*t == _T("!")  ) am = Keymap::AM_true, t = getToken();
+    else if (*t == _T("!!") ) am = Keymap::AM_oneShot, t = getToken();
+    else if (*t == _T("!!!")) am = Keymap::AM_oneShotRepeatable, t = getToken();
+    
+    if      (*t == _T("shift")) mt = Modifier::Type_Shift;
+    else if (*t == _T("alt")  ||
+            *t == _T("meta") ||
+            *t == _T("menu") ) mt = Modifier::Type_Alt;
+    else if (*t == _T("control") ||
+            *t == _T("ctrl") ) mt = Modifier::Type_Control;
+    else if (*t == _T("windows") ||
+            *t == _T("win")  ) mt = Modifier::Type_Windows;
+    else if (*t == _T("mod0") ) mt = Modifier::Type_Mod0;
+    else if (*t == _T("mod1") ) mt = Modifier::Type_Mod1;
+    else if (*t == _T("mod2") ) mt = Modifier::Type_Mod2;
+    else if (*t == _T("mod3") ) mt = Modifier::Type_Mod3;
+    else if (*t == _T("mod4") ) mt = Modifier::Type_Mod4;
+    else if (*t == _T("mod5") ) mt = Modifier::Type_Mod5;
+    else if (*t == _T("mod6") ) mt = Modifier::Type_Mod6;
+    else if (*t == _T("mod7") ) mt = Modifier::Type_Mod7;
+    else if (*t == _T("mod8") ) mt = Modifier::Type_Mod8;
+    else if (*t == _T("mod9") ) mt = Modifier::Type_Mod9;
+    else throw ErrorMessage() << _T("`") << *t
+                             << _T("': invalid modifier name.");
+
+    if (am == Keymap::AM_notModifier)
+      break;
+    
+    m_currentKeymap->addModifier(mt, Keymap::AO_overwrite, am, NULL);
+    if (isEOL())
+      return;
+    t = getToken();
+  }
+  
+  // <ASSIGN_OP>
+  t = getToken();
+  Keymap::AssignOperator ao;
+  if      (*t == _T("=") ) ao = Keymap::AO_new;
+  else if (*t == _T("+=")) ao = Keymap::AO_add;
+  else if (*t == _T("-=")) ao = Keymap::AO_sub;
+  else  throw ErrorMessage() << _T("`") << *t << _T("': is unknown operator.");
+
+  // <ASSIGN_MODE>? <KEY_NAME>
+  while (!isEOL())
+  {
+    // <ASSIGN_MODE>? 
+    t = getToken();
+    Keymap::AssignMode am = Keymap::AM_normal;
+    if      (*t == _T("!")  ) am = Keymap::AM_true, t = getToken();
+    else if (*t == _T("!!") ) am = Keymap::AM_oneShot, t = getToken();
+    else if (*t == _T("!!!")) am = Keymap::AM_oneShotRepeatable, t = getToken();
+    
+    // <KEY_NAME>
+    Key *key = m_setting->m_keyboard.searchKey(t->getString());
+    if (!key)
+      throw ErrorMessage() << _T("`") << *t << _T("': invalid key name.");
+
+    // we can ignore warning C4701
+    m_currentKeymap->addModifier(mt, ao, am, key);
+    if (ao == Keymap::AO_new)
+      ao = Keymap::AO_add;
+  }
+}
+
+
+// <KEYSEQ_DEFINITION>
+void SettingLoader::load_KEYSEQ_DEFINITION()
+{
+  if (*getToken() != _T("$"))
+    throw ErrorMessage() << _T("there must be `$' after `keyseq'");
+  Token *name = getToken();
+  if (*getToken() != _T("="))
+    throw ErrorMessage() << _T("there must be `=' after keyseq naem");
+  load_KEY_SEQUENCE(name->getString(), false, Modifier::Type_ASSIGN);
+}
+
+
+// <DEFINE>
+void SettingLoader::load_DEFINE()
+{
+  m_setting->m_symbols.insert(getToken()->getString());
+}
+
+
+// <IF>
+void SettingLoader::load_IF()
+{
+  if (!getToken()->isOpenParen())
+    throw ErrorMessage() << _T("there must be `(' after `if'.");
+  Token *t = getToken(); // <SYMBOL> or !
+  bool not = false;
+  if (*t == _T("!"))
+  {
+    not = true;
+    t = getToken(); // <SYMBOL>
+  }
+  
+  bool doesSymbolExist = (m_setting->m_symbols.find(t->getString())
+                         != m_setting->m_symbols.end());
+  bool doesRead = ((doesSymbolExist && !not) ||
+                  (!doesSymbolExist && not));
+  if (0 < m_canReadStack.size())
+    doesRead = doesRead && m_canReadStack.back();
+  
+  if (!getToken()->isCloseParen())
+    throw ErrorMessage() << _T("there must be `)'.");
+
+  m_canReadStack.push_back(doesRead);
+  if (!isEOL())
+  {
+    size_t len = m_canReadStack.size();
+    load_LINE();
+    if (len < m_canReadStack.size())
+    {
+      bool r = m_canReadStack.back();
+      m_canReadStack.pop_back();
+      m_canReadStack[len - 1] = r && doesRead;
+    }
+    else if (len == m_canReadStack.size())
+      m_canReadStack.pop_back();
+    else
+      ; // `end' found
+  }
+}
+
+
+// <ELSE> <ELSEIF>
+void SettingLoader::load_ELSE(bool i_isElseIf, const tstringi &i_token)
+{
+  bool doesRead = !load_ENDIF(i_token);
+  if (0 < m_canReadStack.size())
+    doesRead = doesRead && m_canReadStack.back();
+  m_canReadStack.push_back(doesRead);
+  if (!isEOL())
+  {
+    size_t len = m_canReadStack.size();
+    if (i_isElseIf)
+      load_IF();
+    else
+      load_LINE();
+    if (len < m_canReadStack.size())
+    {
+      bool r = m_canReadStack.back();
+      m_canReadStack.pop_back();
+      m_canReadStack[len - 1] = doesRead && r;
+    }
+    else if (len == m_canReadStack.size())
+      m_canReadStack.pop_back();
+    else
+      ; // `end' found
+  }
+}
+
+
+// <ENDIF>
+bool SettingLoader::load_ENDIF(const tstringi &i_token)
+{
+  if (m_canReadStack.size() == 0)
+    throw ErrorMessage() << _T("unbalanced `") << i_token << _T("'");
+  bool r = m_canReadStack.back();
+  m_canReadStack.pop_back();
+  return r;
+}
+
+
+// <LINE>
+void SettingLoader::load_LINE()
+{
+  Token *i_token = getToken();
+
+  // <COND_SYMBOL>
+  if      (*i_token == _T("if") ||
+          *i_token == _T("and")) load_IF();
+  else if (*i_token == _T("else")) load_ELSE(false, i_token->getString());
+  else if (*i_token == _T("elseif") ||
+          *i_token == _T("elsif")  ||
+          *i_token == _T("elif")   ||
+          *i_token == _T("or")) load_ELSE(true, i_token->getString());
+  else if (*i_token == _T("endif")) load_ENDIF(_T("endif"));
+  else if (0 < m_canReadStack.size() && !m_canReadStack.back())
+  {
+    while (!isEOL())
+      getToken();
+  }
+  else if (*i_token == _T("define")) load_DEFINE();
+  // <INCLUDE>
+  else if (*i_token == _T("include")) load_INCLUDE();
+  // <KEYBOARD_DEFINITION>
+  else if (*i_token == _T("def")) load_KEYBOARD_DEFINITION();
+  // <KEYMAP_DEFINITION>
+  else if (*i_token == _T("keymap")  ||
+          *i_token == _T("keymap2") ||
+          *i_token == _T("window")) load_KEYMAP_DEFINITION(i_token);
+  // <KEY_ASSIGN>
+  else if (*i_token == _T("key")) load_KEY_ASSIGN();
+  // <EVENT_ASSIGN>
+  else if (*i_token == _T("event")) load_EVENT_ASSIGN();
+  // <MODIFIER_ASSIGNMENT>
+  else if (*i_token == _T("mod")) load_MODIFIER_ASSIGNMENT();
+  // <KEYSEQ_DEFINITION>
+  else if (*i_token == _T("keyseq")) load_KEYSEQ_DEFINITION();
+  else
+    throw ErrorMessage() << _T("syntax error `") << *i_token << _T("'.");
+}
+
+  
+// prefix sort predicate used in load(const string &)
+static bool prefixSortPred(const tstringi &i_a, const tstringi &i_b)
+{
+  return i_b.size() < i_a.size();
+}
+
+
+/*
+  _UNICODE: read file (UTF-16 LE/BE, UTF-8, locale specific multibyte encoding)
+  _MBCS: read file
+*/
+bool readFile(tstring *o_data, const tstringi &i_filename)
+{
+  // get size of file
+#if 0
+  // bcc's _wstat cannot obtain file size
+  struct _stat sbuf;
+  if (_tstat(i_filename.c_str(), &sbuf) < 0 || sbuf.st_size == 0)
+    return false;
+#else
+  // so, we use _wstati64 for bcc
+  struct stati64_t sbuf;
+  if (_tstati64(i_filename.c_str(), &sbuf) < 0 || sbuf.st_size == 0)
+    return false;
+  // following check is needed to cast sbuf.st_size to size_t safely
+  // this cast occurs because of above workaround for bcc
+  if (sbuf.st_size > UINT_MAX)
+    return false;
+#endif
+  
+  // open
+  FILE *fp = _tfopen(i_filename.c_str(), _T("rb"));
+  if (!fp)
+    return false;
+  
+  // read file
+  Array<BYTE> buf(static_cast<size_t>(sbuf.st_size) + 1);
+  if (fread(buf.get(), static_cast<size_t>(sbuf.st_size), 1, fp) != 1)
+  {
+    fclose(fp);
+    return false;
+  }
+  buf.get()[sbuf.st_size] = 0;                 // mbstowcs() requires null
+                                               // terminated string
+
+#ifdef _UNICODE
+  //
+  if (buf.get()[0] == 0xffU && buf.get()[1] == 0xfeU &&
+      sbuf.st_size % 2 == 0)
+    // UTF-16 Little Endien
+  {
+    size_t size = static_cast<size_t>(sbuf.st_size) / 2;
+    o_data->resize(size);
+    BYTE *p = buf.get();
+    for (size_t i = 0; i < size; ++ i)
+    {
+      wchar_t c = static_cast<wchar_t>(*p ++);
+      c |= static_cast<wchar_t>(*p ++) << 8;
+      (*o_data)[i] = c;
+    }
+    fclose(fp);
+    return true;
+  }
+  
+  //
+  if (buf.get()[0] == 0xfeU && buf.get()[1] == 0xffU &&
+      sbuf.st_size % 2 == 0)
+    // UTF-16 Big Endien
+  {
+    size_t size = static_cast<size_t>(sbuf.st_size) / 2;
+    o_data->resize(size);
+    BYTE *p = buf.get();
+    for (size_t i = 0; i < size; ++ i)
+    {
+      wchar_t c = static_cast<wchar_t>(*p ++) << 8;
+      c |= static_cast<wchar_t>(*p ++);
+      (*o_data)[i] = c;
+    }
+    fclose(fp);
+    return true;
+  }
+
+  // try multibyte charset 
+  size_t wsize = mbstowcs(NULL, reinterpret_cast<char *>(buf.get()), 0);
+  if (wsize != size_t(-1))
+  {
+    Array<wchar_t> wbuf(wsize);
+    mbstowcs(wbuf.get(), reinterpret_cast<char *>(buf.get()), wsize);
+    o_data->assign(wbuf.get(), wbuf.get() + wsize);
+    fclose(fp);
+    return true;
+  }
+  
+  // try UTF-8
+  {
+    Array<wchar_t> wbuf(static_cast<size_t>(sbuf.st_size));
+    BYTE *f = buf.get();
+    BYTE *end = buf.get() + sbuf.st_size;
+    wchar_t *d = wbuf.get();
+    enum { STATE_1, STATE_2of2, STATE_2of3, STATE_3of3 } state = STATE_1;
+    
+    while (f != end)
+    {
+      switch (state)
+      {
+       case STATE_1:
+         if (!(*f & 0x80))                     // 0xxxxxxx: 00-7F
+           *d++ = static_cast<wchar_t>(*f++);
+         else if ((*f & 0xe0) == 0xc0)         // 110xxxxx 10xxxxxx: 0080-07FF
+         {
+           *d = ((static_cast<wchar_t>(*f++) & 0x1f) << 6);
+           state = STATE_2of2;
+         }
+         else if ((*f & 0xf0) == 0xe0)         // 1110xxxx 10xxxxxx 10xxxxxx:
+                                               // 0800 - FFFF
+         {
+           *d = ((static_cast<wchar_t>(*f++) & 0x0f) << 12);
+           state = STATE_2of3;
+         }
+         else
+           goto not_UTF_8;
+         break;
+         
+       case STATE_2of2:
+       case STATE_3of3:
+         if ((*f & 0xc0) != 0x80)
+           goto not_UTF_8;
+         *d++ |= (static_cast<wchar_t>(*f++) & 0x3f);
+         state = STATE_1;
+         break;
+
+       case STATE_2of3:
+         if ((*f & 0xc0) != 0x80)
+           goto not_UTF_8;
+         *d |= ((static_cast<wchar_t>(*f++) & 0x3f) << 6);
+         state = STATE_3of3;
+         break;
+      }
+    }
+    o_data->assign(wbuf.get(), d);
+    fclose(fp);
+    return true;
+    
+    not_UTF_8: ;
+  }
+#endif // _UNICODE
+
+  // assume ascii
+  o_data->resize(static_cast<size_t>(sbuf.st_size));
+  for (off_t i = 0; i < sbuf.st_size; ++ i)
+    (*o_data)[i] = buf.get()[i];
+  fclose(fp);
+  return true;
+}
+
+
+// load (called from load(Setting *, const tstringi &) only)
+void SettingLoader::load(const tstringi &i_filename)
+{
+  m_currentFilename = i_filename;
+  
+  tstring data;
+  if (!readFile(&data, m_currentFilename))
+  {
+    Acquire a(m_soLog);
+    *m_log << m_currentFilename << _T(" : error: file not found") << std::endl;
+#if 1
+    *m_log << data << std::endl;
+#endif
+    m_isThereAnyError = true;
+    return;
+  }
+  
+  // prefix
+  if (m_prefixesRefCcount == 0)
+  {
+    static const _TCHAR *prefixes[] =
+    {
+      _T("="), _T("=>"), _T("&&"), _T("||"), _T(":"), _T("$"), _T("&"),
+      _T("-="), _T("+="), _T("!!!"), _T("!!"), _T("!"), 
+      _T("E0-"), _T("E1-"),                    // <SCAN_CODE_EXTENTION>
+      _T("S-"), _T("A-"), _T("M-"), _T("C-"),  // <BASIC_MODIFIER>
+      _T("W-"), _T("*"), _T("~"),
+      _T("U-"), _T("D-"),                      // <KEYSEQ_MODIFIER>
+      _T("R-"), _T("IL-"), _T("IC-"), _T("I-"),        // <ASSIGN_MODIFIER>
+      _T("NL-"), _T("CL-"), _T("SL-"), _T("KL-"),
+      _T("MAX-"), _T("MIN-"), _T("MMAX-"), _T("MMIN-"),
+      _T("T-"), _T("TS-"),
+      _T("M0-"), _T("M1-"), _T("M2-"), _T("M3-"), _T("M4-"),
+      _T("M5-"), _T("M6-"), _T("M7-"), _T("M8-"), _T("M9-"), 
+      _T("L0-"), _T("L1-"), _T("L2-"), _T("L3-"), _T("L4-"),
+      _T("L5-"), _T("L6-"), _T("L7-"), _T("L8-"), _T("L9-"), 
+    };
+    m_prefixes = new std::vector<tstringi>;
+    for (size_t i = 0; i < NUMBER_OF(prefixes); ++ i)
+      m_prefixes->push_back(prefixes[i]);
+    std::sort(m_prefixes->begin(), m_prefixes->end(), prefixSortPred);
+  }
+  m_prefixesRefCcount ++;
+
+  // create parser
+  Parser parser(data.c_str(), data.size());
+  parser.setPrefixes(m_prefixes);
+    
+  while (true)
+  {
+    try
+    {
+      if (!parser.getLine(&m_tokens))
+       break;
+      m_ti = m_tokens.begin();
+    }
+    catch (ErrorMessage &e)
+    {
+      if (m_log && m_soLog)
+      {
+       Acquire a(m_soLog);
+       *m_log << m_currentFilename << _T("(") << parser.getLineNumber()
+              << _T(") : error: ") << e << std::endl;
+      }
+      m_isThereAnyError = true;
+      continue;
+    }
+      
+    try
+    {
+      load_LINE();
+      if (!isEOL())
+       throw WarningMessage() << _T("back garbage is ignored.");
+    }
+    catch (WarningMessage &w)
+    {
+      if (m_log && m_soLog)
+      {
+       Acquire a(m_soLog);
+       *m_log << i_filename << _T("(") << parser.getLineNumber()
+              << _T(") : warning: ") << w << std::endl;
+      }
+    }
+    catch (ErrorMessage &e)
+    {
+      if (m_log && m_soLog)
+      {
+       Acquire a(m_soLog);
+       *m_log << i_filename << _T("(") << parser.getLineNumber()
+              << _T(") : error: ") << e << std::endl;
+      }
+      m_isThereAnyError = true;
+    }
+  }
+    
+  // m_prefixes
+  -- m_prefixesRefCcount;
+  if (m_prefixesRefCcount == 0)
+    delete m_prefixes;
+
+  if (0 < m_canReadStack.size())
+  {
+    Acquire a(m_soLog);
+    *m_log << m_currentFilename << _T("(") << parser.getLineNumber()
+          << _T(") : error: unbalanced `if'.  ")
+          << _T("you forget `endif', didn'i_token you?")
+          << std::endl;
+    m_isThereAnyError = true;
+  }
+}
+
+
+// is the filename readable ?
+bool SettingLoader::isReadable(const tstringi &i_filename,
+                              int i_debugLevel) const 
+{
+  if (i_filename.empty())
+    return false;
+#ifdef UNICODE
+  tifstream ist(to_string(i_filename).c_str());
+#else
+  tifstream ist(i_filename.c_str());
+#endif
+  if (ist.good())
+  {
+    if (m_log && m_soLog)
+    {
+               Acquire a(m_soLog, 0);
+      *m_log << _T("  loading: ") << i_filename << std::endl;
+    }
+    return true;
+  }
+  else
+  {
+    if (m_log && m_soLog)
+    {
+      Acquire a(m_soLog, i_debugLevel);
+      *m_log << _T("not found: ") << i_filename << std::endl;
+    }
+    return false;
+  }
+}
+
+#if 0
+// get filename from registry
+bool SettingLoader::getFilenameFromRegistry(tstringi *o_path) const
+{
+  // get from registry
+  Registry reg(MAYU_REGISTRY_ROOT);
+  int index;
+  reg.read(_T(".mayuIndex"), &index, 0);
+  char buf[100];
+  snprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
+  if (!reg.read(buf, o_path))
+    return false;
+
+  // parse registry entry
+  Regexp getFilename(_T("^[^;]*;([^;]*);(.*)$"));
+  if (!getFilename.doesMatch(*o_path))
+    return false;
+  
+  tstringi path = getFilename[1];
+  tstringi options = getFilename[2];
+  
+  if (!(0 < path.size() && isReadable(path)))
+    return false;
+  *o_path = path;
+  
+  // set symbols
+  Regexp symbol(_T("-D([^;]*)"));
+  while (symbol.doesMatch(options))
+  {
+    m_setting->symbols.insert(symbol[1]);
+    options = options.substr(symbol.subBegin(1));
+  }
+  
+  return true;
+}
+#endif
+
+
+// get filename
+bool SettingLoader::getFilename(const tstringi &i_name, tstringi *o_path,
+                               int i_debugLevel) const
+{
+  // the default filename is ".mayu"
+  const tstringi &name = i_name.empty() ? tstringi(_T(".mayu")) : i_name;
+  
+  bool isFirstTime = true;
+
+  while (true)
+  {
+    // find file from registry
+    if (i_name.empty())                                // called not from 'include'
+    {
+      Setting::Symbols symbols;
+      if (getFilenameFromRegistry(NULL, o_path, &symbols))
+      {
+       if (o_path->empty())
+         // find file from home directory
+       {
+         HomeDirectories pathes;
+         getHomeDirectories(&pathes);
+         for (HomeDirectories::iterator
+                i = pathes.begin(); i != pathes.end(); ++ i)
+         {
+           *o_path = *i + _T("\\") + name;
+           if (isReadable(*o_path, i_debugLevel))
+             goto add_symbols;
+         }
+         return false;
+       }
+       else
+       {
+         if (!isReadable(*o_path, i_debugLevel))
+           return false;
+       }
+       add_symbols:
+       for (Setting::Symbols::iterator
+              i = symbols.begin(); i != symbols.end(); ++ i)
+         m_setting->m_symbols.insert(*i);
+       return true;
+      }
+    }
+    
+    if (!isFirstTime)
+      return false;
+    
+    // find file from home directory
+    HomeDirectories pathes;
+    getHomeDirectories(&pathes);
+    for (HomeDirectories::iterator i = pathes.begin(); i != pathes.end(); ++ i)
+    {
+      *o_path = *i + _T("\\") + name;
+      if (isReadable(*o_path, i_debugLevel))
+       return true;
+    }
+    
+    if (!i_name.empty())
+      return false;                            // called by 'include'
+    
+    if (!DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_setting),
+                  NULL, dlgSetting_dlgProc))
+      return false;
+  }
+}
+
+
+// constructor
+SettingLoader::SettingLoader(SyncObject *i_soLog, tostream *i_log)
+  : m_setting(NULL),
+    m_isThereAnyError(false),
+    m_soLog(i_soLog),
+    m_log(i_log),
+    m_currentKeymap(NULL)
+{
+  m_defaultKeySeqModifier =
+    m_defaultAssignModifier.release(Modifier::Type_ImeComp);
+}
+
+
+/* load m_setting
+   If called by "include", 'filename' describes filename.
+   Otherwise the 'filename' is empty.
+ */
+bool SettingLoader::load(Setting *i_setting, const tstringi &i_filename)
+{
+  m_setting = i_setting;
+  m_isThereAnyError = false;
+    
+  tstringi path;
+  if (!getFilename(i_filename, &path))
+  {
+    if (i_filename.empty())
+    {
+      Acquire a(m_soLog);
+      getFilename(i_filename, &path, 0);       // show filenames
+      return false;
+    }
+    else
+      throw ErrorMessage() << _T("`") << i_filename
+                          << _T("': no such file or other error.");
+  }
+
+  // create global keymap's default keySeq
+  ActionFunction af(createFunctionData(_T("OtherWindowClass")));
+  KeySeq *globalDefault = m_setting->m_keySeqs.add(KeySeq(_T("")).add(af));
+  
+  // add default keymap
+  m_currentKeymap = m_setting->m_keymaps.add(
+    Keymap(Keymap::Type_windowOr, _T("Global"), _T(""), _T(""),
+          globalDefault, NULL));
+
+  /*
+  // add keyboard layout name
+  if (filename.empty())
+  {
+    char keyboardLayoutName[KL_NAMELENGTH];
+    if (GetKeyboardLayoutName(keyboardLayoutName))
+    {
+      tstringi kl = tstringi(_T("KeyboardLayout/")) + keyboardLayoutName;
+      m_setting->symbols.insert(kl);
+      Acquire a(m_soLog);
+      *m_log << _T("KeyboardLayout: ") << kl << std::endl;
+    }
+  }
+  */
+  
+  // load
+  load(path);
+
+  // finalize
+  if (i_filename.empty())
+    m_setting->m_keymaps.adjustModifier(m_setting->m_keyboard);
+  
+  return !m_isThereAnyError;
+}
+
+
+std::vector<tstringi> *SettingLoader::m_prefixes; // m_prefixes terminal symbol
+size_t SettingLoader::m_prefixesRefCcount;     /* reference count of
+                                                  m_prefixes */
diff --git a/setting.h b/setting.h
new file mode 100644 (file)
index 0000000..a157fac
--- /dev/null
+++ b/setting.h
@@ -0,0 +1,186 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// setting.h
+
+
+#ifndef _SETTING_H
+#  define _SETTING_H
+
+
+#  include "keymap.h"
+#  include "parser.h"
+#  include "multithread.h"
+#  include <set>
+
+
+/// this class contains all of loaded settings
+class Setting
+{
+public:
+  typedef std::set<tstringi> Symbols;          ///
+  typedef std::list<Modifier> Modifiers;       /// 
+  
+public:
+  Keyboard m_keyboard;                         ///
+  Keymaps m_keymaps;                           ///
+  KeySeqs m_keySeqs;                           ///
+  Symbols m_symbols;                           ///
+  bool m_correctKanaLockHandling;              ///
+  bool m_sts4mayu;                             ///
+  bool m_cts4mayu;                             ///
+  unsigned int m_oneShotRepeatableDelay;       ///
+
+public:
+  Setting()
+    : m_correctKanaLockHandling(false),
+      m_sts4mayu(false),
+      m_cts4mayu(false),
+      m_oneShotRepeatableDelay(0) { }
+};
+
+
+///
+namespace Event
+{
+  ///
+  extern Key prefixed;
+  ///
+  extern Key before_key_down;
+  ///
+  extern Key after_key_up;
+  ///
+  extern Key *events[];
+}
+
+
+///
+class SettingLoader
+{
+#  define FUNCTION_FRIEND
+#  include "functions.h"
+#  undef FUNCTION_FRIEND
+  
+public:
+  ///
+  class FunctionCreator
+  {
+  public:
+    const _TCHAR *m_name;                      /// 
+    FunctionData *m_creator;                   /// 
+  };
+
+private:
+  typedef std::vector<Token> Tokens;           ///
+  typedef std::vector<tstringi> Prefixes;      ///
+  typedef std::vector<bool> CanReadStack;      /// 
+  
+private:
+  Setting *m_setting;                          /// loaded setting
+  bool m_isThereAnyError;                      /// is there any error ?
+
+  SyncObject *m_soLog;                         /// guard log output stream
+  tostream *m_log;                             /// log output stream
+  
+  tstringi m_currentFilename;                  /// current filename
+  
+  Tokens m_tokens;                             /// tokens for current line
+  Tokens::iterator m_ti;                       /// current processing token
+
+  static Prefixes *m_prefixes;                 /// prefix terminal symbol
+  static size_t m_prefixesRefCcount;           /// reference count of prefix
+
+  Keymap *m_currentKeymap;                     /// current keymap
+
+  CanReadStack m_canReadStack;                 /// for &lt;COND_SYMBOL&gt;
+
+  Modifier m_defaultAssignModifier;            /** default
+                                                    &lt;ASSIGN_MODIFIER&gt; */
+  Modifier m_defaultKeySeqModifier;            /** default
+                                                    &lt;KEYSEQ_MODIFIER&gt; */
+
+private:
+  bool isEOL();                                        /// is there no more tokens ?
+  Token *getToken();                           /// get next token
+  Token *lookToken();                          /// look next token
+  bool getOpenParen(bool i_doesThrow, const _TCHAR *i_name); /// argument "("
+  bool getCloseParen(bool i_doesThrow, const _TCHAR *i_name); /// argument ")"
+  bool getComma(bool i_doesThrow, const _TCHAR *i_name); /// argument ","
+  
+  void load_LINE();                            /// &lt;LINE&gt;
+  void load_DEFINE();                          /// &lt;DEFINE&gt;
+  void load_IF();                              /// &lt;IF&gt;
+  void load_ELSE(bool i_isElseIf, const tstringi &i_token);
+                                               /// &lt;ELSE&gt; &lt;ELSEIF&gt;
+  bool load_ENDIF(const tstringi &i_token);    /// &lt;ENDIF&gt;
+  void load_INCLUDE();                         /// &lt;INCLUDE&gt;
+  void load_SCAN_CODES(Key *o_key);            /// &lt;SCAN_CODES&gt;
+  void load_DEFINE_KEY();                      /// &lt;DEFINE_KEY&gt;
+  void load_DEFINE_MODIFIER();                 /// &lt;DEFINE_MODIFIER&gt;
+  void load_DEFINE_SYNC_KEY();                 /// &lt;DEFINE_SYNC_KEY&gt;
+  void load_DEFINE_ALIAS();                    /// &lt;DEFINE_ALIAS&gt;
+  void load_DEFINE_SUBSTITUTE();               /// &lt;DEFINE_SUBSTITUTE&gt;
+  void load_DEFINE_OPTION();                   /// &lt;DEFINE_OPTION&gt;
+  void load_KEYBOARD_DEFINITION();             /// &lt;KEYBOARD_DEFINITION&gt;
+  Modifier load_MODIFIER(Modifier::Type i_mode, Modifier i_modifier,
+                        Modifier::Type *o_mode = NULL);
+                                               /// &lt;..._MODIFIER&gt;
+  Key *load_KEY_NAME();                                /// &lt;KEY_NAME&gt;
+  void load_KEYMAP_DEFINITION(const Token *i_which);
+                                               /// &lt;KEYMAP_DEFINITION&gt;
+  void load_ARGUMENT(bool *o_arg);             /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(int *o_arg);              /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(unsigned int *o_arg);     /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(long *o_arg);             /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(tstringq *o_arg);         /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(std::list<tstringq> *o_arg); /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(tregex *o_arg);           /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(VKey *o_arg);             /// &lt;ARGUMENT_VK&gt;
+  void load_ARGUMENT(ToWindowType *o_arg);     /// &lt;ARGUMENT_WINDOW&gt;
+  void load_ARGUMENT(GravityType *o_arg);      /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(MouseHookType *o_arg);    /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(MayuDialogType *o_arg);   /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(ModifierLockType *o_arg); /// &lt;ARGUMENT_LOCK&gt;
+  void load_ARGUMENT(ToggleType *o_arg);       /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(ShowCommandType *o_arg);  ///&lt;ARGUMENT_SHOW_WINDOW&gt;
+  void load_ARGUMENT(TargetWindowType *o_arg);
+                                       /// &lt;ARGUMENT_TARGET_WINDOW_TYPE&gt;
+  void load_ARGUMENT(BooleanType *o_arg);      /// &lt;bool&gt;
+  void load_ARGUMENT(LogicalOperatorType *o_arg);/// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(Modifier *o_arg);         /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(const Keymap **o_arg);    /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(const KeySeq **o_arg);    /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(StrExprArg *o_arg);       /// &lt;ARGUMENT&gt;
+  void load_ARGUMENT(WindowMonitorFromType *o_arg);    /// &lt;ARGUMENT&gt;
+  KeySeq *load_KEY_SEQUENCE(
+    const tstringi &i_name = _T(""), bool i_isInParen = false,
+    Modifier::Type i_mode = Modifier::Type_KEYSEQ); /// &lt;KEY_SEQUENCE&gt;
+  void load_KEY_ASSIGN();                      /// &lt;KEY_ASSIGN&gt;
+  void load_EVENT_ASSIGN();                    /// &lt;EVENT_ASSIGN&gt;
+  void load_MODIFIER_ASSIGNMENT();             /// &lt;MODIFIER_ASSIGN&gt;
+  void load_LOCK_ASSIGNMENT();                 /// &lt;LOCK_ASSIGN&gt;
+  void load_KEYSEQ_DEFINITION();               /// &lt;KEYSEQ_DEFINITION&gt;
+
+  /// load
+  void load(const tstringi &i_filename);
+
+  /// is the filename readable ?
+  bool isReadable(const tstringi &i_filename, int i_debugLevel = 1) const;
+
+  /// get filename
+  bool getFilename(const tstringi &i_name,
+                  tstringi *o_path, int i_debugLevel = 1) const;
+
+public:
+  ///
+  SettingLoader(SyncObject *i_soLog, tostream *i_log);
+
+  /// load setting
+  bool load(Setting *o_setting, const tstringi &i_filename = _T(""));
+};
+
+
+/// get home directory path
+typedef std::list<tstringi> HomeDirectories;
+extern void getHomeDirectories(HomeDirectories *o_path);
+
+
+#endif // !_SETTING_H
diff --git a/stringtool.cpp b/stringtool.cpp
new file mode 100644 (file)
index 0000000..5837626
--- /dev/null
@@ -0,0 +1,480 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// stringtool.cpp
+
+
+#include "stringtool.h"
+#include "array.h"
+#include <locale>
+#include <malloc.h>
+#include <mbstring.h>
+
+
+/* ************************************************************************** *
+   
+STRLCPY(3)                OpenBSD Programmer's Manual               STRLCPY(3)
+
+NAME
+     strlcpy, strlcat - size-bounded string copying and concatenation
+
+
+
+SYNOPSIS
+     #include <string.h>
+
+     size_t
+     strlcpy(char *dst, const char *src, size_t size);
+
+     size_t
+     strlcat(char *dst, const char *src, size_t size);
+
+DESCRIPTION
+     The strlcpy() and strlcat() functions copy and concatenate strings re-
+     spectively.  They are designed to be safer, more consistent, and less er-
+     ror prone replacements for strncpy(3) and strncat(3).  Unlike those func-
+     tions, strlcpy() and strlcat() take the full size of the buffer (not just
+     the length) and guarantee to NUL-terminate the result (as long as size is
+     larger than 0).  Note that you should include a byte for the NUL in size.
+
+     The strlcpy() function copies up to size - 1 characters from the NUL-ter-
+     minated string src to dst, NUL-terminating the result.
+
+     The strlcat() function appends the NUL-terminated string src to the end
+     of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-
+     nating the result.
+
+RETURN VALUES
+     The strlcpy() and strlcat() functions return the total length of the
+     string they tried to create.  For strlcpy() that means the length of src.
+     For strlcat() that means the initial length of dst plus the length of
+     src. While this may seem somewhat confusing it was done to make trunca-
+     tion detection simple.
+
+EXAMPLES
+     The following code fragment illustrates the simple case:
+
+           char *s, *p, buf[BUFSIZ];
+
+           ...
+
+           (void)strlcpy(buf, s, sizeof(buf));
+           (void)strlcat(buf, p, sizeof(buf));
+
+     To detect truncation, perhaps while building a pathname, something like
+     the following might be used:
+
+           char *dir, *file, pname[MAXPATHNAMELEN];
+
+           ...
+
+           if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
+                   goto toolong;
+           if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
+                   goto toolong;
+
+     Since we know how many characters we copied the first time, we can speed
+     things up a bit by using a copy instead on an append:
+
+           char *dir, *file, pname[MAXPATHNAMELEN];
+           size_t n;
+
+           ...
+
+           n = strlcpy(pname, dir, sizeof(pname));
+           if (n >= sizeof(pname))
+                   goto toolong;
+           if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname)-n)
+                   goto toolong;
+
+     However, one may question the validity of such optimizations, as they de-
+     feat the whole purpose of strlcpy() and strlcat().  As a matter of fact,
+     the first version of this manual page got it wrong.
+
+SEE ALSO
+     snprintf(3),  strncat(3),  strncpy(3)
+
+OpenBSD 2.6                      June 22, 1998                               2
+
+
+-------------------------------------------------------------------------------
+
+Source: OpenBSD 2.6 man pages. Copyright: Portions are copyrighted by BERKELEY
+SOFTWARE DESIGN, INC., The Regents of the University of California,
+Massachusetts Institute of Technology, Free Software Foundation, FreeBSD Inc.,
+and others.
+
+* ************************************************************************** */
+
+
+// copy
+template <class T>
+static inline size_t xstrlcpy(T *o_dest, const T *i_src, size_t i_destSize)
+{
+  T *d = o_dest;
+  const T *s = i_src;
+  size_t n = i_destSize;
+
+  ASSERT( o_dest != NULL );
+  ASSERT( i_src != NULL );
+
+  // Copy as many bytes as will fit
+  if (n != 0 && --n != 0)
+  {
+    do
+    {
+      if ((*d++ = *s++) == 0)
+       break;
+    } while (--n != 0);
+  }
+
+  // Not enough room in o_dest, add NUL and traverse rest of i_src
+  if (n == 0)
+  {
+    if (i_destSize != 0)
+      *d = T();                                        // NUL-terminate o_dest
+    while (*s++)
+      ;
+  }
+
+  return (s - i_src - 1);                      // count does not include NUL
+}
+
+
+// copy
+size_t strlcpy(char *o_dest, const char *i_src, size_t i_destSize)
+{
+  return xstrlcpy(o_dest, i_src, i_destSize);
+}
+
+
+// copy
+size_t wcslcpy(wchar_t *o_dest, const wchar_t *i_src, size_t i_destSize)
+{
+  return xstrlcpy(o_dest, i_src, i_destSize);
+}
+
+
+// copy 
+size_t mbslcpy(unsigned char *o_dest, const unsigned char *i_src,
+              size_t i_destSize)
+{
+  unsigned char *d = o_dest;
+  const unsigned char *s = i_src;
+  size_t n = i_destSize;
+
+  ASSERT( o_dest != NULL );
+  ASSERT( i_src != NULL );
+
+  if (n == 0)
+    return strlen(reinterpret_cast<const char *>(i_src));
+  
+  // Copy as many bytes as will fit
+  for (-- n; *s && 0 < n; -- n)
+  {
+    if (_ismbblead(*s))
+    {
+      if (!(s[1] && 2 <= n))
+       break;
+      *d++ = *s++;
+      -- n;
+    }
+    *d++ = *s++;
+  }
+  *d = '\0';
+
+  for (; *s; ++ s)
+    ;
+  
+  return s - i_src;
+}
+
+
+/// stream output
+tostream &operator<<(tostream &i_ost, const tstringq &i_data)
+{
+  i_ost << _T("\"");
+  for (const _TCHAR *s = i_data.c_str(); *s; ++ s)
+  {
+    switch (*s)
+    {
+      case _T('\a'): i_ost << _T("\\a"); break;
+      case _T('\f'): i_ost << _T("\\f"); break;
+      case _T('\n'): i_ost << _T("\\n"); break;
+      case _T('\r'): i_ost << _T("\\r"); break;
+      case _T('\t'): i_ost << _T("\\t"); break;
+      case _T('\v'): i_ost << _T("\\v"); break;
+      case _T('"'): i_ost << _T("\\\""); break;
+      default:
+       if (_istlead(*s))
+       {
+         _TCHAR buf[3] = { s[0], s[1], 0 };
+         i_ost << buf;
+         ++ s;
+       }
+       else if (_istprint(*s))
+       {
+         _TCHAR buf[2] = { *s, 0 };
+         i_ost << buf;
+       }
+       else
+       {
+         i_ost << _T("\\x");
+         _TCHAR buf[5];
+#ifdef _UNICODE
+         _sntprintf(buf, NUMBER_OF(buf), _T("%04x"), *s);
+#else
+         _sntprintf(buf, NUMBER_OF(buf), _T("%02x"), *s);
+#endif
+         i_ost << buf;
+       }
+       break;
+    }
+  }
+  i_ost << _T("\"");
+  return i_ost;
+}
+
+
+// interpret meta characters such as \n
+tstring interpretMetaCharacters(const _TCHAR *i_str, size_t i_len,
+                               const _TCHAR *i_quote,
+                               bool i_doesUseRegexpBackReference)
+{
+  // interpreted string is always less than i_len
+  Array<_TCHAR> result(i_len + 1);
+  // destination
+  _TCHAR *d = result.get();
+  // end pointer
+  const _TCHAR *end = i_str + i_len;
+  
+  while (i_str < end && *i_str)
+  {
+    if (*i_str != _T('\\'))
+    {
+      if (_istlead(*i_str) && *(i_str + 1) && i_str + 1 < end)
+       *d++ = *i_str++;
+      *d++ = *i_str++;
+    }
+    else if (*(i_str + 1) != _T('\0'))
+    {
+      i_str ++;
+      if (i_quote && _tcschr(i_quote, *i_str))
+       *d++ = *i_str++;
+      else
+       switch (*i_str)
+       {
+         case _T('a'): *d++ = _T('\x07'); i_str ++; break;
+           //case _T('b'): *d++ = _T('\b'); i_str ++; break;
+         case _T('e'): *d++ = _T('\x1b'); i_str ++; break;
+         case _T('f'): *d++ = _T('\f'); i_str ++; break;
+         case _T('n'): *d++ = _T('\n'); i_str ++; break;
+         case _T('r'): *d++ = _T('\r'); i_str ++; break;
+         case _T('t'): *d++ = _T('\t'); i_str ++; break;
+         case _T('v'): *d++ = _T('\v'); i_str ++; break;
+           //case _T('?'): *d++ = _T('\x7f'); i_str ++; break;
+           //case _T('_'): *d++ = _T(' '); i_str ++; break;
+           //case _T('\\'): *d++ = _T('\\'); i_str ++; break;
+         case _T('\''): *d++ = _T('\''); i_str ++; break;
+         case _T('"'): *d++ = _T('"'); i_str ++; break;
+         case _T('\\'): *d++ = _T('\\'); i_str ++; break;
+         case _T('c'): // control code, for example '\c[' is escape: '\x1b'
+           i_str ++;
+           if (i_str < end && *i_str)
+           {
+             static const _TCHAR *ctrlchar =
+               _T("@ABCDEFGHIJKLMNO")
+               _T("PQRSTUVWXYZ[\\]^_")
+               _T("@abcdefghijklmno")
+               _T("pqrstuvwxyz@@@@?");
+             static const _TCHAR *ctrlcode =
+               _T("\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17")
+               _T("\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37")
+               _T("\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17")
+               _T("\20\21\22\23\24\25\26\27\30\31\32\00\00\00\00\177");
+             if (const _TCHAR *c = _tcschr(ctrlchar, *i_str))
+               *d++ = ctrlcode[c - ctrlchar], i_str ++;
+           }
+           break;
+         case _T('x'): case _T('X'):
+         {
+           i_str ++;
+           static const _TCHAR *hexchar = _T("0123456789ABCDEFabcdef");
+           static int hexvalue[] = { 0, 1, 2, 3, 4, 5 ,6, 7, 8, 9,
+                                     10, 11, 12, 13, 14, 15,
+                                     10, 11, 12, 13, 14, 15, };
+           bool brace = false;
+           if (i_str < end && *i_str == _T('{'))
+           {
+             i_str ++;
+             brace = true;
+           }
+           int n = 0;
+           for (; i_str < end && *i_str; i_str ++)
+             if (const _TCHAR *c = _tcschr(hexchar, *i_str))
+               n = n * 16 + hexvalue[c - hexchar];
+             else
+               break;
+           if (i_str < end && *i_str == _T('}') && brace)
+             i_str ++;
+           if (0 < n)
+             *d++ = static_cast<_TCHAR>(n);
+           break;
+         }
+         case _T('1'): case _T('2'): case _T('3'):
+         case _T('4'): case _T('5'): case _T('6'): case _T('7'):
+           if (i_doesUseRegexpBackReference)
+             goto case_default;
+           // fall through
+         case _T('0'):
+         {
+           static const _TCHAR *octalchar = _T("01234567");
+           static int octalvalue[] = { 0, 1, 2, 3, 4, 5 ,6, 7, };
+           int n = 0;
+           for (; i_str < end && *i_str; i_str ++)
+             if (const _TCHAR *c = _tcschr(octalchar, *i_str))
+               n = n * 8 + octalvalue[c - octalchar];
+             else
+               break;
+           if (0 < n)
+             *d++ = static_cast<_TCHAR>(n);
+           break;
+         }
+         default:
+         case_default:
+           *d++ = _T('\\');
+           if (_istlead(*i_str) && *(i_str + 1) && i_str + 1 < end)
+             *d++ = *i_str++;
+           *d++ = *i_str++;
+           break;
+       }
+    }
+  }
+  *d =_T('\0');
+  return result.get();
+}
+
+
+// add session id to i_str
+tstring addSessionId(const _TCHAR *i_str)
+{
+    DWORD sessionId;
+    tstring s(i_str);
+    if (ProcessIdToSessionId(GetCurrentProcessId(), &sessionId)) {
+       _TCHAR buf[20];
+       _sntprintf(buf, NUMBER_OF(buf), _T("%u"), sessionId);
+       s += buf;
+    }
+    return s;
+}
+
+
+#ifdef _MBCS
+// escape regexp special characters in MBCS trail bytes
+std::string guardRegexpFromMbcs(const char *i_str)
+{
+  size_t len = strlen(i_str);
+  Array<char> buf(len * 2 + 1);
+  char *p = buf.get();
+  while (*i_str)
+  {
+    if (_ismbblead(static_cast<u_char>(*i_str)) && i_str[1])
+    {
+      *p ++ = *i_str ++;
+      if (strchr(".*?+(){}[]^$", *i_str))
+       *p ++ = '\\';
+    }
+    *p ++ = *i_str ++;
+  }
+  return std::string(buf.get(), p);
+}
+#endif // !_MBCS
+
+
+// converter
+std::wstring to_wstring(const std::string &i_str)
+{
+  size_t size = mbstowcs(NULL, i_str.c_str(), i_str.size() + 1);
+  if (size == (size_t)-1)
+    return std::wstring();
+  Array<wchar_t> result(size + 1);
+  mbstowcs(result.get(), i_str.c_str(), i_str.size() + 1);
+  return std::wstring(result.get());
+}
+
+
+// converter
+std::string to_string(const std::wstring &i_str)
+{
+  size_t size = wcstombs(NULL, i_str.c_str(), i_str.size() + 1);
+  if (size == (size_t)-1)
+    return std::string();
+  Array<char> result(size + 1);
+  wcstombs(result.get(), i_str.c_str(), i_str.size() + 1);
+  return std::string(result.get());
+}
+
+
+/// stream output
+tostream &operator<<(tostream &i_ost, const tregex &i_data)
+{
+  return i_ost << i_data.str();
+}
+
+
+/// get lower string
+tstring toLower(const tstring &i_str)
+{
+  tstring str(i_str);
+  for (size_t i = 0; i < str.size(); ++ i)
+  {
+    if (_ismbblead(str[i]))
+      ++ i;
+    else
+      str[i] = tolower(str[i]);
+  }
+  return str;
+}
+
+
+// convert wstring to UTF-8
+std::string to_UTF_8(const std::wstring &i_str)
+{
+  // 0xxxxxxx: 00-7F
+  // 110xxxxx 10xxxxxx: 0080-07FF
+  // 1110xxxx 10xxxxxx 10xxxxxx: 0800 - FFFF
+
+  int size = 0;
+  
+  // count needed buffer size
+  for (std::wstring::const_iterator i = i_str.begin(); i != i_str.end(); ++ i)
+  {
+    if (0x0000 <= *i && *i <= 0x007f)
+      size += 1;
+    else if (0x0080 <= *i && *i <= 0x07ff)
+      size += 2;
+    else if (0x0800 <= *i && *i <= 0xffff)
+      size += 3;
+  }
+
+  Array<char> result(size);
+  int ri = 0;
+  
+  // make UTF-8
+  for (std::wstring::const_iterator i = i_str.begin(); i != i_str.end(); ++ i)
+  {
+    if (0x0000 <= *i && *i <= 0x007f)
+      result[ri ++] = static_cast<char>(*i);
+    else if (0x0080 <= *i && *i <= 0x07ff)
+    {
+      result[ri ++] = static_cast<char>(((*i & 0x0fc0) >>  6) | 0xc0);
+      result[ri ++] = static_cast<char>(( *i & 0x003f       ) | 0x80);
+    }
+    else if (0x0800 <= *i && *i <= 0xffff)
+    {
+      result[ri ++] = static_cast<char>(((*i & 0xf000) >> 12) | 0xe0);
+      result[ri ++] = static_cast<char>(((*i & 0x0fc0) >>  6) | 0x80);
+      result[ri ++] = static_cast<char>(( *i & 0x003f       ) | 0x80);
+    }
+  }
+
+  return std::string(result.begin(), result.end());
+}
diff --git a/stringtool.h b/stringtool.h
new file mode 100644 (file)
index 0000000..250e023
--- /dev/null
@@ -0,0 +1,192 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// stringtool.h
+
+
+#ifndef _STRINGTOOL_H
+#  define _STRINGTOOL_H
+
+#  include "misc.h"
+#  include <tchar.h>
+#  include <cctype>
+#  include <string>
+#  include <iosfwd>
+#  include <boost/regex.hpp>
+#  include <stdio.h>                           // for snprintf
+
+
+/// string for generic international text
+typedef std::basic_string<_TCHAR> tstring;
+/// istream for generic international text
+typedef std::basic_istream<_TCHAR> tistream;
+/// ostream for generic international text
+typedef std::basic_ostream<_TCHAR> tostream;
+/// streambuf for for generic international text
+typedef std::basic_streambuf<_TCHAR> tstreambuf;
+/// stringstream for generic international text
+typedef std::basic_stringstream<_TCHAR> tstringstream;
+/// ifstream for generic international text
+typedef std::basic_ifstream<_TCHAR> tifstream;
+/// basic_regex for generic international text
+typedef boost::basic_regex<_TCHAR> tregex;
+/// match_results for generic international text
+typedef boost::match_results<tstring::const_iterator> tsmatch;
+
+
+/// string with custom stream output
+class tstringq : public tstring
+{
+public:
+  ///
+  tstringq() { }
+  ///
+  tstringq(const tstringq &i_str) : tstring(i_str) { }
+  ///
+  tstringq(const tstring &i_str) : tstring(i_str) { }
+  ///
+  tstringq(const _TCHAR *i_str) : tstring(i_str) { }
+  ///
+  tstringq(const _TCHAR *i_str, size_t i_n) : tstring(i_str, i_n) { }
+  ///
+  tstringq(const _TCHAR *i_str, size_t i_pos, size_t i_n)
+    : tstring(i_str, i_pos, i_n) { }
+  ///
+  tstringq(size_t i_n, _TCHAR i_c) : tstring(i_n, i_c) { }
+};
+
+
+/// stream output
+extern tostream &operator<<(tostream &i_ost, const tstringq &i_data);
+
+
+/// interpret meta characters such as \n
+tstring interpretMetaCharacters(const _TCHAR *i_str, size_t i_len,
+                               const _TCHAR *i_quote = NULL,
+                               bool i_doesUseRegexpBackReference = false);
+
+/// add session id to i_str
+tstring addSessionId(const _TCHAR *i_str);
+
+/// copy
+size_t strlcpy(char *o_dest, const char *i_src, size_t i_destSize);
+/// copy
+size_t mbslcpy(unsigned char *o_dest, const unsigned char *i_src,
+              size_t i_destSize);
+/// copy
+size_t wcslcpy(wchar_t *o_dest, const wchar_t *i_src, size_t i_destSize);
+/// copy
+inline size_t tcslcpy(char *o_dest, const char *i_src, size_t i_destSize)
+{ return strlcpy(o_dest, i_src, i_destSize); }
+/// copy
+inline size_t tcslcpy(unsigned char *o_dest, const unsigned char *i_src,
+                     size_t i_destSize)
+{ return mbslcpy(o_dest, i_src, i_destSize); }
+/// copy
+inline size_t tcslcpy(wchar_t *o_dest, const wchar_t *i_src, size_t i_destSize)
+{ return wcslcpy(o_dest, i_src, i_destSize); }
+
+// escape regexp special characters in MBCS trail bytes
+std::string guardRegexpFromMbcs(const char *i_str);
+/// converter
+std::wstring to_wstring(const std::string &i_str);
+/// converter
+std::string to_string(const std::wstring &i_str);
+// convert wstring to UTF-8
+std::string to_UTF_8(const std::wstring &i_str);
+
+  
+/// case insensitive string
+class tstringi : public tstring
+{
+public:
+  ///
+  tstringi() { }
+  ///
+  tstringi(const tstringi &i_str) : tstring(i_str) { }
+  ///
+  tstringi(const tstring &i_str) : tstring(i_str) { }
+  ///
+  tstringi(const _TCHAR *i_str) : tstring(i_str) { }
+  ///
+  tstringi(const _TCHAR *i_str, size_t i_n) : tstring(i_str, i_n) { }
+  ///
+  tstringi(const _TCHAR *i_str, size_t i_pos, size_t i_n)
+    : tstring(i_str, i_pos, i_n) { }
+  ///
+  tstringi(size_t i_n, _TCHAR i_c) : tstring(i_n, i_c) { }
+  ///
+  int compare(const tstringi &i_str) const
+  { return compare(i_str.c_str()); }
+  ///
+  int compare(const tstring &i_str) const
+  { return compare(i_str.c_str()); }
+  ///
+  int compare(const _TCHAR *i_str) const
+  { return _tcsicmp(c_str(), i_str); }
+  ///
+  tstring &getString() { return *this; }
+  ///
+  const tstring &getString() const { return *this; }
+};
+
+/// case insensitive string comparison
+inline bool operator<(const tstringi &i_str1, const _TCHAR *i_str2)
+{ return i_str1.compare(i_str2) < 0; }
+/// case insensitive string comparison
+inline bool operator<(const _TCHAR *i_str1, const tstringi &i_str2)
+{ return 0 < i_str2.compare(i_str1); }
+/// case insensitive string comparison
+inline bool operator<(const tstringi &i_str1, const tstring &i_str2)
+{ return i_str1.compare(i_str2) < 0; }
+/// case insensitive string comparison
+inline bool operator<(const tstring &i_str1, const tstringi &i_str2)
+{ return 0 < i_str2.compare(i_str1); }
+/// case insensitive string comparison
+inline bool operator<(const tstringi &i_str1, const tstringi &i_str2)
+{ return i_str1.compare(i_str2) < 0; }
+
+/// case insensitive string comparison
+inline bool operator==(const _TCHAR *i_str1, const tstringi &i_str2)
+{ return i_str2.compare(i_str1) == 0; }
+/// case insensitive string comparison
+inline bool operator==(const tstringi &i_str1, const _TCHAR *i_str2)
+{ return i_str1.compare(i_str2) == 0; }
+/// case insensitive string comparison
+inline bool operator==(const tstring &i_str1, const tstringi &i_str2)
+{ return i_str2.compare(i_str1) == 0; }
+/// case insensitive string comparison
+inline bool operator==(const tstringi &i_str1, const tstring &i_str2)
+{ return i_str1.compare(i_str2) == 0; }
+/// case insensitive string comparison
+inline bool operator==(const tstringi &i_str1, const tstringi &i_str2)
+{ return i_str1.compare(i_str2) == 0; }
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// workarounds for Borland C++
+
+
+/// case insensitive string comparison
+inline bool operator!=(const _TCHAR *i_str1, const tstringi &i_str2)
+{ return i_str2.compare(i_str1) != 0; }
+/// case insensitive string comparison
+inline bool operator!=(const tstringi &i_str1, const _TCHAR *i_str2)
+{ return i_str1.compare(i_str2) != 0; }
+/// case insensitive string comparison
+inline bool operator!=(const tstring &i_str1, const tstringi &i_str2)
+{ return i_str2.compare(i_str1) != 0; }
+/// case insensitive string comparison
+inline bool operator!=(const tstringi &i_str1, const tstring &i_str2)
+{ return i_str1.compare(i_str2) != 0; }
+/// case insensitive string comparison
+inline bool operator!=(const tstringi &i_str1, const tstringi &i_str2)
+{ return i_str1.compare(i_str2) != 0; }
+
+
+/// stream output
+extern tostream &operator<<(tostream &i_ost, const tregex &i_data);
+
+/// get lower string
+extern tstring toLower(const tstring &i_str);
+
+
+#endif // !_STRINGTOOL_H
diff --git a/target.cpp b/target.cpp
new file mode 100644 (file)
index 0000000..66f9ae2
--- /dev/null
@@ -0,0 +1,232 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// target.cpp
+
+
+#include "misc.h"
+
+#include "mayurc.h"
+#include "target.h"
+#include "windowstool.h"
+
+
+///
+class Target
+{
+  HWND m_hwnd;                                 ///
+  HWND m_preHwnd;                              ///
+  HICON m_hCursor;                             ///
+
+  ///
+  static void invertFrame(HWND i_hwnd)
+  {
+    HDC hdc = GetWindowDC(i_hwnd);
+    ASSERT(hdc);
+    int rop2 = SetROP2(hdc, R2_XORPEN);
+    if (rop2)
+    {
+      RECT rc;
+      CHECK_TRUE( GetWindowRect(i_hwnd, &rc) );
+      int width = rcWidth(&rc);
+      int height = rcHeight(&rc);
+    
+      HANDLE hpen = SelectObject(hdc, GetStockObject(WHITE_PEN));
+      HANDLE hbr  = SelectObject(hdc, GetStockObject(NULL_BRUSH));
+      CHECK_TRUE( Rectangle(hdc, 0, 0, width    , height    ) );
+      CHECK_TRUE( Rectangle(hdc, 1, 1, width - 1, height - 1) );
+      CHECK_TRUE( Rectangle(hdc, 2, 2, width - 2, height - 2) );
+      SelectObject(hdc, hpen);
+      SelectObject(hdc, hbr);
+      // no need to DeleteObject StockObject
+      SetROP2(hdc, rop2);
+    }
+    CHECK_TRUE( ReleaseDC(i_hwnd, hdc) );
+  }
+  
+  ///
+  Target(HWND i_hwnd)
+    : m_hwnd(i_hwnd),
+      m_preHwnd(NULL),
+      m_hCursor(NULL)
+  {
+  }
+
+  /// WM_CREATE
+  int wmCreate(CREATESTRUCT * /* i_cs */)
+  {
+    CHECK_TRUE( m_hCursor =
+               LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_CURSOR_target)) );
+    return 0;
+  }
+
+  /// WM_PAINT
+  int wmPaint()
+  {
+    PAINTSTRUCT ps;
+    HDC hdc = BeginPaint(m_hwnd, &ps);
+    ASSERT(hdc);
+
+    if (GetCapture() != m_hwnd)
+    {
+      RECT rc;
+      CHECK_TRUE( GetClientRect(m_hwnd, &rc) );
+      CHECK_TRUE(
+       DrawIcon(hdc, (rcWidth(&rc) - GetSystemMetrics(SM_CXICON)) / 2,
+                (rcHeight(&rc) - GetSystemMetrics(SM_CYICON)) / 2,
+                m_hCursor) );
+    }
+    
+    EndPaint(m_hwnd, &ps);
+    return 0;
+  }
+
+  ///
+  struct PointWindow
+  {
+    POINT m_p;                                 ///
+    HWND m_hwnd;                               ///
+    RECT m_rc;                                 ///
+  };
+  
+  ///
+  static BOOL CALLBACK childWindowFromPoint(HWND i_hwnd, LPARAM i_lParam)
+  {
+    if (IsWindowVisible(i_hwnd))
+    {
+      PointWindow &pw = *(PointWindow *)i_lParam;
+      RECT rc;
+      CHECK_TRUE( GetWindowRect(i_hwnd, &rc) );
+      if (PtInRect(&rc, pw.m_p))
+       if (isRectInRect(&rc, &pw.m_rc))
+       {
+         pw.m_hwnd = i_hwnd;
+         pw.m_rc = rc;
+       }
+    }
+    return TRUE;
+  }
+  
+  ///
+  static BOOL CALLBACK windowFromPoint(HWND i_hwnd, LPARAM i_lParam)
+  {
+    if (IsWindowVisible(i_hwnd))
+    {
+      PointWindow &pw = *(PointWindow *)i_lParam;
+      RECT rc;
+      CHECK_TRUE( GetWindowRect(i_hwnd, &rc) );
+      if (PtInRect(&rc, pw.m_p))
+      {
+       pw.m_hwnd = i_hwnd;
+       pw.m_rc = rc;
+       return FALSE;
+      }
+    }
+    return TRUE;
+  }
+
+  /// WM_MOUSEMOVE
+  int wmMouseMove(WORD /* i_keys */, int /* i_x */, int /* i_y */)
+  {
+    if (GetCapture() == m_hwnd)
+    {
+      PointWindow pw;
+      CHECK_TRUE( GetCursorPos(&pw.m_p) );
+      pw.m_hwnd = 0;
+      CHECK_TRUE( GetWindowRect(GetDesktopWindow(), &pw.m_rc) );
+      EnumWindows(windowFromPoint, (LPARAM)&pw);
+      while (1)
+      {
+       HWND hwndParent = pw.m_hwnd;
+       if (!EnumChildWindows(pw.m_hwnd, childWindowFromPoint, (LPARAM)&pw))
+         break;
+       if (hwndParent == pw.m_hwnd)
+         break;
+      }
+      if (pw.m_hwnd != m_preHwnd)
+      {
+       if (m_preHwnd)
+         invertFrame(m_preHwnd);
+       m_preHwnd = pw.m_hwnd;
+       invertFrame(m_preHwnd);
+       SendMessage(GetParent(m_hwnd), WM_APP_targetNotify, 0,
+                   (LPARAM)m_preHwnd);
+      }
+      SetCursor(m_hCursor);
+    }
+    return 0;
+  }
+
+  /// WM_LBUTTONDOWN
+  int wmLButtonDown(WORD /* i_keys */, int /* i_x */, int /* i_y */)
+  {
+    SetCapture(m_hwnd);
+    SetCursor(m_hCursor);
+    CHECK_TRUE( InvalidateRect(m_hwnd, NULL, TRUE) );
+    CHECK_TRUE( UpdateWindow(m_hwnd) );
+    return 0;
+  }
+
+  /// WM_LBUTTONUP
+  int wmLButtonUp(WORD /* i_keys */, int /* i_x */, int /* i_y */)
+  {
+    if (m_preHwnd)
+      invertFrame(m_preHwnd);
+    m_preHwnd = NULL;
+    ReleaseCapture();
+    CHECK_TRUE( InvalidateRect(m_hwnd, NULL, TRUE) );
+    CHECK_TRUE( UpdateWindow(m_hwnd) );
+    return 0;
+  }
+
+public:
+  ///
+  static LRESULT CALLBACK WndProc(HWND i_hwnd, UINT i_message,
+                                 WPARAM i_wParam, LPARAM i_lParam)
+  {
+    Target *wc;
+    getUserData(i_hwnd, &wc);
+    if (!wc)
+      switch (i_message)
+      {
+       case WM_CREATE:
+         wc = setUserData(i_hwnd, new Target(i_hwnd));
+         return wc->wmCreate((CREATESTRUCT *)i_lParam);
+      }
+    else 
+      switch (i_message)
+      {
+       case WM_PAINT:
+         return wc->wmPaint();
+       case WM_LBUTTONDOWN:
+         return wc->wmLButtonDown((WORD)i_wParam, (short)LOWORD(i_lParam),
+                                  (short)HIWORD(i_lParam));
+       case WM_LBUTTONUP:
+         return wc->wmLButtonUp((WORD)i_wParam, (short)LOWORD(i_lParam),
+                                (short)HIWORD(i_lParam));
+       case WM_MOUSEMOVE:
+         return wc->wmMouseMove((WORD)i_wParam, (short)LOWORD(i_lParam),
+                                (short)HIWORD(i_lParam));
+       case WM_NCDESTROY:
+         delete wc;
+         return 0;
+      }
+    return DefWindowProc(i_hwnd, i_message, i_wParam, i_lParam);
+  }
+};
+  
+
+//
+ATOM Register_target()
+{
+  WNDCLASS wc;
+  wc.style         = CS_HREDRAW | CS_VREDRAW;
+  wc.lpfnWndProc   = Target::WndProc;
+  wc.cbClsExtra    = 0;
+  wc.cbWndExtra    = 0;
+  wc.hInstance     = g_hInst;
+  wc.hIcon         = NULL;
+  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
+  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+  wc.lpszMenuName  = NULL;
+  wc.lpszClassName = _T("mayuTarget");
+  return RegisterClass(&wc);
+}
diff --git a/target.h b/target.h
new file mode 100644 (file)
index 0000000..e270b9a
--- /dev/null
+++ b/target.h
@@ -0,0 +1,22 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// target.h
+
+
+#ifndef _TARGET_H
+#  define _TARGET_H
+
+#  include <windows.h>
+
+
+///
+extern ATOM Register_target();
+
+///
+enum
+{
+  ///
+  WM_APP_targetNotify = WM_APP + 102,
+};
+
+
+#endif // !_TARGET_H
diff --git a/tools/checkversion b/tools/checkversion
new file mode 100755 (executable)
index 0000000..76b3eab
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/perl -w
+
+if ( $#ARGV < 0 ) {
+  print <<'__EOM__';
+usage: checkversion FILENAME.EXE [EXCLUDE_TEXT]
+example:
+       C:> tools/checkversion mayu.exe "Windows 95 or later"
+       This outputs imported APIs that are not supported on Windows 95.
+required:      
+       DUMPBIN.EXE
+       %MSDevDir%\..\..\VC98\Lib\/WIN32API.CSV
+__EOM__
+  exit(1);
+}
+
+open(IMPORTS, "dumpbin.exe -imports $ARGV[0]|") || die;
+
+while (<IMPORTS>) {
+  chomp;
+  if ( /^\s+\S+\s+(\S+)$/ ) {
+    my ($name) = $1;
+    $IMPORTS{$name} = 1;
+    if ( $name =~ /(U|A)$/ ) {
+      chop($name);
+      $IMPORTS{$name} = 1;
+    }
+  }
+}
+
+open(WIN32API, "<$ENV{MSDevDir}/../../VC98/Lib/WIN32API.CSV") || die;
+
+$items = <WIN32API>;
+chomp($items);
+@items = split(/,/, $items);
+
+while (<WIN32API>) {
+  chomp;
+  my (@API) = split(/,/, $_);
+  if ( $IMPORTS{$API[0]} ) {
+
+    next if ( 1 <= $#ARGV && /$ARGV[1]/ ); # filter by $ARGV[1];
+    
+    my ($i);
+    for ($i = 0; $i <= $#items; ++ $i) {
+      printf('%-20s%s' . "\n", $items[$i] . ":", $API[$i]);
+    }
+    print "\n";
+  }
+}
diff --git a/tools/dos2unix b/tools/dos2unix
new file mode 100755 (executable)
index 0000000..3129fcb
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/local/bin/perl -w
+# -*- cperl -*-
+
+binmode STDIN;
+binmode STDOUT;
+
+foreach $i ( @ARGV ) {
+  open (FILE, "<$i");
+  binmode FILE;
+  @lines = <FILE>;
+  close (FILE);
+  
+  open (FILE, ">$i");
+  binmode FILE;
+  foreach $j ( @lines ) {
+    $j =~ s/\x0d\x0a/\x0a/g;
+    print FILE $j;
+  }
+  close (FILE);
+}
diff --git a/tools/geniexpress b/tools/geniexpress
new file mode 100755 (executable)
index 0000000..c10052f
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/perl -w
+
+if ( $#ARGV < 3 ) {
+  printf("usage: geniexpress SFX.EXE TITLE SETUP.EXE [Files...]\n");
+  exit(1);
+}
+
+$TargetName   = shift @ARGV;
+$FriendlyName = shift @ARGV;
+$AppLaunched  = shift @ARGV;
+
+$template = <<"__EOM__";
+[Version]
+Class=IEXPRESS
+SEDVersion=3
+
+[Options]
+PackagePurpose=InstallApp
+ShowInstallProgramWindow=0
+HideExtractAnimation=0
+UseLongFileName=1
+InsideCompressed=0
+CAB_FixedSize=0
+CAB_ResvCodeSigning=0
+RebootMode=N
+InstallPrompt=
+DisplayLicense=
+FinishMessage=
+TargetName=$TargetName
+FriendlyName=$FriendlyName
+AppLaunched=$AppLaunched
+PostInstallCmd=<None>
+AdminQuietInstCmd=
+UserQuietInstCmd=
+SourceFiles=SourceFiles
+
+[SourceFiles]
+SourceFiles0=.\\
+
+[SourceFiles0]
+__EOM__
+
+foreach $i ( sort @ARGV ) {
+  $template .= "$i=\n";
+}
+print $template;
diff --git a/tools/getcvsfiles b/tools/getcvsfiles
new file mode 100755 (executable)
index 0000000..0b7fd63
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/perl -w
+
+#
+# print filenames existing in CVS Repository
+#
+
+sub getcvsfiles {
+  my ($dir) = @_;
+  return if (! -d $dir);       # empty directory 
+  open(CVS_Entries, "<$dir/CVS/Entries") || die;
+  my (@lines) = <CVS_Entries>;
+  close(CVS_Entries);
+  my ($i);
+  foreach $i ( @lines ) {
+    if ( $i =~ /dummy timestamp/) { # removed file
+    } elsif ( $i =~ m:^D/([^/]*)/: ) {
+      &getcvsfiles("$dir/$1");
+    } elsif ( $i =~ m:^/([^/]*)/: ) {
+      $files{"$dir/$1"} = 1;
+    }
+  }
+}
+
+getcvsfiles(".");
+
+foreach $i ( sort keys %files ) {
+  print $i . "\n";
+}
diff --git a/tools/linkcheck b/tools/linkcheck
new file mode 100755 (executable)
index 0000000..0d0d1f2
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/perl
+
+# HTML local link checker
+# usage: linkcheck ../doc/*.html
+
+my %HREF_EXTERNAL;
+my %HREF_LOCAL_FILE;
+my %HREF_LOCAL;
+my %NAME;
+
+foreach $i ( @ARGV ) {
+  open(FILE, "<$i");
+  $NAME{"$i"} = 1;
+  $NAME{"$i#"} = 1;
+  while (<FILE>) {
+    chomp;
+    while (/href\s*?=\s*?"([^"]*)"/ig) {
+      my $href = $1;
+      if ($href =~ /^\w+:/) {
+       $HREF_EXTERNAL{"$href"} = 1;
+      } elsif ($href =~ /^#/) {
+       $HREF_LOCAL{"$i$href"} = 1;
+      } elsif ($href =~ /html$/ || $href =~ /html#/) {
+       $HREF_LOCAL{"$href"} = 1;
+      } else {
+       $HREF_LOCAL_FILE{"$href"} = 1;
+      }
+    }
+    while (/name\s*?=\s*?"([^"]*)"/ig) {
+      $NAME{"$i#$1"} = 1;
+    }
+  }
+}
+
+foreach $i ( sort keys %HREF_EXTERNAL ) {
+  print "external: $i\n";
+}
+
+foreach $i ( sort keys %HREF_LOCAL_FILE ) {
+  if (-f $i) {
+    print "file: $i\n";
+  } else {
+    print "missing: $i\n";
+  }
+}
+
+foreach $i ( sort keys %HREF_LOCAL ) {
+  if ($NAME{$i}) {
+    print "local: $i\n";
+  } else {
+    print "missing: $i\n";
+  }
+}
diff --git a/tools/makedepend b/tools/makedepend
new file mode 100755 (executable)
index 0000000..15c1548
--- /dev/null
@@ -0,0 +1,669 @@
+#!/usr/local/bin/perl -w
+# -*- cperl -*-
+
+###############################################################################
+#
+#
+#                      Makedepend 0.05
+#
+#
+#  1. What is different form the X11 makedepend ?
+#
+#      * This works on ANY platform which has perl, for instance on
+#        Windows.
+#      * This works for ANY compilers / preprocessors.
+#      * This can eliminate the system include headers like gcc -MM.
+#      * Some options are omittid (-m, -v, -Y).
+#
+#  2. How to customize makedepend for your preprocessor ?
+#
+#      0. for gcc, no problem!
+#         for g++, use --cpp=g++ option.
+#         for Visual C++, use --cpp=vc -o.obj option.
+#         for Borland C++ 5.5, use --cpp=bcc32 -o.obj option
+#           (but it is too slow to use)
+#         for other compilers/preprocessors, read next.
+#
+#      1. search CUSTOMIZABLE1 in this file.
+#
+#      2. cusomize $commandline, $line, $path_delimiter for your
+#         preprocessor.
+#
+#      3. if you know how to get the system include directory from
+#         your preprocessor, customize @OPTION_IGNORE in the
+#         CUSTOMIZABLE2 section in this file.
+#
+#  3. History
+#
+#      2001/08/08 version 0.05
+#              * First, Makefile.new is created, then Makefile is
+#                renamed to Makefile.bak, and Makefile.new is renamed
+#                to Makefile.  (Thanks to Marvin Wolfthal)
+#
+#      2000/11/10 version 0.04
+#              * now dir/.. is eliminated.
+#              * --abosolute added.
+#              * --path-delimiter added.
+#              * --cpp-bin added.
+#
+#      2000/10/31 version 0.03
+#      2000/10/30 version 0.02
+#      2000/04/12 version 0.01
+#              
+#  4. Copyright
+#
+#      Copyright (c) 1998-2000 TAGA Nayuta <nayuta@ganaware.org>
+#      All rights reserved.
+#
+#      Redistribution and use in source and binary forms, with or
+#      without modification, are permitted provided that the
+#      following conditions are met:
+#      1. Redistributions of source code must retain the above
+#         copyright notice, this list of conditions and the following
+#         disclaimer.
+#      2. Redistributions in binary form must reproduce the above
+#         copyright notice, this list of conditions and the following
+#         disclaimer in the documentation and/or other materials
+#         provided with the distribution.
+#      3. The name of the author may not be used to endorse or
+#         promote products derived from this software without
+#         specific prior written permission.
+#
+#      THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+#      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+#      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+#      PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+#      AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#      SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+#      NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+#      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+#      HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+#      CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#      OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+#      EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#
+###############################################################################
+
+use Cwd;
+use File::Spec;
+
+sub usage {
+  print <<'__EOM__'
+Usage: makedepend [OPTION]... <SRCS>...
+Make dependency informations for Makefile on ANY platform.
+
+-a
+       Append the dependencies to the end of the file instead of
+       replacing them.
+
+-f<MAKEFILE>
+       Filename.  This allows you to specify an alternate makefile in
+       which makedepend can place its output.  Specifying "-" as the
+       file name (i.e., -f-) sends the output to standard output
+       instead of modifying an existing file.  The default is
+       "Makefile".
+
+-o<OBJSUFFIX>
+       Object file suffix.  Some systems may have object files whose
+       suffix is something other than ".o".  This option allows you
+       to specify another suffix, such as ".obj" with -o.obj and so
+       forth.
+
+-p<OBJPREFIX>
+       Object file prefix.  The prefix is prepended to the name of
+       the object file.  This is usually used to designate a
+       different directory for the object file.  The default is the
+       empty string.
+
+-s<STRING>
+       Starting string delimiter.  This option permits you to specify
+       a different string for makedepend to look for in the makefile.
+       The default is "# DO NOT DELETE".
+
+-w<WIDTH>
+       Line width.  Normally, makedepend will ensure that every
+       output line that it writes will be no wider than 78 characters
+       for the sake of readability.  This option enables you to
+       change this width.
+
+-- [OPTION]... --
+       If makedepend encounters a double hyphen (--) in the argument
+       list, then any unrecognized argument following it will be
+       silently ignored; a second double hyphen terminates this
+       special treatment.  In this way, makedepend can be made to
+       safely ignore esoteric compiler arguments that might normally
+       be found in a CFLAGS make macro.  All options that makedepend
+       recognizes and appear between the pair of double hyphens are
+       processed normally.
+
+--cpp=<PREPROCESSORTYPE>
+       The preprocessor type.
+       Currently supported <PREPROCESSORTYPES>s are:
+               gcc   ... it uses gcc with -E (default).
+               g++   ... it uses g++ with -E.
+               vc    ... it uses cl.exe with -E.
+               bcc32 ... it uses cpp32.exe with -ocon (too slow).
+
+--cpp-bin=<PREPROCESSORPATH>
+       The preprocessor executable file name.
+       The default depends on --cpp.
+
+--ignore=<INCLUDEPATH>
+       A list of default include pathes separated by ";".  Makedepend
+       ignores header files in the default include pathes as if a
+       source had no dependency on them.  Currently the default is
+       the system include directories if PREPROCESSORTYPE is gcc, g++
+       or vc.  However it is empty PREPROCESSORTYPE is bcc32.  If you
+       don't want to ignore the system include directories but
+       INCLUDEPATH, specify --ignore= --ignore=<INCLUDEPATH>.
+
+--newline=<NEWLINE>
+       Newline code.  If NEWLINE is:
+               unix ... 0x0a (unix default).
+               dos  ... 0x0d 0x0a (windows default).
+               mac  ... 0x0d .
+
+--path-delimiter=<PATH_DELIMITER>
+       Output path delimiter.
+               unix ... '/' (default)
+               os   ... os default
+               dos  ... '\'
+               dosq ... '\\'
+
+--absolute
+       Makedepend output filenames by relative directory from current
+       directory.  If you prefer absolute directory, specify this
+       option.  This option affect only #include <...>.
+
+--verbose[=LEVEL]
+       0, 1 or 2.  The default LEVEL is 1.
+
+-D<NAME>=<DEF> or -D<NAME> or -I<INCLUDEDIR>
+       They are simply passed to the preprocessor.
+
+-m or -v or -Y<INCLUDEDIR>
+       They are ignored.
+
+Copyright (c) 1998-2000 TAGA Nayuta <nayuta@ganaware.org>
+__EOM__
+  ;
+  exit;
+}
+
+
+###############################################################################
+# system configuration
+
+# Is using Windows ?
+$isActivePerlWindows = $^O eq "MSWin32";
+$isCygwin = $^O eq "cygwin";
+$isWindows = $isActivePerlWindows || $isCygwin;
+
+# Does ignore case of filename ?
+$ignoreCase = $isWindows;
+
+# null device filename
+if ( $isActivePerlWindows ) {
+  $nullDevice = "nul";
+} else {
+  $nullDevice = "/dev/null";
+}
+
+
+###############################################################################
+# options
+
+# -a
+$OPTION_APPEND = 0;
+
+# -f
+$OPTION_FILENAME = "Makefile";
+
+# -o
+$OPTION_SUFFIX = ".o";
+
+# -p
+$OPTION_PREFIX = "";
+
+# -s
+$OPTION_STRING = "# DO NOT DELETE";
+
+# -w
+$OPTION_WIDTH = 78;
+
+# --cpp
+$OPTION_CPP = "gcc";
+
+# --cpp-bin
+$OPTION_CPP_BIN = "";
+
+# newline code (--newline select this value)
+$OPTION_NEWLINE = $isActivePerlWindows ? "\x0d\x0a" : "\x0a";
+
+# path delimiter (--path-delimiter select this value)
+$OPTION_PATH_DELIMITER = "/";
+
+# --verbose
+$OPTION_VERBOSE = 0;
+
+# --absolute
+$OPTION_ABSOLUTE = 0;
+
+# options passed to preprocessor
+@OPTION_OPTIONS = ();
+
+# ignored include path
+@OPTION_IGNORE = ();
+
+# source filenames
+@OPTION_SRCS = ();
+
+# ignore system include directories ?
+$ignoreSystemIncludeDirectories = 0;
+
+
+###############################################################################
+# parse options
+
+$isInMixed = 0;                        # is in -- <OPTIONS> -- ?
+
+foreach $i ( @ARGV ) {
+  if ( $i =~ /^-a(.*)$/ ) {
+    $OPTION_APPEND = 1;
+    
+  } elsif ( $i =~ /^-f(.*)$/ ) {
+    $OPTION_FILENAME = $1;
+
+  } elsif ( $i =~ /^-o(.*)$/ ) {
+    $OPTION_SUFFIX = $1;
+
+  } elsif ( $i =~ /^-p(.*)$/ ) {
+    $OPTION_PREFIX = $1;
+
+  } elsif ( $i =~ /^-s(.*)$/ ) {
+    $OPTION_STRING = $1;
+
+  } elsif ( $i =~ /^-w(.*)$/ ) {
+    $OPTION_WIDTH = $1;
+
+  } elsif ( $i =~ /^--$/ ) {
+    $isInMixed = 1 - $isInMixed;
+
+  } elsif ( $i =~ /^--cpp=(.*)$/ ) {
+    $OPTION_CPP = $1;
+
+  } elsif ( $i =~ /^--cpp-bin=(.*)$/ ) {
+    $OPTION_CPP_BIN = $1;
+
+  } elsif ( $i =~ /^--ignore=$/ ) {
+    $ignoreSystemIncludeDirectories = 1;
+    @OPTION_IGNORE = ();
+
+  } elsif ( $i =~ /^--ignore=(.*)$/ ) {
+    &parseIgnore($1);
+
+  } elsif ( $i =~ /^--newline=(.*)$/ ) {
+    if ( $1 eq "unix" ) {
+      $OPTION_NEWLINE = "\x0a";
+    } elsif ( $1 eq "dos" ) {
+      $OPTION_NEWLINE = "\x0d\x0a";
+    } elsif ( $1 eq "mac" ) {
+      $OPTION_NEWLINE = "\x0d";
+    } else {
+      &usage;
+    }
+
+  } elsif ( $i =~ /^--path-delimiter=(.*)$/ ) {
+    if ( $1 eq "unix" ) {
+      $OPTION_PATH_DELIMITER = "/";
+    } elsif ( $1 eq "os" ) {
+      $OPTION_PATH_DELIMITER = $isActivePerlWindows ? "\\" : "/";
+    } elsif ( $1 eq "dos" ) {
+      $OPTION_PATH_DELIMITER = "\\";
+    } elsif ( $1 eq "dosq" ) {
+      $OPTION_PATH_DELIMITER = "\\\\";
+    } else {
+      &usage;
+    }
+
+  } elsif ( $i =~ /^--verbose$/ ) {
+    $OPTION_VERBOSE = 1;
+
+  } elsif ( $i =~ /^--verbose=(\d+)$/ ) {
+    $OPTION_VERBOSE = $1;
+
+  } elsif ( $i =~ /^--absolute$/ ) {
+    $OPTION_ABSOLUTE = 1;
+
+  } elsif ( $i =~ /^-[DI]/ ) {
+    push(@OPTION_OPTIONS, $i);
+
+  } elsif ( $i =~ /^(-m|-v|-Y.*)$/ ) {
+    # ignored
+
+  } else {
+    if ( $isInMixed ) {
+      push(@OPTION_OPTIONS, $i);
+
+    } elsif ( $i =~ /^-/ ) {
+      &usage;
+
+    } else {
+      push(@OPTION_SRCS, &reduceDirectory($i));
+    }
+  }
+}
+
+&usage if ( @OPTION_SRCS == 0 );
+
+
+###############################################################################
+# CUSTOMIZABLE1: select preprocessor and set $IGNORE
+
+# $commandline
+#      It executes a C/C++ preprocessor.  The preprocessed source
+#      code must be printed to the stdout.
+
+# $line
+#      It is a regexp to retrieve included filename from preprocessor
+#      output.  $1 must be a filename.
+
+# $path_delimiter
+#      $1 of $line is separated by this $path_delimiter.  Makedepend
+#      automatically replaces it with '/'.
+
+if ( $OPTION_CPP =~ /^(gcc|g\+\+)$/ ) {
+  $OPTION_CPP_BIN = $OPTION_CPP unless ( $OPTION_CPP_BIN );
+  $commandline = $OPTION_CPP_BIN . " -E ";
+  $line = '^# \\d+ "(.*)"';
+  # $path_delimiter = '/';     # default
+  
+} elsif ( $OPTION_CPP eq "vc" ) {
+  $OPTION_CPP_BIN = "cl.exe" unless ( $OPTION_CPP_BIN );
+  $commandline = $OPTION_CPP_BIN . " -E -nologo ";
+  $line = '^#line \\d+ "(.*)"';
+  $path_delimiter = '\\\\';
+
+} elsif ( $OPTION_CPP eq "bcc32" ) {
+  $OPTION_CPP_BIN = "cpp32.exe" unless ( $OPTION_CPP_BIN );
+  $commandline = $OPTION_CPP_BIN . " -ocon ";
+  $line = '^/[*] (\\S+) \\d+: [*]/';
+  $path_delimiter = '\\';
+
+} else {
+  &usage;
+  
+}
+
+
+###############################################################################
+# CUSTOMIZABLE2: set @OPTION_IGNORE
+
+# @OPTION_IGNORE
+#      It is a list of include path that should be ignored by
+#      makedepend.  Generally, it is directories specified by
+#      --ignore option, if it is specified.  If --ignore option is
+#      not specified, we set the system include directories on it.
+
+if ( ! $ignoreSystemIncludeDirectories ) {
+  if ( $OPTION_CPP =~ /^(gcc|g\+\+)$/ ) {
+    my($get_cpp_path) = "$OPTION_CPP_BIN -print-prog-name=cpp";
+    if ( 2 <= $OPTION_VERBOSE ) {
+      print STDERR "Getting cpp path ...\n";
+      print STDERR "  $get_cpp_path\n";
+      print STDERR "\n";
+    }
+    my($cpp) = `$get_cpp_path`;
+    chomp($cpp);
+    $cpp .= " -lang-c++" if ( $OPTION_CPP eq "g++" );
+    $cpp = "sh -c '$cpp -v < $nullDevice 2>&1'";
+    if ( 2 <= $OPTION_VERBOSE ) {
+      print STDERR "Getting system include directories ...\n";
+      print STDERR "  $cpp\n";
+      print STDERR "\n";
+    }
+    open(CPP, "$cpp|") || die $!;
+    while (<CPP>) {
+      goto get_inc_list if ( /^#include <...> search starts here:/ );
+    }
+    goto end_get_inc_list;
+  get_inc_list:
+    while (<CPP>) {
+      last if ( /^End of search list./ );
+      chomp;
+      push(@OPTION_IGNORE, &reduceDirectory($1)) if ( /^\s+(\S.*)\s*$/ );
+    }
+    close CPP;
+  end_get_inc_list:
+  
+  } elsif ( $OPTION_CPP eq "vc" ) {
+    &parseIgnore($ENV{include});
+
+  } elsif ( $OPTION_CPP eq "bcc32" ) {
+    ;
+  } else {
+    ;
+  }
+}
+
+
+###############################################################################
+
+# parse ignored directories for --option
+sub parseIgnore {
+  my ($ignore) = $_[0];
+  return unless ($ignore);
+  @OPTION_IGNORE = ( @OPTION_IGNORE , split( /;/ , $ignore));
+  my($i);
+  for ( $i = 0; $i < @OPTION_IGNORE; $i ++ ) {
+    # DOS-style-path to UNIX path
+    $OPTION_IGNORE[$i] =~ s:\\:/:g if ( $isWindows );
+    $OPTION_IGNORE[$i] =~ s/^\s*(\S.*\S)\s*$/$1/;
+  }
+}
+
+if ( 2 <= $OPTION_VERBOSE && 0 < @OPTION_IGNORE) {
+  print STDERR "The following include directories are ignored.\n";
+  foreach $i (@OPTION_IGNORE) {
+    print STDERR "  " . $i . "\n";
+  }
+  print "\n";
+}
+
+
+###############################################################################
+# create cpp commandline
+
+
+foreach $i ( @OPTION_OPTIONS ) {
+  # quote
+  if ( $isActivePerlWindows ) {
+    $i =~ s/\"/\"\"\"\"/g;
+  } else {
+    $i =~ s/\"/\\\"/g;
+  }
+  $commandline .= $i . " ";
+}
+
+
+###############################################################################
+# prepare output
+
+
+if ( $OPTION_FILENAME eq "-" ) {
+  binmode STDOUT;
+} else {
+  if ( ! -f $OPTION_FILENAME ) {
+    print "$0: error: $OPTION_FILENAME is not present\n" ;
+    exit 1;
+  }
+  $NEW_FILENAME = $OPTION_FILENAME . ".new";
+  $BACKUP_FILENAME = $OPTION_FILENAME . ".bak";
+  open(MAKEFILEORIG, "<$OPTION_FILENAME") || die $!;
+  unlink $NEW_FILENAME;
+  open(MAKEFILENEW, ">$NEW_FILENAME") || die $!;
+  binmode MAKEFILENEW;
+  select MAKEFILENEW;
+  while (<MAKEFILEORIG>) {
+    chomp;
+    if ( /^\Q$OPTION_STRING\E/ ) {
+      if ( $OPTION_APPEND ) {
+       $OPTION_STRING = "";
+      } else {
+       last;
+      }
+    }
+    print $_ . $OPTION_NEWLINE;
+  }
+  close(MAKEFILEORIG);
+}
+
+if ( $OPTION_STRING ) {
+  print $OPTION_STRING . $OPTION_NEWLINE;
+  print $OPTION_NEWLINE;
+}
+
+
+###############################################################################
+# cpp
+
+# eliminate dir/.. 
+sub reduceDirectory {
+  my($path) = @_;
+
+  # C:/hogehoge => C:, /hogehoge
+  # //localhost/hogehoge => //localhost, /hogehoge
+  my($drive) = "";
+  if ($isWindows) {
+    if ( $path =~ /^([a-zA-Z]:)(.*)$/ ||
+        $path =~ m@^(//[^/]+)(|/.*)$@ ) {
+      $drive = $1;
+      $path = $2;
+    }
+  }
+
+  # /./ => /, // => /
+  while ( $path =~ s:/\.?/:/: ) { ; }
+
+  # /hoge/../ => /
+  my($normalDir) = "(?:[^./]|[^./][^/]|[^/][^./]|[^/][^/][^/]+)";
+  while ( $path =~ m:^(.*)/$normalDir/\.\.(|/.*)$:o ) {
+    $path = $1 . $2;
+  }
+
+  # ^hoge/../muha => muha
+  $path =~ s:^$normalDir/\.\.(|/(.*))$:$2:o;
+
+  return $drive . $path if ($isWindows);
+  return $path;
+}
+
+# absolute path to relative directory against cwd
+#      $path = /usr/bin
+#      $cwd = /usr/local/lib
+#      return: ../../bin
+sub getRelativeDirectory {
+  my($path) = @_;
+  $path = &reduceDirectory($path);
+  my($cwd) = getcwd() . "/";
+  $cwd =~ s:\\:/:g if ( $isWindows );
+  $cwd = &reduceDirectory($cwd);
+  my($cwd2) = $cwd;
+  $cwd2 =~ s@^/cygdrive/([a-z])@$1:@i if ( $isCygwin );
+  
+  if ( ( $ignoreCase  && "$path\n$cwd" =~ m:^(.*)/(.*)\n\1/(.*)$:i ) ||
+       ( !$ignoreCase && "$path\n$cwd" =~ m:^(.*)/(.*)\n\1/(.*)$:  ) ||
+       ( $ignoreCase  && "$path\n$cwd2" =~ m:^(.*)/(.*)\n\1/(.*)$:i ) ||
+       ( !$ignoreCase && "$path\n$cwd2" =~ m:^(.*)/(.*)\n\1/(.*)$:  )) {
+    my($path) = $2;
+    my($dir) = $3;
+    if (0 < length($dir)) {
+      $dir =~ s:[^/]+:..:g;
+      return "$dir/$path";
+    } else {
+      return $path;
+    }
+  }
+  return $path;
+}
+
+# make dependency information
+foreach $source ( @OPTION_SRCS ) {
+
+  $source = &getRelativeDirectory($source);
+  if ( $OPTION_VERBOSE == 1 ) {
+    print STDERR "$source\n";
+  } elsif ( 2 <= $OPTION_VERBOSE ) {
+    print STDERR "Running preprocessor ...\n";
+    print STDERR "  $commandline $source\n";
+  }
+  
+  open(CXX, "$commandline $source|") || next;
+  my(%dependFiles);
+
+  while (<CXX>) {
+    chomp;
+    next if ( ! /$line/o );
+    $_ = $1;
+
+    # replace path delimiter
+    s/\Q$path_delimiter\E/\//og if ( $path_delimiter );
+
+    # exclude source file name
+    if ( $ignoreCase ) {
+      next if ( /^\Q$source\E$/i );
+    } else {
+      next if ( /^\Q$source\E$/ );
+    }
+    $dependFiles{&reduceDirectory($_)} = 1;
+  }
+
+  close (CXX);
+  
+  # exclude standard header file
+  my(@dependFiles) = ();
+ EXCLUDE: foreach $i ( sort(keys(%dependFiles)) ) {
+    foreach $j ( @OPTION_IGNORE ) {
+      next if ( $j eq "" );
+      if ( $ignoreCase ) {
+       next EXCLUDE if ( $i =~ /^\Q$j\E/i );
+      } else {
+       next EXCLUDE if ( $i =~ /^\Q$j\E/ );
+      }
+    }
+    push(@dependFiles, $i);
+  }
+
+  next if ( scalar(@dependFiles) == 0 );
+
+  # output object filename
+  $source =~ s/(\.(C|c|cc|cxx|cpp)|)$/$OPTION_SUFFIX/;
+  $source =~ s:/:$OPTION_PATH_DELIMITER:g;
+  print $OPTION_PREFIX . $source . ":";
+  $len = length($OPTION_PREFIX . $source . ":");
+
+  # output header filenames
+ HEADER: foreach $i ( @dependFiles ) {
+    # get relative directory
+    $i = &getRelativeDirectory($i) if ( ! $OPTION_ABSOLUTE );
+    $i =~ s:/:$OPTION_PATH_DELIMITER:g;
+
+    # output
+    if ( $OPTION_WIDTH - 2 <= $len + length(" " . $i) ) {
+      printf " \\" . $OPTION_NEWLINE;
+      $len = 0;
+    }
+    print " ", $i;
+    $len += length(" " . $i);
+  }
+  print $OPTION_NEWLINE;
+}
+
+if ( $OPTION_FILENAME ne "-" ) {
+  select STDIN;
+  close MAKEFILENEW;
+  
+  rename $OPTION_FILENAME, $BACKUP_FILENAME;
+  rename $NEW_FILENAME, $OPTION_FILENAME;
+}
diff --git a/tools/makefunc b/tools/makefunc
new file mode 100755 (executable)
index 0000000..c601406
--- /dev/null
@@ -0,0 +1,240 @@
+#!/usr/bin/perl -w
+# -*- cperl -*-
+
+binmode STDOUT;
+
+while (<>) {
+  last if (m#BEGINING OF FUNCTION DEFINITION#);
+}
+
+$line = "";
+
+while (<>) {
+  last if (m#END OF FUNCTION DEFINITION#);
+  chomp;
+  $line .= $_ unless (m{^\s*//});
+}
+
+$line =~ s/\s+/ /g;
+
+print <<"__EOM__";
+// DO NOT EDIT
+// this file is automatically generated by makefunc
+// see dependency information in mayu-common.mak
+
+#ifdef FUNCTION_DATA
+__EOM__
+foreach $functionDefinition ( split(/;/, $line) ) {
+  # void funcPrefix(FunctionParam *i_param, const Keymap *i_keymap,
+  #                 bool i_doesIgnoreModifiers = true);
+  next unless ( $functionDefinition =~ m{^
+       \s*     \w+             # void
+       \s+     func(\w+)       # funcPrefix
+       \s*     \(              # (
+       \s*     FunctionParam   # FunctionParam
+       \s*     \*              # *
+       \s*     \w+             # i_param
+       \s*     ,?              # ,
+       \s*     (.*?)           # const Keymap *i_keymap,
+                               # bool i_doesIgnoreModifiers = true
+       \s*     \)              # )
+       \s*$}x );
+  my($name) = $1;
+  push(@names, $name);
+  print <<"__EOM__";
+class FunctionData_$name : public FunctionData
+{
+public:
+__EOM__
+  my(@args) = split(/\s*,\s*/, $2);
+  
+  my $argc = 0;
+  my @argIsReference = ();
+  my @argTypes = ();
+  my @argNames = ();
+  my @argDefaultValues = ();
+  
+  foreach $arg ( @args ) {
+    my $isReference = 0;
+    my $type = "";
+    my $argName = "";
+    my $defaultValue = "";
+    # bool i_doesIgnoreModifiers = true
+    if ( $arg =~ m{^
+               (.*\S)          # bool i_doesIgnoreModifiers
+       \s*     =               # =
+       \s*     (\S.*)          # true
+       $}x ) {
+      $arg = $1;
+      $defaultValue = $2;
+    }
+    # const Keymap *i_keymap
+    if ( $arg =~ m{^
+               (.*\S           # const Keymap
+       \s*     \*)             # *
+       \s*     i_(\w+)         # i_keymap
+       $}x ) {
+      # const Hoge *i_hoge
+      $type = $1;
+      $argName = $2;
+    } elsif ( $arg =~ m{^
+               const           # const
+       \s*     (.*\S)          # ...
+       \s*     &               # &
+       \s*     i_(\w+)         # i_...
+       $}x ) {
+      # const Hoge &i_hoge
+      $type = $1;
+      $argName = $2;
+      $isReference = 1;
+    } elsif ( $arg =~ m{^
+               (.*\S)          # ...
+       \s*     i_(\w+)         # i_...
+       $}x ) {
+      # Hoge i_hoge
+      $type = $1;
+      $argName = $2;
+    } else {
+      die;
+    }
+    
+    push(@argIsReference, $isReference);
+    push(@argTypes, $type);
+    push(@argNames, $argName);
+    push(@argDefaultValues, $defaultValue);
+    $argc ++;
+  }
+  
+  for ($i = 0; $i < $argc; $i ++) {
+    print <<"__EOM__";
+  $argTypes[$i] m_$argNames[$i];
+__EOM__
+  }
+  print <<"__EOM__";
+
+public:
+  static FunctionData *create()
+  {
+    FunctionData_$name *fd
+      = new FunctionData_$name;
+__EOM__
+  for ($i = 0; $i < $argc; $i ++) {
+    if ($argDefaultValues[$i]) {
+      print "    fd->m_$argNames[$i] = $argDefaultValues[$i];\n";
+    }
+  }
+  print <<"__EOM__";
+    return fd;
+  }
+  
+  virtual void load(SettingLoader *i_sl)
+  {
+__EOM__
+  if ($argc == 0 || $argDefaultValues[0]) {
+    print <<"__EOM__";
+    if (!i_sl->getOpenParen(false, FunctionData_${name}::getName()))
+      return;
+__EOM__
+  } else {
+    print <<"__EOM__";
+    i_sl->getOpenParen(true, FunctionData_${name}::getName()); // throw ...
+__EOM__
+  }
+  for ($i = 0; $i < $argc; $i ++) {
+    if ($argDefaultValues[$i]) {
+      print <<"__EOM__";
+    if (i_sl->getCloseParen(false, FunctionData_${name}::getName()))
+      return;
+__EOM__
+    }
+    if (0 < $i) {
+      print <<"__EOM__";
+    i_sl->getComma(false, FunctionData_${name}::getName()); // throw ...
+__EOM__
+    }
+    print "    i_sl->load_ARGUMENT(&m_$argNames[$i]);\n";
+  }
+  print <<"__EOM__";
+    i_sl->getCloseParen(true, FunctionData_${name}::getName()); // throw ...
+  }
+
+  virtual void exec(Engine *i_engine, FunctionParam *i_param) const
+  {
+__EOM__
+  print "    i_engine->func$name(i_param";
+  for ($i = 0; $i < $argc; $i ++) {
+    print ", m_$argNames[$i]";
+  }
+  print ");\n";
+  
+  print <<"__EOM__";
+  }
+
+  inline virtual const _TCHAR *getName() const
+  {
+    return _T("$name");
+  }
+
+  virtual tostream &output(tostream &i_ost) const
+  {
+    i_ost << _T("&") << getName();
+__EOM__
+  if ( 0 < $argc ) {
+    print <<"__EOM__";
+    i_ost << _T("(");
+__EOM__
+  }
+  for ($i = 0; $i < $argc; $i ++) {
+    if ($i == $argc - 1) {
+    print <<"__EOM__";
+    i_ost << m_$argNames[$i];
+__EOM__
+    } else {
+    print <<"__EOM__";
+    i_ost << m_$argNames[$i] << _T(", ");
+__EOM__
+    }
+  }
+  if ( 0 < $argc ) {
+    print <<"__EOM__";
+    i_ost << _T(") ");
+__EOM__
+  }
+  print <<"__EOM__";
+    return i_ost;
+  }
+
+  virtual FunctionData *clone() const
+  {
+    return new FunctionData_${name}(*this);
+  }
+};
+
+__EOM__
+}
+
+print <<"__EOM__";
+#endif // FUNCTION_DATA
+
+#ifdef FUNCTION_FRIEND
+__EOM__
+foreach $name ( @names ) {
+  print <<"__EOM__";
+friend class FunctionData_$name;
+__EOM__
+}
+print <<"__EOM__";
+#endif // FUNCTION_FRIEND
+
+#ifdef FUNCTION_CREATOR
+FunctionCreator functionCreators[] = {
+__EOM__
+foreach $name ( @names ) {
+  print <<"__EOM__";
+  { _T("$name"), FunctionData_${name}::create },
+__EOM__
+}
+print <<"__EOM__";
+};
+#endif // FUNCTION_CREATOR
+__EOM__
diff --git a/tools/unix2dos b/tools/unix2dos
new file mode 100755 (executable)
index 0000000..d82efb2
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/local/bin/perl -w
+# -*- cperl -*-
+
+binmode STDIN;
+binmode STDOUT;
+
+foreach $i ( @ARGV ) {
+  open (FILE, "<$i");
+  binmode FILE;
+  @lines = <FILE>;
+  close (FILE);
+  
+  open (FILE, ">$i");
+  binmode FILE;
+  foreach $j ( @lines ) {
+    $j =~ s/\x0d\x0a/\x0a/g;
+    $j =~ s/\x0a/\x0d\x0a/g;
+    print FILE $j;
+  }
+  close (FILE);
+}
diff --git a/ts4mayu/Makefile b/ts4mayu/Makefile
new file mode 100755 (executable)
index 0000000..833d3d3
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Makefile for VC
+#
+
+!include <win32.mak>
+
+!if "$(TS4MAYU)" == "STS4MAYU"
+TARGET_NAME = sts4mayu
+!elseif "$(TS4MAYU)" == "CTS4MAYU"
+TARGET_NAME = cts4mayu
+!else
+TARGET_NAME = dummy
+!endif
+
+SRCS = ts4mayu.cpp
+HEADERS = 
+OBJS = $(TARGET_NAME)/ts4mayu.obj
+DEFS = ts4mayu.def
+TARGET = $(TARGET_NAME)/$(TARGET_NAME).dll
+
+CFLAGS = -DUNICODE -D_UNICODE -D_MT -MT
+INCLUDES = -I../../SynCOMAPIv1_0/Include -I"$(PROGRAMFILES)"/Touchpad
+LDFLAGS =  $(dlllflags) /libpath:../../SynCOMAPIv1_0/Lib /libpath:"$(PROGRAMFILES)"/Touchpad
+LDLIBS = user32.lib
+
+RM = rd
+MKDIR = md
+
+all:
+       $(MAKE) /$(MAKEFLAGS) TS4MAYU=STS4MAYU sts4mayu/sts4mayu.dll
+       $(MAKE) /$(MAKEFLAGS) TS4MAYU=CTS4MAYU cts4mayu/cts4mayu.dll
+
+$(TARGET_NAME):
+       if not exist "$(TARGET_NAME)" $(MKDIR) $(TARGET_NAME)
+
+$(TARGET): $(TARGET_NAME) $(OBJS) $(DEFS)
+       $(link) $(LDFLAGS) $(OBJS) -def:$(DEFS) $(LDLIBS) -out:$@
+
+{}.cpp.obj:
+       $(cc) -D$(TS4MAYU) -GX $(cdebug) $(cflags) $(cvarsmt) $(DEFINES) $(INCLUDES) \
+               $(DEBUG_FLAG) -Fo$@ $(*B).cpp
+
+clean:
+       -$(RM) /Q /S sts4mayu cts4mayu
diff --git a/ts4mayu/thumbsense.mayu b/ts4mayu/thumbsense.mayu
new file mode 100755 (executable)
index 0000000..4b7540e
--- /dev/null
@@ -0,0 +1,76 @@
+# ts4mayu.dll \82ð\8eg\82Á\82Ä ThumbSense \82ð\8eÀ\8c»\82·\82é\82½\82ß\82Ì\83T\83\93\83v\83\8b
+# \83I\83\8a\83W\83i\83\8b\82Ì ThumbSense \82Ì\83L\81[\8a\84\82è\93\96\82Ä\91S\82Ä\82ð\8eÀ\8c»\82µ\82Ä\82¢\82é\82í\82¯\82Å\82Í\82È\82¢\81B
+
+# F,J,Space \82ð\8d\83{\83^\83\93\82Ì\83N\83\8a\83b\83N\82É\8a\84\82è\93\96\82Ä\82é\81B
+  key TS-*F TS-*J TS-*Space = &VK(LButton)
+# \83N\83\8a\83b\83N\82ª\83\8a\83s\81[\83g\82³\82ê\82é\82Ì\82ð\96h\82®
+  key D-R-TS-*F D-R-TS-*J D-R-TS-*Space = &Ignore
+
+# D,K \82ð\89E\83{\83^\83\93\82Ì\83N\83\8a\83b\83N\82É\8a\84\82è\93\96\82Ä\82é\81B
+  key TS-*D TS-*K = &VK(RButton)
+# \83N\83\8a\83b\83N\82ª\83\8a\83s\81[\83g\82³\82ê\82é\82Ì\82ð\96h\82®
+  key D-R-TS-*D D-R-TS-*K = &Ignore
+
+# V \82ð\8d\83{\83^\83\93\82Ì\83_\83u\83\8b\83N\83\8a\83b\83N\82É\8a\84\82è\93\96\82Ä\82é\81B
+  key D-T-*V = &VK(LButton) &Wait(10) &VK(LButton)
+# \83N\83\8a\83b\83N\82ª\83\8a\83s\81[\83g\82³\82ê\82é\82Ì\82ð\96h\82¬\81A\83L\81[\97£\82µ\82½\82Æ\82«\82Í\96³\8e\8b\82·\82é\81B
+  key D-R-T-*V U-T-*V = &Ignore
+
+# G \82ð\91æ4\83{\83^\83\93\82Ì\83N\83\8a\83b\83N\82É\8a\84\82è\93\96\82Ä\82é\81B
+  key TS-*G = &VK(XButton1)
+# \83N\83\8a\83b\83N\82ª\83\8a\83s\81[\83g\82³\82ê\82é\82Ì\82ð\96h\82®
+  key D-R-TS-*G = &Ignore
+
+# H \82ð\91æ5\83{\83^\83\93\82Ì\83N\83\8a\83b\83N\82É\8a\84\82è\93\96\82Ä\82é\81B
+  key TS-*H = &VK(XButton2)
+# \83N\83\8a\83b\83N\82ª\83\8a\83s\81[\83g\82³\82ê\82é\82Ì\82ð\96h\82®
+  key D-R-TS-*H = &Ignore
+
+# S,L \82ð\89\9f\82µ\82È\82ª\82ç\82Ì\8fã\89º\95û\8cü\83h\83\89\83b\83O\82ð\83z\83C\81[\83\8b\89ñ\93]\82É\82·\82é\81B
+  key D-TS-*S D-TS-*L = &MouseHook(Wheel, -5)
+# \83\8a\83s\81[\83g\82Í\96³\8e\8b\81B
+  key D-R-TS-*S D-R-TS-*L = &Ignore
+# \83L\81[\82ð\97£\82µ\82½\82ç\89ð\8f\9c\82·\82é\81B
+  key U-TS-*S U-TS-*L = &MouseHook(None, 0)
+
+# A \82ð\89\9f\82µ\82È\82ª\82ç\83h\83\89\83b\83O\82·\82é\82Æ\83A\83N\83e\83B\83u\83E\83B\83\93\83h\83E\82ª\88Ú\93®\82·\82é\81B
+  key D-TS-*A = &MouseHook(WindowMove, 1)
+# \83\8a\83s\81[\83g\82Í\96³\8e\8b\81B
+  key D-R-TS-*A = &Ignore
+# \83L\81[\82ð\97£\82µ\82½\82ç\89ð\8f\9c\82·\82é\81B
+  key U-TS-*A = &MouseHook(None, 0)
+
+# R \82Å\83E\83B\83\93\83h\83E\82Ì\8dÅ\91å\89»/\89ð\8f\9c\82ð\83g\83O\83\8b\82·\82é\81B
+  key T-R = &WindowMaximize
+
+# W,B \82Å\83E\83B\83\93\83h\83E\82ð\95Â\82\82é\81B
+  key T-W T-B = &WindowClose
+
+# M \82Å My Document \82ð\8aJ\82­\81B
+  key T-M = &ShellExecute("open", "C:\\WINDOWS\\explorer.exe", "::{450D8FBA-AD25-11D0-98A8-0800361B1103}",, ShowNormal)
+
+# O \82Å Outlook Express \82ð\8bN\93®\82·\82é\81B
+  key T-O = &ShellExecute("open", "C:\\Program Files\\Outlook Express\\msimn.exe",,, ShowNormal)
+
+# I \82Å Internet Explorer \82ð\8bN\93®\82·\82é\81B
+  key T-I = &ShellExecute("open", "C:\\Program Files\\Internet Explorer\\iexplore.exe",,, ShowNormal)
+
+# P \82Å\83R\83}\83\93\83h\83v\83\8d\83\93\83v\83g\82ð\8bN\93®\82·\82é\81B
+  key T-P = &ShellExecute("open", "C:\\WINDOWS\\system32\\cmd.exe",,, ShowNormal)
+
+# \88È\89º\82Í\83I\83\8a\83W\83i\83\8b\82Ì ThumbSense \82É\82Í\82È\82¢\8a\84\82è\93\96\82Ä\82ð\8eÀ\8c»\82·\82é\81B
+
+# C \82ð\92\86\83{\83^\83\93\82Ì\83N\83\8a\83b\83N\82É\8a\84\82è\93\96\82Ä\82é\81B
+#  key TS-*C = &VK(MButton)
+#  key D-R-TS-*C = &Ignore
+
+# \83E\83C\83\93\83h\83E\82ª\8dÅ\91å\89»\82³\82ê\82Ä\82¢\82é\8e\9e\82É A \82ð\89\9f\82µ\82È\82ª\82ç\83h\83\89\83b\83O\82·\82é\82Æ
+# \83A\83N\83e\83B\83u MDI \8eq\83A\83N\83e\83B\83u\83E\83B\83\93\83h\83E\82ª\88Ú\93®\82·\82é\81B
+#  key D-TS-MAX-*A = &MouseHook(WindowMove, -1)
+
+# Control+A \82ð\89\9f\82µ\82È\82ª\82ç\83h\83\89\83b\83O\82·\82é\82Æ\83}\83E\83X\83J\81[\83\\83\8b\92¼\89º\82Ì\83E\83B\83\93\83h\83E\82ª\88Ú\93®\82·\82é\81B
+#  key D-TS-C-*A = &MouseHook(WindowMove, 2)
+
+# \83E\83C\83\93\83h\83E\82ª\8dÅ\91å\89»\82³\82ê\82Ä\82¢\82é\8e\9e\82É Control+A \82ð\89\9f\82µ\82È\82ª\82ç\83h\83\89\83b\83O\82·\82é\82Æ
+# \83}\83E\83X\83J\81[\83\\83\8b\92¼\89º\82Ì MDI \8eq\83A\83N\83e\83B\83u\83E\83B\83\93\83h\83E\82ª\88Ú\93®\82·\82é\81B
+#  key D-TS-MAX-C-*A = &MouseHook(WindowMove, -2)
diff --git a/ts4mayu/ts4mayu.cpp b/ts4mayu/ts4mayu.cpp
new file mode 100755 (executable)
index 0000000..6837816
--- /dev/null
@@ -0,0 +1,246 @@
+#include <windows.h>
+#include <process.h>
+#include <tchar.h>
+#include "../driver.h"
+#ifdef STS4MAYU
+#include "SynKit.h"
+#pragma comment(lib, "SynCom.lib")
+#endif /* STS4MAYU */
+#ifdef CTS4MAYU
+#include "Touchpad.h"
+#pragma comment(lib, "TouchPad.lib")
+#endif /* CTS4MAYU */
+
+static HANDLE s_instance;
+static UINT s_engineThreadId;
+
+#ifdef STS4MAYU
+static ISynAPI *s_synAPI;
+static ISynDevice *s_synDevice;
+static HANDLE s_notifyEvent;
+
+static int s_terminated;
+static HANDLE s_loopThread;
+static unsigned int s_loopThreadId;
+#endif /* STS4MAYU */
+#ifdef CTS4MAYU
+static HTOUCHPAD s_hTP[16];
+static int s_devNum;
+#endif /* CTS4MAYU */
+
+static void changeTouch(int i_isBreak)
+{
+  PostThreadMessage(s_engineThreadId, WM_APP + 201, i_isBreak ? 0 : 1, 0);
+}
+
+static void postEvent(WPARAM wParam, LPARAM lParam)
+{
+  PostThreadMessage(s_engineThreadId, WM_APP + 201, wParam, lParam);
+}
+
+#ifdef STS4MAYU
+static unsigned int WINAPI loop(void *dummy)
+{
+  HRESULT result;
+  SynPacket packet;
+  int isTouched = 0;
+
+  while (s_terminated == 0) {
+    WaitForSingleObject(s_notifyEvent, INFINITE);
+    if (s_terminated) {
+      break;
+    }
+
+    for (;;) {
+      long value;
+
+      result = s_synAPI->GetEventParameter(&value);
+      if (result != SYN_OK) {
+       break;
+      }
+      if (value == SE_Configuration_Changed) {
+       s_synDevice->SetEventNotification(s_notifyEvent);
+      }
+    }
+
+    for (;;) {
+      result = s_synDevice->LoadPacket(packet);
+      if (result == SYNE_FAIL) {
+       break;
+      }
+
+      if (isTouched) {
+       if (!(packet.FingerState() & SF_FingerTouch)) {
+         changeTouch(1);
+         isTouched = 0;
+       }
+      } else {
+       if (packet.FingerState() & SF_FingerTouch) {
+         changeTouch(0);
+         isTouched = 1;
+       }
+      }
+    }
+  }
+  _endthreadex(0);
+  return 0;
+}
+#endif /* STS4MAYU */
+#ifdef CTS4MAYU
+static void CALLBACK TouchpadFunc(HTOUCHPAD hTP, LPFEEDHDR lpFeedHdr, LPARAM i_lParam)
+{
+       LPRAWFEED lpRawFeed;
+       static int isTouched = 0;
+       static WPARAM s_wParam;
+       static LPARAM s_lParam;
+       WPARAM wParam;
+       LPARAM lParam;
+
+       lpRawFeed = (LPRAWFEED)(lpFeedHdr + 1);
+#if 1
+       wParam = lpRawFeed->wPressure;
+       lParam = lpRawFeed->y << 16 | lpRawFeed->x;
+       if (wParam != s_wParam || lParam != s_lParam) {
+         postEvent(wParam, lParam);
+         s_wParam = wParam;
+         s_lParam = lParam;
+       }
+#else
+       if (isTouched) {
+         if (!lpRawFeed->wPressure) {
+           changeTouch(1);
+           isTouched = 0;
+         }
+       } else {
+         if (lpRawFeed->wPressure) {
+           changeTouch(0);
+           isTouched = 1;
+         }
+       }
+#endif
+       EnableWindowsCursor(hTP, TRUE);
+}
+
+static BOOL CALLBACK DevicesFunc(LPGENERICDEVICE device, LPARAM lParam)
+{
+       HTOUCHPAD hTP = NULL;
+       BOOL ret = FALSE;
+
+       s_hTP[s_devNum] = GetPad(device->devicePort);
+       CreateCallback(s_hTP[s_devNum], TouchpadFunc,
+                      TPF_RAW | TPF_POSTMESSAGE, NULL);
+       StartFeed(s_hTP[s_devNum]);
+       ++s_devNum;
+       return TRUE;
+}
+#endif /* CTS4MAYU */
+
+bool WINAPI ts4mayuInit(UINT i_engineThreadId)
+{
+  s_engineThreadId = i_engineThreadId;
+
+#ifdef STS4MAYU
+  HRESULT result;
+  long hdl;
+
+  s_synAPI = NULL;
+  s_synDevice = NULL;
+  s_notifyEvent = NULL;
+
+  s_terminated = 0;
+
+  result = SynCreateAPI(&s_synAPI);
+  if (result != SYN_OK) {
+    goto error_on_init;
+  }
+
+  hdl = -1;
+  result = s_synAPI->FindDevice(SE_ConnectionAny, SE_DeviceTouchPad, &hdl);
+  if (result != SYN_OK) {
+    goto error_on_init;
+  }
+
+  result = s_synAPI->CreateDevice(hdl, &s_synDevice);
+  if (result != SYN_OK) {
+    goto error_on_init;
+  }
+
+  s_notifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+  if (s_notifyEvent == NULL) {
+    goto error_on_init;
+  }
+
+  s_synAPI->SetEventNotification(s_notifyEvent);
+  s_synDevice->SetEventNotification(s_notifyEvent);
+
+  s_loopThread =
+    (HANDLE)_beginthreadex(NULL, 0, loop, NULL, 0, &s_loopThreadId);
+  if (s_loopThread == 0) {
+    goto error_on_init;
+  }
+
+  return true;
+
+error_on_init:
+  if (s_notifyEvent) {
+    CloseHandle(s_notifyEvent);
+  }
+
+  if (s_synDevice) {
+    s_synDevice->Release();
+  }
+
+  if (s_synAPI) {
+    s_synAPI->Release();
+  }
+
+  return false;
+#endif /* STS4MAYU */
+#ifdef CTS4MAYU
+  // enumerate devices
+  EnumDevices(DevicesFunc, NULL);
+  return true;
+#endif /* CTS4MAYU */
+}
+
+
+bool WINAPI ts4mayuTerm()
+{
+#ifdef STS4MAYU
+  s_terminated = 1;
+
+  if (s_loopThread) {
+    SetEvent(s_notifyEvent);
+    WaitForSingleObject(s_loopThread, INFINITE);
+    CloseHandle(s_loopThread);
+  }
+
+  if (s_notifyEvent) {
+    CloseHandle(s_notifyEvent);
+  }
+
+  if (s_synDevice) {
+    s_synDevice->Release();
+  }
+
+  if (s_synAPI) {
+    s_synAPI->Release();
+  }
+
+  return true;
+#endif /* STS4MAYU */
+#ifdef CTS4MAYU
+  for (int i = 0; i < s_devNum; i++) {
+    StopFeed(s_hTP[i]);
+  }
+  return false;
+#endif /* CTS4MAYU */
+}
+
+
+BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserve)
+{
+    s_instance = (HINSTANCE)module;
+
+    return TRUE;
+}
diff --git a/ts4mayu/ts4mayu.def b/ts4mayu/ts4mayu.def
new file mode 100755 (executable)
index 0000000..566250b
--- /dev/null
@@ -0,0 +1,3 @@
+EXPORTS
+       ts4mayuInit     @1
+       ts4mayuTerm     @2
diff --git a/vc.mak b/vc.mak
new file mode 100644 (file)
index 0000000..b3fde55
--- /dev/null
+++ b/vc.mak
@@ -0,0 +1,72 @@
+############################################################## -*- Makefile -*-
+#
+# Makefile (Visual C++)
+#
+#      make release version: nmake nodebug=1
+#      make debug version: nmake
+#
+###############################################################################
+
+
+# VC++ rules   ###############################################################
+
+!if "$(TARGETOS)" == ""
+TARGETOS       = WINNT
+!endif # TARGETOS
+
+!if "$(TARGETOS)" == "WINNT"
+APPVER         = 5.0
+!ifdef nodebug
+OUT_DIR                = out$(MAYU_VC)_winnt
+!else  # nodebug
+OUT_DIR                = out$(MAYU_VC)_winnt_debug
+!endif # nodebug
+!endif # TARGETOS
+
+!if "$(TARGETOS)" == "WIN95"
+APPVER         = 4.0
+!ifdef nodebug
+OUT_DIR                = out$(MAYU_VC)_win9x
+!else  # nodebug
+OUT_DIR                = out$(MAYU_VC)_win9x_debug
+!endif # nodebug
+!endif # TARGETOS
+
+!if "$(TARGETOS)" == "BOTH"
+!error Must specify TARGETOS=WIN95 or TARGETOS=WINNT
+!endif # TARGETOS
+
+#_WIN32_IE     = 0x0500
+!include <win32.mak>
+#NMAKE_WINVER  = 0x0500        # trick for WS_EX_LAYERED
+
+!ifdef nodebug
+DEBUG_FLAG     = $(cdebug)
+!else  # nodebug
+DEBUG_FLAG     =
+!endif # nodebug
+
+{}.cpp{$(OUT_DIR)}.obj:
+       $(cc) -GX $(cflags) $(cvarsmt) $(DEFINES) $(INCLUDES) \
+               $(DEBUG_FLAG) -Fo$@ $(*B).cpp
+{}.rc{$(OUT_DIR)}.res:
+       $(rc) $(rcflags) $(rcvars) /fo$@ $(*B).rc
+
+conxlibsmt     = $(conlibsmt) libcpmt.lib libcmt.lib
+guixlibsmt     = $(guilibsmt) libcpmt.lib libcmt.lib
+
+DEPENDFLAGS    = --cpp=vc --ignore='$(INCLUDE)' -p"$$(OUT_DIR)\\"      \
+               --path-delimiter=dos --newline=unix                     \
+               $(DEPENDIGNORE) -GX $(cflags) $(cvarsmt)        \
+               $(DEFINES) $(INCLUDES) $(DEBUG_FLAG)
+
+CLEAN          = $(OUT_DIR)\*.pdb
+
+
+# tools                ###############################################################
+
+RM             = del
+COPY           = copy
+ECHO           = echo
+MKDIR          = mkdir
+RMDIR          = rmdir
diff --git a/vkeytable.cpp b/vkeytable.cpp
new file mode 100644 (file)
index 0000000..d23b566
--- /dev/null
@@ -0,0 +1,337 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// vkeytable.cpp
+
+
+#include "vkeytable.h"
+#include <ime.h>
+
+
+// Vkey table (terminated by NULL)
+const VKeyTable g_vkeyTable[] =
+{
+#define VK(name) { VK_##name, _T(#name) }
+
+/*
+ * from WinUser.h
+ */
+
+  VK(LBUTTON),         // 0x01
+  VK(RBUTTON),         // 0x02
+  VK(CANCEL),          // 0x03
+  VK(MBUTTON),         // 0x04    /* NOT contiguous with L & RBUTTON */
+
+#if(_WIN32_WINNT >= 0x0500)
+  VK(XBUTTON1),                // 0x05    /* NOT contiguous with L & RBUTTON */
+  VK(XBUTTON2),                // 0x06    /* NOT contiguous with L & RBUTTON */
+#endif /* _WIN32_WINNT >= 0x0500 */
+
+/*
+ * 0x07 : unassigned
+ */
+
+  VK(BACK),            // 0x08
+  VK(TAB),             // 0x09
+
+/*
+ * 0x0A - 0x0B : reserved
+ */
+
+  VK(CLEAR),           // 0x0C
+  VK(RETURN),          // 0x0D
+
+  VK(SHIFT),           // 0x10
+  VK(CONTROL),         // 0x11
+  VK(MENU),            // 0x12
+  VK(PAUSE),           // 0x13
+  VK(CAPITAL),         // 0x14
+
+  VK(KANA),            // 0x15
+  VK(HANGEUL),         // 0x15  /* old name - should be here for compatibility */
+  VK(HANGUL),          // 0x15
+  VK(JUNJA),           // 0x17
+  VK(FINAL),           // 0x18
+  VK(HANJA),           // 0x19
+  VK(KANJI),           // 0x19
+
+  VK(ESCAPE),          // 0x1B
+
+  VK(CONVERT),         // 0x1C
+  VK(NONCONVERT),      // 0x1D
+  VK(ACCEPT),          // 0x1E
+  VK(MODECHANGE),      // 0x1F
+
+  VK(SPACE),           // 0x20
+  VK(PRIOR),           // 0x21
+  VK(NEXT),            // 0x22
+  VK(END),             // 0x23
+  VK(HOME),            // 0x24
+  VK(LEFT),            // 0x25
+  VK(UP),              // 0x26
+  VK(RIGHT),           // 0x27
+  VK(DOWN),            // 0x28
+  VK(SELECT),          // 0x29
+  VK(PRINT),           // 0x2A
+  VK(EXECUTE),         // 0x2B
+  VK(SNAPSHOT),                // 0x2C
+  VK(INSERT),          // 0x2D
+  VK(DELETE),          // 0x2E
+  VK(HELP),            // 0x2F
+
+/*
+ * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
+ * 0x40 : unassigned
+ * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
+ */
+
+  { _T('0'), _T("_0") },               // 30 0
+  { _T('1'), _T("_1") },               // 31 1
+  { _T('2'), _T("_2") },               // 32 2
+  { _T('3'), _T("_3") },               // 33 3
+  { _T('4'), _T("_4") },               // 34 4
+  { _T('5'), _T("_5") },               // 35 5
+  { _T('6'), _T("_6") },               // 36 6
+  { _T('7'), _T("_7") },               // 37 7
+  { _T('8'), _T("_8") },               // 38 8
+  { _T('9'), _T("_9") },               // 39 9
+
+  { _T('A'), _T("A") },                        // 41 A
+  { _T('B'), _T("B") },                        // 42 B
+  { _T('C'), _T("C") },                        // 43 C
+  { _T('D'), _T("D") },                        // 44 D
+  { _T('E'), _T("E") },                        // 45 E
+  { _T('F'), _T("F") },                        // 46 F
+  { _T('G'), _T("G") },                        // 47 G
+  { _T('H'), _T("H") },                        // 48 H
+  { _T('I'), _T("I") },                        // 49 I
+  { _T('J'), _T("J") },                        // 4A J
+  { _T('K'), _T("K") },                        // 4B K
+  { _T('L'), _T("L") },                        // 4C L
+  { _T('M'), _T("M") },                        // 4D M
+  { _T('N'), _T("N") },                        // 4E N
+  { _T('O'), _T("O") },                        // 4F O
+  { _T('P'), _T("P") },                        // 50 P
+  { _T('Q'), _T("Q") },                        // 51 Q
+  { _T('R'), _T("R") },                        // 52 R
+  { _T('S'), _T("S") },                        // 53 S
+  { _T('T'), _T("T") },                        // 54 T
+  { _T('U'), _T("U") },                        // 55 U
+  { _T('V'), _T("V") },                        // 56 V
+  { _T('W'), _T("W") },                        // 57 W
+  { _T('X'), _T("X") },                        // 58 X
+  { _T('Y'), _T("Y") },                        // 59 Y
+  { _T('Z'), _T("Z") },                        // 5A Z
+
+  VK(LWIN),            // 0x5B
+  VK(RWIN),            // 0x5C
+  VK(APPS),            // 0x5D
+
+/*
+ * 0x5E : reserved
+ */
+
+  VK(SLEEP),           // 0x5F
+
+  VK(NUMPAD0),         // 0x60
+  VK(NUMPAD1),         // 0x61
+  VK(NUMPAD2),         // 0x62
+  VK(NUMPAD3),         // 0x63
+  VK(NUMPAD4),         // 0x64
+  VK(NUMPAD5),         // 0x65
+  VK(NUMPAD6),         // 0x66
+  VK(NUMPAD7),         // 0x67
+  VK(NUMPAD8),         // 0x68
+  VK(NUMPAD9),         // 0x69
+  VK(MULTIPLY),                // 0x6A
+  VK(ADD),             // 0x6B
+  VK(SEPARATOR),       // 0x6C
+  VK(SUBTRACT),                // 0x6D
+  VK(DECIMAL),         // 0x6E
+  VK(DIVIDE),          // 0x6F
+  VK(F1),              // 0x70
+  VK(F2),              // 0x71
+  VK(F3),              // 0x72
+  VK(F4),              // 0x73
+  VK(F5),              // 0x74
+  VK(F6),              // 0x75
+  VK(F7),              // 0x76
+  VK(F8),              // 0x77
+  VK(F9),              // 0x78
+  VK(F10),             // 0x79
+  VK(F11),             // 0x7A
+  VK(F12),             // 0x7B
+  VK(F13),             // 0x7C
+  VK(F14),             // 0x7D
+  VK(F15),             // 0x7E
+  VK(F16),             // 0x7F
+  VK(F17),             // 0x80
+  VK(F18),             // 0x81
+  VK(F19),             // 0x82
+  VK(F20),             // 0x83
+  VK(F21),             // 0x84
+  VK(F22),             // 0x85
+  VK(F23),             // 0x86
+  VK(F24),             // 0x87
+
+/*
+ * 0x88 - 0x8F : unassigned
+ */
+
+  VK(NUMLOCK),         // 0x90
+  VK(SCROLL),          // 0x91
+
+/*
+ * NEC PC-9800 kbd definitions
+ */
+  VK(OEM_NEC_EQUAL),   // 0x92 // '=' key on numpad
+
+/*
+ * Fujitsu/OASYS kbd definitions
+ */
+  VK(OEM_FJ_JISHO),    // 0x92 // 'Dictionary' key
+  VK(OEM_FJ_MASSHOU),  // 0x93 // 'Unregister word' key
+  VK(OEM_FJ_TOUROKU),  // 0x94 // 'Register word' key
+  VK(OEM_FJ_LOYA),     // 0x95 // 'Left OYAYUBI' key
+  VK(OEM_FJ_ROYA),     // 0x96 // 'Right OYAYUBI' key
+
+/*
+ * 0x97 - 0x9F : unassigned
+ */
+
+/*
+ * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
+ * Used only as parameters to GetAsyncKeyState() and GetKeyState().
+ * No other API or message will distinguish left and right keys in this way.
+ */
+  VK(LSHIFT),          // 0xA0
+  VK(RSHIFT),          // 0xA1
+  VK(LCONTROL),                // 0xA2
+  VK(RCONTROL),                // 0xA3
+  VK(LMENU),           // 0xA4
+  VK(RMENU),           // 0xA5
+
+#if(_WIN32_WINNT >= 0x0500)
+  VK(BROWSER_BACK),    // 0xA6
+  VK(BROWSER_FORWARD), // 0xA7
+  VK(BROWSER_REFRESH), // 0xA8
+  VK(BROWSER_STOP),    // 0xA9
+  VK(BROWSER_SEARCH),  // 0xAA
+  VK(BROWSER_FAVORITES),// 0xAB
+  VK(BROWSER_HOME),    // 0xAC
+
+  VK(VOLUME_MUTE),     // 0xAD
+  VK(VOLUME_DOWN),     // 0xAE
+  VK(VOLUME_UP),       // 0xAF
+  VK(MEDIA_NEXT_TRACK),        // 0xB0
+  VK(MEDIA_PREV_TRACK),        // 0xB1
+  VK(MEDIA_STOP),      // 0xB2
+  VK(MEDIA_PLAY_PAUSE),        // 0xB3
+  VK(LAUNCH_MAIL),     // 0xB4
+  VK(LAUNCH_MEDIA_SELECT),     // 0xB5
+  VK(LAUNCH_APP1),      // 0xB6
+  VK(LAUNCH_APP2),      // 0xB7
+
+#endif /* _WIN32_WINNT >= 0x0500 */
+
+/*
+ * 0xB8 - 0xB9 : reserved
+ */
+
+  VK(OEM_1),           // 0xBA // ';:' for US
+  VK(OEM_PLUS),                // 0xBB // '+' any country
+  VK(OEM_COMMA),       // 0xBC // ',' any country
+  VK(OEM_MINUS),       // 0xBD // '-' any country
+  VK(OEM_PERIOD),      // 0xBE // '.' any country
+  VK(OEM_2),           // 0xBF // '/?' for US
+  VK(OEM_3),           // 0xC0 // '`~' for US
+
+/*
+ * 0xC1 - 0xD7 : reserved
+ */
+
+/*
+ * 0xD8 - 0xDA : unassigned
+ */
+
+  VK(OEM_4),           // 0xDB //  '[{' for US
+  VK(OEM_5),           // 0xDC //  '\|' for US
+  VK(OEM_6),           // 0xDD //  ']}' for US
+  VK(OEM_7),           // 0xDE //  ''"' for US
+  VK(OEM_8),           // 0xDF
+
+/*
+ * 0xE0 : reserved
+ */
+
+/*
+ * Various extended or enhanced keyboards
+ */
+  VK(OEM_AX),          // 0xE1 //  'AX' key on Japanese AX kbd
+  VK(OEM_102),         // 0xE2 //  "<>" or "\|" on RT 102-key kbd.
+  VK(ICO_HELP),                // 0xE3 //  Help key on ICO
+  VK(ICO_00),          // 0xE4 //  00 key on ICO
+
+#if(WINVER >= 0x0400)
+  VK(PROCESSKEY),      // 0xE5
+#endif /* WINVER >= 0x0400 */
+
+  VK(ICO_CLEAR),       // 0xE6
+
+#if(_WIN32_WINNT >= 0x0500)
+  VK(PACKET),          // 0xE7
+#endif /* _WIN32_WINNT >= 0x0500 */
+
+/*
+ * 0xE8 : unassigned
+ */
+
+/*
+ * Nokia/Ericsson definitions
+ */
+  VK(OEM_RESET),       // 0xE9
+  VK(OEM_JUMP),                // 0xEA
+  VK(OEM_PA1),         // 0xEB
+  VK(OEM_PA2),         // 0xEC
+  VK(OEM_PA3),         // 0xED
+  VK(OEM_WSCTRL),      // 0xEE
+  VK(OEM_CUSEL),       // 0xEF
+  VK(OEM_ATTN),                // 0xF0
+  VK(OEM_FINISH),      // 0xF1
+  VK(OEM_COPY),                // 0xF2
+  VK(OEM_AUTO),                // 0xF3
+  VK(OEM_ENLW),                // 0xF4
+  VK(OEM_BACKTAB),     // 0xF5
+
+  VK(ATTN),            // 0xF6
+  VK(CRSEL),           // 0xF7
+  VK(EXSEL),           // 0xF8
+  VK(EREOF),           // 0xF9
+  VK(PLAY),            // 0xFA
+  VK(ZOOM),            // 0xFB
+  VK(NONAME),          // 0xFC
+  VK(PA1),             // 0xFD
+  VK(OEM_CLEAR),       // 0xFE
+
+/*
+ * from Ime.h
+ */
+
+#if !defined(VK_DBE_ALPHANUMERIC)
+  VK(DBE_ALPHANUMERIC),                        // 0x0f0
+  VK(DBE_KATAKANA),                    // 0x0f1
+  VK(DBE_HIRAGANA),                    // 0x0f2
+  VK(DBE_SBCSCHAR),                    // 0x0f3
+  VK(DBE_DBCSCHAR),                    // 0x0f4
+  VK(DBE_ROMAN),                       // 0x0f5
+  VK(DBE_NOROMAN),                     // 0x0f6
+  VK(DBE_ENTERWORDREGISTERMODE),       // 0x0f7
+  VK(DBE_ENTERIMECONFIGMODE),          // 0x0f8
+  VK(DBE_FLUSHSTRING),                 // 0x0f9
+  VK(DBE_CODEINPUT),                   // 0x0fa
+  VK(DBE_NOCODEINPUT),                 // 0x0fb
+  VK(DBE_DETERMINESTRING),             // 0x0fc
+  VK(DBE_ENTERDLGCONVERSIONMODE),      // 0x0fd
+#endif
+
+  { 0, NULL },
+#undef VK
+};
diff --git a/vkeytable.h b/vkeytable.h
new file mode 100644 (file)
index 0000000..a2267a0
--- /dev/null
@@ -0,0 +1,24 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// vkeytable.h
+
+
+#ifndef _VKEYTABLE_H
+#  define _VKEYTABLE_H
+
+#  include "misc.h"
+#  include <tchar.h>
+
+
+/// define virtual key code and its name
+class VKeyTable
+{
+public:
+  u_int8 m_code;                               /// VKey code
+  const _TCHAR *m_name;                                /// VKey name
+};
+
+extern const VKeyTable g_vkeyTable[];          /** Vkey table (terminated by
+                                                   NULL) */
+
+
+#endif // !_VKEYTABLE_H
diff --git a/windowstool.cpp b/windowstool.cpp
new file mode 100644 (file)
index 0000000..c96e4c7
--- /dev/null
@@ -0,0 +1,511 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// windowstool.cpp
+
+
+#include "misc.h"
+
+#include "windowstool.h"
+#include "array.h"
+
+#include <windowsx.h>
+#include <malloc.h>
+#include <shlwapi.h>
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Global variables
+
+
+// instance handle of this application
+HINSTANCE g_hInst = NULL;
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Functions
+
+
+// load resource string
+tstring loadString(UINT i_id)
+{
+  _TCHAR buf[1024];
+  if (LoadString(g_hInst, i_id, buf, NUMBER_OF(buf)))
+    return tstring(buf);
+  else
+    return _T("");
+}
+
+
+// load small icon resource
+HICON loadSmallIcon(UINT i_id)
+{
+  return reinterpret_cast<HICON>(
+    LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 16, 16, 0));
+}
+
+
+// load big icon resource
+HICON loadBigIcon(UINT i_id)
+{
+  return reinterpret_cast<HICON>(
+    LoadImage(g_hInst, MAKEINTRESOURCE(i_id), IMAGE_ICON, 32, 32, 0));
+}
+
+
+// set small icon to the specified window.
+// @return handle of previous icon or NULL
+HICON setSmallIcon(HWND i_hwnd, UINT i_id)
+{
+  HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadSmallIcon(i_id);
+  return reinterpret_cast<HICON>(
+    SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_SMALL),
+               reinterpret_cast<LPARAM>(hicon)));
+}
+
+
+// set big icon to the specified window.
+// @return handle of previous icon or NULL
+HICON setBigIcon(HWND i_hwnd, UINT i_id)
+{
+  HICON hicon = (i_id == static_cast<UINT>(-1)) ? NULL : loadBigIcon(i_id);
+  return reinterpret_cast<HICON>(
+    SendMessage(i_hwnd, WM_SETICON, static_cast<WPARAM>(ICON_BIG),
+               reinterpret_cast<LPARAM>(hicon)));
+}
+
+
+// remove icon from a window that is set by setSmallIcon
+void unsetSmallIcon(HWND i_hwnd)
+{
+  HICON hicon = setSmallIcon(i_hwnd, -1);
+  if (hicon)
+    CHECK_TRUE( DestroyIcon(hicon) );
+}
+
+
+// remove icon from a window that is set by setBigIcon
+void unsetBigIcon(HWND i_hwnd)
+{
+  HICON hicon = setBigIcon(i_hwnd, -1);
+  if (hicon)
+    CHECK_TRUE( DestroyIcon(hicon) );
+}
+
+
+// resize the window (it does not move the window)
+bool resizeWindow(HWND i_hwnd, int i_w, int i_h, bool i_doRepaint)
+{
+  UINT flag = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
+  if (!i_doRepaint)
+    flag |= SWP_NOREDRAW;
+  return !!SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h, flag);
+}
+
+
+// get rect of the window in client coordinates
+// @return rect of the window in client coordinates
+bool getChildWindowRect(HWND i_hwnd, RECT *o_rc)
+{
+  if (!GetWindowRect(i_hwnd, o_rc))
+    return false;
+  POINT p = { o_rc->left, o_rc->top };
+  HWND phwnd = GetParent(i_hwnd);
+  if (!phwnd)
+    return false;
+  if (!ScreenToClient(phwnd, &p))
+    return false;
+  o_rc->left = p.x;
+  o_rc->top = p.y;
+  p.x = o_rc->right;
+  p.y = o_rc->bottom;
+  ScreenToClient(phwnd, &p);
+  o_rc->right = p.x;
+  o_rc->bottom = p.y;
+  return true;
+}
+
+
+// get toplevel (non-child) window
+HWND getToplevelWindow(HWND i_hwnd, bool *io_isMDI)
+{
+  while (i_hwnd)
+  {
+    LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
+    if ((style & WS_CHILD) == 0)
+      break;
+    if (io_isMDI && *io_isMDI)
+    {
+      LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
+      if (exStyle & WS_EX_MDICHILD)
+       return i_hwnd;
+    }
+    i_hwnd = GetParent(i_hwnd);
+  }
+  if (io_isMDI)
+    *io_isMDI = false;
+  return i_hwnd;
+}
+
+
+// move window asynchronously
+void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y)
+{
+  SetWindowPos(i_hwnd, NULL, i_x, i_y, 0, 0,
+              SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+              SWP_NOSIZE | SWP_NOZORDER);
+}
+
+
+// move window asynchronously
+void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h)
+{
+  SetWindowPos(i_hwnd, NULL, i_x, i_y, i_w, i_h,
+              SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+              SWP_NOZORDER);
+}
+
+
+// resize asynchronously
+void asyncResize(HWND i_hwnd, int i_w, int i_h)
+{
+  SetWindowPos(i_hwnd, NULL, 0, 0, i_w, i_h,
+              SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+              SWP_NOMOVE | SWP_NOZORDER);
+}
+
+
+// get dll version
+DWORD getDllVersion(const _TCHAR *i_dllname)
+{
+  DWORD dwVersion = 0;
+  
+  if (HINSTANCE hinstDll = LoadLibrary(i_dllname))
+  {
+    DLLGETVERSIONPROC pDllGetVersion
+      = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
+    /* Because some DLLs may not implement this function, you
+     * must test for it explicitly. Depending on the particular 
+     * DLL, the lack of a DllGetVersion function may
+     * be a useful indicator of the version.
+     */
+    if (pDllGetVersion)
+    {
+      DLLVERSIONINFO dvi;
+      ZeroMemory(&dvi, sizeof(dvi));
+      dvi.cbSize = sizeof(dvi);
+
+      HRESULT hr = (*pDllGetVersion)(&dvi);
+      if (SUCCEEDED(hr))
+       dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
+    }
+        
+    FreeLibrary(hinstDll);
+  }
+  return dwVersion;
+}
+
+
+// workaround of SetForegroundWindow
+bool setForegroundWindow(HWND i_hwnd)
+{
+  int nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
+  int nTargetID = GetWindowThreadProcessId(i_hwnd, NULL);
+  
+  //if (!AttachThreadInput(nTargetID, nForegroundID, TRUE))
+  //return false;
+  AttachThreadInput(nTargetID, nForegroundID, TRUE);
+
+  DWORD sp_time;
+  SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &sp_time, 0);
+  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)0, 0);
+
+  SetForegroundWindow(i_hwnd);
+
+  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (void *)sp_time, 0);
+  
+  AttachThreadInput(nTargetID, nForegroundID, FALSE);
+  return true;
+}
+
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// edit control
+
+
+// get edit control's text size
+// @return bytes of text
+size_t editGetTextBytes(HWND i_hwnd)
+{
+  return Edit_GetTextLength(i_hwnd);
+}
+
+
+// delete a line
+void editDeleteLine(HWND i_hwnd, size_t i_n)
+{
+  int len = Edit_LineLength(i_hwnd, i_n);
+  if (len < 0)
+    return;
+  len += 2;
+  int index = Edit_LineIndex(i_hwnd, i_n);
+  Edit_SetSel(i_hwnd, index, index + len);
+  Edit_ReplaceSel(i_hwnd, _T(""));
+}
+  
+
+// insert text at last
+void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,
+                         size_t i_threshold)
+{
+  if (i_text.empty())
+    return;
+  
+  size_t len = editGetTextBytes(i_hwnd);
+  
+  if (i_threshold < len)
+  {
+    Edit_SetSel(i_hwnd, 0, len / 3 * 2);
+    Edit_ReplaceSel(i_hwnd, _T(""));
+    editDeleteLine(i_hwnd, 0);
+    len = editGetTextBytes(i_hwnd);
+  }
+  
+  Edit_SetSel(i_hwnd, len, len);
+  
+  // \n -> \r\n
+  Array<_TCHAR> buf(i_text.size() * 2 + 1);
+  _TCHAR *d = buf.get();
+  const _TCHAR *str = i_text.c_str();
+  for (const _TCHAR *s = str; s < str + i_text.size(); ++ s)
+  {
+    if (*s == _T('\n'))
+      *d++ = _T('\r');
+    *d++ = *s;
+  }
+  *d = _T('\0');
+  
+  Edit_ReplaceSel(i_hwnd, buf.get());
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Windows2000/XP specific API
+
+
+// initialize layerd window
+static BOOL WINAPI initalizeLayerdWindow(
+  HWND i_hwnd, COLORREF i_crKey, BYTE i_bAlpha, DWORD i_dwFlags)
+{
+  HMODULE hModule = GetModuleHandle(_T("user32.dll"));
+  if (!hModule) {
+    return FALSE;
+  }
+  SetLayeredWindowAttributes_t proc = 
+    reinterpret_cast<SetLayeredWindowAttributes_t>(
+      GetProcAddress(hModule, "SetLayeredWindowAttributes"));
+  if (setLayeredWindowAttributes) {
+    setLayeredWindowAttributes = proc;
+    return setLayeredWindowAttributes(i_hwnd, i_crKey, i_bAlpha, i_dwFlags);
+  } else {
+    return FALSE;
+  }
+}
+
+
+// SetLayeredWindowAttributes API
+SetLayeredWindowAttributes_t setLayeredWindowAttributes
+  = initalizeLayerdWindow;
+
+
+// emulate MonitorFromWindow API
+static HMONITOR WINAPI emulateMonitorFromWindow(HWND hwnd, DWORD dwFlags)
+{
+  return reinterpret_cast<HMONITOR>(1); // dummy HMONITOR
+}
+
+// initialize MonitorFromWindow API
+static HMONITOR WINAPI initializeMonitorFromWindow(HWND hwnd, DWORD dwFlags)
+{
+  HMODULE hModule = GetModuleHandle(_T("user32.dll"));
+  if (!hModule)
+    return FALSE;
+
+  FARPROC proc = GetProcAddress(hModule, "MonitorFromWindow");
+  if(proc)
+    monitorFromWindow =
+      reinterpret_cast<HMONITOR (WINAPI *)(HWND, DWORD)>(proc);
+  else
+    monitorFromWindow = emulateMonitorFromWindow;
+
+  return monitorFromWindow(hwnd, dwFlags);
+}
+
+// MonitorFromWindow API
+HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags)
+    = initializeMonitorFromWindow;
+
+
+// emulate GetMonitorInfo API
+static BOOL WINAPI emulateGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
+{
+  if(lpmi->cbSize != sizeof(MONITORINFO))
+    return FALSE;
+
+  lpmi->rcMonitor.left = 0;
+  lpmi->rcMonitor.top = 0;
+  lpmi->rcMonitor.right = GetSystemMetrics(SM_CXFULLSCREEN);
+  lpmi->rcMonitor.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
+  SystemParametersInfo(SPI_GETWORKAREA, 0,
+                       reinterpret_cast<PVOID>(&lpmi->rcWork), FALSE);
+  lpmi->dwFlags = MONITORINFOF_PRIMARY;
+
+  return TRUE;
+}
+
+// initialize GetMonitorInfo API
+static
+BOOL WINAPI initializeGetMonitorInfo(HMONITOR hMonitor, LPMONITORINFO lpmi)
+{
+  HMODULE hModule = GetModuleHandle(_T("user32.dll"));
+  if (!hModule)
+    return FALSE;
+
+  FARPROC proc = GetProcAddress(hModule, "GetMonitorInfoA");
+  if(proc)
+    getMonitorInfo =
+      reinterpret_cast<BOOL (WINAPI *)(HMONITOR, LPMONITORINFO)>(proc);
+  else
+    getMonitorInfo = emulateGetMonitorInfo;
+
+  return getMonitorInfo(hMonitor, lpmi);
+}
+
+// GetMonitorInfo API
+BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi)
+  = initializeGetMonitorInfo;
+
+
+// enumalte EnumDisplayMonitors API
+static BOOL WINAPI emulateEnumDisplayMonitors(
+  HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
+{
+  lpfnEnum(reinterpret_cast<HMONITOR>(1), hdc, lprcClip, dwData);
+  return TRUE;
+}
+
+// initialize EnumDisplayMonitors API
+static BOOL WINAPI initializeEnumDisplayMonitors(
+  HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
+{
+  HMODULE hModule = GetModuleHandle(_T("user32.dll"));
+  if (!hModule)
+    return FALSE;
+
+  FARPROC proc = GetProcAddress(hModule, "EnumDisplayMonitors");
+  if(proc)
+    enumDisplayMonitors =
+      reinterpret_cast<BOOL (WINAPI *)(HDC, LPRECT, MONITORENUMPROC, LPARAM)>
+      (proc);
+  else
+    enumDisplayMonitors = emulateEnumDisplayMonitors;
+
+  return enumDisplayMonitors(hdc, lprcClip, lpfnEnum, dwData);
+}
+
+// EnumDisplayMonitors API
+BOOL (WINAPI *enumDisplayMonitors)
+    (HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData)
+  = initializeEnumDisplayMonitors;
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Windows2000/XP specific API
+
+
+static BOOL WINAPI
+initializeWTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
+{
+  LoadLibrary(_T("wtsapi32.dll"));
+  HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
+  if (!hModule) {
+    return FALSE;
+  }
+  WTSRegisterSessionNotification_t proc = 
+    reinterpret_cast<WTSRegisterSessionNotification_t>(
+      GetProcAddress(hModule, "WTSRegisterSessionNotification"));
+  if (proc) {
+    wtsRegisterSessionNotification = proc;
+    return wtsRegisterSessionNotification(hWnd, dwFlags);
+  } else {
+    return 0;
+  }
+}
+
+// WTSRegisterSessionNotification API
+WTSRegisterSessionNotification_t wtsRegisterSessionNotification
+  = initializeWTSRegisterSessionNotification;
+
+
+static BOOL WINAPI initializeWTSUnRegisterSessionNotification(HWND hWnd)
+{
+  HMODULE hModule = GetModuleHandle(_T("wtsapi32.dll"));
+  if (!hModule) {
+    return FALSE;
+  }
+  WTSUnRegisterSessionNotification_t proc = 
+    reinterpret_cast<WTSUnRegisterSessionNotification_t>(
+      GetProcAddress(hModule, "WTSUnRegisterSessionNotification"));
+  if (proc) {
+    wtsUnRegisterSessionNotification = proc;
+    return wtsUnRegisterSessionNotification(hWnd);
+  } else {
+    return 0;
+  }
+}
+
+// WTSUnRegisterSessionNotification API
+WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification
+  = initializeWTSUnRegisterSessionNotification;
+
+
+static DWORD WINAPI initializeWTSGetActiveConsoleSessionId(void)
+{
+  HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
+  if (!hModule) {
+    return FALSE;
+  }
+  WTSGetActiveConsoleSessionId_t proc = 
+    reinterpret_cast<WTSGetActiveConsoleSessionId_t>(
+      GetProcAddress(hModule, "WTSGetActiveConsoleSessionId"));
+  if (proc) {
+    wtsGetActiveConsoleSessionId = proc;
+    return wtsGetActiveConsoleSessionId();
+  } else {
+    return 0;
+  }
+}
+
+// WTSGetActiveConsoleSessionId API
+WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId
+  = initializeWTSGetActiveConsoleSessionId;
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Utility
+
+// PathRemoveFileSpec()
+tstring pathRemoveFileSpec(const tstring &i_path)
+{
+  const _TCHAR *str = i_path.c_str();
+  const _TCHAR *b = _tcsrchr(str, _T('\\'));
+  const _TCHAR *s = _tcsrchr(str, _T('/'));
+  if (b && s)
+    return tstring(str, MIN(b, s));
+  if (b)
+    return tstring(str, b);
+  if (s)
+    return tstring(str, s);
+  if (const _TCHAR *c = _tcsrchr(str, _T(':')))
+    return tstring(str, c + 1);
+  return i_path;
+}
diff --git a/windowstool.h b/windowstool.h
new file mode 100644 (file)
index 0000000..f622c60
--- /dev/null
@@ -0,0 +1,165 @@
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// windowstool.h
+
+
+#ifndef _WINDOWSTOOL_H
+#  define _WINDOWSTOOL_H
+
+
+#  include "stringtool.h"
+#  include <windows.h>
+
+
+/// instance handle of this application
+extern HINSTANCE g_hInst;
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// resource
+
+/// load resource string
+extern tstring loadString(UINT i_id);
+
+/// load small icon resource (it must be deleted by DestroyIcon())
+extern HICON loadSmallIcon(UINT i_id);
+
+///load big icon resource (it must be deleted by DestroyIcon())
+extern HICON loadBigIcon(UINT i_id);
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// window
+
+/// resize the window (it does not move the window)
+extern bool resizeWindow(HWND i_hwnd, int i_w, int i_h, bool i_doRepaint);
+
+/** get rect of the window in client coordinates.
+    @return rect of the window in client coordinates */
+extern bool getChildWindowRect(HWND i_hwnd, RECT *o_rc);
+
+/** set small icon to the specified window.
+    @return handle of previous icon or NULL */
+extern HICON setSmallIcon(HWND i_hwnd, UINT i_id);
+
+/** set big icon to the specified window.
+    @return handle of previous icon or NULL */
+extern HICON setBigIcon(HWND i_hwnd, UINT i_id);
+
+/// remove icon from a window that is set by setSmallIcon
+extern void unsetSmallIcon(HWND i_hwnd);
+
+/// remove icon from a window that is set by setBigIcon
+extern void unsetBigIcon(HWND i_hwnd);
+
+/// get toplevel (non-child) window
+extern HWND getToplevelWindow(HWND i_hwnd, bool *io_isMDI);
+
+/// move window asynchronously
+extern void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y);
+
+/// move window asynchronously
+extern void asyncMoveWindow(HWND i_hwnd, int i_x, int i_y, int i_w, int i_h);
+
+/// resize asynchronously
+extern void asyncResize(HWND i_hwnd, int i_w, int i_h);
+
+/// get dll version
+extern DWORD getDllVersion(const _TCHAR *i_dllname);
+#define PACKVERSION(major, minor) MAKELONG(minor, major)
+
+// workaround of SetForegroundWindow
+extern bool setForegroundWindow(HWND i_hwnd);
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// dialog
+
+/// get/set GWL_USERDATA
+template <class T> inline T getUserData(HWND i_hwnd, T *i_wc)
+{
+  return (*i_wc = reinterpret_cast<T>(GetWindowLong(i_hwnd, GWL_USERDATA)));
+}
+
+///
+template <class T> inline T setUserData(HWND i_hwnd, T i_wc)
+{
+  SetWindowLong(i_hwnd, GWL_USERDATA, reinterpret_cast<long>(i_wc));
+  return i_wc;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// RECT
+
+///
+inline int rcWidth(const RECT *i_rc) { return i_rc->right - i_rc->left; }
+
+///
+inline int rcHeight(const RECT *i_rc) { return i_rc->bottom - i_rc->top; }
+
+///
+inline bool isRectInRect(const RECT *i_rcin, const RECT *i_rcout)
+{
+  return (i_rcout->left <= i_rcin->left &&
+         i_rcin->right <= i_rcout->right &&
+         i_rcout->top <= i_rcin->top &&
+         i_rcin->bottom <= i_rcout->bottom);
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// edit control
+
+/// returns bytes of text
+extern size_t editGetTextBytes(HWND i_hwnd);
+
+/// delete a line
+extern void editDeleteLine(HWND i_hwnd, size_t i_n);
+
+/// insert text at last
+extern void editInsertTextAtLast(HWND i_hwnd, const tstring &i_text,
+                                size_t i_threshold);
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Windows2000/XP specific API
+
+/// SetLayeredWindowAttributes API
+typedef BOOL (WINAPI *SetLayeredWindowAttributes_t)
+  (HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
+extern SetLayeredWindowAttributes_t setLayeredWindowAttributes;
+
+/// MonitorFromWindow API
+extern HMONITOR (WINAPI *monitorFromWindow)(HWND hwnd, DWORD dwFlags);
+
+/// GetMonitorInfo API
+extern BOOL (WINAPI *getMonitorInfo)(HMONITOR hMonitor, LPMONITORINFO lpmi);
+
+/// EnumDisplayMonitors API
+extern BOOL (WINAPI *enumDisplayMonitors)
+  (HDC hdc, LPRECT lprcClip, MONITORENUMPROC lpfnEnum, LPARAM dwData);
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// WindowsXP specific API
+
+/// WTSRegisterSessionNotification API
+typedef BOOL (WINAPI *WTSRegisterSessionNotification_t)
+  (HWND hWnd, DWORD dwFlags);
+extern WTSRegisterSessionNotification_t wtsRegisterSessionNotification;
+
+/// WTSUnRegisterSessionNotification API
+typedef BOOL (WINAPI *WTSUnRegisterSessionNotification_t)(HWND hWnd);
+extern WTSUnRegisterSessionNotification_t wtsUnRegisterSessionNotification;
+
+/// WTSGetActiveConsoleSessionId API
+typedef DWORD (WINAPI *WTSGetActiveConsoleSessionId_t)(void);
+extern WTSGetActiveConsoleSessionId_t wtsGetActiveConsoleSessionId;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Utility
+
+// PathRemoveFileSpec()
+tstring pathRemoveFileSpec(const tstring &i_path);
+
+
+#endif // _WINDOWSTOOL_H