paste64.pl revision e0a2b6df
1#!/usr/bin/env perl
2# $XTermId: paste64.pl,v 1.11 2014/02/26 20:14:32 tom Exp $
3# -----------------------------------------------------------------------------
4# this file is part of xterm
5#
6# Copyright 2006,2014 by Thomas E. Dickey
7#
8#                         All Rights Reserved
9#
10# Permission is hereby granted, free of charge, to any person obtaining a
11# copy of this software and associated documentation files (the
12# "Software"), to deal in the Software without restriction, including
13# without limitation the rights to use, copy, modify, merge, publish,
14# distribute, sublicense, and/or sell copies of the Software, and to
15# permit persons to whom the Software is furnished to do so, subject to
16# the following conditions:
17#
18# The above copyright notice and this permission notice shall be included
19# in all copies or substantial portions of the Software.
20#
21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
25# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28#
29# Except as contained in this notice, the name(s) of the above copyright
30# holders shall not be used in advertising or otherwise to promote the
31# sale, use or other dealings in this Software without prior written
32# authorization.
33# -----------------------------------------------------------------------------
34# Test the paste64 option of xterm.
35
36use strict;
37use warnings;
38
39
40use Term::ReadKey;
41use IO::Handle;
42use MIME::Base64;
43
44our $target = "";
45
46sub to_hex($) {
47	my $value = $_[0];
48	my $result = "";
49	my $n;
50
51	for ( $n = 0; $n < length($value); ++$n) {
52		$result .= sprintf("%02X", ord substr($value,$n,1));
53	}
54	return $result;
55}
56
57sub show_string($) {
58	my $value = $_[0];
59	my $n;
60
61	my $result = "";
62	for ( $n = 0; $n < length($value); $n += 1) {
63		my $c = ord substr($value,$n,1);
64		if ( $c == ord '\\' ) {
65			$result .= "\\\\";
66		} elsif ( $c == 0x1b ) {
67			$result .= "\\E";
68		} elsif ( $c == 0x7f ) {
69			$result .= "^?";
70		} elsif ( $c == 32 ) {
71			$result .= "\\s";
72		} elsif ( $c < 32 ) {
73			$result .= sprintf("^%c", $c + 64);
74		} elsif ( $c > 128 ) {
75			$result .= sprintf("\\%03o", $c);
76		} else {
77			$result .= chr($c);
78		}
79	}
80
81	printf "%s\r\n", $result;
82}
83
84sub get_reply($) {
85	my $command = $_[0];
86	my $reply = "";
87
88	printf "send: ";
89	show_string($command);
90
91	print STDOUT $command;
92	autoflush STDOUT 1;
93	while (1) {
94		my $test=ReadKey 1;
95		last if not defined $test;
96		#printf "%d:%s\r\n", length($reply), to_hex($test);
97		$reply .= $test;
98	}
99	return $reply;
100}
101
102sub get_paste() {
103	my $reply = get_reply("\x1b]52;" . $target . ";?\x1b\\");
104
105	printf "read: ";
106	show_string($reply);
107
108	my $data = $reply;
109	$data =~ s/^\x1b]52;[[:alnum:]]*;//;
110	$data =~ s/\x1b\\$//;
111	printf "chop: ";
112	show_string($data);
113
114        $data = decode_base64($data);
115	printf "data: ";
116	show_string($data);
117}
118
119sub put_paste() {
120	ReadMode 1;
121
122	printf "data: ";
123	my $data = ReadLine 0;
124	chomp $data;
125	ReadMode 5;
126
127	$data = encode_base64($data);
128	chomp $data;
129	printf "data: ";
130	show_string($data);
131
132	my $send = "\x1b]52;" . $target . ";" . $data . "\x1b\\";
133
134	printf "send: ";
135	show_string($send);
136}
137
138sub set_target() {
139	ReadMode 1;
140
141	printf "target: ";
142	$target = ReadLine 0;
143	$target =~ s/[^[:alnum:]]//g;
144	ReadMode 5;
145	printf "result: %s\r\n", $target;
146}
147
148ReadMode 5, 'STDIN'; # allow single-character inputs
149while (1) {
150	my $cmd;
151
152	printf "\r\nCommand (? for help):";
153	$cmd = ReadKey 0;
154	if ( $cmd eq "?" ) {
155		printf "\r\np=put selection, g=get selection, q=quit, r=reset target, s=set target\r\n";
156	} elsif ($cmd eq "p") {
157		printf " ...put selection\r\n";
158		put_paste();
159	} elsif ($cmd eq "g") {
160		printf " ...get selection\r\n";
161		get_paste();
162	} elsif ($cmd eq "q") {
163		printf " ...quit\r\n";
164		last;
165	} elsif ($cmd eq "r") {
166		printf " ...reset\r\n";
167		$target = "";
168	} elsif ($cmd eq "s") {
169		printf " ...set target\r\n";
170		set_target();
171	}
172}
173ReadMode 0, 'STDIN'; # Reset tty mode before exiting
174