diff options
author | root <root> | 2012-09-04 22:41:11 +0000 |
---|---|---|
committer | root <root> | 2012-09-04 22:41:11 +0000 |
commit | d50a22a63f36f3d4fb5bd2f4d7d0f89f36d84e8f (patch) | |
tree | 64566414b54ff274345437c2b02a4f1e73b80e72 /src/perl/xim-onthespot | |
parent | 5ee396e7ac453f939e8ec74546756dba45906827 (diff) |
*** empty log message ***
Diffstat (limited to 'src/perl/xim-onthespot')
-rw-r--r-- | src/perl/xim-onthespot | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/perl/xim-onthespot b/src/perl/xim-onthespot new file mode 100644 index 0000000..b5acee2 --- /dev/null +++ b/src/perl/xim-onthespot @@ -0,0 +1,90 @@ +#! perl + +=head1 NAME + +xim-onthespot - implement XIM "on-the-spot" behaviour + +=head1 DESCRIPTION + +This perl extension implements OnTheSpot editing. It does not work +perfectly, and some input methods don't seem to work well with OnTheSpot +editing in general, but it seems to work at least for SCIM and kinput2. + +You enable it by specifying this extension and a preedit style of +C<OnTheSpot>, i.e.: + + urxvt -pt OnTheSpot -pe xim-onthespot + +=cut + +# +# problems with this implementation include +# +# - primary, secondary, tertiary are NO different to other highlighting styles +# - if rend values are missing, they are not being interpolated +# + +my $SIZEOF_LONG = length pack "l!", 0; + +sub refresh { + my ($self) = @_; + + delete $self->{overlay}; + + my $text = $self->{text}; + + return unless length $text; + + my ($row, $col) = $self->screen_cur; + + my $idx = 0; + + my @rend = map { + my $rstyle = $self->{caret} == $idx ? urxvt::OVERLAY_RSTYLE : $self->rstyle; + + $rstyle |= urxvt::RS_Uline if $_ & (urxvt::XIMUnderline | urxvt::XIMPrimary); + $rstyle |= urxvt::RS_RVid if $_ & (urxvt::XIMReverse | urxvt::XIMSecondary); + $rstyle |= urxvt::RS_Italic if $_ & (urxvt::XIMHighlight | urxvt::XIMTertiary); + + ($rstyle) x ($self->strwidth (substr $text, $idx++, 1)) + } unpack "l!*", $self->{rend}; + + if ($self->{caret} >= length $text) { + $text .= " "; + push @rend, urxvt::OVERLAY_RSTYLE; + } + + $self->{overlay} = $self->overlay ($col, $row, $self->strwidth ($text), 1, $self->rstyle, 0); + $self->{overlay}->set (0, 0, $self->special_encode ($text), \@rend); +} + +sub on_xim_preedit_start { + my ($self) = @_; + + () +} + +sub on_xim_preedit_done { + my ($self) = @_; + + delete $self->{overlay}; + delete $self->{text}; + delete $self->{rend}; + + () +} + +sub on_xim_preedit_draw { + my ($self, $caret, $pos, $len, $feedback, $chars) = @_; + + $self->{caret} = $caret; + + substr $self->{rend}, $pos * $SIZEOF_LONG, $len * $SIZEOF_LONG, $feedback; + substr $self->{text}, $pos , $len , $chars if defined $feedback || !defined $chars; + + $self->refresh; + + () +} + + |