UI-KeyboardLayout
view release on metacpan or search on metacpan
examples/klc2c.pl view on Meta::CPAN
my($VK2bind, $scan2VK) = scan_layout $IN{LAYOUT}, \@VK2binds, \@VK2bindsX;
my %VK2bind = %$VK2bind;
my %scan2VK = %$scan2VK;
($VK2bind, $scan2VK) = scan_layout $L_default, \@VK2binds, \@VK2bindsX, $VK2bind, $scan2VK;
%VK2bind = (%VK2bind, %$VK2bind);
%scan2VK = (%scan2VK, %$scan2VK);
############################# Output redefinition of scancodes (if needed)
my($FX_scans, $add_X, $add_Y, @sc_pref) = ('', '', '', qw(X Y));
my @pre_NUMPAD = qw(INSERT END DOWN PRIOR LEFT CLEAR RIGHT HOME UP NEXT DELETE); # Not used
for my $sc (sort keys %fix_scans) {
my($vk, $was) = ($fix_scans{$sc}, '');
next if $vk =~ /^(NUMPAD(\d)|DECIMAL)$/ # Ignore fake codes (usually these VK's are not associated with scancodes; produced by translation of pre_NUMPAD)
and (hex $sc >= 0xE0E0 and hex $sc < 0xE0F0 or "$vk-$sc" eq 'DECIMAL-53'); # kbdutool only accepts DECIMAL on 53
$was = "\t// was $scancodes{$sc}" if exists $scancodes{$sc};
(my $osc = "T$sc") =~ s/^TE([01])/$sc_pref[$1]/;
$FX_scans .= <<EOF;
#undef $osc
#define $osc _EQ( $vk )$was
EOF
if (not $was and $sc =~ /^E([01])\w/) {
($1 ? $add_Y : $add_X) .= <<EOA;
{ 0x$sc, $osc | KBDEXT }, // $vk$was
EOA
}
}
$REPL{fix_scancodes} = $FX_scans; # join ' ', keys %fix_scans, values %fix_scans;
$REPL{addX_scancodes} = $add_X;
$REPL{addY_scancodes} = $add_Y;
############################# Output SC_ part of the Layout
my @lay_lens = grep defined $VK2binds[$_], 0..$#VK2binds;
my @lay_lensX = grep defined $VK2bindsX[$_], 0..$#VK2bindsX;
warn "Existing lengths of bindings: [@lay_lens], [@lay_lensX]";
my @extralendefs = map "TYPEDEF_VK_TO_WCHARS($_)\n", grep $_>10, @lay_lens; # std definition file defines up to 10
$REPL{extralendefs} = join '', @extralendefs;
my(%VK2scan,@xtrascans, $ext) = reverse %scan2VK;
if ($VK2bind{DIVIDE} and ($ext = (~0xff & hex $VK2scan{DIVIDE}))) {
warn "Unknown extended modifier for the scancode for VK_DIVIDE: $VK2scan{DIVIDE} -> $ext, expect " . 0xe000
unless 0xe000 == $ext;
push @xtrascans, " { 0x35, X35 | KBDEXT }, // Numpad Divide\n"
}
$REPL{xtrascans} = join '', @xtrascans;
############################# Output VK part of the Layout
my $prevVK;
my %compatTR = qw( 0008 '\b' 000a '\n' 000d '\r' 005c '\\\\' 0027 '\'' 0022 '\"' );
my $compatRx = qr/^00(0[8ad]|2[27]|5c)$/i; # these frivolous conversions simplify comparison with kbdutool; may be removed!
sub s2c($;$) {my($i,$o) = shift; return $prevVK if $i eq '-1';
$o = ($i =~ /^[''""\\]$/ ? "'\\$i'" : ($i =~ /^.$/ ? "'$i'" : ($i =~ /^0x[\da-z]+$/i ? $i : "VK_$i"))); $prevVK = $o if shift; $o}
sub hex2c($$) {my($i,$h) = (shift,shift); my $n = hex $i; return "0x\L$i" if !$h or $n<0x20 or $n > 0x7e; "L" . s2c chr $n }
sub ch2c($;$) {my($i,$h) = (shift,shift); return $compatTR{lc $i} if $h and $i =~ $compatRx;
$i =~ /^[\da-f]{2,}$/i ? hex2c($i,$h) : ($i =~ /^.$/ ? s2c($i) : ($i =~ /^-1$/ ? 'WCH_NONE'
: ($i =~ /\@$/ ? 'WCH_DEAD' : ($i eq '%%' ? 'WCH_LGTR' : $i))))}
sub mx($$) {my($i,$j)=(shift, shift); $i<$j? $j : $i}
sub fmt_st($$$) {my($i,$j,$l) = (shift, shift, shift); "$i" . (' ' x mx(1, $l - 3 - length "$i$j")) . ",$j ,"}
my($sublayouts, @sublayouts) = '';
sub emit_layout_line ($$$$) { # XXXX Need to take into account required length too ???
my($vk, $caps, $bind, $x, @xx) = (shift, shift, shift, shift || []);
(my $ss, $caps) = (hex($caps) & 0xF, hex($caps) & ~0xF);
$caps ||= '';
$caps .= '|' if $caps;
$caps .= join ' | ', map {$ss&(1<<$_) ? $capsFl->[$_] : ()} 0..$#$capsFl; # [1,'CAPLOK'], [2,'SGCAPS'], [4,'CAPLOKALTGR'], [8,'KANALOK'];
my @bind = map ch2c($_,'unhex'), @$bind;
my $comment = $comment_vkcodes{$vk} ? '//' : ' ';
$sublayouts .= $comment . fmt_st("{" . s2c($vk, 'prev'), $caps||"0", 26) . join(" ,", map {sprintf "%-8s", $_} @bind) . " },\n";
return unless grep /^WCH_DEAD$/, @bind or @$x;
if (@$x) {
$#$x = 1 if $#$x > 1;
shift @$bind for 0..$#$x; # XXXX actually, not shift, but splice, and not 0,1, but columns of bitmaps 0,1???
@xx = map ch2c($_,'unhex'), @$x;
}
$sublayouts .= $comment . fmt_st('{' . (@$x? s2c($vk, 'prev') : '0xff'), 0, 26)
. join(" ,", @xx, map {sprintf "%-8s", (/^(.*)\@$/ ? "0x$1" : 'WCH_NONE')} @$bind) . " },\n";
return unless "@$x" =~ /\@/; # Emit short initializer, as kbdutool does with the preceding row:
$sublayouts .= $comment . fmt_st('{0xff', 0, 26) . join(" ,", map {sprintf "%-8s", (/^(.*)\@$/ ? "0x$1" : 'WCH_NONE')} @$x) . " },\n";
}
for my $X ('', 'X') {
my $L = ($X ? $lenX : $len);
my @tbl = ($X ? @VK2bindsX : @VK2binds);
$sublayouts .= <<'EOS' if $X;
// The following keys are put last so that VkKeyScan interprets
// (e.g.) number characters
// as coming from the main section of the kbd (aVkToWch2 and
// aVkToWch5) before considering the numpad (aVkToWch1).
EOS
for my $_len (@$L) {
(my $len = $_len) =~ s/^X//;
my $lst = $tbl[$len] or next;
push @sublayouts, [$len, "aVkToWch$_len"];
$sublayouts .= <<EOP;
static ALLOC_SECTION_LDATA VK_TO_WCHARS$len aVkToWch$_len\[] = {
// | | Shift | Ctrl |S+Ctrl | C+ X1 | C+ X1 |
// |=========|=========|=========|=========|=========|=========|
EOP
emit_layout_line $_->[0], $_->[1], $_->[2], $_->[3] for @$lst;
$sublayouts .= " {\t" . join(",\t", (0) x ($len+2)) . "}\n" . <<'EOP';
};
EOP
}
}
$REPL{sublayouts} = $sublayouts;
my $LL = '';
for my $sub (@sublayouts) {
# warn "[<<<$sub>>>]";
# warn "<<@$sub>>";
$LL .= <<EOS;
{ (PVK_TO_WCHARS1)$sub->[1], $sub->[0], sizeof($sub->[1]\[0]) },
EOS
}
( run in 0.648 second using v1.01-cache-2.11-cpan-524268b4103 )