On Thu Sep 01 15:11:05 2011, TODDR wrote:
Show quoted text> The authors on this module are overloaded (including me). A patch
> would be good.
Find attached. :)
I have no idea how to test this one though, short of just create a new
Pty/Tty pair, set a size, check it can be read. Not sure what you want to
do in terms of unit testing / configure-time checking.
--
Paul Evans
=== modified file 'Pty.pm'
--- Pty.pm 2012-01-05 19:19:07 +0000
+++ Pty.pm 2012-01-05 19:59:10 +0000
@@ -141,6 +141,8 @@
}
*clone_winsize_from = \&IO::Tty::clone_winsize_from;
+*get_winsize = \&IO::Tty::get_winsize;
+*set_winsize = \&IO::Tty::set_winsize;
*set_raw = \&IO::Tty::set_raw;
1;
@@ -254,6 +256,17 @@
See the C<try> script for example code how to propagate SIGWINCH.
+=item get_winsize()
+
+Returns the terminal size, in a 4-element list.
+
+ ($row, $col, $xpixel, $ypixel) = $tty->get_winsize()
+
+=item set_winsize($row, $col, $xpixel, $ypixel)
+
+Sets the terminal size. If not specified, C<$xpixel> and C<$ypixel> are set to
+0. As with C<clone_winsize_from>, this must be called upon the I<slave>.
+
=back
=== modified file 'Tty.pm'
--- Tty.pm 2012-01-05 19:19:07 +0000
+++ Tty.pm 2012-01-05 19:59:10 +0000
@@ -62,6 +62,26 @@
return undef;
}
+# ioctl() doesn't tell us how long the structure is, so we'll have to trim it
+# after TIOCGWINSZ
+my $SIZEOF_WINSIZE = length IO::Tty::pack_winsize(0,0,0,0);
+
+sub get_winsize {
+ my $self = shift;
+ ioctl($self, IO::Tty::Constant::TIOCGWINSZ(), my $winsize)
+ or croak "Cannot TIOCGWINSZ - $!";
+ substr($winsize, $SIZEOF_WINSIZE) = "";
+ printf STDERR "winsize{%d bytes}: %v02x\n", length $winsize, $winsize;
+ return IO::Tty::unpack_winsize($winsize);
+}
+
+sub set_winsize {
+ my $self = shift;
+ my $winsize = IO::Tty::unpack_winsize(@_);
+ ioctl($self, IO::Tty::Constant::TIOCSWINSZ(), $winsize)
+ or croak "Cannot TIOCSWINSZ - $!";
+}
+
sub set_raw($) {
require POSIX;
my $self = shift;
=== modified file 'Tty.xs'
--- Tty.xs 2012-01-05 19:19:07 +0000
+++ Tty.xs 2012-01-05 19:59:10 +0000
@@ -803,6 +803,39 @@
OUTPUT:
RETVAL
+SV *
+pack_winsize(row, col, xpixel = 0, ypixel = 0)
+ int row
+ int col
+ int xpixel
+ int ypixel
+ INIT:
+ struct winsize ws;
+ CODE:
+ ws.ws_row = row;
+ ws.ws_col = col;
+ ws.ws_xpixel = xpixel;
+ ws.ws_ypixel = ypixel;
+ RETVAL = newSVpvn((char *)&ws, sizeof(ws));
+ OUTPUT:
+ RETVAL
+
+void
+unpack_winsize(winsize)
+ SV *winsize;
+ INIT:
+ struct winsize ws;
+ PPCODE:
+ if(SvCUR(winsize) != sizeof(ws))
+ croak("IO::Tty::unpack_winsize(): Bad arg length - got %d, expected %d",
+ SvCUR(winsize), sizeof(ws));
+ Copy(SvPV_nolen(winsize), &ws, sizeof(ws), char);
+ EXTEND(SP, 4);
+ PUSHs(sv_2mortal(newSViv(ws.ws_row)));
+ PUSHs(sv_2mortal(newSViv(ws.ws_col)));
+ PUSHs(sv_2mortal(newSViv(ws.ws_xpixel)));
+ PUSHs(sv_2mortal(newSViv(ws.ws_ypixel)));
+
BOOT:
{