root/foundation-apps/mxterm-maxx/gen-pc-fkeys.pl

Revision 8, 8.8 KB (checked in by emasson, 3 years ago)

initial import for the community edition

Line 
1#! /usr/bin/perl -w
2# Author: Thomas E. Dickey
3# $XTermId: gen-pc-fkeys.pl,v 1.21 2007/11/30 23:03:55 tom Exp $
4#
5# Construct a list of function-key definitions corresponding to xterm's
6# Sun/PC keyboard.  This uses ncurses' infocmp to obtain the strings (including
7# extensions) to modify (and verify).
8use strict;
9
10my($max_modifier, $terminfo);
11my(@old_fkeys, $opt_fkeys, $min_fkeys, $max_fkeys);
12my(%old_ckeys, $opt_ckeys, $min_ckeys, $max_ckeys);
13my(%old_ekeys, $opt_ekeys, $min_ekeys, $max_ekeys);
14
15my(@ckey_names);
16@ckey_names = (
17        'kcud1', 'kcub1', 'kcuf1', 'kcuu1',     # 1 = no modifiers
18        'kDN',   'kLFT''kRIT''kUP',       # 2 = shift
19        # make_ckey_names() repeats this row, appending the modifier code
20        );
21my %ckey_names;
22my(@ckey_known);
23@ckey_known = (
24        'kind''kLFT''kRIT''kri',       # 2 = shift (standard)
25        );
26
27my(@ekey_names);
28@ekey_names = (
29        'khome', 'kend''knp',   'kpp',   'kdch1', 'kich1', # 1 = no modifiers
30        'kHOM''kEND''kNXT''kPRV''kDC',   'kIC',   # 2 = shift
31        # make_ekey_names() repeats this row, appending the modifier code
32);
33my %ekey_names;
34
35$min_fkeys=12;          # the number of "real" function keys on your keyboard
36$max_fkeys=64;          # the number of function-keys terminfo can support
37$max_modifier=8;        # modifier 1 + (1=shift, 2=alt, 4=control 8=meta)
38
39$min_ckeys=4;           # the number of "real" cursor keys on your keyboard
40$max_ckeys=($min_ckeys * ($max_modifier - 1));
41
42$min_ekeys=6;           # the number of "real" editing keys on your keyboard
43$max_ekeys=($min_ekeys * ($max_modifier - 1));
44
45$opt_ckeys=2;           # xterm's modifyCursorKeys resource
46$opt_ekeys=2;           # xterm's modifyCursorKeys resource
47$opt_fkeys=2;           # xterm's modifyFunctionKeys resource
48$terminfo="xterm-new"# the terminfo entry to use
49
50# apply the given modifier to the terminfo string, return the result
51sub modify_fkey($$$) {
52        my $code = $_[0];
53        my $text = $_[1];
54        my $opts = $_[2];
55        if (not defined($text)) {
56                $text = "";
57        } elsif ($code != 1) {
58                $text =~ s/\\EO/\\E\[/ if ($opts >= 1);
59
60                my $piece = substr $text, 0, length ($text) - 1;
61                my $final = substr $text, length ($text) - 1;
62                my $check = substr $piece, length ($piece) - 1;
63                if ($check =~ /[0-9]/) {
64                        $code = ";" . $code;
65                } elsif ( $check =~ /\[/ and $opts >= 2) {
66                        $code = "1;" . $code;
67                }
68                if ( $opts >= 3 ) {
69                        $code = ">" . $code;
70                }
71                $text = $piece . $code . $final;
72                $text =~ s/([\d;]+)>/>$1/;
73        }
74        return $text;
75}
76
77# compute the next modifier value -
78# Cycling through the modifiers is not just like counting.  Users prefer
79# pressing one modifier (even if using Emacs).  So first we cycle through
80# the individual modifiers, then for completeness two, three, etc.
81sub next_modifier {
82        my $code = $_[0];
83        my $mask = $code - 1;
84        if ($mask == 0) {
85                $mask = 1;      # shift
86        } elsif ($mask == 1) {
87                $mask = 4;      # control
88        } elsif ($mask == 2) {
89                $mask = 3;      # shift+alt
90        } elsif ($mask == 4) {
91                $mask = 5;      # shift+control
92        } elsif ($mask == 5) {
93                $mask = 2;      # alt
94        }
95        # printf ("# next_modifier(%d) = %d\n", $code, $mask + 1);
96        return $mask + 1;
97}
98
99sub make_ckey_names() {
100        my ($j, $k);
101        my $min = $min_ckeys * 2;
102        my $max = $max_ckeys - 1;
103
104        # printf "# make_ckey_names\n";
105        for $j ($min..$max) {
106                $k = 1 + substr($j / $min_ckeys, 0, 1);
107                $ckey_names[$j] = $ckey_names[$min_ckeys + ($j % $min_ckeys)] . $k;
108                # printf "# make %d:%s\n", $j, $ckey_names[$j];
109        }
110        for $j (0..$#ckey_names) {
111                # printf "# %d:%s\n", $j, $ckey_names[$j];
112                $ckey_names{$ckey_names[$j]} = $j;
113        }
114}
115
116sub make_ekey_names() {
117        my ($j, $k);
118        my $min = $min_ekeys * 2;
119        my $max = $max_ekeys - 1;
120
121        # printf "# make_ekey_names\n";
122        for $j ($min..$max) {
123                $k = 1 + substr($j / $min_ekeys, 0, 1);
124                $ekey_names[$j] = $ekey_names[$min_ekeys + ($j % $min_ekeys)] . $k;
125                # printf "# make %d:%s\n", $j, $ekey_names[$j];
126        }
127        for $j (0..$#ekey_names) {
128                # printf "# %d:%s\n", $j, $ekey_names[$j];
129                $ekey_names{$ekey_names[$j]} = $j;
130        }
131}
132
133# Read the terminfo entry's list of function keys $old_fkeys[].
134# We could handle $old_fkeys[0], but choose to start numbering from 1.
135sub readterm($) {
136        my $term = $_[0];
137        my($key, $n, $str);
138        my(@list) = `infocmp -x -1 $term`;
139
140        for $n (0..$#list) {
141                chop $list[$n];
142                $list[$n] =~ s/^[[:space:]]//;
143
144                $key = $list[$n];
145                $key =~ s/=.*//;
146
147                $str = $list[$n];
148                $str =~ s/^[^=]+=//;
149                $str =~ s/,$//;
150
151                if ( $list[$n] =~ /^kf[[:digit:]]+=/ ) {
152                        $key =~ s/^kf//;
153                        # printf "# $n:%s(%d)(%s)\n", $list[$n], $key, $str;
154                        $old_fkeys[$key] = $str;
155                } elsif ( $key =~ /^kc[[:alpha:]]+1/
156                        or $key =~ /^k(LFT|RIT|UP|DN)\d?/) {
157                        # printf "# $n:%s(%d)(%s)\n", $list[$n], $key, $str;
158                        $old_ckeys{$key} = $str;
159                } elsif ( defined $ekey_names{$key} ) {
160                        # printf "# $n:%s(%s)(%s)\n", $list[$n], $key, $str;
161                        $old_ekeys{$key} = $str;
162                }
163        }
164        # printf ("last index:%d\n", $#old_fkeys);
165}
166
167# read the whole terminfo to ensure we get the non-modified stuff, then read
168# the part that contains modifiers.
169sub read_part($) {
170        my $part = $_[0];
171
172        %old_ckeys = ();
173        @old_fkeys = ();
174        readterm($terminfo);
175        readterm($part);
176}
177
178sub nameof_ckeys($) {
179        my $opts = $_[0];
180        my $optname = "xterm+pcc" . ($opts >= 0 ? $opts : "n");
181        return $optname;
182}
183
184sub generate_ckeys($) {
185        my $opts = $_[0];
186        my($modifier, $cur_ckey, $index);
187
188        printf "%s|fragment with modifyCursorKeys:%s,\n",
189                nameof_ckeys($opts), $opts;
190
191        # show the standard cursor definitions
192        $modifier = 1;
193        for ($index = 0; $index < $min_ckeys; ++$index) {
194                $cur_ckey = $index + ($modifier * $min_ckeys);
195                my $name = $ckey_known[$index];
196                my $input = $old_ckeys{$ckey_names[$index]};
197                my $result = modify_fkey($modifier + 1, $input, $opts);
198                printf "\t%s=%s,\n", $name, $result;
199                if (defined $old_ckeys{$name}) {
200                        if ($old_ckeys{$name} ne $result) {
201                                printf "# found %s=%s\n", $name, $old_ckeys{$name};
202                        }
203                }
204        }
205
206        # show the extended cursor definitions
207        for ($index = 0; $index < $min_ckeys; ++$index) {
208                for ($modifier = 1; $modifier < $max_modifier; ++$modifier) {
209                        $cur_ckey = $index + ($modifier * $min_ckeys);
210                        if (defined $ckey_names[$cur_ckey] and
211                                $ckey_names[$cur_ckey] ne "kLFT" and
212                                $ckey_names[$cur_ckey] ne "kRIT" ) {
213                                my $name = $ckey_names[$cur_ckey];
214                                my $input = $old_ckeys{$ckey_names[$index]};
215                                my $result = modify_fkey($modifier + 1, $input, $opts);
216                                printf "\t%s=%s,\n", $name, $result;
217                                if (defined $old_ckeys{$name}) {
218                                        if ($old_ckeys{$name} ne $result) {
219                                                printf "# found %s=%s\n", $name, $old_ckeys{$name};
220                                        }
221                                }
222                        }
223                }
224        }
225}
226
227sub nameof_ekeys($) {
228        my $opts = $_[0];
229        my $optname = "xterm+pce" . ($opts >= 0 ? $opts : "n");
230        return $optname;
231}
232
233sub generate_ekeys($) {
234        my $opts = $_[0];
235        my($modifier, $cur_ekey, $index);
236
237        printf "%s|fragment with modifyCursorKeys:%s,\n",
238                nameof_ekeys($opts), $opts;
239
240        for ($index = 0; $index < $min_ekeys; ++$index) {
241                for ($modifier = 1; $modifier < $max_modifier; ++$modifier) {
242                        $cur_ekey = $index + ($modifier * $min_ekeys);
243                        if (defined $ekey_names[$cur_ekey] ) {
244                                my $name = $ekey_names[$cur_ekey];
245                                my $input = $old_ekeys{$ekey_names[$index]};
246                                my $result = modify_fkey($modifier + 1, $input, $opts);
247                                printf "\t%s=%s,\n", $name, $result;
248                                if (defined $old_ekeys{$name}) {
249                                        if ($old_ekeys{$name} ne $result) {
250                                                printf "# found %s=%s\n", $name, $old_ekeys{$name};
251                                        }
252                                }
253                        }
254                }
255        }
256}
257
258sub nameof_fkeys($) {
259        my $opts = $_[0];
260        my $optname = "xterm+pcf" . ($opts >= 0 ? $opts : "n");
261        return $optname;
262}
263
264sub generate_fkeys($) {
265        my $opts = $_[0];
266        my($modifier, $cur_fkey);
267
268        printf "%s|fragment with modifyFunctionKeys:%s and ctrlFKeys:10,\n",
269                nameof_fkeys($opts), $opts;
270
271        for ($cur_fkey = 1, $modifier = 1; $cur_fkey < $max_fkeys; ++$cur_fkey) {
272                my $index = (($cur_fkey - 1) % $min_fkeys);
273                if ($index == 0 && $cur_fkey != 1) {
274                        $modifier = next_modifier($modifier);
275                }
276                if (defined $old_fkeys[$index + 1]) {
277                        my $input = $old_fkeys[$index + 1];
278                        my $result = modify_fkey($modifier, $input, $opts);
279                        printf "\tkf%d=%s,\n", $cur_fkey, $result;
280                        if (defined $old_fkeys[$cur_fkey]) {
281                                if ($old_fkeys[$cur_fkey] ne $result) {
282                                        printf "# found kf%d=%s\n", $cur_fkey, $old_fkeys[$cur_fkey];
283                                }
284                        }
285                }
286        }
287}
288
289sub show_default() {
290        readterm($terminfo);
291
292        printf "xterm+pcfkeys|fragment for PC-style keys,\n";
293        printf "\tuse=%s,\n", nameof_ckeys($opt_ckeys);
294        printf "\tuse=%s,\n", nameof_ekeys($opt_ekeys);
295        printf "\tuse=%s,\n", nameof_fkeys($opt_fkeys);
296
297        generate_ckeys($opt_ckeys);
298        generate_ekeys($opt_ekeys);
299        generate_fkeys($opt_fkeys);
300}
301
302sub show_nondefault()
303{
304        my $opts;
305
306        for ($opts = 0; $opts <= 3; ++$opts) {
307                if ($opts != $opt_ckeys) {
308                        read_part(nameof_ckeys($opts));
309                        generate_ckeys($opts);
310                }
311        }
312
313        for ($opts = 0; $opts <= 3; ++$opts) {
314                if ($opts != $opt_ekeys) {
315                        read_part(nameof_ekeys($opts));
316                        generate_ekeys($opts);
317                }
318        }
319
320        for ($opts = 0; $opts <= 3; ++$opts) {
321                if ($opts != $opt_fkeys) {
322                        read_part(nameof_fkeys($opts));
323                        generate_fkeys($opts);
324                }
325        }
326}
327
328make_ckey_names();
329make_ekey_names();
330
331printf "# gen-pc-fkeys.pl\n";
332printf "# %s:timode\n", "vile";
333show_default();
334show_nondefault();
Note: See TracBrowser for help on using the browser.