*** empty log message ***
authorroot <root>
Sun, 16 Jan 2005 15:59:45 +0000 (15:59 +0000)
committerroot <root>
Sun, 16 Jan 2005 15:59:45 +0000 (15:59 +0000)
12 files changed:
README.FAQ
README.configure
doc/rxvt.1.html
doc/rxvt.1.man.in
doc/rxvt.1.txt
doc/rxvt.7.html
doc/rxvt.7.man.in
doc/rxvt.7.txt
src/feature.h
src/keyboard.C [new file with mode: 0644]
src/keyboard.h [new file with mode: 0644]
src/rxvtutil.h

index 41fb7290548793946e0d258fa2b14a298104a59c..0e457a0c9a91421eec55b2083f404e4cd86fd6d0 100644 (file)
@@ -503,49 +503,31 @@ FREQUENTLY ASKED QUESTIONS
         There are some compile-time selections available via configure.
         Unless you have run "configure" with the "--disable-resources"
         option you can use the `keysym' resource to alter the keystrings
-        associated with keysym 0xFF00 - 0xFFFF (function, cursor keys, etc).
-
-        Here's an example for a tn3270 session started using `rxvt -name
-        tn3270'
-
-           !#  ----- special uses ------:
-           ! tn3270 login, remap function and arrow keys.
-           tn3270*font:      *clean-bold-*-*--15-*
-
-           ! keysym - used by rxvt only
-           ! Delete - ^D
-           tn3270*keysym.0xFFFF:      \004
-
-           ! Home - ^A
-           tn3270*keysym.0xFF50:      \001
-           ! Left - ^B
-           tn3270*keysym.0xFF51:      \002
-           ! Up - ^P
-           tn3270*keysym.0xFF52:      \020
-           ! Right - ^F
-           tn3270*keysym.0xFF53:      \006
-           ! Down - ^N
-           tn3270*keysym.0xFF54:      \016
-           ! End - ^E
-           tn3270*keysym.0xFF57:      \005
-
-           ! F1 - F12
-           tn3270*keysym.0xFFBE:      \e1
-           tn3270*keysym.0xFFBF:      \e2
-           tn3270*keysym.0xFFC0:      \e3
-           tn3270*keysym.0xFFC1:      \e4
-           tn3270*keysym.0xFFC2:      \e5
-           tn3270*keysym.0xFFC3:      \e6
-           tn3270*keysym.0xFFC4:      \e7
-           tn3270*keysym.0xFFC5:      \e8
-           tn3270*keysym.0xFFC6:      \e9
-           tn3270*keysym.0xFFC7:      \e0
-           tn3270*keysym.0xFFC8:      \e-
-           tn3270*keysym.0xFFC9:      \e=
-
-           ! map Prior/Next to F7/F8
-           tn3270*keysym.0xFF55:      \e7
-           tn3270*keysym.0xFF56:      \e8
+        associated with keysyms.
+
+        Here's an example for a URxvt session started using `rxvt -name
+        URxvt'
+
+                URxvt*keysym.Home:          \e[1~
+                URxvt*keysym.End:           \e[4~
+                URxvt*keysym.C-apostrophe:  \e<C-'>
+                URxvt*keysym.C-slash:       \e<C-/>
+                URxvt*keysym.C-semicolon:   \e<C-;>
+                URxvt*keysym.C-grave:       \e<C-`>
+                URxvt*keysym.C-comma:       \e<C-,>
+                URxvt*keysym.C-period:      \e<C-.>
+                URxvt*keysym.C-0x60:        \e<C-`>
+                URxvt*keysym.C-Tab:         \e<C-Tab>
+                URxvt*keysym.C-Return:      \e<C-Return>
+                URxvt*keysym.S-Return:      \e<S-Return>
+                URxvt*keysym.S-space:       \e<S-Space>
+                URxvt*keysym.M-Up:          \e<M-Up>
+                URxvt*keysym.M-Down:        \e<M-Down>
+                URxvt*keysym.M-Left:        \e<M-Left>
+                URxvt*keysym.M-Right:       \e<M-Right>
+                URxvt*keysym.M-C-0:         list.0123456789.\e<M-C-.>
+                URxvt*keysym.M-C-a:         list.abcdefghijklmnopqrstuvwxyz.\033<M-C-.>
+                URxvt*keysym.F12:           proto:\033]701;zh_CN.GBK\007
 
     I'm using keyboard model XXX that has extra Prior/Next/Insert keys. How
     do I make use of them? For example, the Sun Keyboard type 4 has the
index ba48d36494a6048b2419c219391ed085ff0a5355..39c1b6356af4d4f5b4fd30e64703ffa0b1ad20a2 100644 (file)
@@ -169,6 +169,20 @@ CONFIGURE OPTIONS
         to have. Normally you want this, but for very small binaries you may
         want to disable this.
 
+        A non-exhaustive list of features enabled by "--enable-frills"
+        (possibly in combination with other switches) is:
+
+          MWM-hints
+          seperate underline colour
+          settable border widths and borderless switch
+          settable extra linespacing
+          extra window properties (e.g. UTF-8 window names and PID)
+          iso-14755-2 and -3, and visual feedback
+          backindex and forwardindex escape sequence
+          window op and locale change escape sequences
+          tripleclickwords
+          settable insecure mode
+
     --enable-iso14755
         Enable extended ISO 14755 support (see rxvt(1), or doc/rxvt.1.txt).
         Basic support (section 5.1) is enabled by "--enable-frills", while
index 97df44a15788e2931b1fc4c438a71f7d66862c9b..2d9b0b834ac544db4de2b9ae07a47f50c0bc8be5 100644 (file)
@@ -1103,14 +1103,52 @@ instead scroll the screen up.
 <dt><strong><a name="item_keysym_2esym_3a_string"><strong>keysym.</strong><em>sym</em>: <em>string</em></a></strong><br />
 </dt>
 <dd>
-Associate <em>string</em> with keysym <em>sym</em> (<strong>0xFF00 - 0xFFFF</strong>). It may
+Associate <em>string</em> with keysym <em>sym</em>.  The intervening resource
+name <strong>keysym.</strong> cannot be omitted. This resource is only available
+when compiled with KEYSYM_RESOURCE.
+</dd>
+<dd>
+<p>The format of <em>sym</em> is ``<em>(mask-)key</em>'',
+where <em>mask</em> can be any combination of <strong>Control</strong>, <strong>NumLock</strong>,
+<strong>Shift</strong>, <strong>Meta</strong>, <strong>Lock</strong>, <strong>Mod1</strong>, <strong>Mod2</strong>, <strong>Mod3</strong>, <strong>Mod4</strong>,
+<strong>Mod5</strong>, and the abbreviated
+<strong>C</strong>, <strong>N</strong>, <strong>S</strong>, <strong>M</strong>, <strong>A</strong>, <strong>L</strong>, <strong>1</strong>, <strong>2</strong>, <strong>3</strong>, <strong>4</strong>, <strong>5</strong>.
+The spellings of <em>key</em> can be obtained by using <strong>xev</strong>(1)
+command or searching keysym macros from
+<strong>/usr/X11R6/include/X11/keysymdef.h</strong> and omit the prefix <strong>XK_</strong>.
+Alternatively you can specify <em>key</em> by its hex keysym value 
+(<strong>0x0000 - 0xFFFF</strong>).
+Note that the lookup of <em>sym</em>s is not performed in an exact manner;
+however, the closest match is assured.</p>
+</dd>
+<dd>
+<p><em>string</em> may
 contain escape values (\a: bell, \b: backspace, \e, \E: escape, \n:
 newline, \r: return, \t:
 tab, \000: octal number) or control characters (^?: delete, ^@: null,
 ^A ...) and may enclosed with double quotes so that it can start or end
-with whitespace. The intervening resource name <strong>keysym.</strong> cannot be
-omitted. This resource is only available when compiled with
-KEYSYM_RESOURCE.
+with whitespace.</p>
+</dd>
+<dd>
+<p>You can define a range of keysyms in one shot by providing a <em>string</em>
+with pattern <strong>list/STRING1/STRING2/STRING3</strong>, where the delimeter `/'
+should be a character not used by the <strong>STRING</strong>s.</p>
+</dd>
+<dd>
+<p>Its usage can be demonstrated by an example:
+        URxvt.keysym.M-C-0x61:    list.abc.\e&lt;M-C-.&gt;</p>
+</dd>
+<dd>
+<p>The above line is equivalent to the following three lines:
+        URxvt.keysym.Meta-Control-0x61:    \e&lt;M-C-a&gt;
+        URxvt.keysym.Meta-Control-0x62:    \e&lt;M-C-b&gt;
+        URxvt.keysym.Meta-Control-0x63:    \e&lt;M-C-c&gt;</p>
+</dd>
+<dd>
+<p>If <em>string</em> takes the form of <strong>proto:STRING</strong>,
+the specified <strong>STRING</strong> is interpreted and executed as <strong>rxvt</strong>'s
+control sequence. For example, <strong>``proto:\033]701;zh_CN.GBK\007''</strong>
+means changing the current locale to zh_CN.GBK.</p>
 </dd>
 <p></p></dl>
 <p>
index 45afbf65b1df685dc430a08cc29156e458f4659e..b58a7e5aa6d24f45645e810fefd86cd812f3bc2e 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "rxvt 1"
-.TH rxvt 1 "2005-01-11" "4.8" "RXVT-UNICODE"
+.TH rxvt 1 "2005-01-16" "4.8" "RXVT-UNICODE"
 .SH "NAME"
 rxvt\-unicode (ouR XVT, unicode) \- (a VT102 emulator for the X window system)
 .SH "SYNOPSIS"
@@ -830,14 +830,46 @@ scrollback buffer and switching to/from the secondary screen will
 instead scroll the screen up.
 .IP "\fBkeysym.\fR\fIsym\fR: \fIstring\fR" 4
 .IX Item "keysym.sym: string"
-Associate \fIstring\fR with keysym \fIsym\fR (\fB0xFF00 \- 0xFFFF\fR). It may
+Associate \fIstring\fR with keysym \fIsym\fR.  The intervening resource
+name \fBkeysym.\fR cannot be omitted. This resource is only available
+when compiled with \s-1KEYSYM_RESOURCE\s0.
+.Sp
+The format of \fIsym\fR is "\fI(mask\-)key\fR",
+where \fImask\fR can be any combination of \fBControl\fR, \fBNumLock\fR,
+\&\fBShift\fR, \fBMeta\fR, \fBLock\fR, \fBMod1\fR, \fBMod2\fR, \fBMod3\fR, \fBMod4\fR,
+\&\fBMod5\fR, and the abbreviated
+\&\fBC\fR, \fBN\fR, \fBS\fR, \fBM\fR, \fBA\fR, \fBL\fR, \fB1\fR, \fB2\fR, \fB3\fR, \fB4\fR, \fB5\fR.
+The spellings of \fIkey\fR can be obtained by using \fBxev\fR(1)
+command or searching keysym macros from
+\&\fB/usr/X11R6/include/X11/keysymdef.h\fR and omit the prefix \fB\s-1XK_\s0\fR.
+Alternatively you can specify \fIkey\fR by its hex keysym value 
+(\fB0x0000 \- 0xFFFF\fR).
+Note that the lookup of \fIsym\fRs is not performed in an exact manner;
+however, the closest match is assured.
+.Sp
+\&\fIstring\fR may
 contain escape values (\ea: bell, \eb: backspace, \ee, \eE: escape, \en:
 newline, \er: return, \et:
 tab, \e000: octal number) or control characters (^?: delete, ^@: null,
 ^A ...) and may enclosed with double quotes so that it can start or end
-with whitespace. The intervening resource name \fBkeysym.\fR cannot be
-omitted. This resource is only available when compiled with
-\&\s-1KEYSYM_RESOURCE\s0.
+with whitespace.
+.Sp
+You can define a range of keysyms in one shot by providing a \fIstring\fR
+with pattern \fBlist/STRING1/STRING2/STRING3\fR, where the delimeter `/'
+should be a character not used by the \fB\s-1STRING\s0\fRs.
+.Sp
+Its usage can be demonstrated by an example:
+        URxvt.keysym.M\-C\-0x61:    list.abc.\ee<M\-C\-.>
+.Sp
+The above line is equivalent to the following three lines:
+        URxvt.keysym.Meta\-Control\-0x61:    \ee<M\-C\-a>
+        URxvt.keysym.Meta\-Control\-0x62:    \ee<M\-C\-b>
+        URxvt.keysym.Meta\-Control\-0x63:    \ee<M\-C\-c>
+.Sp
+If \fIstring\fR takes the form of \fBproto:STRING\fR,
+the specified \fB\s-1STRING\s0\fR is interpreted and executed as \fB@@RXVT_NAME@@\fR's
+control sequence. For example, \fB\*(L"proto:\e033]701;zh_CN.GBK\e007\*(R"\fR
+means changing the current locale to zh_CN.GBK.
 .SH "THE SCROLLBAR"
 .IX Header "THE SCROLLBAR"
 Lines of text that scroll off the top of the \fB@@RXVT_NAME@@\fR window
index ec855c06197a7bb66394b7f56b4de243d93e4c1b..bf2e70c93075cabd5daa1899d4c41751e8eed73b 100644 (file)
@@ -692,13 +692,41 @@ RESOURCES (available also as long-options)
         instead scroll the screen up.
 
     keysym.*sym*: *string*
-        Associate *string* with keysym *sym* (0xFF00 - 0xFFFF). It may
-        contain escape values (\a: bell, \b: backspace, \e, \E: escape, \n:
-        newline, \r: return, \t: tab, \000: octal number) or control
-        characters (^?: delete, ^@: null, ^A ...) and may enclosed with
-        double quotes so that it can start or end with whitespace. The
-        intervening resource name keysym. cannot be omitted. This resource
-        is only available when compiled with KEYSYM_RESOURCE.
+        Associate *string* with keysym *sym*. The intervening resource name
+        keysym. cannot be omitted. This resource is only available when
+        compiled with KEYSYM_RESOURCE.
+
+        The format of *sym* is "*(mask-)key*", where *mask* can be any
+        combination of Control, NumLock, Shift, Meta, Lock, Mod1, Mod2,
+        Mod3, Mod4, Mod5, and the abbreviated C, N, S, M, A, L, 1, 2, 3, 4,
+        5. The spellings of *key* can be obtained by using xev(1) command or
+        searching keysym macros from /usr/X11R6/include/X11/keysymdef.h and
+        omit the prefix XK_. Alternatively you can specify *key* by its hex
+        keysym value (0x0000 - 0xFFFF). Note that the lookup of *sym*s is
+        not performed in an exact manner; however, the closest match is
+        assured.
+
+        *string* may contain escape values (\a: bell, \b: backspace, \e, \E:
+        escape, \n: newline, \r: return, \t: tab, \000: octal number) or
+        control characters (^?: delete, ^@: null, ^A ...) and may enclosed
+        with double quotes so that it can start or end with whitespace.
+
+        You can define a range of keysyms in one shot by providing a
+        *string* with pattern list/STRING1/STRING2/STRING3, where the
+        delimeter `/' should be a character not used by the STRINGs.
+
+        Its usage can be demonstrated by an example: URxvt.keysym.M-C-0x61:
+        list.abc.\e<M-C-.>
+
+        The above line is equivalent to the following three lines:
+        URxvt.keysym.Meta-Control-0x61: \e<M-C-a>
+        URxvt.keysym.Meta-Control-0x62: \e<M-C-b>
+        URxvt.keysym.Meta-Control-0x63: \e<M-C-c>
+
+        If *string* takes the form of proto:STRING, the specified STRING is
+        interpreted and executed as rxvt's control sequence. For example,
+        "proto:\033]701;zh_CN.GBK\007" means changing the current locale to
+        zh_CN.GBK.
 
 THE SCROLLBAR
     Lines of text that scroll off the top of the rxvt window (resource:
index acab850394bea5163aa14a1194c3a0e46c211ff6..47b57aa77f6470d3b4676a4ef406e44fe63a6b4e 100644 (file)
@@ -724,60 +724,33 @@ GNU Emacs (and Emacs-like editors) use ^H for help.</p>
 <dd>
 There are some compile-time selections available via configure. Unless
 you have run ``configure'' with the <a href="#item__2d_2ddisable_2dresources"><code>--disable-resources</code></a> option you can
-use the `keysym' resource to alter the keystrings associated with keysym
-0xFF00 - 0xFFFF (function, cursor keys, etc).
+use the `keysym' resource to alter the keystrings associated with keysyms.
 </dd>
 <dd>
-<p>Here's an example for a tn3270 session started using `rxvt -name tn3270'</p>
+<p>Here's an example for a URxvt session started using `rxvt -name URxvt'</p>
 </dd>
 <dd>
 <pre>
-   !#  ----- special uses ------:
-   ! tn3270 login, remap function and arrow keys.
-   tn3270*font:      *clean-bold-*-*--15-*</pre>
-</dd>
-<dd>
-<pre>
-   ! keysym - used by rxvt only
-   ! Delete - ^D
-   tn3270*keysym.0xFFFF:      \004</pre>
-</dd>
-<dd>
-<pre>
-   ! Home - ^A
-   tn3270*keysym.0xFF50:      \001
-   ! Left - ^B
-   tn3270*keysym.0xFF51:      \002
-   ! Up - ^P
-   tn3270*keysym.0xFF52:      \020
-   ! Right - ^F
-   tn3270*keysym.0xFF53:      \006
-   ! Down - ^N
-   tn3270*keysym.0xFF54:      \016
-   ! End - ^E
-   tn3270*keysym.0xFF57:      \005</pre>
-</dd>
-<dd>
-<pre>
-   ! F1 - F12
-   tn3270*keysym.0xFFBE:      \e1
-   tn3270*keysym.0xFFBF:      \e2
-   tn3270*keysym.0xFFC0:      \e3
-   tn3270*keysym.0xFFC1:      \e4
-   tn3270*keysym.0xFFC2:      \e5
-   tn3270*keysym.0xFFC3:      \e6
-   tn3270*keysym.0xFFC4:      \e7
-   tn3270*keysym.0xFFC5:      \e8
-   tn3270*keysym.0xFFC6:      \e9
-   tn3270*keysym.0xFFC7:      \e0
-   tn3270*keysym.0xFFC8:      \e-
-   tn3270*keysym.0xFFC9:      \e=</pre>
-</dd>
-<dd>
-<pre>
-   ! map Prior/Next to F7/F8
-   tn3270*keysym.0xFF55:      \e7
-   tn3270*keysym.0xFF56:      \e8</pre>
+        URxvt*keysym.Home:          \e[1~
+        URxvt*keysym.End:           \e[4~
+        URxvt*keysym.C-apostrophe:  \e&lt;C-'&gt;
+        URxvt*keysym.C-slash:       \e&lt;C-/&gt;
+        URxvt*keysym.C-semicolon:   \e&lt;C-;&gt;
+        URxvt*keysym.C-grave:       \e&lt;C-`&gt;
+        URxvt*keysym.C-comma:       \e&lt;C-,&gt;
+        URxvt*keysym.C-period:      \e&lt;C-.&gt;
+        URxvt*keysym.C-0x60:        \e&lt;C-`&gt;
+        URxvt*keysym.C-Tab:         \e&lt;C-Tab&gt;
+        URxvt*keysym.C-Return:      \e&lt;C-Return&gt;
+        URxvt*keysym.S-Return:      \e&lt;S-Return&gt;
+        URxvt*keysym.S-space:       \e&lt;S-Space&gt;
+        URxvt*keysym.M-Up:          \e&lt;M-Up&gt;
+        URxvt*keysym.M-Down:        \e&lt;M-Down&gt;
+        URxvt*keysym.M-Left:        \e&lt;M-Left&gt;
+        URxvt*keysym.M-Right:       \e&lt;M-Right&gt;
+        URxvt*keysym.M-C-0:         list.0123456789.\e&lt;M-C-.&gt;
+        URxvt*keysym.M-C-a:         list.abcdefghijklmnopqrstuvwxyz.\033&lt;M-C-.&gt;
+        URxvt*keysym.F12:           proto:\033]701;zh_CN.GBK\007</pre>
 </dd>
 <p></p>
 <dt><strong><a name="item_i_27m_using_keyboard_model_xxx_that_has_extra_prio">I'm using keyboard model XXX that has extra Prior/Next/Insert keys.
@@ -2663,6 +2636,23 @@ Add support for many small features that are not essential but nice to
 have. Normally you want this, but for very small binaries you may want to
 disable this.
 </dd>
+<dd>
+<p>A non-exhaustive list of features enabled by <a href="#item__2d_2denable_2dfrills"><code>--enable-frills</code></a> (possibly
+in combination with other switches) is:</p>
+</dd>
+<dd>
+<pre>
+  MWM-hints
+  seperate underline colour
+  settable border widths and borderless switch
+  settable extra linespacing
+  extra window properties (e.g. UTF-8 window names and PID)
+  iso-14755-2 and -3, and visual feedback
+  backindex and forwardindex escape sequence
+  window op and locale change escape sequences
+  tripleclickwords
+  settable insecure mode</pre>
+</dd>
 <p></p>
 <dt><strong><a name="item__2d_2denable_2diso14755">--enable-iso14755</a></strong><br />
 </dt>
index e7063fb2619b881df6cab75e8b200b12efa030ef..fbbb25294b8038c6fcc8675703fc39726e154c32 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "rxvt 7"
-.TH rxvt 7 "2005-01-11" "4.8" "RXVT-UNICODE"
+.TH rxvt 7 "2005-01-16" "4.8" "RXVT-UNICODE"
 .SH "NAME"
 RXVT REFERENCE \- FAQ, command sequences and other background information
 .SH "FREQUENTLY ASKED QUESTIONS"
@@ -680,58 +680,31 @@ Perhaps someday this will all be resolved in a consistent manner.
 .IX Item "I don't like the key-bindings.  How do I change them?"
 There are some compile-time selections available via configure. Unless
 you have run \*(L"configure\*(R" with the \f(CW\*(C`\-\-disable\-resources\*(C'\fR option you can
-use the `keysym' resource to alter the keystrings associated with keysym
-0xFF00 \- 0xFFFF (function, cursor keys, etc).
-.Sp
-Here's an example for a tn3270 session started using `@@RXVT_NAME@@ \-name tn3270'
-.Sp
-.Vb 3
-\&   !#  ----- special uses ------:
-\&   ! tn3270 login, remap function and arrow keys.
-\&   tn3270*font:      *clean-bold-*-*--15-*
-.Ve
-.Sp
-.Vb 3
-\&   ! keysym - used by rxvt only
-\&   ! Delete - ^D
-\&   tn3270*keysym.0xFFFF:      \e004
-.Ve
-.Sp
-.Vb 12
-\&   ! Home - ^A
-\&   tn3270*keysym.0xFF50:      \e001
-\&   ! Left - ^B
-\&   tn3270*keysym.0xFF51:      \e002
-\&   ! Up - ^P
-\&   tn3270*keysym.0xFF52:      \e020
-\&   ! Right - ^F
-\&   tn3270*keysym.0xFF53:      \e006
-\&   ! Down - ^N
-\&   tn3270*keysym.0xFF54:      \e016
-\&   ! End - ^E
-\&   tn3270*keysym.0xFF57:      \e005
-.Ve
-.Sp
-.Vb 13
-\&   ! F1 - F12
-\&   tn3270*keysym.0xFFBE:      \ee1
-\&   tn3270*keysym.0xFFBF:      \ee2
-\&   tn3270*keysym.0xFFC0:      \ee3
-\&   tn3270*keysym.0xFFC1:      \ee4
-\&   tn3270*keysym.0xFFC2:      \ee5
-\&   tn3270*keysym.0xFFC3:      \ee6
-\&   tn3270*keysym.0xFFC4:      \ee7
-\&   tn3270*keysym.0xFFC5:      \ee8
-\&   tn3270*keysym.0xFFC6:      \ee9
-\&   tn3270*keysym.0xFFC7:      \ee0
-\&   tn3270*keysym.0xFFC8:      \ee-
-\&   tn3270*keysym.0xFFC9:      \ee=
-.Ve
-.Sp
-.Vb 3
-\&   ! map Prior/Next to F7/F8
-\&   tn3270*keysym.0xFF55:      \ee7
-\&   tn3270*keysym.0xFF56:      \ee8
+use the `keysym' resource to alter the keystrings associated with keysyms.
+.Sp
+Here's an example for a URxvt session started using `@@RXVT_NAME@@ \-name URxvt'
+.Sp
+.Vb 20
+\&        URxvt*keysym.Home:          \ee[1~
+\&        URxvt*keysym.End:           \ee[4~
+\&        URxvt*keysym.C-apostrophe:  \ee<C-'>
+\&        URxvt*keysym.C-slash:       \ee<C-/>
+\&        URxvt*keysym.C-semicolon:   \ee<C-;>
+\&        URxvt*keysym.C-grave:       \ee<C-`>
+\&        URxvt*keysym.C-comma:       \ee<C-,>
+\&        URxvt*keysym.C-period:      \ee<C-.>
+\&        URxvt*keysym.C-0x60:        \ee<C-`>
+\&        URxvt*keysym.C-Tab:         \ee<C-Tab>
+\&        URxvt*keysym.C-Return:      \ee<C-Return>
+\&        URxvt*keysym.S-Return:      \ee<S-Return>
+\&        URxvt*keysym.S-space:       \ee<S-Space>
+\&        URxvt*keysym.M-Up:          \ee<M-Up>
+\&        URxvt*keysym.M-Down:        \ee<M-Down>
+\&        URxvt*keysym.M-Left:        \ee<M-Left>
+\&        URxvt*keysym.M-Right:       \ee<M-Right>
+\&        URxvt*keysym.M-C-0:         list.0123456789.\ee<M-C-.>
+\&        URxvt*keysym.M-C-a:         list.abcdefghijklmnopqrstuvwxyz.\e033<M-C-.>
+\&        URxvt*keysym.F12:           proto:\e033]701;zh_CN.GBK\e007
 .Ve
 .IP "I'm using keyboard model \s-1XXX\s0 that has extra Prior/Next/Insert keys. How do I make use of them?  For example, the Sun Keyboard type 4 has the following mappings that rxvt-unicode doesn't recognize." 4
 .IX Item "I'm using keyboard model XXX that has extra Prior/Next/Insert keys. How do I make use of them?  For example, the Sun Keyboard type 4 has the following mappings that rxvt-unicode doesn't recognize."
@@ -2256,6 +2229,22 @@ Remove support for swap screen.
 Add support for many small features that are not essential but nice to
 have. Normally you want this, but for very small binaries you may want to
 disable this.
+.Sp
+A non-exhaustive list of features enabled by \f(CW\*(C`\-\-enable\-frills\*(C'\fR (possibly
+in combination with other switches) is:
+.Sp
+.Vb 10
+\&  MWM-hints
+\&  seperate underline colour
+\&  settable border widths and borderless switch
+\&  settable extra linespacing
+\&  extra window properties (e.g. UTF-8 window names and PID)
+\&  iso-14755-2 and -3, and visual feedback
+\&  backindex and forwardindex escape sequence
+\&  window op and locale change escape sequences
+\&  tripleclickwords
+\&  settable insecure mode
+.Ve
 .IP "\-\-enable\-iso14755" 4
 .IX Item "--enable-iso14755"
 Enable extended \s-1ISO\s0 14755 support (see @@RXVT_NAME@@(1), or
index a56704895bd2bbc3549c8bee89b05e8e82c331fb..7eff48cb0f74de27fba0a806b08d627316ac9c9a 100644 (file)
@@ -506,49 +506,31 @@ FREQUENTLY ASKED QUESTIONS
         There are some compile-time selections available via configure.
         Unless you have run "configure" with the "--disable-resources"
         option you can use the `keysym' resource to alter the keystrings
-        associated with keysym 0xFF00 - 0xFFFF (function, cursor keys, etc).
-
-        Here's an example for a tn3270 session started using `rxvt -name
-        tn3270'
-
-           !#  ----- special uses ------:
-           ! tn3270 login, remap function and arrow keys.
-           tn3270*font:      *clean-bold-*-*--15-*
-
-           ! keysym - used by rxvt only
-           ! Delete - ^D
-           tn3270*keysym.0xFFFF:      \004
-
-           ! Home - ^A
-           tn3270*keysym.0xFF50:      \001
-           ! Left - ^B
-           tn3270*keysym.0xFF51:      \002
-           ! Up - ^P
-           tn3270*keysym.0xFF52:      \020
-           ! Right - ^F
-           tn3270*keysym.0xFF53:      \006
-           ! Down - ^N
-           tn3270*keysym.0xFF54:      \016
-           ! End - ^E
-           tn3270*keysym.0xFF57:      \005
-
-           ! F1 - F12
-           tn3270*keysym.0xFFBE:      \e1
-           tn3270*keysym.0xFFBF:      \e2
-           tn3270*keysym.0xFFC0:      \e3
-           tn3270*keysym.0xFFC1:      \e4
-           tn3270*keysym.0xFFC2:      \e5
-           tn3270*keysym.0xFFC3:      \e6
-           tn3270*keysym.0xFFC4:      \e7
-           tn3270*keysym.0xFFC5:      \e8
-           tn3270*keysym.0xFFC6:      \e9
-           tn3270*keysym.0xFFC7:      \e0
-           tn3270*keysym.0xFFC8:      \e-
-           tn3270*keysym.0xFFC9:      \e=
-
-           ! map Prior/Next to F7/F8
-           tn3270*keysym.0xFF55:      \e7
-           tn3270*keysym.0xFF56:      \e8
+        associated with keysyms.
+
+        Here's an example for a URxvt session started using `rxvt -name
+        URxvt'
+
+                URxvt*keysym.Home:          \e[1~
+                URxvt*keysym.End:           \e[4~
+                URxvt*keysym.C-apostrophe:  \e<C-'>
+                URxvt*keysym.C-slash:       \e<C-/>
+                URxvt*keysym.C-semicolon:   \e<C-;>
+                URxvt*keysym.C-grave:       \e<C-`>
+                URxvt*keysym.C-comma:       \e<C-,>
+                URxvt*keysym.C-period:      \e<C-.>
+                URxvt*keysym.C-0x60:        \e<C-`>
+                URxvt*keysym.C-Tab:         \e<C-Tab>
+                URxvt*keysym.C-Return:      \e<C-Return>
+                URxvt*keysym.S-Return:      \e<S-Return>
+                URxvt*keysym.S-space:       \e<S-Space>
+                URxvt*keysym.M-Up:          \e<M-Up>
+                URxvt*keysym.M-Down:        \e<M-Down>
+                URxvt*keysym.M-Left:        \e<M-Left>
+                URxvt*keysym.M-Right:       \e<M-Right>
+                URxvt*keysym.M-C-0:         list.0123456789.\e<M-C-.>
+                URxvt*keysym.M-C-a:         list.abcdefghijklmnopqrstuvwxyz.\033<M-C-.>
+                URxvt*keysym.F12:           proto:\033]701;zh_CN.GBK\007
 
     I'm using keyboard model XXX that has extra Prior/Next/Insert keys. How
     do I make use of them? For example, the Sun Keyboard type 4 has the
@@ -1729,6 +1711,20 @@ CONFIGURE OPTIONS
         to have. Normally you want this, but for very small binaries you may
         want to disable this.
 
+        A non-exhaustive list of features enabled by "--enable-frills"
+        (possibly in combination with other switches) is:
+
+          MWM-hints
+          seperate underline colour
+          settable border widths and borderless switch
+          settable extra linespacing
+          extra window properties (e.g. UTF-8 window names and PID)
+          iso-14755-2 and -3, and visual feedback
+          backindex and forwardindex escape sequence
+          window op and locale change escape sequences
+          tripleclickwords
+          settable insecure mode
+
     --enable-iso14755
         Enable extended ISO 14755 support (see rxvt(1), or doc/rxvt.1.txt).
         Basic support (section 5.1) is enabled by "--enable-frills", while
index 0aeee49b1a045ffe1a79972268256f58c0ab6589..a3f38f4ac4e2c366c1ff4acd2b48d132bf0d5edb 100644 (file)
  * with various KeySyms (0xFF00 - 0xFFFF).
  * Only works with the default hand-rolled resources.
  */
-#ifndef NO_RESOURCES
+#if !NO_RESOURCES && ENABLE_FRILLS
 # define KEYSYM_RESOURCE
 #endif
 
diff --git a/src/keyboard.C b/src/keyboard.C
new file mode 100644 (file)
index 0000000..5491125
--- /dev/null
@@ -0,0 +1,501 @@
+#include "../config.h"
+#include "rxvt.h"
+#include "keyboard.h"
+#include "command.h"
+#include <string.h>
+#include <X11/X.h>
+
+#ifdef KEYSYM_RESOURCE
+
+////////////////////////////////////////////////////////////////////////////////
+// default keycode translation map and keyevent handlers
+keyevent_handler keysym_translator;
+keyevent_handler keyrange_translator;
+keyevent_handler keyrange_translator_meta8;
+keyevent_handler keylist_translator;
+
+keysym_t keyboard_manager::stock_keymap_[] =
+{
+  /* examples */
+  /*        keysym,                state, range,                   handler,             str*/
+//{XK_ISO_Left_Tab,                    0,     1,         keysym_translator,           "\033[Z"},
+//{            'a',                    0,    26, keyrange_translator_meta8,           "a" "%c"},
+//{            'a',          ControlMask,    26, keyrange_translator_meta8,          "\ 1" "%c"},
+//{        XK_Left,                    0,     4,        keylist_translator,   "DACBZ" "\033[Z"},
+//{        XK_Left,            ShiftMask,     4,        keylist_translator,   "dacbZ" "\033[Z"},
+//{        XK_Left,          ControlMask,     4,        keylist_translator,   "dacbZ" "\033OZ"},
+//{         XK_Tab,          ControlMask,     1,         keysym_translator,      "\033<C-Tab>"},
+//{  XK_apostrophe,          ControlMask,     1,         keysym_translator,        "\033<C-'>"},
+//{       XK_slash,          ControlMask,     1,         keysym_translator,        "\033<C-/>"},
+//{   XK_semicolon,          ControlMask,     1,         keysym_translator,        "\033<C-;>"},
+//{       XK_grave,          ControlMask,     1,         keysym_translator,        "\033<C-`>"},
+//{       XK_comma,          ControlMask,     1,         keysym_translator,     "\033<C-\054>"},
+//{      XK_Return,          ControlMask,     1,         keysym_translator,    "\033<C-Return>"},
+//{      XK_Return,            ShiftMask,     1,         keysym_translator,    "\033<S-Return>"},
+//{            ' ',            ShiftMask,     1,         keysym_translator,    "\033<S-Space>"},
+//{            '.',          ControlMask,     1,         keysym_translator,        "\033<C-.>"},
+//{            '0',          ControlMask,    10,       keyrange_translator,   "0" "\033<C-%c>"},
+//{            '0', MetaMask|ControlMask,    10,       keyrange_translator, "0" "\033<M-C-%c>"},
+//{            'a', MetaMask|ControlMask,    26,       keyrange_translator, "a" "\033<M-C-%c>"},
+};
+
+void output_string (rxvt_term *rt,
+                    const char *str)
+{
+  assert (rt && str);
+  if (strncmp (str, "proto:", 6) == 0)
+    rt->cmd_write ((unsigned char*)str + 6, strlen (str) - 6);
+  else
+    rt->tt_write ((unsigned char*)str, strlen (str));
+}
+
+void output_string_meta8 (rxvt_term *rt,
+                          unsigned int state,
+                          char buf[],
+                          int buflen)
+{
+  if (state & rt->ModMetaMask)
+    {
+#ifdef META8_OPTION
+      if(rt->meta_char == 0x80) /* set 8-bit on */
+        {
+          for (char *ch = buf; ch < buf + buflen; ch++)
+            *ch |= 0x80;
+        }
+      else if(rt->meta_char == C0_ESC) /* escape prefix */
+#endif
+        {
+          const unsigned char ch = C0_ESC;
+          rt->tt_write (&ch, 1);
+        }
+    }
+
+  rt->tt_write ((unsigned char*)buf, buflen);
+}
+
+int format_keyrange_string (keysym_t *key,
+                            KeySym keysym,
+                            char buf[],
+                            int bufsize)
+{
+  int len;
+
+  assert (key->str);
+  len = snprintf (buf, bufsize, key->str + 1,
+                  keysym - key->keysym + (int)(key->str[0]));
+  if (len >= bufsize)
+    {
+      fprintf (stderr, "buffer overflowed!\n");
+      buf[bufsize-1] = '\0';
+    }
+  else if (len < 0)
+    {
+      perror("keyrange_translator()");
+    }
+
+  return len;
+}
+
+bool format_keylist_string (keysym_t *key,
+                            KeySym keysym,
+                            char buf[],
+                            int bufsize)
+{
+  char *p;
+
+  assert (key->str);
+  strncpy (buf, key->str + key->range + 1, bufsize);
+  buf[bufsize-1] = '\0';
+
+  p = strchr (buf, key->str[key->range]);
+  if (p)
+    {
+      *p = key->str[keysym - key->keysym];
+      return true;
+    }
+  else
+    {
+      fprintf (stderr, "invalid str for keylist_translator()!\n");
+      return false;
+    }
+}
+
+/////////////////////////////////////////////////////////////////
+void keysym_translator (rxvt_term *rt,
+                        keysym_t *key,
+                        KeySym keysym,
+                        unsigned int state)
+{
+  output_string (rt, key->str);
+}
+
+void keyrange_translator (rxvt_term *rt,
+                          keysym_t *key,
+                          KeySym keysym,
+                          unsigned int state)
+{
+  char buf[STRING_MAX];
+
+  if (format_keyrange_string (key, keysym, buf, sizeof(buf)) > 0)
+    output_string (rt, buf);
+}
+
+void keyrange_translator_meta8 (rxvt_term *rt,
+                                keysym_t *key,
+                                KeySym keysym,
+                                unsigned int state)
+{
+  int len;
+  char buf[STRING_MAX];
+
+  len = format_keyrange_string (key, keysym, buf, sizeof(buf));
+  if (len > 0)
+    output_string_meta8 (rt, state, buf, len);
+}
+
+void keylist_translator (rxvt_term *rt,
+                         keysym_t *key,
+                         KeySym keysym,
+                         unsigned int state)
+{
+  char buf[STRING_MAX];
+
+  format_keylist_string (key, keysym, buf, sizeof(buf));
+  output_string (rt, buf);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// return: #bits of '1'
+int
+bitcount (unsigned int n)
+{
+  int i;
+  for (i = 0; n; ++i, n &= (n - 1));
+  return i;
+}
+
+// return: priority_of_a - priority_of_b
+int
+compare_priority (keysym_t *a, keysym_t *b)
+{
+  assert (a && b);
+
+  // (the more '1's in state; the less range): the greater priority
+  int ca = bitcount (a->state/* & AllModMask*/);
+  int cb = bitcount (b->state/* & AllModMask*/);
+  if (ca != cb)
+    return ca - cb;
+//else if (a->state != b->state) // this behavior is to be disscussed
+//  return b->state - a->state;
+  else
+    return b->range - a->range;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+keyboard_manager::keyboard_manager (rxvt_term *rt)
+  :term_(rt)
+{
+  keymap_.reserve (256);
+  hash_[0] = 1; // hash_[0] != 0 indicates uninitialized data
+}
+
+keyboard_manager::~keyboard_manager ()
+{
+  clear ();
+}
+
+void
+keyboard_manager::clear ()
+{
+  keymap_.clear ();
+  hash_[0] = 2;
+
+  for(unsigned int i = 0;i < user_translations_.size();++i)
+    {
+      delete[] user_translations_[i];
+      user_translations_[i] = 0;
+    }
+
+  for(unsigned int i = 0;i < user_keymap_.size();++i)
+    {
+      delete user_keymap_[i];
+      user_keymap_[i] = 0;
+    }
+
+  user_keymap_.clear();
+  user_translations_.clear();
+}
+
+// a wrapper for register_keymap,
+// so that outside codes don't have to know so much details.
+//
+// the string 'trans' is copied to an internal managed buffer,
+// so the caller can free memory of 'trans' at any time.
+void
+keyboard_manager::register_user_translation (KeySym keysym,
+                                             unsigned int state,
+                                             const char *trans)
+{
+  assert(trans);
+
+  keysym_t *key = new keysym_t;
+  const char *translation = new char[1+strlen(trans)];
+
+  if(key && translation)
+    {
+      key->keysym = keysym;
+      key->state = state;
+      key->range = 1;
+      key->str = translation;
+
+      if (strncmp (trans, "list", 4) == 0)
+        {
+          const char *p = &trans[4];
+          if (*p && (p = strchr (p+1, *p)))
+            if ((p - trans - 5 > 1) && strchr (p+1, *p))
+              {
+                strcpy (translation, trans+5);
+                key->range = p - trans - 5;
+                key->handler = keylist_translator;
+              }
+        }
+      if (key->range == 1)
+        {
+          strcpy (translation, trans);
+          key->handler = keysym_translator;
+        }
+
+      user_keymap_.push_back (key);
+      user_translations_.push_back (translation);
+      register_keymap (key);
+    }
+  else
+    {
+      delete key;
+      delete[] translation;
+      rxvt_fatal ("out of memory, aborting.\n");
+    }
+}
+
+void
+keyboard_manager::register_keymap (keysym_t *key)
+{
+  assert (key);
+  assert (key->handler);
+  assert (key->range >= 1);
+
+  if (keymap_.size () == keymap_.capacity ())
+    keymap_.reserve (keymap_.size () * 2);
+
+  keymap_.push_back (key);
+  hash_[0] = 3;
+}
+
+void
+keyboard_manager::register_done ()
+{
+  unsigned int i, n = sizeof(stock_keymap_)/sizeof(keysym_t);
+
+  if(keymap_.back() != &stock_keymap_[n-1])
+    for(i = 0;i < n;++i)
+      register_keymap(&stock_keymap_[i]);
+
+  purge_duplicate_keymap ();
+
+  for (i = 0; i < keymap_.size(); ++i)
+    {
+      keysym_t *key = keymap_[i];
+
+      assert (bitcount (term_->ModMetaMask) == 1
+              && "call me after ModMetaMask was set!");
+      if (key->state & MetaMask)
+        {
+          //key->state &= ~MetaMask;
+          key->state |= term_->ModMetaMask;
+        }
+
+      assert (bitcount (term_->ModNumLockMask) == 1
+              && "call me after ModNumLockMask was set!");
+      if (key->state & NumLockMask)
+        {
+          //key->state &= ~NumLockMask;
+          key->state |= term_->ModNumLockMask;
+        }
+    }
+
+  setup_hash ();
+}
+
+bool keyboard_manager::dispatch (KeySym keysym, unsigned int state)
+{
+  assert(hash_[0] == 0 && "register_done() need to be called");
+
+  int index = find_keysym (keysym, state);
+
+  if (index >= 0)
+    {
+      assert (term_ && keymap_[index] && keymap_[index]->handler);
+      keymap_[index]->handler (term_, keymap_[index], keysym, state);
+      return true;
+    }
+  else
+  {
+    // fprintf(stderr,"[%x:%x]",state,keysym);
+    return false;
+  }
+}
+
+// purge duplicate keymap_ entries
+void
+keyboard_manager::purge_duplicate_keymap ()
+{
+  for (unsigned int i = 0; i < keymap_.size (); ++i)
+    {
+      for (unsigned int j = 0; j < i; ++j)
+        {
+          if (keymap_[i] == keymap_[j])
+            {
+              while (keymap_[i] == keymap_.back ())
+                keymap_.pop_back ();
+              if (i < keymap_.size ())
+                {
+                  keymap_[i] = keymap_.back ();
+                  keymap_.pop_back ();
+                }
+              break;
+            }
+        }
+    }
+}
+
+void
+keyboard_manager::setup_hash ()
+{
+  unsigned int i, index, hashkey;
+  vector<keysym_t *> sorted_keymap;
+  u16 hash_budget_size[KEYSYM_HASH_BUDGETS];     // size of each budget
+  u16 hash_budget_counter[KEYSYM_HASH_BUDGETS];  // #elements in each budget
+
+  memset (hash_budget_size, 0, sizeof (hash_budget_size));
+  memset (hash_budget_counter, 0, sizeof (hash_budget_counter));
+
+  // count keysyms for corresponding hash budgets
+  for (i = 0; i < keymap_.size (); ++i)
+    {
+      assert (keymap_[i]);
+      hashkey = (keymap_[i]->keysym & KEYSYM_HASH_MASK);
+      ++hash_budget_size[hashkey];
+    }
+
+  // keysym A with range>1 is counted one more time for
+  // every keysym B lies in its range
+  for (i = 0; i < keymap_.size (); ++i)
+    {
+      if (keymap_[i]->range > 1)
+        {
+          for (int j = min (keymap_[i]->range, KEYSYM_HASH_BUDGETS) - 1;j > 0; --j)
+            {
+              hashkey = ((keymap_[i]->keysym + j) & KEYSYM_HASH_MASK);
+              if (hash_budget_size[hashkey])
+                ++hash_budget_size[hashkey];
+            }
+        }
+    }
+
+  // now we know the size of each budget
+  // compute the index of each budget
+  hash_[0] = 0;
+  for (index = 0,i = 1; i < KEYSYM_HASH_BUDGETS; ++i)
+    {
+      index += hash_budget_size[i-1];
+      hash_[i] = (hash_budget_size[i] ? index : hash_[i-1]);
+    }
+  // and allocate just enough space
+  //sorted_keymap.reserve (hash_[i - 1] + hash_budget_size[i - 1]);
+  sorted_keymap.insert (sorted_keymap.begin(), index + hash_budget_size[i - 1], 0);
+
+  // fill in sorted_keymap
+  // it is sorted in each budget
+  for (i = 0; i < keymap_.size (); ++i)
+    {
+      for (int j = min (keymap_[i]->range, KEYSYM_HASH_BUDGETS) - 1;j >= 0; --j)
+        {
+          hashkey = ((keymap_[i]->keysym + j) & KEYSYM_HASH_MASK);
+          if (hash_budget_size[hashkey])
+            {
+              index = hash_[hashkey] + hash_budget_counter[hashkey];
+              while (index > hash_[hashkey] &&
+                     compare_priority (keymap_[i],
+                                       sorted_keymap[index - 1]) > 0)
+                {
+                  sorted_keymap[index] = sorted_keymap[index - 1];
+                  --index;
+                }
+              sorted_keymap[index] = keymap_[i];
+              ++hash_budget_counter[hashkey];
+            }
+        }
+    }
+
+  keymap_.swap (sorted_keymap);
+
+#if defined (DEBUG_STRICT) || defined (DEBUG_KEYBOARD)
+  // check for invariants
+  for (i = 0; i < KEYSYM_HASH_BUDGETS; ++i)
+    {
+      index = hash_[i];
+      for (int j = 0; j < hash_budget_size[i]; ++j)
+        {
+          if (keymap_[index + j]->range == 1)
+            assert (i == (keymap_[index + j]->keysym & KEYSYM_HASH_MASK));
+          if (j)
+            assert (compare_priority (keymap_[index + j - 1],
+                                      keymap_[index + j]) >= 0);
+        }
+    }
+
+  // this should be able to detect most possible bugs
+  for (i = 0; i < sorted_keymap.size (); ++i)
+    {
+      keysym_t *a = sorted_keymap[i];
+      for (int j = 0; j < a->range; ++j)
+        {
+          int index = find_keysym (a->keysym + j, a->state & AllModMask);
+          assert (index >= 0);
+          keysym_t *b = keymap_[index];
+          assert (i == (signed)index || // the normally expected result
+              (a->keysym + j) >= b->keysym &&
+              (a->keysym + j) <= (b->keysym + b->range) &&
+              compare_priority (a, b) <= 0); // is effectively the same
+        }
+    }
+#endif
+}
+
+int
+keyboard_manager::find_keysym (KeySym keysym, unsigned int state)
+{
+  int hashkey = (keysym & KEYSYM_HASH_MASK);
+  unsigned int index = hash_[hashkey];
+
+  for (;index < keymap_.size(); ++index)
+    {
+      keysym_t *key = keymap_[index];
+      assert (key);
+      if (key->keysym <= keysym &&
+          key->keysym + key->range > keysym &&
+          // match only the specified bits in state and ignore others
+          (key->state & (unsigned int)AllModMask) == (key->state & state))
+        {
+          return index;
+        }
+      else if (key->keysym > keysym &&
+               key->range == 1)
+        return -1;
+    }
+
+  return -1;
+}
+
+#endif /* KEYSYM_RESOURCE */
+// vim:et:ts=2:sw=2
diff --git a/src/keyboard.h b/src/keyboard.h
new file mode 100644 (file)
index 0000000..75b837a
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef KEYBOARD_H_
+#define KEYBOARD_H_
+
+#include "feature.h"
+#include "rxvtutil.h"
+
+#ifdef KEYSYM_RESOURCE
+
+#define KEYSYM_HASH_BITS        9       /* lowest #bits of keysym is used as hash key */
+#define KEYSYM_HASH_BUDGETS     (1<<KEYSYM_HASH_BITS)
+#define KEYSYM_HASH_MASK        (KEYSYM_HASH_BUDGETS-1)
+
+#define MetaMask                0x0100
+#define NumLockMask             0x0200
+#define AllModMask              (ShiftMask | LockMask | ControlMask \
+                                | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)
+
+#if (AllModMask & (MetaMask | NumLockMask)) != 0
+#error redefine MetaMask or NumLockMask!
+#endif
+
+struct rxvt_term;
+struct keysym_t;
+typedef void (keyevent_handler) (rxvt_term *rt,
+                                 keysym_t *key,
+                                 KeySym keysym,
+                                 unsigned int state);
+typedef unsigned short u16;
+
+struct keysym_t
+{
+  KeySym            keysym;
+  /* only the lower 8 bits of state are used for matching according to X.h */
+  /* the higher bits are preserved for Meta/NumLock keys */
+  /* which are mapped to corresponding lower bits at register time */
+  u16               state;    /* indicates each modifiers' DOWN/UP status         */
+  u16               range;    /* =1: single keysym; >1: a of range keysyms        */
+  keyevent_handler *handler;  /* event handler                                    */
+  const char       *str;      /* would normally be a keycode translation          */
+};
+
+
+class keyboard_manager
+{
+public:
+  keyboard_manager (rxvt_term *rt);
+  ~keyboard_manager ();
+
+  void clear ();
+  void register_user_translation (KeySym keysym, unsigned int state, const char *trans);
+  void register_done ();        // call this to make newly registered keymaps take effect
+  bool dispatch (KeySym keysym, unsigned int state);
+
+private:
+  void register_keymap (keysym_t *key);
+  void purge_duplicate_keymap ();
+  void setup_hash ();
+  int find_keysym (KeySym keysym, unsigned int state);
+
+private:
+  rxvt_term * const term_;
+
+  u16 hash_[KEYSYM_HASH_BUDGETS];               //
+  vector<keysym_t *> keymap_;
+
+  // stock keymaps are all static data
+  static keysym_t stock_keymap_[];
+  // user keymaps and their .string are dynamicly allocated and freed
+  vector<keysym_t *> user_keymap_;
+  vector<const char *> user_translations_;
+};
+
+#endif /* KEYSYM_RESOURCE */
+#endif /* KEYBOARD_H_ */
+// vim:et:ts=2:sw=2
index fd063ddbe3f1f12b093a94660a37f5ef60adf084..9e3bdf5342b2b6d8292efe0d428d52d33660b2b8 100644 (file)
@@ -18,6 +18,9 @@ template<typename T, typename U>
 static inline T min (T a, U b) { return a < b ? a : (T)b; }
 template<typename T, typename U>
 static inline T max (T a, U b) { return a > b ? a : (T)b; }
+template<typename T>
+static inline void swap (T& a, T& b) { T t=a; a=b; b=t; }
+
 
 struct zero_initialized {
   void *operator new (size_t s);
@@ -42,72 +45,72 @@ private:
 public:
     const_iterator begin () const
     {
-       return &_buf[0];
+        return &_buf[0];
     }
     iterator begin ()
     {
-       return &_buf[0];
+        return &_buf[0];
     }
     const_iterator end () const
     {
-       return &_buf[_last];
+        return &_buf[_last];
     }
     iterator end ()
     {
-       return &_buf[_last];
+        return &_buf[_last];
     }
     size_type capacity () const
     {
-       return _size;
+        return _size;
     }
     size_type size () const
     {
-       return _last;
+        return _last;
     }
 
 private:
     static T *alloc (size_type n)
     {
-       return (T *)::operator new ((size_t) (n * sizeof (T)));
+        return (T *)::operator new ((size_t) (n * sizeof (T)));
     }
     static void dealloc (T *buf)
     {
-       if (buf)
-           ::operator delete (buf);
+        if (buf)
+            ::operator delete (buf);
     }
 
     void reserve (iterator where, size_type n)
     {
-       if (_last + n <= _size) {
-           memmove (where+n, where, (end ()-where)*sizeof (T));
-       } else {
-           size_type sz = _last+n;
-           sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
-           T *nbuf = alloc (sz);
-           if (_buf) {
-               memcpy (nbuf, begin (), (where-begin ())*sizeof (T));
-               memcpy (nbuf + (where-begin ()) + n, where,
-                       (end ()-where)*sizeof (T));
-               dealloc (_buf);
-           }
-           _buf = nbuf;
-           _size = sz;
-       }
+        if (_last + n <= _size) {
+            memmove (where+n, where, (end ()-where)*sizeof (T));
+        } else {
+            size_type sz = _last+n;
+            sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
+            T *nbuf = alloc (sz);
+            if (_buf) {
+                memcpy (nbuf, begin (), (where-begin ())*sizeof (T));
+                memcpy (nbuf + (where-begin ()) + n, where,
+                        (end ()-where)*sizeof (T));
+                dealloc (_buf);
+            }
+            _buf = nbuf;
+            _size = sz;
+        }
     }
 
 public:
     void reserve (size_type sz)
     {
-       if (_size < sz) {
-           sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
-           T *nbuf = alloc (sz);
-           if (_buf) {
-               memcpy (nbuf, begin (), size ()*sizeof (T));
-               dealloc (_buf);
-           }
-           _buf = nbuf;
-           _size = sz;
-       }
+        if (_size < sz) {
+            sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size);
+            T *nbuf = alloc (sz);
+            if (_buf) {
+                memcpy (nbuf, begin (), size ()*sizeof (T));
+                dealloc (_buf);
+            }
+            _buf = nbuf;
+            _size = sz;
+        }
     }
     simplevec ()
     : _last(0), _size(0), _buf(0)
@@ -116,146 +119,152 @@ public:
     simplevec (size_type n, const T& t = T ())
     : _last(0), _size(0), _buf(0)
     {
-       insert (begin (), n, t);
+        insert (begin (), n, t);
     }
     simplevec (const_iterator first, const_iterator last)
     : _last(0), _size(0), _buf(0)
     {
-       insert (begin (), first, last);
+        insert (begin (), first, last);
     }
     simplevec (const simplevec<T> &v)
     : _last(0), _size(0), _buf(0)
     {
-       reserve (v._last);
-       memcpy (_buf, v.begin (), v.size ()*sizeof (T));
-       _last = v._last;
+        reserve (v._last);
+        memcpy (_buf, v.begin (), v.size ()*sizeof (T));
+        _last = v._last;
     }
     simplevec<T> &operator= (const simplevec<T> &v)
     {
-       if (this != &v) {
-           _last = 0;
-           reserve (v._last);
-           memcpy (_buf, v.begin (), v.size ()*sizeof (T));
-           _last = v._last;
-       }
+        if (this != &v) {
+            _last = 0;
+            reserve (v._last);
+            memcpy (_buf, v.begin (), v.size ()*sizeof (T));
+            _last = v._last;
+        }
         return *this;
     }
     ~simplevec ()
     {
-       dealloc (_buf);
+        dealloc (_buf);
     }
     const T &front () const
     {
-       //ministl_assert (size () > 0);
-       return _buf[0];
+        //ministl_assert (size () > 0);
+        return _buf[0];
     }
     T &front ()
     {
-       //ministl_assert (size () > 0);
-       return _buf[0];
+        //ministl_assert (size () > 0);
+        return _buf[0];
     }
     const T &back () const
     {
-       //ministl_assert (size () > 0);
-       return _buf[_last-1];
+        //ministl_assert (size () > 0);
+        return _buf[_last-1];
     }
     T &back ()
     {
-       //ministl_assert (size () > 0);
-       return _buf[_last-1];
+        //ministl_assert (size () > 0);
+        return _buf[_last-1];
     }
     bool empty () const
     {
-       return _last == 0;
+        return _last == 0;
     }
     void clear ()
     {
-       _last = 0;
+        _last = 0;
     }
     void push_back (const T &t)
     {
-       reserve (_last+1);
-       *end () = t;
-       ++_last;
+        reserve (_last+1);
+        *end () = t;
+        ++_last;
     }
     void push_back (T &t)
     {
-       reserve (_last+1);
-       *end () = t;
-       ++_last;
+        reserve (_last+1);
+        *end () = t;
+        ++_last;
     }
     void pop_back ()
     {
-       //ministl_assert (size () > 0);
-       --_last;
+        //ministl_assert (size () > 0);
+        --_last;
     }
     const T &operator[] (size_type idx) const
     {
-       //ministl_assert (idx < size ());
-       return _buf[idx];
+        //ministl_assert (idx < size ());
+        return _buf[idx];
     }
     T &operator[] (size_type idx)
     {
-       //ministl_assert (idx < size ());
-       return _buf[idx];
+        //ministl_assert (idx < size ());
+        return _buf[idx];
     }
     iterator insert (iterator pos, const T &t)
     {
-       //ministl_assert (pos <= end ());
-       long at = pos - begin ();
-       reserve (pos, 1);
-       pos = begin ()+at;
-       *pos = t;
-       ++_last;
-       return pos;
+        //ministl_assert (pos <= end ());
+        long at = pos - begin ();
+        reserve (pos, 1);
+        pos = begin ()+at;
+        *pos = t;
+        ++_last;
+        return pos;
     }
     iterator insert (iterator pos, const_iterator first, const_iterator last)
     {
         //ministl_assert (pos <= end ());
-       long n = last - first;
-       long at = pos - begin ();
-       if (n > 0) {
-           reserve (pos, n);
-           pos = begin ()+at;
-           memcpy (pos, first, (last-first)*sizeof (T));
-           _last += n;
-       }
-       return pos;
+        long n = last - first;
+        long at = pos - begin ();
+        if (n > 0) {
+            reserve (pos, n);
+            pos = begin ()+at;
+            memcpy (pos, first, (last-first)*sizeof (T));
+            _last += n;
+        }
+        return pos;
     }
     iterator insert (iterator pos, size_type n, const T &t)
     {
         //ministl_assert (pos <= end ());
-       long at = pos - begin ();
-       if (n > 0) {
-           reserve (pos, n);
-           pos = begin ()+at;
-           for (int i = 0; i < n; ++i)
-               pos[i] = t;
-           _last += n;
-       }
-       return pos;
+        long at = pos - begin ();
+        if (n > 0) {
+            reserve (pos, n);
+            pos = begin ()+at;
+            for (int i = 0; i < n; ++i)
+                pos[i] = t;
+            _last += n;
+        }
+        return pos;
     }
     void erase (iterator first, iterator last)
     {
-       if (last != first) {
-           memmove (first, last, (end ()-last)*sizeof (T));
-           _last -= last - first;
-       }
+        if (last != first) {
+            memmove (first, last, (end ()-last)*sizeof (T));
+            _last -= last - first;
+        }
     }
     void erase (iterator pos)
     {
         if (pos != end ()) {
-           memmove (pos, pos+1, (end ()- (pos+1))*sizeof (T));
+            memmove (pos, pos+1, (end ()- (pos+1))*sizeof (T));
             --_last;
         }
     }
+    void swap (simplevec<T> &t)
+    {
+        ::swap(_last, t._last);
+        ::swap(_size, t._size);
+        ::swap(_buf, t._buf);
+    }
 };
 
 template<class T>
 bool operator== (const simplevec<T> &v1, const simplevec<T> &v2)
 {
     if (v1.size () != v2.size ())
-       return false;
+        return false;
     return !v1.size () || !memcmp (&v1[0], &v2[0], v1.size ()*sizeof (T));
 }
 
@@ -265,9 +274,9 @@ bool operator< (const simplevec<T> &v1, const simplevec<T> &v2)
     unsigned long minlast = min (v1.size (), v2.size ());
     for (unsigned long i = 0; i < minlast; ++i) {
         if (v1[i] < v2[i])
-           return true;
-       if (v2[i] < v1[i])
-           return false;
+            return true;
+        if (v2[i] < v1[i])
+            return false;
     }
     return v1.size () < v2.size ();
 }