line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Term::VT102 - module for VT102 emulation in Perl |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Copyright (C) Andrew Wood |
4
|
|
|
|
|
|
|
# NO WARRANTY - see COPYING. |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
package Term::VT102; |
8
|
|
|
|
|
|
|
|
9
|
14
|
|
|
14
|
|
14008
|
use strict; |
|
14
|
|
|
|
|
31
|
|
|
14
|
|
|
|
|
702
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
BEGIN { |
12
|
14
|
|
|
14
|
|
76
|
use Exporter (); |
|
14
|
|
|
|
|
28
|
|
|
14
|
|
|
|
|
299
|
|
13
|
14
|
|
|
14
|
|
73
|
use vars qw($VERSION @ISA); |
|
14
|
|
|
|
|
26
|
|
|
14
|
|
|
|
|
1052
|
|
14
|
|
|
|
|
|
|
|
15
|
14
|
|
|
14
|
|
36
|
$VERSION = '0.91'; |
16
|
|
|
|
|
|
|
|
17
|
14
|
|
|
|
|
4238
|
@ISA = qw(Exporter); |
18
|
|
|
|
|
|
|
} |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Return the packed version of a set of attributes fg, bg, bo, fa, st, ul, |
22
|
|
|
|
|
|
|
# bl, rv. |
23
|
|
|
|
|
|
|
# |
24
|
|
|
|
|
|
|
sub attr_pack { |
25
|
132
|
100
|
|
132
|
1
|
836
|
shift if ref($_[0]); # called in object context, ditch the object |
26
|
132
|
|
|
|
|
207
|
my ($fg, $bg, $bo, $fa, $st, $ul, $bl, $rv) = @_; |
27
|
132
|
|
|
|
|
142
|
my $num = 0; |
28
|
|
|
|
|
|
|
|
29
|
132
|
|
|
|
|
291
|
$num = ($fg & 7) |
30
|
|
|
|
|
|
|
| (($bg & 7) << 4) |
31
|
|
|
|
|
|
|
| ($bo << 8) |
32
|
|
|
|
|
|
|
| ($fa << 9) |
33
|
|
|
|
|
|
|
| ($st << 10) |
34
|
|
|
|
|
|
|
| ($ul << 11) |
35
|
|
|
|
|
|
|
| ($bl << 12) |
36
|
|
|
|
|
|
|
| ($rv << 13); |
37
|
132
|
|
|
|
|
184854
|
return pack ('S', $num); |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Return the unpacked version of a packed attribute. |
42
|
|
|
|
|
|
|
# |
43
|
|
|
|
|
|
|
sub attr_unpack { |
44
|
30
|
50
|
|
30
|
1
|
109
|
shift if ref($_[0]); # called in object context, ditch the object |
45
|
30
|
|
|
|
|
39
|
my $data = shift; |
46
|
30
|
|
|
|
|
34
|
my ($num, $fg, $bg, $bo, $fa, $st, $ul, $bl, $rv); |
47
|
|
|
|
|
|
|
|
48
|
30
|
|
|
|
|
76
|
$num = unpack ('S', $data); |
49
|
|
|
|
|
|
|
|
50
|
30
|
|
|
|
|
119
|
($fg, $bg, $bo, $fa, $st, $ul, $bl, $rv) = ( |
51
|
|
|
|
|
|
|
$num & 7, |
52
|
|
|
|
|
|
|
($num >> 4) & 7, |
53
|
|
|
|
|
|
|
($num >> 8) & 1, |
54
|
|
|
|
|
|
|
($num >> 9) & 1, |
55
|
|
|
|
|
|
|
($num >> 10) & 1, |
56
|
|
|
|
|
|
|
($num >> 11) & 1, |
57
|
|
|
|
|
|
|
($num >> 12) & 1, |
58
|
|
|
|
|
|
|
($num >> 13) & 1 |
59
|
|
|
|
|
|
|
); |
60
|
|
|
|
|
|
|
|
61
|
30
|
|
|
|
|
99
|
return ($fg, $bg, $bo, $fa, $st, $ul, $bl, $rv); |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# Default attribute set (in both packed and unpacked flavors) |
66
|
|
|
|
|
|
|
# |
67
|
14
|
|
|
14
|
|
93
|
use constant DEFAULT_ATTR => (7, 0, 0, 0, 0, 0, 0, 0); |
|
14
|
|
|
|
|
27
|
|
|
14
|
|
|
|
|
1426
|
|
68
|
14
|
|
|
14
|
|
73
|
use constant DEFAULT_ATTR_PACKED => attr_pack(&DEFAULT_ATTR); |
|
14
|
|
|
|
|
30
|
|
|
14
|
|
|
|
|
66
|
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# Constructor function. |
72
|
|
|
|
|
|
|
# |
73
|
|
|
|
|
|
|
sub new { |
74
|
81
|
|
|
81
|
1
|
24919
|
my ($proto, %init) = @_; |
75
|
81
|
|
33
|
|
|
411
|
my $class = ref ($proto) || $proto; |
76
|
81
|
|
|
|
|
141
|
my $self = {}; |
77
|
|
|
|
|
|
|
|
78
|
81
|
|
|
|
|
1180
|
$self->{'_ctlseq'} = { ( # control characters |
79
|
|
|
|
|
|
|
"\000" => 'NUL', # ignored |
80
|
|
|
|
|
|
|
"\005" => 'ENQ', # trigger answerback message |
81
|
|
|
|
|
|
|
"\007" => 'BEL', # beep |
82
|
|
|
|
|
|
|
"\010" => 'BS', # backspace one column |
83
|
|
|
|
|
|
|
"\011" => 'HT', # horizontal tab to next tab stop |
84
|
|
|
|
|
|
|
"\012" => 'LF', # line feed |
85
|
|
|
|
|
|
|
"\013" => 'VT', # line feed |
86
|
|
|
|
|
|
|
"\014" => 'FF', # line feed |
87
|
|
|
|
|
|
|
"\015" => 'CR', # carriage return |
88
|
|
|
|
|
|
|
"\016" => 'SO', # activate G1 character set & newline |
89
|
|
|
|
|
|
|
"\017" => 'SI', # activate G0 character set |
90
|
|
|
|
|
|
|
"\021" => 'XON', # resume transmission |
91
|
|
|
|
|
|
|
"\023" => 'XOFF', # stop transmission, ignore characters |
92
|
|
|
|
|
|
|
"\030" => 'CAN', # interrupt escape sequence |
93
|
|
|
|
|
|
|
"\032" => 'SUB', # interrupt escape sequence |
94
|
|
|
|
|
|
|
"\033" => 'ESC', # start escape sequence |
95
|
|
|
|
|
|
|
"\177" => 'DEL', # ignored |
96
|
|
|
|
|
|
|
"\233" => 'CSI' # equivalent to ESC [ |
97
|
|
|
|
|
|
|
) }; |
98
|
|
|
|
|
|
|
|
99
|
81
|
|
|
|
|
2134
|
$self->{'_escseq'} = { ( # escape sequences |
100
|
|
|
|
|
|
|
'c' => 'RIS', # reset |
101
|
|
|
|
|
|
|
'D' => 'IND', # line feed |
102
|
|
|
|
|
|
|
'E' => 'NEL', # newline |
103
|
|
|
|
|
|
|
'H' => 'HTS', # set tab stop at current column |
104
|
|
|
|
|
|
|
'M' => 'RI', # reverse line feed |
105
|
|
|
|
|
|
|
'Z' => 'DECID', # DEC private ID; return ESC [ ? 6 c (VT102) |
106
|
|
|
|
|
|
|
'7' => 'DECSC', # save state (position, charset, attributes) |
107
|
|
|
|
|
|
|
'8' => 'DECRC', # restore most recently saved state |
108
|
|
|
|
|
|
|
'[' => 'CSI', # control sequence introducer |
109
|
|
|
|
|
|
|
'[[' => 'IGN', # ignored control sequence |
110
|
|
|
|
|
|
|
'%@' => 'CSDFL', # select default charset (ISO646/8859-1) |
111
|
|
|
|
|
|
|
'%G' => 'CSUTF8', # select UTF-8 |
112
|
|
|
|
|
|
|
'%8' => 'CSUTF8', # select UTF-8 (obsolete) |
113
|
|
|
|
|
|
|
'#8' => 'DECALN', # DEC alignment test - fill screen with E's |
114
|
|
|
|
|
|
|
'(8' => 'G0DFL', # G0 charset = default mapping (ISO8859-1) |
115
|
|
|
|
|
|
|
'(0' => 'G0GFX', # G0 charset = VT100 graphics mapping |
116
|
|
|
|
|
|
|
'(U' => 'G0ROM', # G0 charset = null mapping (straight to ROM) |
117
|
|
|
|
|
|
|
'(K' => 'G0USR', # G0 charset = user defined mapping |
118
|
|
|
|
|
|
|
'(B' => 'G0TXT', # G0 charset = ASCII mapping |
119
|
|
|
|
|
|
|
')8' => 'G1DFL', # G1 charset = default mapping (ISO8859-1) |
120
|
|
|
|
|
|
|
')0' => 'G1GFX', # G1 charset = VT100 graphics mapping |
121
|
|
|
|
|
|
|
')U' => 'G1ROM', # G1 charset = null mapping (straight to ROM) |
122
|
|
|
|
|
|
|
')K' => 'G1USR', # G1 charset = user defined mapping |
123
|
|
|
|
|
|
|
')B' => 'G1TXT', # G1 charset = ASCII mapping |
124
|
|
|
|
|
|
|
'*8' => 'G2DFL', # G2 charset = default mapping (ISO8859-1) |
125
|
|
|
|
|
|
|
'*0' => 'G2GFX', # G2 charset = VT100 graphics mapping |
126
|
|
|
|
|
|
|
'*U' => 'G2ROM', # G2 charset = null mapping (straight to ROM) |
127
|
|
|
|
|
|
|
'*K' => 'G2USR', # G2 charset = user defined mapping |
128
|
|
|
|
|
|
|
'+8' => 'G3DFL', # G3 charset = default mapping (ISO8859-1) |
129
|
|
|
|
|
|
|
'+0' => 'G3GFX', # G3 charset = VT100 graphics mapping |
130
|
|
|
|
|
|
|
'+U' => 'G3ROM', # G3 charset = null mapping (straight to ROM) |
131
|
|
|
|
|
|
|
'+K' => 'G3USR', # G3 charset = user defined mapping |
132
|
|
|
|
|
|
|
'>' => 'DECPNM', # set numeric keypad mode |
133
|
|
|
|
|
|
|
'=' => 'DECPAM', # set application keypad mode |
134
|
|
|
|
|
|
|
'N' => 'SS2', # select G2 charset for next char only |
135
|
|
|
|
|
|
|
'O' => 'SS3', # select G3 charset for next char only |
136
|
|
|
|
|
|
|
'P' => 'DCS', # device control string (ended by ST) |
137
|
|
|
|
|
|
|
'X' => 'SOS', # start of string |
138
|
|
|
|
|
|
|
'^' => 'PM', # privacy message (ended by ST) |
139
|
|
|
|
|
|
|
'_' => 'APC', # application program command (ended by ST) |
140
|
|
|
|
|
|
|
"\\" => 'ST', # string terminator |
141
|
|
|
|
|
|
|
'n' => 'LS2', # invoke G2 charset |
142
|
|
|
|
|
|
|
'o' => 'LS3', # invoke G3 charset |
143
|
|
|
|
|
|
|
'|' => 'LS3R', # invoke G3 charset as GR |
144
|
|
|
|
|
|
|
'}' => 'LS2R', # invoke G2 charset as GR |
145
|
|
|
|
|
|
|
'~' => 'LS1R', # invoke G1 charset as GR |
146
|
|
|
|
|
|
|
']' => 'OSC', # operating system command |
147
|
|
|
|
|
|
|
'g' => 'BEL', # alternate BEL |
148
|
|
|
|
|
|
|
) }; |
149
|
|
|
|
|
|
|
|
150
|
81
|
|
|
|
|
1238
|
$self->{'_csiseq'} = { ( # ECMA-48 CSI sequences |
151
|
|
|
|
|
|
|
'[' => 'IGN', # ignored control sequence |
152
|
|
|
|
|
|
|
'@' => 'ICH', # insert blank characters |
153
|
|
|
|
|
|
|
'A' => 'CUU', # move cursor up |
154
|
|
|
|
|
|
|
'B' => 'CUD', # move cursor down |
155
|
|
|
|
|
|
|
'C' => 'CUF', # move cursor right |
156
|
|
|
|
|
|
|
'D' => 'CUB', # move cursor left |
157
|
|
|
|
|
|
|
'E' => 'CNL', # move cursor down and to column 1 |
158
|
|
|
|
|
|
|
'F' => 'CPL', # move cursor up and to column 1 |
159
|
|
|
|
|
|
|
'G' => 'CHA', # move cursor to column in current row |
160
|
|
|
|
|
|
|
'H' => 'CUP', # move cursor to row, column |
161
|
|
|
|
|
|
|
'J' => 'ED', # erase display |
162
|
|
|
|
|
|
|
'K' => 'EL', # erase line |
163
|
|
|
|
|
|
|
'L' => 'IL', # insert blank lines |
164
|
|
|
|
|
|
|
'M' => 'DL', # delete lines |
165
|
|
|
|
|
|
|
'P' => 'DCH', # delete characters on current line |
166
|
|
|
|
|
|
|
'X' => 'ECH', # erase characters on current line |
167
|
|
|
|
|
|
|
'a' => 'HPR', # move cursor right |
168
|
|
|
|
|
|
|
'c' => 'DA', # return ESC [ ? 6 c (VT102) |
169
|
|
|
|
|
|
|
'd' => 'VPA', # move to row (current column) |
170
|
|
|
|
|
|
|
'e' => 'VPR', # move cursor down |
171
|
|
|
|
|
|
|
'f' => 'HVP', # move cursor to row, column |
172
|
|
|
|
|
|
|
'g' => 'TBC', # clear tab stop (CSI 3 g = clear all stops) |
173
|
|
|
|
|
|
|
'h' => 'SM', # set mode |
174
|
|
|
|
|
|
|
'l' => 'RM', # reset mode |
175
|
|
|
|
|
|
|
'm' => 'SGR', # set graphic rendition |
176
|
|
|
|
|
|
|
'n' => 'DSR', # device status report |
177
|
|
|
|
|
|
|
'q' => 'DECLL', # set keyboard LEDs |
178
|
|
|
|
|
|
|
'r' => 'DECSTBM', # set scrolling region to (top, bottom) rows |
179
|
|
|
|
|
|
|
's' => 'CUPSV', # save cursor position |
180
|
|
|
|
|
|
|
'u' => 'CUPRS', # restore cursor position |
181
|
|
|
|
|
|
|
'`' => 'HPA' # move cursor to column in current row |
182
|
|
|
|
|
|
|
) }; |
183
|
|
|
|
|
|
|
|
184
|
81
|
|
|
|
|
1503
|
$self->{'_modeseq'} = { ( # ANSI/DEC specified modes for SM/RM |
185
|
|
|
|
|
|
|
# ANSI Specified Modes |
186
|
|
|
|
|
|
|
'0' => 'IGN', # Error (Ignored) |
187
|
|
|
|
|
|
|
'1' => 'GATM', # guarded-area transfer mode (ignored) |
188
|
|
|
|
|
|
|
'2' => 'KAM', # keyboard action mode (always reset) |
189
|
|
|
|
|
|
|
'3' => 'CRM', # control representation mode (always reset) |
190
|
|
|
|
|
|
|
'4' => 'IRM', # insertion/replacement mode (always reset) |
191
|
|
|
|
|
|
|
'5' => 'SRTM', # status-reporting transfer mode |
192
|
|
|
|
|
|
|
'6' => 'ERM', # erasure mode (always set) |
193
|
|
|
|
|
|
|
'7' => 'VEM', # vertical editing mode (ignored) |
194
|
|
|
|
|
|
|
'10' => 'HEM', # horizontal editing mode |
195
|
|
|
|
|
|
|
'11' => 'PUM', # positioning unit mode |
196
|
|
|
|
|
|
|
'12' => 'SRM', # send/receive mode (echo on/off) |
197
|
|
|
|
|
|
|
'13' => 'FEAM', # format effector action mode |
198
|
|
|
|
|
|
|
'14' => 'FETM', # format effector transfer mode |
199
|
|
|
|
|
|
|
'15' => 'MATM', # multiple area transfer mode |
200
|
|
|
|
|
|
|
'16' => 'TTM', # transfer termination mode |
201
|
|
|
|
|
|
|
'17' => 'SATM', # selected area transfer mode |
202
|
|
|
|
|
|
|
'18' => 'TSM', # tabulation stop mode |
203
|
|
|
|
|
|
|
'19' => 'EBM', # editing boundary mode |
204
|
|
|
|
|
|
|
'20' => 'LNM', # Line Feed / New Line Mode |
205
|
|
|
|
|
|
|
# DEC Private Modes |
206
|
|
|
|
|
|
|
'?0' => 'IGN', # Error (Ignored) |
207
|
|
|
|
|
|
|
'?1' => 'DECCKM', # Cursorkeys application (set); Cursorkeys normal (reset) |
208
|
|
|
|
|
|
|
'?2' => 'DECANM', # ANSI (set); VT52 (reset) |
209
|
|
|
|
|
|
|
'?3' => 'DECCOLM', # 132 columns (set); 80 columns (reset) |
210
|
|
|
|
|
|
|
'?4' => 'DECSCLM', # Jump scroll (set); Smooth scroll (reset) |
211
|
|
|
|
|
|
|
'?5' => 'DECSCNM', # Reverse screen (set); Normal screen (reset) |
212
|
|
|
|
|
|
|
'?6' => 'DECOM', # Sets relative coordinates (set); Sets absolute coordinates (reset) |
213
|
|
|
|
|
|
|
'?7' => 'DECAWM', # Auto Wrap |
214
|
|
|
|
|
|
|
'?8' => 'DECARM', # Auto Repeat |
215
|
|
|
|
|
|
|
'?9' => 'DECINLM', # Interlace |
216
|
|
|
|
|
|
|
'?18' => 'DECPFF', # Send FF to printer after print screen (set); No char after PS (reset) |
217
|
|
|
|
|
|
|
'?19' => 'DECPEX', # Print screen: prints full screen (set); prints scroll region (reset) |
218
|
|
|
|
|
|
|
'?25' => 'DECTCEM', # Cursor on (set); Cursor off (reset) |
219
|
|
|
|
|
|
|
) }; |
220
|
|
|
|
|
|
|
|
221
|
81
|
|
|
|
|
14845
|
$self->{'_funcs'} = { ( # supported character sequences |
222
|
|
|
|
|
|
|
'BS' => \&_code_BS, # backspace one column |
223
|
|
|
|
|
|
|
'CR' => \&_code_CR, # carriage return |
224
|
|
|
|
|
|
|
'DA' => \&_code_DA, # return ESC [ ? 6 c (VT102) |
225
|
|
|
|
|
|
|
'DL' => \&_code_DL, # delete lines |
226
|
|
|
|
|
|
|
'ED' => \&_code_ED, # erase display |
227
|
|
|
|
|
|
|
'EL' => \&_code_EL, # erase line |
228
|
|
|
|
|
|
|
'FF' => \&_code_LF, # line feed |
229
|
|
|
|
|
|
|
'HT' => \&_code_HT, # horizontal tab to next tab stop |
230
|
|
|
|
|
|
|
'IL' => \&_code_IL, # insert blank lines |
231
|
|
|
|
|
|
|
'LF' => \&_code_LF, # line feed |
232
|
|
|
|
|
|
|
'PM' => \&_code_PM, # privacy message (ended by ST) |
233
|
|
|
|
|
|
|
'RI' => \&_code_RI, # reverse line feed |
234
|
|
|
|
|
|
|
'RM' => \&_code_RM, # reset mode |
235
|
|
|
|
|
|
|
'SI' => undef, # activate G0 character set |
236
|
|
|
|
|
|
|
'SM' => \&_code_SM, # set mode |
237
|
|
|
|
|
|
|
'SO' => undef, # activate G1 character set & CR |
238
|
|
|
|
|
|
|
'ST' => undef, # string terminator |
239
|
|
|
|
|
|
|
'VT' => \&_code_LF, # line feed |
240
|
|
|
|
|
|
|
'APC' => \&_code_APC, # application program command (ended by ST) |
241
|
|
|
|
|
|
|
'BEL' => \&_code_BEL, # beep |
242
|
|
|
|
|
|
|
'CAN' => \&_code_CAN, # interrupt escape sequence |
243
|
|
|
|
|
|
|
'CHA' => \&_code_CHA, # move cursor to column in current row |
244
|
|
|
|
|
|
|
'CNL' => \&_code_CNL, # move cursor down and to column 1 |
245
|
|
|
|
|
|
|
'CPL' => \&_code_CPL, # move cursor up and to column 1 |
246
|
|
|
|
|
|
|
'CRM' => undef, # control representation mode |
247
|
|
|
|
|
|
|
'CSI' => \&_code_CSI, # equivalent to ESC [ |
248
|
|
|
|
|
|
|
'CUB' => \&_code_CUB, # move cursor left |
249
|
|
|
|
|
|
|
'CUD' => \&_code_CUD, # move cursor down |
250
|
|
|
|
|
|
|
'CUF' => \&_code_CUF, # move cursor right |
251
|
|
|
|
|
|
|
'CUP' => \&_code_CUP, # move cursor to row, column |
252
|
|
|
|
|
|
|
'CUU' => \&_code_CUU, # move cursor up |
253
|
|
|
|
|
|
|
'DCH' => \&_code_DCH, # delete characters on current line |
254
|
|
|
|
|
|
|
'DCS' => \&_code_DCS, # device control string (ended by ST) |
255
|
|
|
|
|
|
|
'DEL' => \&_code_IGN, # ignored |
256
|
|
|
|
|
|
|
'DSR' => \&_code_DSR, # device status report |
257
|
|
|
|
|
|
|
'EBM' => undef, # editing boundary mode |
258
|
|
|
|
|
|
|
'ECH' => \&_code_ECH, # erase characters on current line |
259
|
|
|
|
|
|
|
'ENQ' => undef, # trigger answerback message |
260
|
|
|
|
|
|
|
'ERM' => undef, # erasure mode |
261
|
|
|
|
|
|
|
'ESC' => \&_code_ESC, # start escape sequence |
262
|
|
|
|
|
|
|
'HEM' => undef, # horizontal editing mode |
263
|
|
|
|
|
|
|
'HPA' => \&_code_CHA, # move cursor to column in current row |
264
|
|
|
|
|
|
|
'HPR' => \&_code_CUF, # move cursor right |
265
|
|
|
|
|
|
|
'HTS' => \&_code_HTS, # set tab stop at current column |
266
|
|
|
|
|
|
|
'HVP' => \&_code_CUP, # move cursor to row, column |
267
|
|
|
|
|
|
|
'ICH' => \&_code_ICH, # insert blank characters |
268
|
|
|
|
|
|
|
'IGN' => \&_code_IGN, # ignored control sequence |
269
|
|
|
|
|
|
|
'IND' => \&_code_LF, # line feed |
270
|
|
|
|
|
|
|
'IRM' => undef, # insert/replace mode |
271
|
|
|
|
|
|
|
'KAM' => undef, # keyboard action mode |
272
|
|
|
|
|
|
|
'LNM' => undef, # line feed / newline mode |
273
|
|
|
|
|
|
|
'LS2' => undef, # invoke G2 charset |
274
|
|
|
|
|
|
|
'LS3' => undef, # invoke G3 charset |
275
|
|
|
|
|
|
|
'NEL' => \&_code_NEL, # newline |
276
|
|
|
|
|
|
|
'NUL' => \&_code_IGN, # ignored |
277
|
|
|
|
|
|
|
'OSC' => \&_code_OSC, # operating system command |
278
|
|
|
|
|
|
|
'PUM' => undef, # positioning unit mode |
279
|
|
|
|
|
|
|
'RIS' => \&_code_RIS, # reset |
280
|
|
|
|
|
|
|
'SGR' => \&_code_SGR, # set graphic rendition |
281
|
|
|
|
|
|
|
'SOS' => undef, # start of string |
282
|
|
|
|
|
|
|
'SRM' => undef, # send/receive mode (echo on/off) |
283
|
|
|
|
|
|
|
'SS2' => undef, # select G2 charset for next char only |
284
|
|
|
|
|
|
|
'SS3' => undef, # select G3 charset for next char only |
285
|
|
|
|
|
|
|
'SUB' => \&_code_CAN, # interrupt escape sequence |
286
|
|
|
|
|
|
|
'TBC' => \&_code_TBC, # clear tab stop (CSI 3 g = clear all stops) |
287
|
|
|
|
|
|
|
'TSM' => undef, # tabulation stop mode |
288
|
|
|
|
|
|
|
'TTM' => undef, # transfer termination mode |
289
|
|
|
|
|
|
|
'VEM' => undef, # vertical editing mode |
290
|
|
|
|
|
|
|
'VPA' => \&_code_VPA, # move to row (current column) |
291
|
|
|
|
|
|
|
'VPR' => \&_code_CUD, # move cursor down |
292
|
|
|
|
|
|
|
'XON' => \&_code_XON, # resume transmission |
293
|
|
|
|
|
|
|
'FEAM' => undef, # format effector action mode |
294
|
|
|
|
|
|
|
'FETM' => undef, # format effector transfer mode |
295
|
|
|
|
|
|
|
'GATM' => undef, # guarded-area transfer mode |
296
|
|
|
|
|
|
|
'LS1R' => undef, # invoke G1 charset as GR |
297
|
|
|
|
|
|
|
'LS2R' => undef, # invoke G2 charset as GR |
298
|
|
|
|
|
|
|
'LS3R' => undef, # invoke G3 charset as GR |
299
|
|
|
|
|
|
|
'MATM' => undef, # multiple area transfer mode |
300
|
|
|
|
|
|
|
'SATM' => undef, # selected area transfer mode |
301
|
|
|
|
|
|
|
'SRTM' => undef, # status-reporting transfer mode |
302
|
|
|
|
|
|
|
'XOFF' => \&_code_XOFF, # stop transmission, ignore characters |
303
|
|
|
|
|
|
|
'CSDFL' => undef, # select default charset (ISO646/8859-1) |
304
|
|
|
|
|
|
|
'CUPRS' => \&_code_CUPRS, # restore cursor position |
305
|
|
|
|
|
|
|
'CUPSV' => \&_code_CUPSV, # save cursor position |
306
|
|
|
|
|
|
|
'DECID' => \&_code_DA, # DEC private ID; return ESC [ ? 6 c (VT102) |
307
|
|
|
|
|
|
|
'DECLL' => undef, # set keyboard LEDs |
308
|
|
|
|
|
|
|
'DECOM' => undef, # relative/absolute coordinate mode |
309
|
|
|
|
|
|
|
'DECRC' => \&_code_DECRC, # restore most recently saved state |
310
|
|
|
|
|
|
|
'DECSC' => \&_code_DECSC, # save state (position, charset, attributes) |
311
|
|
|
|
|
|
|
'G0DFL' => undef, # G0 charset = default mapping (ISO8859-1) |
312
|
|
|
|
|
|
|
'G0GFX' => undef, # G0 charset = VT100 graphics mapping |
313
|
|
|
|
|
|
|
'G0ROM' => undef, # G0 charset = null mapping (straight to ROM) |
314
|
|
|
|
|
|
|
'G0TXT' => undef, # G0 charset = ASCII mapping |
315
|
|
|
|
|
|
|
'G0USR' => undef, # G0 charset = user defined mapping |
316
|
|
|
|
|
|
|
'G1DFL' => undef, # G1 charset = default mapping (ISO8859-1) |
317
|
|
|
|
|
|
|
'G1GFX' => undef, # G1 charset = VT100 graphics mapping |
318
|
|
|
|
|
|
|
'G1ROM' => undef, # G1 charset = null mapping (straight to ROM) |
319
|
|
|
|
|
|
|
'G1TXT' => undef, # G1 charset = ASCII mapping |
320
|
|
|
|
|
|
|
'G1USR' => undef, # G1 charset = user defined mapping |
321
|
|
|
|
|
|
|
'G2DFL' => undef, # G2 charset = default mapping (ISO8859-1) |
322
|
|
|
|
|
|
|
'G2GFX' => undef, # G2 charset = VT100 graphics mapping |
323
|
|
|
|
|
|
|
'G2ROM' => undef, # G2 charset = null mapping (straight to ROM) |
324
|
|
|
|
|
|
|
'G2USR' => undef, # G2 charset = user defined mapping |
325
|
|
|
|
|
|
|
'G3DFL' => undef, # G3 charset = default mapping (ISO8859-1) |
326
|
|
|
|
|
|
|
'G3GFX' => undef, # G3 charset = VT100 graphics mapping |
327
|
|
|
|
|
|
|
'G3ROM' => undef, # G3 charset = null mapping (straight to ROM) |
328
|
|
|
|
|
|
|
'G3USR' => undef, # G3 charset = user defined mapping |
329
|
|
|
|
|
|
|
'CSUTF8' => undef, # select UTF-8 (obsolete) |
330
|
|
|
|
|
|
|
'DECALN' => \&_code_DECALN,# DEC alignment test - fill screen with E's |
331
|
|
|
|
|
|
|
'DECANM' => undef, # ANSI/VT52 mode |
332
|
|
|
|
|
|
|
'DECARM' => undef, # auto repeat mode |
333
|
|
|
|
|
|
|
'DECAWM' => undef, # auto wrap mode |
334
|
|
|
|
|
|
|
'DECCKM' => undef, # cursor key mode |
335
|
|
|
|
|
|
|
'DECPAM' => undef, # set application keypad mode |
336
|
|
|
|
|
|
|
'DECPEX' => undef, # print screen / scrolling region |
337
|
|
|
|
|
|
|
'DECPFF' => undef, # sent FF after print screen, or not |
338
|
|
|
|
|
|
|
'DECPNM' => undef, # set numeric keypad mode |
339
|
|
|
|
|
|
|
'DECCOLM' => undef, # 132 column mode |
340
|
|
|
|
|
|
|
'DECINLM' => undef, # interlace mode |
341
|
|
|
|
|
|
|
'DECSCLM' => undef, # jump/smooth scroll mode |
342
|
|
|
|
|
|
|
'DECSCNM' => undef, # reverse/normal screen mode |
343
|
|
|
|
|
|
|
'DECSTBM' => \&_code_DECSTBM, # set scrolling region |
344
|
|
|
|
|
|
|
'DECTCEM' => \&_code_DECTCEM, # Cursor on (set); Cursor off (reset) |
345
|
|
|
|
|
|
|
) }; |
346
|
|
|
|
|
|
|
|
347
|
81
|
|
|
|
|
766
|
$self->{'_callbacks'} = { ( # available callbacks |
348
|
|
|
|
|
|
|
'BELL' => undef, # bell character received |
349
|
|
|
|
|
|
|
'CLEAR' => undef, # screen cleared |
350
|
|
|
|
|
|
|
'OUTPUT' => undef, # data to be sent back to originator |
351
|
|
|
|
|
|
|
'ROWCHANGE' => undef, # screen row changed |
352
|
|
|
|
|
|
|
'SCROLL_DOWN' => undef, # text about to move up (par=top row) |
353
|
|
|
|
|
|
|
'SCROLL_UP' => undef, # text about to move down (par=bott.) |
354
|
|
|
|
|
|
|
'UNKNOWN' => undef, # unknown character / sequence |
355
|
|
|
|
|
|
|
'STRING' => undef, # string received |
356
|
|
|
|
|
|
|
'XICONNAME' => undef, # xterm icon name changed |
357
|
|
|
|
|
|
|
'XWINTITLE' => undef, # xterm window title changed |
358
|
|
|
|
|
|
|
'LINEFEED' => undef, # line feed about to be processed |
359
|
|
|
|
|
|
|
) }; |
360
|
|
|
|
|
|
|
|
361
|
81
|
|
|
|
|
173
|
$self->{'_callbackarg'} = { () }; # stored arguments for callbacks |
362
|
|
|
|
|
|
|
|
363
|
81
|
|
|
|
|
215
|
$self->{'_decsc'} = [ () ]; # saved state for DECSC/DECRC |
364
|
81
|
|
|
|
|
178
|
$self->{'_cupsv'} = [ () ]; # saved state for CUPSV/CUPRS |
365
|
81
|
|
|
|
|
651
|
$self->{'_xon'} = 1; # state is XON (characters accepted) |
366
|
|
|
|
|
|
|
|
367
|
81
|
|
|
|
|
109
|
$self->{'cols'} = 80; # default: 80 columns |
368
|
81
|
|
|
|
|
115
|
$self->{'rows'} = 24; # default: 24 rows |
369
|
|
|
|
|
|
|
|
370
|
81
|
|
|
|
|
139
|
$self->{'_tabstops'} = []; # tab stops |
371
|
|
|
|
|
|
|
|
372
|
81
|
100
|
66
|
|
|
571
|
$self->{'cols'} = $init{'cols'} |
373
|
|
|
|
|
|
|
if ((defined $init{'cols'}) && ($init{'cols'} > 0)); |
374
|
81
|
100
|
66
|
|
|
463
|
$self->{'rows'} = $init{'rows'} |
375
|
|
|
|
|
|
|
if ((defined $init{'rows'}) && ($init{'rows'} > 0)); |
376
|
|
|
|
|
|
|
|
377
|
81
|
|
|
|
|
212
|
bless ($self, $class); |
378
|
|
|
|
|
|
|
|
379
|
81
|
|
|
|
|
219
|
$self->reset (); |
380
|
|
|
|
|
|
|
|
381
|
81
|
|
|
|
|
257
|
return $self; |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# Call a callback function with the given parameters. |
386
|
|
|
|
|
|
|
# |
387
|
|
|
|
|
|
|
sub callback_call { |
388
|
823
|
|
|
823
|
1
|
1600
|
my ($self, $callback, $par1, $par2) = (@_); |
389
|
823
|
|
|
|
|
813
|
my ($func, $arg); |
390
|
|
|
|
|
|
|
|
391
|
823
|
|
|
|
|
1437
|
$func = $self->{'_callbacks'}->{$callback}; |
392
|
823
|
100
|
|
|
|
2225
|
return if (not defined $func); |
393
|
|
|
|
|
|
|
|
394
|
4
|
|
|
|
|
7
|
$arg = $self->{'_callbackarg'}->{$callback}; |
395
|
|
|
|
|
|
|
|
396
|
4
|
|
|
|
|
5
|
&{$func} ($self, $callback, $par1, $par2, $arg); |
|
4
|
|
|
|
|
12
|
|
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
# Set a callback function. |
401
|
|
|
|
|
|
|
# |
402
|
|
|
|
|
|
|
sub callback_set { |
403
|
8
|
|
|
8
|
1
|
67
|
my ($self, $callback, $ref, $arg) = (@_); |
404
|
8
|
|
|
|
|
15
|
$self->{'_callbacks'}->{$callback} = $ref; |
405
|
8
|
|
|
|
|
83
|
$self->{'_callbackarg'}->{$callback} = $arg; |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
# Reset the terminal to "power-on" values. |
410
|
|
|
|
|
|
|
# |
411
|
|
|
|
|
|
|
sub reset { |
412
|
81
|
|
|
81
|
1
|
104
|
my $self = shift; |
413
|
81
|
|
|
|
|
93
|
my ($a, $b, $i); |
414
|
|
|
|
|
|
|
|
415
|
81
|
|
|
|
|
256
|
$self->{'x'} = 1; # default X position: 1 |
416
|
81
|
|
|
|
|
127
|
$self->{'y'} = 1; # default Y position: 1 |
417
|
|
|
|
|
|
|
|
418
|
81
|
|
|
|
|
243
|
$self->{'attr'} = DEFAULT_ATTR_PACKED; |
419
|
|
|
|
|
|
|
|
420
|
81
|
|
|
|
|
132
|
$self->{'ti'} = ''; # default: blank window title |
421
|
81
|
|
|
|
|
132
|
$self->{'ic'} = ''; # default: blank icon title |
422
|
|
|
|
|
|
|
|
423
|
81
|
|
|
|
|
108
|
$self->{'srt'} = 1; # scrolling region top: row 1 |
424
|
81
|
|
|
|
|
127
|
$self->{'srb'} = $self->{'rows'}; # scrolling region bottom |
425
|
|
|
|
|
|
|
|
426
|
81
|
|
|
|
|
138
|
$self->{'opts'} = {}; # blank all options |
427
|
81
|
|
|
|
|
157
|
$self->{'opts'}->{'LINEWRAP'} = 0; # line wrapping off |
428
|
81
|
|
|
|
|
128
|
$self->{'opts'}->{'LFTOCRLF'} = 0; # don't map LF -> CRLF |
429
|
81
|
|
|
|
|
122
|
$self->{'opts'}->{'IGNOREXOFF'} = 1; # ignore XON/XOFF by default |
430
|
|
|
|
|
|
|
|
431
|
81
|
|
|
|
|
137
|
$self->{'scrt'} = [ () ]; # blank screen text |
432
|
81
|
|
|
|
|
136
|
$self->{'scra'} = [ () ]; # blank screen attributes |
433
|
|
|
|
|
|
|
|
434
|
81
|
|
|
|
|
371
|
$a = "\000" x $self->{'cols'}; # set text to NUL |
435
|
81
|
|
|
|
|
189
|
$b = $self->{'attr'} x $self->{'cols'}; # set attributes to default |
436
|
|
|
|
|
|
|
|
437
|
81
|
|
|
|
|
198
|
foreach $i (1 .. $self->{'rows'}) { |
438
|
1452
|
|
|
|
|
7705
|
($self->{'scrt'}->[$i], $self->{'scra'}->[$i]) = ($a, $b); |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
81
|
|
|
|
|
166
|
$self->{'_tabstops'} = []; # reset tab stops |
442
|
81
|
|
|
|
|
267
|
for ($i = 1; $i < $self->{'cols'}; $i += 8) { |
443
|
342
|
|
|
|
|
961
|
$self->{'_tabstops'}->[$i] = 1; |
444
|
|
|
|
|
|
|
} |
445
|
|
|
|
|
|
|
|
446
|
81
|
|
|
|
|
118
|
$self->{'_buf'} = undef; # blank the esc-sequence buffer |
447
|
81
|
|
|
|
|
132
|
$self->{'_inesc'} = ''; # not in any escape sequence |
448
|
81
|
|
|
|
|
98
|
$self->{'_xon'} = 1; # state is XON (chars accepted) |
449
|
|
|
|
|
|
|
|
450
|
81
|
|
|
|
|
166
|
$self->{'cursor'} = 1; # turn cursor on |
451
|
|
|
|
|
|
|
} |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
# Resize the terminal. |
455
|
|
|
|
|
|
|
# |
456
|
|
|
|
|
|
|
sub resize { |
457
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
458
|
0
|
|
|
|
|
0
|
my $cols = shift; |
459
|
0
|
|
|
|
|
0
|
my $rows = shift; |
460
|
|
|
|
|
|
|
|
461
|
0
|
|
|
|
|
0
|
$self->callback_call ('CLEAR', 0, 0); |
462
|
|
|
|
|
|
|
|
463
|
0
|
|
|
|
|
0
|
$self->{'cols'} = $cols; |
464
|
0
|
|
|
|
|
0
|
$self->{'rows'} = $rows; |
465
|
|
|
|
|
|
|
|
466
|
0
|
|
|
|
|
0
|
$self->reset (); |
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
# Return the package version. |
471
|
|
|
|
|
|
|
# |
472
|
|
|
|
|
|
|
sub version { |
473
|
1
|
|
|
1
|
1
|
22
|
return $VERSION; |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
# Return the current number of columns. |
478
|
|
|
|
|
|
|
# |
479
|
|
|
|
|
|
|
sub cols { |
480
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
481
|
0
|
|
|
|
|
0
|
return $self->{'cols'}; |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
# Return the current number of rows. |
486
|
|
|
|
|
|
|
# |
487
|
|
|
|
|
|
|
sub rows { |
488
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
489
|
0
|
|
|
|
|
0
|
return $self->{'rows'}; |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
# Return the current terminal size. |
494
|
|
|
|
|
|
|
# |
495
|
|
|
|
|
|
|
sub size { |
496
|
79
|
|
|
79
|
1
|
270
|
my $self = shift; |
497
|
79
|
|
|
|
|
261
|
return ( $self->{'cols'}, $self->{'rows'} ); |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
# Return the current cursor X co-ordinate. |
502
|
|
|
|
|
|
|
# |
503
|
|
|
|
|
|
|
sub x { |
504
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
505
|
0
|
|
|
|
|
0
|
return $self->{'x'}; |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
# Return the current cursor Y co-ordinate. |
510
|
|
|
|
|
|
|
# |
511
|
|
|
|
|
|
|
sub y { |
512
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
513
|
0
|
|
|
|
|
0
|
return $self->{'y'}; |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
# Return the current cursor state (1=on, 0=off). |
518
|
|
|
|
|
|
|
# |
519
|
|
|
|
|
|
|
sub cursor { |
520
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
521
|
0
|
|
|
|
|
0
|
return $self->{'cursor'}; |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
# Return the current xterm title text. |
526
|
|
|
|
|
|
|
# |
527
|
|
|
|
|
|
|
sub xtitle { |
528
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
529
|
0
|
|
|
|
|
0
|
return $self->{'ti'}; |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
# Return the current xterm icon text. |
534
|
|
|
|
|
|
|
# |
535
|
|
|
|
|
|
|
sub xicon { |
536
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
537
|
0
|
|
|
|
|
0
|
return $self->{'ic'}; |
538
|
|
|
|
|
|
|
} |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
# Return the current terminal status. |
542
|
|
|
|
|
|
|
# |
543
|
|
|
|
|
|
|
sub status { |
544
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
return ( |
547
|
0
|
|
|
|
|
0
|
$self->{'x'}, # cursor X position |
548
|
|
|
|
|
|
|
$self->{'y'}, # cursor Y position |
549
|
|
|
|
|
|
|
$self->{'attr'}, # packed attributes |
550
|
|
|
|
|
|
|
$self->{'ti'}, # xterm title text |
551
|
|
|
|
|
|
|
$self->{'ic'} # xterm icon text |
552
|
|
|
|
|
|
|
); |
553
|
|
|
|
|
|
|
} |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
# Process the given string, updating the terminal object and calling any |
557
|
|
|
|
|
|
|
# necessary callbacks on the way. |
558
|
|
|
|
|
|
|
# |
559
|
|
|
|
|
|
|
sub process { |
560
|
77
|
|
|
77
|
1
|
495
|
my $self = shift; |
561
|
77
|
|
|
|
|
111
|
my ($string) = @_; |
562
|
|
|
|
|
|
|
|
563
|
77
|
50
|
|
|
|
173
|
return if (not defined $string); |
564
|
|
|
|
|
|
|
|
565
|
77
|
|
|
|
|
189
|
while (length $string > 0) { |
566
|
1914
|
100
|
|
|
|
3538
|
if (defined $self->{'_buf'}) { # in escape sequence |
567
|
835
|
50
|
|
|
|
2848
|
if ($string =~ s/^(.)//s) { |
568
|
835
|
|
|
|
|
1315
|
my $ch = $1; |
569
|
835
|
100
|
|
|
|
1596
|
if ($ch =~ /[\x00-\x1F]/s) { |
570
|
3
|
|
|
|
|
5
|
$self->_process_ctl ($ch); |
571
|
|
|
|
|
|
|
} else { |
572
|
832
|
|
|
|
|
1123
|
$self->{'_buf'} .= $ch; |
573
|
832
|
|
|
|
|
1550
|
$self->_process_escseq (); |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
} |
576
|
|
|
|
|
|
|
} else { # not in escape sequence |
577
|
1079
|
100
|
|
|
|
4851
|
if ($string =~ |
|
|
50
|
|
|
|
|
|
578
|
|
|
|
|
|
|
s/^([^\x00-\x1F\x7F\x9B]+)//s) { |
579
|
410
|
|
|
|
|
864
|
$self->_process_text ($1); |
580
|
|
|
|
|
|
|
} elsif ($string =~ s/^(.)//s) { |
581
|
669
|
|
|
|
|
1236
|
$self->_process_ctl ($1); |
582
|
|
|
|
|
|
|
} |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
} |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
# Return the current value of the given option, or undef if it doesn't exist. |
589
|
|
|
|
|
|
|
# |
590
|
|
|
|
|
|
|
sub option_read { |
591
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
592
|
0
|
|
|
|
|
0
|
my ($option) = @_; |
593
|
|
|
|
|
|
|
|
594
|
0
|
0
|
|
|
|
0
|
return undef if (not defined $option); |
595
|
0
|
|
|
|
|
0
|
return $self->{'opts'}->{$option}; |
596
|
|
|
|
|
|
|
} |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
# Set the value of the given option to the given value, returning the old |
600
|
|
|
|
|
|
|
# value or undef if an invalid option was given. |
601
|
|
|
|
|
|
|
# |
602
|
|
|
|
|
|
|
sub option_set { |
603
|
4
|
|
|
4
|
1
|
34
|
my $self = shift; |
604
|
4
|
|
|
|
|
5
|
my ($option, $value) = @_; |
605
|
4
|
|
|
|
|
4
|
my $prev; |
606
|
|
|
|
|
|
|
|
607
|
4
|
50
|
|
|
|
10
|
return undef if (not defined $option); |
608
|
4
|
50
|
|
|
|
8
|
return undef if (not defined $value); |
609
|
4
|
50
|
|
|
|
13
|
return undef if (not defined $self->{'opts'}->{$option}); |
610
|
|
|
|
|
|
|
|
611
|
4
|
|
|
|
|
6
|
$prev = $self->{'opts'}->{$option}; |
612
|
4
|
|
|
|
|
6
|
$self->{'opts'}->{$option} = $value; |
613
|
4
|
|
|
|
|
10
|
return $prev; |
614
|
|
|
|
|
|
|
} |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
# Return the attributes of the given row, or undef if out of range. |
618
|
|
|
|
|
|
|
# |
619
|
|
|
|
|
|
|
sub row_attr { |
620
|
15
|
|
|
15
|
1
|
82
|
my $self = shift; |
621
|
15
|
|
|
|
|
32
|
my ($row, $startcol, $endcol) = @_; |
622
|
15
|
|
|
|
|
23
|
my ($data); |
623
|
|
|
|
|
|
|
|
624
|
15
|
50
|
|
|
|
34
|
return undef if ($row < 1); |
625
|
15
|
50
|
|
|
|
38
|
return undef if ($row > $self->{'rows'}); |
626
|
|
|
|
|
|
|
|
627
|
15
|
|
|
|
|
32
|
$data = $self->{'scra'}->[$row]; |
628
|
|
|
|
|
|
|
|
629
|
15
|
50
|
33
|
|
|
40
|
if (defined $startcol && defined $endcol) { |
630
|
0
|
|
|
|
|
0
|
$data = substr ( |
631
|
|
|
|
|
|
|
$data, |
632
|
|
|
|
|
|
|
($startcol - 1) * 2, |
633
|
|
|
|
|
|
|
(($endcol - $startcol) + 1) * 2 |
634
|
|
|
|
|
|
|
); |
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
|
637
|
15
|
|
|
|
|
149
|
return $data; |
638
|
|
|
|
|
|
|
} |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
# Return the textual contents of the given row, or undef if out of range. |
642
|
|
|
|
|
|
|
# |
643
|
|
|
|
|
|
|
sub row_text { |
644
|
212
|
|
|
212
|
1
|
1672
|
my $self = shift; |
645
|
212
|
|
|
|
|
267
|
my ($row, $startcol, $endcol) = @_; |
646
|
212
|
|
|
|
|
245
|
my $text; |
647
|
|
|
|
|
|
|
|
648
|
212
|
50
|
|
|
|
391
|
return undef if ($row < 1); |
649
|
212
|
50
|
|
|
|
426
|
return undef if ($row > $self->{'rows'}); |
650
|
|
|
|
|
|
|
|
651
|
212
|
|
|
|
|
334
|
$text = $self->{'scrt'}->[$row]; |
652
|
|
|
|
|
|
|
|
653
|
212
|
50
|
33
|
|
|
471
|
if (defined $startcol && defined $endcol) { |
654
|
0
|
|
|
|
|
0
|
$text = substr ( |
655
|
|
|
|
|
|
|
$text, |
656
|
|
|
|
|
|
|
$startcol - 1, |
657
|
|
|
|
|
|
|
($endcol - $startcol) + 1 |
658
|
|
|
|
|
|
|
); |
659
|
|
|
|
|
|
|
} |
660
|
|
|
|
|
|
|
|
661
|
212
|
|
|
|
|
530
|
return $text; |
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
# Return the textual contents of the given row, or undef if out of range, |
666
|
|
|
|
|
|
|
# with unused characters represented as a space instead of \0. |
667
|
|
|
|
|
|
|
# |
668
|
|
|
|
|
|
|
sub row_plaintext { |
669
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
670
|
0
|
|
|
|
|
0
|
my ($row, $startcol, $endcol) = @_; |
671
|
0
|
|
|
|
|
0
|
my $text; |
672
|
|
|
|
|
|
|
|
673
|
0
|
0
|
|
|
|
0
|
return undef if ($row < 1); |
674
|
0
|
0
|
|
|
|
0
|
return undef if ($row > $self->{'rows'}); |
675
|
|
|
|
|
|
|
|
676
|
0
|
|
|
|
|
0
|
$text = $self->{'scrt'}->[$row]; |
677
|
0
|
|
|
|
|
0
|
$text =~ s/\0/ /g; |
678
|
|
|
|
|
|
|
|
679
|
0
|
0
|
0
|
|
|
0
|
if (defined $startcol && defined $endcol) { |
680
|
0
|
|
|
|
|
0
|
$text = substr ( |
681
|
|
|
|
|
|
|
$text, |
682
|
|
|
|
|
|
|
$startcol - 1, |
683
|
|
|
|
|
|
|
($endcol - $startcol) + 1 |
684
|
|
|
|
|
|
|
); |
685
|
|
|
|
|
|
|
} |
686
|
|
|
|
|
|
|
|
687
|
0
|
|
|
|
|
0
|
return $text; |
688
|
|
|
|
|
|
|
} |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
# Return a set of SGR escape sequences that will change colours and |
692
|
|
|
|
|
|
|
# attributes from "source" to "dest" (packed attributes). |
693
|
|
|
|
|
|
|
# |
694
|
|
|
|
|
|
|
sub sgr_change { |
695
|
0
|
0
|
|
0
|
1
|
0
|
shift if ref($_[0]); |
696
|
0
|
|
|
|
|
0
|
my ($source, $dest) = @_; |
697
|
0
|
|
|
|
|
0
|
my ($out, %off, %on) = ('', (), ()); |
698
|
|
|
|
|
|
|
|
699
|
0
|
0
|
|
|
|
0
|
$source = DEFAULT_ATTR_PACKED if (not defined $source); |
700
|
0
|
0
|
|
|
|
0
|
$dest = DEFAULT_ATTR_PACKED if (not defined $dest); |
701
|
|
|
|
|
|
|
|
702
|
0
|
0
|
|
|
|
0
|
return '' if ($source eq $dest); |
703
|
0
|
0
|
|
|
|
0
|
return "\e[m" if ($dest eq DEFAULT_ATTR_PACKED); |
704
|
|
|
|
|
|
|
|
705
|
0
|
|
|
|
|
0
|
my ($sfg, $sbg, $sbo, $sfa, $sst, $sul, $sbl, $srv) = attr_unpack ($source); |
706
|
0
|
|
|
|
|
0
|
my ($dfg, $dbg, $dbo, $dfa, $dst, $dul, $dbl, $drv) = attr_unpack ($dest); |
707
|
|
|
|
|
|
|
|
708
|
0
|
0
|
0
|
|
|
0
|
if (($sfg != $dfg) || ($sbg != $dbg)) { |
709
|
0
|
|
|
|
|
0
|
$out .= sprintf ("\e[m\e[3%d;4%dm", $dfg, $dbg); |
710
|
0
|
|
|
|
|
0
|
($sbo, $sfa, $sst, $sul, $sbl, $srv) = (0, 0, 0, 0, 0, 0); |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
|
713
|
0
|
0
|
0
|
|
|
0
|
if (($sbo > $dbo) || ($sfa > $dfa)) { |
714
|
0
|
|
|
|
|
0
|
$off{'22'} = 1; |
715
|
0
|
|
|
|
|
0
|
($sbo, $sfa) = (0, 0); |
716
|
|
|
|
|
|
|
} |
717
|
0
|
0
|
|
|
|
0
|
$off{'24'} = 1 if ($sul > $dul); |
718
|
0
|
0
|
|
|
|
0
|
$off{'25'} = 1 if ($sbl > $dbl); |
719
|
0
|
0
|
|
|
|
0
|
$off{'27'} = 1 if ($srv > $drv); |
720
|
|
|
|
|
|
|
|
721
|
0
|
0
|
|
|
|
0
|
if (scalar keys %off > 2) { |
|
|
0
|
|
|
|
|
|
722
|
0
|
|
|
|
|
0
|
$out .= "\e[m"; |
723
|
0
|
|
|
|
|
0
|
($sbo, $sfa, $sst, $sul, $sbl, $srv) = (0, 0, 0, 0, 0, 0); |
724
|
|
|
|
|
|
|
} elsif (scalar keys %off > 0) { |
725
|
0
|
|
|
|
|
0
|
$out .= "\e[" . join (';', keys %off) . "m"; |
726
|
|
|
|
|
|
|
} |
727
|
|
|
|
|
|
|
|
728
|
0
|
0
|
|
|
|
0
|
$on{'1'} = 1 if ($dbo > $sbo); |
729
|
0
|
0
|
0
|
|
|
0
|
$on{'2'} = 1 if (($dfa > $sfa) && !($dbo > $sbo)); |
730
|
0
|
0
|
|
|
|
0
|
$on{'4'} = 1 if ($dul > $sul); |
731
|
0
|
0
|
|
|
|
0
|
$on{'5'} = 1 if ($dbl > $sbl); |
732
|
0
|
0
|
|
|
|
0
|
$on{'7'} = 1 if ($drv > $srv); |
733
|
|
|
|
|
|
|
|
734
|
0
|
0
|
|
|
|
0
|
$out .= "\e[" . join (';', keys %on) . "m" if (scalar keys %on > 0); |
735
|
|
|
|
|
|
|
|
736
|
0
|
|
|
|
|
0
|
return $out; |
737
|
|
|
|
|
|
|
} |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
# Return the textual contents of the given row, or undef if out of range, |
741
|
|
|
|
|
|
|
# with unused characters represented as a space instead of \0, and any |
742
|
|
|
|
|
|
|
# colour or attribute changes expressed by the relevant SGR escape |
743
|
|
|
|
|
|
|
# sequences. |
744
|
|
|
|
|
|
|
# |
745
|
|
|
|
|
|
|
sub row_sgrtext { |
746
|
0
|
|
|
0
|
1
|
0
|
my ($self, $row, $startcol, $endcol) = @_; |
747
|
0
|
|
|
|
|
0
|
my ($row_text, $row_attr, $text, $char, $attr_cur, $attr_next); |
748
|
|
|
|
|
|
|
|
749
|
0
|
0
|
|
|
|
0
|
return undef if ($row < 1); |
750
|
0
|
0
|
|
|
|
0
|
return undef if ($row > $self->{'rows'}); |
751
|
|
|
|
|
|
|
|
752
|
0
|
0
|
|
|
|
0
|
$startcol = 1 if (not defined $startcol); |
753
|
0
|
0
|
|
|
|
0
|
$endcol = $self->{'cols'} if (not defined $endcol); |
754
|
|
|
|
|
|
|
|
755
|
0
|
0
|
0
|
|
|
0
|
return undef if (($startcol < 1) || ($startcol > $self->{'cols'})); |
756
|
0
|
0
|
0
|
|
|
0
|
return undef if (($endcol < 1) || ($endcol > $self->{'cols'})); |
757
|
0
|
0
|
|
|
|
0
|
return undef if ($endcol < $startcol); |
758
|
|
|
|
|
|
|
|
759
|
0
|
|
|
|
|
0
|
$row_text = $self->{'scrt'}->[$row]; |
760
|
0
|
|
|
|
|
0
|
$row_attr = $self->{'scra'}->[$row]; |
761
|
|
|
|
|
|
|
|
762
|
0
|
|
|
|
|
0
|
$text = ''; |
763
|
0
|
|
|
|
|
0
|
$attr_cur = DEFAULT_ATTR_PACKED; |
764
|
|
|
|
|
|
|
|
765
|
0
|
|
|
|
|
0
|
for (; $startcol <= $endcol; $startcol++) { |
766
|
0
|
|
|
|
|
0
|
$char = substr ($row_text, $startcol - 1, 1); |
767
|
0
|
|
|
|
|
0
|
$char =~ s/\0/ /g; |
768
|
0
|
0
|
|
|
|
0
|
$char = ' ' if ($char !~ /./); |
769
|
0
|
|
|
|
|
0
|
$attr_next = substr ($row_attr, ($startcol - 1) * 2, 2); |
770
|
0
|
|
|
|
|
0
|
$text .= $self->sgr_change ($attr_cur, $attr_next) . $char; |
771
|
0
|
|
|
|
|
0
|
$attr_cur = $attr_next; |
772
|
|
|
|
|
|
|
} |
773
|
|
|
|
|
|
|
|
774
|
0
|
|
|
|
|
0
|
$attr_next = DEFAULT_ATTR_PACKED; |
775
|
0
|
|
|
|
|
0
|
$text .= $self->sgr_change ($attr_cur, $attr_next); |
776
|
|
|
|
|
|
|
|
777
|
0
|
|
|
|
|
0
|
return $text; |
778
|
|
|
|
|
|
|
} |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
# Process a string of plain text, with no special characters in it. |
782
|
|
|
|
|
|
|
# |
783
|
|
|
|
|
|
|
sub _process_text { |
784
|
410
|
|
|
410
|
|
453
|
my $self = shift; |
785
|
410
|
|
|
|
|
681
|
my ($text) = @_; |
786
|
410
|
|
|
|
|
423
|
my ($width, $segment); |
787
|
|
|
|
|
|
|
|
788
|
410
|
100
|
|
|
|
1092
|
return if ($self->{'_xon'} == 0); |
789
|
|
|
|
|
|
|
|
790
|
408
|
|
|
|
|
620
|
$width = ($self->{'cols'} + 1) - $self->{'x'}; |
791
|
|
|
|
|
|
|
|
792
|
408
|
100
|
|
|
|
918
|
if ($self->{'opts'}->{'LINEWRAP'} == 0) { # no line wrap - truncate |
793
|
407
|
50
|
|
|
|
891
|
return if ($width < 1); |
794
|
407
|
|
|
|
|
641
|
$text = substr ($text, 0, $width); |
795
|
407
|
|
|
|
|
886
|
substr ( |
796
|
|
|
|
|
|
|
$self->{'scrt'}->[$self->{'y'}], $self->{'x'} - 1, |
797
|
|
|
|
|
|
|
length $text |
798
|
|
|
|
|
|
|
) = $text; |
799
|
407
|
|
|
|
|
1280
|
substr ( |
800
|
|
|
|
|
|
|
$self->{'scra'}->[$self->{'y'}], 2 * ($self->{'x'} - 1), |
801
|
|
|
|
|
|
|
2 * (length $text) |
802
|
|
|
|
|
|
|
) = $self->{'attr'} x (length $text); |
803
|
407
|
|
|
|
|
527
|
$self->{'x'} += length $text; |
804
|
407
|
100
|
|
|
|
1031
|
$self->{'x'} = $self->{'cols'} |
805
|
|
|
|
|
|
|
if ($self->{'x'} > $self->{'cols'}); |
806
|
407
|
|
|
|
|
1037
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
807
|
407
|
|
|
|
|
1532
|
return; |
808
|
|
|
|
|
|
|
} |
809
|
|
|
|
|
|
|
|
810
|
1
|
|
|
|
|
3
|
while (length $text > 0) { # line wrapping enabled |
811
|
5
|
100
|
|
|
|
10
|
if ($width > 0) { |
812
|
3
|
|
|
|
|
7
|
$segment = substr ($text, 0, $width, ''); |
813
|
3
|
|
|
|
|
6
|
substr ( |
814
|
|
|
|
|
|
|
$self->{'scrt'}->[$self->{'y'}], $self->{'x'} - 1, |
815
|
|
|
|
|
|
|
length $segment |
816
|
|
|
|
|
|
|
) = $segment; |
817
|
3
|
|
|
|
|
12
|
substr ( |
818
|
|
|
|
|
|
|
$self->{'scra'}->[$self->{'y'}], |
819
|
|
|
|
|
|
|
2 * ($self->{'x'} - 1), |
820
|
|
|
|
|
|
|
2 * (length $segment) |
821
|
|
|
|
|
|
|
) = $self->{'attr'} x (length $segment); |
822
|
3
|
|
|
|
|
6
|
$self->{'x'} += length $segment; |
823
|
|
|
|
|
|
|
} else { |
824
|
2
|
50
|
|
|
|
5
|
if ($self->{'x'} > $self->{'cols'}) { # wrap to next line |
825
|
2
|
|
|
|
|
5
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
826
|
2
|
|
|
|
|
19
|
$self->callback_call ('LINEFEED', $self->{'y'}, 0); |
827
|
2
|
|
|
|
|
4
|
$self->{'x'} = 1; |
828
|
2
|
|
|
|
|
14
|
$self->_move_down; |
829
|
|
|
|
|
|
|
} |
830
|
|
|
|
|
|
|
} |
831
|
5
|
|
|
|
|
14
|
$width = ($self->{'cols'} + 1) - $self->{'x'}; |
832
|
|
|
|
|
|
|
} |
833
|
|
|
|
|
|
|
|
834
|
1
|
|
|
|
|
4
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
835
|
|
|
|
|
|
|
} |
836
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
# Process a control character. |
839
|
|
|
|
|
|
|
# |
840
|
|
|
|
|
|
|
sub _process_ctl { |
841
|
672
|
|
|
672
|
|
721
|
my $self = shift; |
842
|
672
|
|
|
|
|
1053
|
my $ctl = shift; |
843
|
672
|
|
|
|
|
642
|
my ($name, $func); |
844
|
|
|
|
|
|
|
|
845
|
672
|
|
|
|
|
1116
|
$name = $self->{'_ctlseq'}->{$ctl}; |
846
|
672
|
50
|
|
|
|
1194
|
return if (not defined $name); # ignore unknown characters |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
# If we're in XOFF mode, ignore anything other than XON |
849
|
|
|
|
|
|
|
# |
850
|
672
|
100
|
|
|
|
1259
|
if ($self->{'_xon'} == 0) { |
851
|
2
|
100
|
|
|
|
7
|
return if ($name ne 'XON'); |
852
|
|
|
|
|
|
|
} |
853
|
|
|
|
|
|
|
|
854
|
671
|
|
|
|
|
987
|
$func = $self->{'_funcs'}->{$name}; |
855
|
671
|
50
|
|
|
|
1125
|
if (not defined $func) { # do nothing if unsupported |
856
|
0
|
|
|
|
|
0
|
$self->callback_call ('UNKNOWN', $name, $ctl); |
857
|
|
|
|
|
|
|
} else { # call handler function |
858
|
671
|
|
|
|
|
703
|
&{$func} ($self, $name); |
|
671
|
|
|
|
|
1326
|
|
859
|
|
|
|
|
|
|
} |
860
|
|
|
|
|
|
|
} |
861
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
# Check the escape-sequence buffer, and process it if necessary. |
864
|
|
|
|
|
|
|
# |
865
|
|
|
|
|
|
|
sub _process_escseq { |
866
|
835
|
|
|
835
|
|
994
|
my $self = shift; |
867
|
835
|
|
|
|
|
847
|
my ($prefix, $suffix, $func, $name, $dat); |
868
|
0
|
|
|
|
|
0
|
my @params; |
869
|
|
|
|
|
|
|
|
870
|
835
|
50
|
|
|
|
7185
|
return if (not defined $self->{'_buf'}); |
871
|
835
|
50
|
|
|
|
1626
|
return if (length $self->{'_buf'} < 1); |
872
|
835
|
50
|
|
|
|
1676
|
return if ($self->{'_xon'} == 0); |
873
|
|
|
|
|
|
|
|
874
|
835
|
100
|
|
|
|
2508
|
if ($self->{'_inesc'} eq 'OSC') { # in OSC sequence |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
875
|
32
|
50
|
|
|
|
293
|
if ( |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
876
|
|
|
|
|
|
|
$self->{'_buf'} =~ /^0;([^\007]*)(?:\007|\033\\)/ |
877
|
|
|
|
|
|
|
) { # icon & window |
878
|
0
|
|
|
|
|
0
|
$dat = $1; |
879
|
0
|
|
|
|
|
0
|
$self->callback_call ('XWINTITLE', $dat, 0); |
880
|
0
|
|
|
|
|
0
|
$self->callback_call ('XICONNAME', $dat, 0); |
881
|
0
|
|
|
|
|
0
|
$self->{'ic'} = $dat; |
882
|
0
|
|
|
|
|
0
|
$self->{'ti'} = $dat; |
883
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
884
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
885
|
|
|
|
|
|
|
} elsif ( |
886
|
|
|
|
|
|
|
$self->{'_buf'} =~ /^1;([^\007]*)(?:\007|\033\\)/ |
887
|
|
|
|
|
|
|
) { # set icon name |
888
|
1
|
|
|
|
|
3
|
$dat = $1; |
889
|
1
|
|
|
|
|
3
|
$self->callback_call ('XICONNAME', $dat, 0); |
890
|
1
|
|
|
|
|
6
|
$self->{'ic'} = $dat; |
891
|
1
|
|
|
|
|
2
|
$self->{'_buf'} = undef; |
892
|
1
|
|
|
|
|
5
|
$self->{'_inesc'} = ''; |
893
|
|
|
|
|
|
|
} elsif ( |
894
|
|
|
|
|
|
|
$self->{'_buf'} =~ /^2;([^\007]*)(?:\007|\033\\)/ |
895
|
|
|
|
|
|
|
) { # set window title |
896
|
1
|
|
|
|
|
2
|
$dat = $1; |
897
|
1
|
|
|
|
|
12
|
$self->callback_call ('XWINTITLE', $dat, 0); |
898
|
1
|
|
|
|
|
7
|
$self->{'ti'} = $dat; |
899
|
1
|
|
|
|
|
2
|
$self->{'_buf'} = undef; |
900
|
1
|
|
|
|
|
4
|
$self->{'_inesc'} = ''; |
901
|
|
|
|
|
|
|
} elsif ( |
902
|
|
|
|
|
|
|
$self->{'_buf'} =~ /^\d+;([^\007]*)(?:\007|\033\\)/ |
903
|
|
|
|
|
|
|
) { # unknown OSC |
904
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
905
|
|
|
|
|
|
|
'UNKNOWN', 'OSC', "\033]" . $self->{'_buf'} |
906
|
|
|
|
|
|
|
); |
907
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
908
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
909
|
|
|
|
|
|
|
} elsif ( |
910
|
|
|
|
|
|
|
length $self->{'_buf'} > 1024 |
911
|
|
|
|
|
|
|
) { # OSC too long |
912
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
913
|
|
|
|
|
|
|
'UNKNOWN', 'OSC', "\033]" . $self->{'_buf'} |
914
|
|
|
|
|
|
|
); |
915
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
916
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
917
|
|
|
|
|
|
|
} |
918
|
|
|
|
|
|
|
} elsif ($self->{'_inesc'} eq 'CSI') { # in CSI sequence |
919
|
534
|
|
|
|
|
540
|
foreach $suffix (keys %{$self->{'_csiseq'}}) { |
|
534
|
|
|
|
|
2956
|
|
920
|
13700
|
50
|
|
|
|
24559
|
next if (length $self->{'_buf'} < length $suffix); |
921
|
|
|
|
|
|
|
next if ( |
922
|
13700
|
100
|
|
|
|
32054
|
substr ( |
923
|
|
|
|
|
|
|
$self->{'_buf'}, |
924
|
|
|
|
|
|
|
(length $self->{'_buf'}) - (length $suffix), |
925
|
|
|
|
|
|
|
length $suffix |
926
|
|
|
|
|
|
|
) ne $suffix |
927
|
|
|
|
|
|
|
); |
928
|
227
|
|
|
|
|
649
|
$self->{'_buf'} = substr ( |
929
|
|
|
|
|
|
|
$self->{'_buf'}, |
930
|
|
|
|
|
|
|
0, |
931
|
|
|
|
|
|
|
(length $self->{'_buf'}) - (length $suffix) |
932
|
|
|
|
|
|
|
); |
933
|
227
|
|
|
|
|
348
|
$name = $self->{'_csiseq'}->{$suffix}; |
934
|
227
|
|
|
|
|
386
|
$func = $self->{'_funcs'}->{$name}; |
935
|
227
|
50
|
|
|
|
439
|
if (not defined $func) { # unsupported sequence |
936
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
937
|
|
|
|
|
|
|
'UNKNOWN', |
938
|
|
|
|
|
|
|
$name, |
939
|
|
|
|
|
|
|
"\033[" . $self->{'_buf'} . $suffix |
940
|
|
|
|
|
|
|
); |
941
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
942
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
943
|
0
|
|
|
|
|
0
|
return; |
944
|
|
|
|
|
|
|
} |
945
|
227
|
|
|
|
|
664
|
@params = split (';', $self->{'_buf'}); |
946
|
227
|
|
|
|
|
329
|
$self->{'_buf'} = undef; |
947
|
227
|
|
|
|
|
312
|
$self->{'_inesc'} = ''; |
948
|
227
|
|
|
|
|
258
|
&{$func} ($self, @params); |
|
227
|
|
|
|
|
551
|
|
949
|
227
|
|
|
|
|
1298
|
return; |
950
|
|
|
|
|
|
|
} |
951
|
307
|
50
|
|
|
|
2091
|
if ( |
952
|
|
|
|
|
|
|
length $self->{'_buf'} > 64 |
953
|
|
|
|
|
|
|
) { # abort CSI sequence if too long |
954
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
955
|
|
|
|
|
|
|
'UNKNOWN', 'CSI', "\033[" . $self->{'_buf'} |
956
|
|
|
|
|
|
|
); |
957
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
958
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
959
|
|
|
|
|
|
|
} |
960
|
|
|
|
|
|
|
} elsif ($self->{'_inesc'} =~ /_ST$/) { |
961
|
13
|
100
|
|
|
|
70
|
if ($self->{'_buf'} =~ s/\033\\$//) { |
|
|
50
|
|
|
|
|
|
962
|
1
|
|
|
|
|
4
|
$self->{'_inesc'} =~ s/_ST$//; |
963
|
1
|
|
|
|
|
5
|
$self->callback_call ( |
964
|
|
|
|
|
|
|
'STRING', $self->{'_inesc'}, $self->{'_buf'} |
965
|
|
|
|
|
|
|
); |
966
|
1
|
|
|
|
|
6
|
$self->{'_buf'} = undef; |
967
|
1
|
|
|
|
|
2
|
$self->{'_inesc'} = ''; |
968
|
1
|
|
|
|
|
2
|
$self->{'_buf'} = undef; |
969
|
1
|
|
|
|
|
4
|
$self->{'_inesc'} = ''; |
970
|
|
|
|
|
|
|
} elsif ( |
971
|
|
|
|
|
|
|
length $self->{'_buf'} > 1024 |
972
|
|
|
|
|
|
|
) { # string too long |
973
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} =~ s/_ST$//; |
974
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
975
|
|
|
|
|
|
|
'STRING', $self->{'_inesc'}, $self->{'_buf'} |
976
|
|
|
|
|
|
|
); |
977
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
978
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
979
|
|
|
|
|
|
|
} |
980
|
|
|
|
|
|
|
} else { # in ESC sequence |
981
|
256
|
|
|
|
|
265
|
foreach $prefix ( |
|
256
|
|
|
|
|
2101
|
|
982
|
|
|
|
|
|
|
keys %{$self->{'_escseq'}} |
983
|
|
|
|
|
|
|
) { |
984
|
|
|
|
|
|
|
next if ( |
985
|
5725
|
100
|
|
|
|
16070
|
substr ($self->{'_buf'}, 0, length $prefix) |
986
|
|
|
|
|
|
|
ne $prefix |
987
|
|
|
|
|
|
|
); |
988
|
255
|
|
|
|
|
527
|
$name = $self->{'_escseq'}->{$prefix}; |
989
|
255
|
|
|
|
|
389
|
$func = $self->{'_funcs'}->{$name}; |
990
|
255
|
50
|
|
|
|
563
|
if (not defined $func) { # unsupported sequence |
991
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
992
|
|
|
|
|
|
|
'UNKNOWN', |
993
|
|
|
|
|
|
|
$name, |
994
|
|
|
|
|
|
|
"\033" . $self->{'_buf'} |
995
|
|
|
|
|
|
|
); |
996
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
997
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
998
|
0
|
|
|
|
|
0
|
return; |
999
|
|
|
|
|
|
|
} |
1000
|
255
|
|
|
|
|
367
|
$self->{'_buf'} = undef; |
1001
|
255
|
|
|
|
|
343
|
$self->{'_inesc'} = ''; |
1002
|
255
|
|
|
|
|
273
|
&{$func} ($self); |
|
255
|
|
|
|
|
508
|
|
1003
|
255
|
|
|
|
|
1529
|
return; |
1004
|
|
|
|
|
|
|
} |
1005
|
1
|
50
|
|
|
|
10
|
if ( |
1006
|
|
|
|
|
|
|
length $self->{'_buf'} > 8 |
1007
|
|
|
|
|
|
|
) { # abort ESC sequence if too long |
1008
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
1009
|
|
|
|
|
|
|
'UNKNOWN', |
1010
|
|
|
|
|
|
|
'ESC', |
1011
|
|
|
|
|
|
|
"\033" . $self->{'_buf'} |
1012
|
|
|
|
|
|
|
); |
1013
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
1014
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
1015
|
|
|
|
|
|
|
} |
1016
|
|
|
|
|
|
|
} |
1017
|
|
|
|
|
|
|
} |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
# Scroll the scrolling region up such that the text in the scrolling region |
1021
|
|
|
|
|
|
|
# moves down, by the given number of lines. |
1022
|
|
|
|
|
|
|
# |
1023
|
|
|
|
|
|
|
sub _scroll_up { |
1024
|
7
|
|
|
7
|
|
7
|
my $self = shift; |
1025
|
7
|
|
|
|
|
9
|
my $lines = shift; |
1026
|
7
|
|
|
|
|
10
|
my ($attr, $a, $b, $i); |
1027
|
|
|
|
|
|
|
|
1028
|
7
|
50
|
|
|
|
22
|
return if ($lines < 1); |
1029
|
|
|
|
|
|
|
|
1030
|
7
|
|
|
|
|
16
|
$self->callback_call ('SCROLL_UP', $self->{'srb'}, $lines); |
1031
|
|
|
|
|
|
|
|
1032
|
7
|
|
|
|
|
35
|
for ($i = $self->{'srb'}; $i >= ($self->{'srt'} + $lines); $i --) { |
1033
|
8
|
|
|
|
|
17
|
$self->{'scrt'}->[$i] = $self->{'scrt'}->[$i - $lines]; |
1034
|
8
|
|
|
|
|
26
|
$self->{'scra'}->[$i] = $self->{'scra'}->[$i - $lines]; |
1035
|
|
|
|
|
|
|
} |
1036
|
|
|
|
|
|
|
|
1037
|
7
|
|
|
|
|
17
|
$a = "\000" x $self->{'cols'}; # set text to NUL |
1038
|
7
|
|
|
|
|
9
|
$attr = DEFAULT_ATTR_PACKED; |
1039
|
7
|
|
|
|
|
15
|
$b = $attr x $self->{'cols'}; # set attributes to default |
1040
|
|
|
|
|
|
|
|
1041
|
7
|
|
100
|
|
|
51
|
for ( |
1042
|
|
|
|
|
|
|
$i = $self->{'srt'}; |
1043
|
|
|
|
|
|
|
($i <= $self->{'srb'}) && ($i < ($self->{'srt'} + $lines)); |
1044
|
|
|
|
|
|
|
$i ++ |
1045
|
|
|
|
|
|
|
) { |
1046
|
14
|
|
|
|
|
18
|
$self->{'scrt'}->[$i] = $a; # blank new lines |
1047
|
14
|
|
|
|
|
66
|
$self->{'scra'}->[$i] = $b; # wipe attributes of new lines |
1048
|
|
|
|
|
|
|
} |
1049
|
|
|
|
|
|
|
} |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
# Scroll the scrolling region down such that the text in the scrolling region |
1053
|
|
|
|
|
|
|
# moves up, by the given number of lines. |
1054
|
|
|
|
|
|
|
# |
1055
|
|
|
|
|
|
|
sub _scroll_down { |
1056
|
9
|
|
|
9
|
|
11
|
my $self = shift; |
1057
|
9
|
|
|
|
|
11
|
my $lines = shift; |
1058
|
9
|
|
|
|
|
51
|
my ($a, $b, $i, $attr); |
1059
|
|
|
|
|
|
|
|
1060
|
9
|
|
|
|
|
23
|
$self->callback_call ('SCROLL_DOWN', $self->{'srt'}, $lines); |
1061
|
|
|
|
|
|
|
|
1062
|
9
|
|
|
|
|
28
|
for ($i = $self->{'srt'}; $i <= ($self->{'srb'} - $lines); $i ++) { |
1063
|
14
|
|
|
|
|
31
|
$self->{'scrt'}->[$i] = $self->{'scrt'}->[$i + $lines]; |
1064
|
14
|
|
|
|
|
44
|
$self->{'scra'}->[$i] = $self->{'scra'}->[$i + $lines]; |
1065
|
|
|
|
|
|
|
} |
1066
|
|
|
|
|
|
|
|
1067
|
9
|
|
|
|
|
22
|
$a = "\000" x $self->{'cols'}; # set text to NUL |
1068
|
9
|
|
|
|
|
10
|
$attr = DEFAULT_ATTR_PACKED; |
1069
|
9
|
|
|
|
|
19
|
$b = $attr x $self->{'cols'}; # set attributes to default |
1070
|
|
|
|
|
|
|
|
1071
|
9
|
|
100
|
|
|
50
|
for ( |
1072
|
|
|
|
|
|
|
$i = $self->{'srb'}; |
1073
|
|
|
|
|
|
|
($i >= $self->{'srt'}) && ($i > ($self->{'srb'} - $lines)); |
1074
|
|
|
|
|
|
|
$i -- |
1075
|
|
|
|
|
|
|
) { |
1076
|
16
|
|
|
|
|
37
|
$self->{'scrt'}->[$i] = $a; # blank new lines |
1077
|
16
|
|
|
|
|
83
|
$self->{'scra'}->[$i] = $b; # wipe attributes of new lines |
1078
|
|
|
|
|
|
|
} |
1079
|
|
|
|
|
|
|
} |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
# Move the cursor up the given number of lines, without triggering a GOTO callback, taking scrolling into account. |
1083
|
|
|
|
|
|
|
# |
1084
|
|
|
|
|
|
|
sub _move_up { |
1085
|
11
|
|
|
11
|
|
66
|
my $self = shift; |
1086
|
11
|
|
|
|
|
16
|
my $num = shift; |
1087
|
11
|
100
|
|
|
|
24
|
$num = 1 if (not defined $num); |
1088
|
11
|
50
|
|
|
|
21
|
$num = 1 if ($num < 1); |
1089
|
11
|
|
|
|
|
16
|
$self->{'y'} -= $num; |
1090
|
11
|
100
|
|
|
|
30
|
return if ($self->{'y'} >= $self->{'srt'}); |
1091
|
7
|
|
|
|
|
23
|
$self->_scroll_up ($self->{'srt'} - $self->{'y'}); # scroll |
1092
|
7
|
|
|
|
|
17
|
$self->{'y'} = $self->{'srt'}; |
1093
|
|
|
|
|
|
|
} |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
|
1096
|
|
|
|
|
|
|
# Move the cursor down the given number of lines, without triggering a GOTO |
1097
|
|
|
|
|
|
|
# callback, taking scrolling into account. |
1098
|
|
|
|
|
|
|
# |
1099
|
|
|
|
|
|
|
sub _move_down { |
1100
|
195
|
|
|
195
|
|
209
|
my $self = shift; |
1101
|
195
|
|
|
|
|
196
|
my $num = shift; |
1102
|
195
|
100
|
|
|
|
382
|
$num = 1 if (not defined $num); |
1103
|
195
|
50
|
|
|
|
393
|
$num = 1 if ($num < 1); |
1104
|
195
|
|
|
|
|
268
|
$self->{'y'} += $num; |
1105
|
195
|
100
|
|
|
|
914
|
return if ($self->{'y'} <= $self->{'srb'}); |
1106
|
9
|
|
|
|
|
25
|
$self->_scroll_down ($self->{'y'} - $self->{'srb'}); # scroll |
1107
|
9
|
|
|
|
|
23
|
$self->{'y'} = $self->{'srb'}; |
1108
|
|
|
|
|
|
|
} |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
sub _code_BEL { # beep |
1112
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1113
|
0
|
0
|
0
|
|
|
0
|
if ((defined $self->{'_buf'}) && ($self->{'_inesc'} eq 'OSC')) { |
1114
|
|
|
|
|
|
|
# CSI OSC can be terminated with a BEL |
1115
|
0
|
|
|
|
|
0
|
$self->{'_buf'} .= "\007"; |
1116
|
0
|
|
|
|
|
0
|
$self->_process_escseq (); |
1117
|
|
|
|
|
|
|
} else { |
1118
|
0
|
|
|
|
|
0
|
$self->callback_call ('BELL', 0, 0); |
1119
|
|
|
|
|
|
|
} |
1120
|
|
|
|
|
|
|
} |
1121
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
sub _code_BS { # move left 1 character |
1123
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1124
|
0
|
|
|
|
|
0
|
$self->{'x'} --; |
1125
|
0
|
0
|
|
|
|
0
|
$self->{'x'} = 1 if ($self->{'x'} < 1); |
1126
|
|
|
|
|
|
|
} |
1127
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
sub _code_CAN { # cancel escape sequence |
1129
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1130
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
1131
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
1132
|
|
|
|
|
|
|
} |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
sub _code_TBC { # clear tab stop (CSI 3 g = clear all stops) |
1135
|
4
|
|
|
4
|
|
6
|
my $self = shift; |
1136
|
4
|
|
|
|
|
5
|
my $num = shift; |
1137
|
4
|
100
|
66
|
|
|
16
|
if ((defined $num) && ($num eq '3')) { |
1138
|
3
|
|
|
|
|
7
|
$self->{'_tabstops'} = []; |
1139
|
|
|
|
|
|
|
} else { |
1140
|
1
|
|
|
|
|
5
|
$self->{'_tabstops'}->[$self->{'x'}] = undef; |
1141
|
|
|
|
|
|
|
} |
1142
|
|
|
|
|
|
|
} |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
sub _code_CHA { # move to column in current row |
1145
|
18
|
|
|
18
|
|
21
|
my $self = shift; |
1146
|
18
|
|
|
|
|
23
|
my $col = shift; |
1147
|
18
|
100
|
|
|
|
34
|
$col = 1 if (not defined $col); |
1148
|
18
|
50
|
|
|
|
55
|
return if ($self->{'x'} == $col); |
1149
|
18
|
|
|
|
|
43
|
$self->callback_call ('GOTO', $col, $self->{'y'}); |
1150
|
18
|
|
|
|
|
23
|
$self->{'x'} = $col; |
1151
|
18
|
50
|
|
|
|
70
|
$self->{'x'} = 1 if ($self->{'x'} < 1); |
1152
|
18
|
100
|
|
|
|
46
|
$self->{'x'} = $self->{'cols'} if ($self->{'x'} > $self->{'cols'}); |
1153
|
|
|
|
|
|
|
} |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
sub _code_CNL { # move cursor down and to column 1 |
1156
|
6
|
|
|
6
|
|
10
|
my $self = shift; |
1157
|
6
|
|
|
|
|
8
|
my $num = shift; |
1158
|
6
|
100
|
|
|
|
17
|
$num = 1 if (not defined $num); |
1159
|
6
|
|
|
|
|
23
|
$self->callback_call ('GOTO', 1, $self->{'y'} + $num); |
1160
|
6
|
|
|
|
|
11
|
$self->{'x'} = 1; |
1161
|
6
|
|
|
|
|
16
|
$self->_move_down ($num); |
1162
|
|
|
|
|
|
|
} |
1163
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
sub _code_CPL { # move cursor up and to column 1 |
1165
|
5
|
|
|
5
|
|
10
|
my $self = shift; |
1166
|
5
|
|
|
|
|
8
|
my $num = shift; |
1167
|
5
|
100
|
|
|
|
13
|
$num = 1 if (not defined $num); |
1168
|
5
|
|
|
|
|
20
|
$self->callback_call ('GOTO', $self->{'x'}, $self->{'y'} - $num); |
1169
|
5
|
|
|
|
|
9
|
$self->{'x'} = 1; |
1170
|
5
|
|
|
|
|
35
|
$self->_move_up ($num); |
1171
|
|
|
|
|
|
|
} |
1172
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
sub _code_CR { # carriage return |
1174
|
181
|
|
|
181
|
|
289
|
my $self = shift; |
1175
|
181
|
|
|
|
|
645
|
$self->{'x'} = 1; |
1176
|
|
|
|
|
|
|
} |
1177
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
sub _code_CSI { # ESC [ |
1179
|
227
|
|
|
227
|
|
256
|
my $self = shift; |
1180
|
227
|
|
|
|
|
287
|
$self->{'_buf'} = ''; # restart ESC buffering |
1181
|
227
|
|
|
|
|
379
|
$self->{'_inesc'} = 'CSI'; # ...for a CSI, not an ESC |
1182
|
|
|
|
|
|
|
} |
1183
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
sub _code_CUB { # move cursor left |
1185
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
1186
|
1
|
|
|
|
|
3
|
my $num = shift; |
1187
|
1
|
50
|
|
|
|
4
|
$num = 1 if (not defined $num); |
1188
|
1
|
50
|
|
|
|
7
|
$num = 1 if ($num < 1); |
1189
|
1
|
|
|
|
|
29
|
$self->callback_call ('GOTO', $self->{'x'} - $num, $self->{'y'}); |
1190
|
1
|
|
|
|
|
2
|
$self->{'x'} -= $num; |
1191
|
1
|
50
|
|
|
|
10
|
$self->{'x'} = 1 if ($self->{'x'} < 1); |
1192
|
|
|
|
|
|
|
} |
1193
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
sub _code_CUD { # move cursor down |
1195
|
3
|
|
|
3
|
|
5
|
my $self = shift; |
1196
|
3
|
|
|
|
|
5
|
my $num = shift; |
1197
|
3
|
100
|
|
|
|
11
|
$num = 1 if (not defined $num); |
1198
|
3
|
50
|
|
|
|
9
|
$num = 1 if ($num < 1); |
1199
|
3
|
|
|
|
|
11
|
$self->callback_call ('GOTO', $self->{'x'}, $self->{'y'} + $num); |
1200
|
3
|
|
|
|
|
8
|
$self->_move_down ($num); |
1201
|
|
|
|
|
|
|
} |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
sub _code_CUF { # move cursor right |
1204
|
4
|
|
|
4
|
|
5
|
my $self = shift; |
1205
|
4
|
|
|
|
|
4
|
my $num = shift; |
1206
|
4
|
100
|
|
|
|
11
|
$num = 1 if (not defined $num); |
1207
|
4
|
50
|
|
|
|
9
|
$num = 1 if ($num < 1); |
1208
|
4
|
|
|
|
|
13
|
$self->callback_call ('GOTO', $self->{'x'} + $num, $self->{'y'}); |
1209
|
4
|
|
|
|
|
6
|
$self->{'x'} += $num; |
1210
|
4
|
50
|
|
|
|
17
|
$self->{'x'} = $self->{'cols'} if ($self->{'x'} > $self->{'cols'}); |
1211
|
|
|
|
|
|
|
} |
1212
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
sub _code_CUP { # move cursor to row, column |
1214
|
102
|
|
|
102
|
|
121
|
my $self = shift; |
1215
|
102
|
|
|
|
|
152
|
my ($row, $col) = (@_); |
1216
|
102
|
100
|
|
|
|
197
|
$row = 1 if (not defined $row); |
1217
|
102
|
100
|
|
|
|
217
|
$col = 1 if (not defined $col); |
1218
|
102
|
50
|
|
|
|
215
|
$row = 1 if ($row < 1); |
1219
|
102
|
50
|
|
|
|
194
|
$col = 1 if ($col < 1); |
1220
|
102
|
100
|
|
|
|
218
|
$row = $self->{'rows'} if ($row > $self->{'rows'}); |
1221
|
102
|
100
|
|
|
|
212
|
$col = $self->{'cols'} if ($col > $self->{'cols'}); |
1222
|
102
|
|
|
|
|
225
|
$self->callback_call ('GOTO', $col, $row); |
1223
|
102
|
|
|
|
|
163
|
$self->{'x'} = $col; |
1224
|
102
|
|
|
|
|
198
|
$self->{'y'} = $row; |
1225
|
|
|
|
|
|
|
} |
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
sub _code_RI { # reverse line feed |
1228
|
3
|
|
|
3
|
|
5
|
my $self = shift; |
1229
|
3
|
|
|
|
|
11
|
$self->callback_call ('GOTO', $self->{'x'}, $self->{'y'} - 1); |
1230
|
3
|
|
|
|
|
13
|
$self->_move_up; |
1231
|
|
|
|
|
|
|
} |
1232
|
|
|
|
|
|
|
|
1233
|
|
|
|
|
|
|
sub _code_CUU { # move cursor up |
1234
|
3
|
|
|
3
|
|
4
|
my $self = shift; |
1235
|
3
|
|
|
|
|
5
|
my $num = shift; |
1236
|
3
|
100
|
|
|
|
10
|
$num = 1 if (not defined $num); |
1237
|
3
|
50
|
|
|
|
8
|
$num = 1 if ($num < 1); |
1238
|
3
|
|
|
|
|
10
|
$self->callback_call ('GOTO', $self->{'x'}, $self->{'y'} - $num); |
1239
|
3
|
|
|
|
|
9
|
$self->_move_up ($num); |
1240
|
|
|
|
|
|
|
} |
1241
|
|
|
|
|
|
|
|
1242
|
|
|
|
|
|
|
sub _code_DA { # return ESC [ ? 6 c (VT102) |
1243
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1244
|
0
|
|
|
|
|
0
|
$self->callback_call ('OUTPUT', "\033[?6c", 0); |
1245
|
|
|
|
|
|
|
} |
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
sub _code_DCH { # delete characters on current line |
1248
|
3
|
|
|
3
|
|
5
|
my $self = shift; |
1249
|
3
|
|
|
|
|
3
|
my $num = shift; |
1250
|
3
|
|
|
|
|
3
|
my ($width, $todel, $line, $lsub, $rsub, $attr); |
1251
|
|
|
|
|
|
|
|
1252
|
3
|
100
|
|
|
|
8
|
$num = 1 if (not defined $num); |
1253
|
3
|
50
|
|
|
|
35
|
$num = 1 if ($num < 1); |
1254
|
|
|
|
|
|
|
|
1255
|
3
|
|
|
|
|
5
|
$width = $self->{'cols'} + 1 - $self->{'x'}; |
1256
|
3
|
|
|
|
|
4
|
$todel = $num; |
1257
|
3
|
100
|
|
|
|
5
|
$todel = $width if ($todel > $width); |
1258
|
|
|
|
|
|
|
|
1259
|
3
|
|
|
|
|
5
|
$line = $self->{'scrt'}->[$self->{'y'}]; |
1260
|
3
|
|
|
|
|
4
|
($lsub, $rsub) = ("", ""); |
1261
|
3
|
100
|
|
|
|
9
|
$lsub = substr ($line, 0, $self->{'x'} - 1) if ($self->{'x'} > 1); |
1262
|
3
|
|
|
|
|
5
|
$rsub = substr ($line, $self->{'x'} - 1 + $todel); |
1263
|
3
|
|
|
|
|
7
|
$self->{'scrt'}->[$self->{'y'}] = $lsub . $rsub . ("\0" x $todel); |
1264
|
|
|
|
|
|
|
|
1265
|
3
|
|
|
|
|
3
|
$attr = DEFAULT_ATTR_PACKED; |
1266
|
3
|
|
|
|
|
4
|
$line = $self->{'scra'}->[$self->{'y'}]; |
1267
|
3
|
|
|
|
|
4
|
($lsub, $rsub) = ("", ""); |
1268
|
3
|
100
|
|
|
|
9
|
$lsub = substr ($line, 0, 2 * ($self->{'x'} - 1)) if ($self->{'x'} > 1); |
1269
|
3
|
|
|
|
|
5
|
$rsub = substr ($line, 2 * ($self->{'x'} - 1 + $todel)); |
1270
|
3
|
|
|
|
|
6
|
$self->{'scra'}->[$self->{'y'}] = $lsub . $rsub . ($attr x $todel); |
1271
|
|
|
|
|
|
|
|
1272
|
3
|
|
|
|
|
6
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1273
|
|
|
|
|
|
|
} |
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
sub _code_DCS { # device control string (ignored) |
1276
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1277
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = ''; |
1278
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = 'DCS_ST'; |
1279
|
|
|
|
|
|
|
} |
1280
|
|
|
|
|
|
|
|
1281
|
|
|
|
|
|
|
sub _code_DECSTBM { # set scrolling region |
1282
|
15
|
|
|
15
|
|
22
|
my $self = shift; |
1283
|
15
|
|
|
|
|
23
|
my ($top, $bottom) = (@_); |
1284
|
15
|
50
|
|
|
|
33
|
$top = 1 if (not defined $top); |
1285
|
15
|
50
|
|
|
|
27
|
$bottom = $self->{'rows'} if (not defined $bottom); |
1286
|
15
|
50
|
|
|
|
38
|
$top = 1 if ($top < 1); |
1287
|
15
|
50
|
|
|
|
30
|
$bottom = 1 if ($bottom < 1); |
1288
|
15
|
50
|
|
|
|
36
|
$top = $self->{'rows'} if ($top > $self->{'rows'}); |
1289
|
15
|
50
|
|
|
|
33
|
$bottom = $self->{'rows'} if ($bottom > $self->{'rows'}); |
1290
|
15
|
50
|
|
|
|
27
|
if ($bottom < $top) { |
1291
|
0
|
|
|
|
|
0
|
my $a = $bottom; |
1292
|
0
|
|
|
|
|
0
|
$bottom = $top; |
1293
|
0
|
|
|
|
|
0
|
$top = $a; |
1294
|
|
|
|
|
|
|
} |
1295
|
15
|
|
|
|
|
27
|
$self->{'srt'} = $top; |
1296
|
15
|
|
|
|
|
34
|
$self->{'srb'} = $bottom; |
1297
|
|
|
|
|
|
|
} |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
sub _code_DECTCEM { # Cursor on (set); Cursor off (reset) |
1300
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1301
|
0
|
|
|
|
|
0
|
$self->{'cursor'} = shift; |
1302
|
|
|
|
|
|
|
} |
1303
|
|
|
|
|
|
|
|
1304
|
0
|
|
|
0
|
|
0
|
sub _code_IGN { # ignored control sequence |
1305
|
|
|
|
|
|
|
} |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
sub _code_DL { # delete lines |
1308
|
8
|
|
|
8
|
|
11
|
my $self = shift; |
1309
|
8
|
|
|
|
|
10
|
my $lines = shift; |
1310
|
8
|
|
|
|
|
9
|
my ($attr, $scrb, $row); |
1311
|
|
|
|
|
|
|
|
1312
|
8
|
100
|
|
|
|
19
|
$lines = 1 if (not defined $lines); |
1313
|
8
|
50
|
|
|
|
19
|
$lines = 1 if ($lines < 1); |
1314
|
|
|
|
|
|
|
|
1315
|
8
|
|
|
|
|
13
|
$attr = DEFAULT_ATTR_PACKED; |
1316
|
|
|
|
|
|
|
|
1317
|
8
|
|
|
|
|
12
|
$scrb = $self->{'srb'}; |
1318
|
8
|
50
|
|
|
|
18
|
$scrb = $self->{'rows'} if ($self->{'y'} > $self->{'srb'}); |
1319
|
8
|
100
|
|
|
|
20
|
$scrb = $self->{'srt'} - 1 if ($self->{'y'} < $self->{'srt'}); |
1320
|
|
|
|
|
|
|
|
1321
|
8
|
|
|
|
|
24
|
for ($row = $self->{'y'}; $row <= ($scrb - $lines); $row ++) { |
1322
|
6
|
|
|
|
|
19
|
$self->{'scrt'}->[$row] = $self->{'scrt'}->[$row + $lines]; |
1323
|
6
|
|
|
|
|
14
|
$self->{'scra'}->[$row] = $self->{'scra'}->[$row + $lines]; |
1324
|
6
|
|
|
|
|
25
|
$self->callback_call ('ROWCHANGE', $row, 0); |
1325
|
|
|
|
|
|
|
} |
1326
|
|
|
|
|
|
|
|
1327
|
8
|
|
100
|
|
|
51
|
for ( |
1328
|
|
|
|
|
|
|
$row = $scrb; |
1329
|
|
|
|
|
|
|
($row > ($scrb - $lines)) && ($row >= ($self->{'y'})); |
1330
|
|
|
|
|
|
|
$row -- |
1331
|
|
|
|
|
|
|
) { |
1332
|
14
|
|
|
|
|
33
|
$self->{'scrt'}->[$row] = "\000" x $self->{'cols'}; |
1333
|
14
|
|
|
|
|
31
|
$self->{'scra'}->[$row] = $attr x $self->{'cols'}; |
1334
|
14
|
|
|
|
|
26
|
$self->callback_call ('ROWCHANGE', $row, 0); |
1335
|
|
|
|
|
|
|
} |
1336
|
|
|
|
|
|
|
} |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
sub _code_DSR { # device status report |
1339
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1340
|
0
|
|
|
|
|
0
|
my $num = shift; |
1341
|
0
|
0
|
|
|
|
0
|
$num = 5 if (not defined $num); |
1342
|
0
|
0
|
|
|
|
0
|
if ($num == 6) { # CPR - cursor position report |
|
|
0
|
|
|
|
|
|
1343
|
0
|
|
|
|
|
0
|
$self->callback_call ( |
1344
|
|
|
|
|
|
|
'OUTPUT', "\e[" . $self->{'y'} . ";" . $self->{'x'} . "R", 0 |
1345
|
|
|
|
|
|
|
); |
1346
|
|
|
|
|
|
|
} elsif ($num == 5) { # DSR - reply ESC [ 0 n |
1347
|
0
|
|
|
|
|
0
|
$self->callback_call ('OUTPUT', "\e[0n", 0); |
1348
|
|
|
|
|
|
|
} |
1349
|
|
|
|
|
|
|
} |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
sub _code_ECH { # erase characters on current line |
1352
|
3
|
|
|
3
|
|
4
|
my $self = shift; |
1353
|
3
|
|
|
|
|
3
|
my $num = shift; |
1354
|
3
|
|
|
|
|
4
|
my ($width, $todel, $line, $lsub, $rsub, $attr); |
1355
|
|
|
|
|
|
|
|
1356
|
3
|
100
|
|
|
|
8
|
$num = 1 if (not defined $num); |
1357
|
3
|
50
|
|
|
|
16
|
$num = 1 if ($num < 1); |
1358
|
|
|
|
|
|
|
|
1359
|
3
|
|
|
|
|
5
|
$width = $self->{'cols'} + 1 - $self->{'x'}; |
1360
|
3
|
|
|
|
|
4
|
$todel = $num; |
1361
|
3
|
100
|
|
|
|
11
|
$todel = $width if ($todel > $width); |
1362
|
|
|
|
|
|
|
|
1363
|
3
|
|
|
|
|
7
|
$line = $self->{'scrt'}->[$self->{'y'}]; |
1364
|
3
|
|
|
|
|
4
|
($lsub, $rsub) = ("", ""); |
1365
|
3
|
100
|
|
|
|
9
|
$lsub = substr ($line, 0, $self->{'x'} - 1) if ($self->{'x'} > 1); |
1366
|
3
|
|
|
|
|
6
|
$rsub = substr ($line, $self->{'x'} - 1 + $todel); |
1367
|
3
|
|
|
|
|
10
|
$self->{'scrt'}->[$self->{'y'}] = $lsub . ("\0" x $todel) . $rsub; |
1368
|
|
|
|
|
|
|
|
1369
|
3
|
|
|
|
|
3
|
$attr = DEFAULT_ATTR_PACKED; |
1370
|
|
|
|
|
|
|
|
1371
|
|
|
|
|
|
|
|
1372
|
3
|
|
|
|
|
7
|
$line = $self->{'scra'}->[$self->{'y'}]; |
1373
|
3
|
|
|
|
|
4
|
($lsub, $rsub) = ("", ""); |
1374
|
3
|
100
|
|
|
|
11
|
$lsub = substr ($line, 0, 2 * ($self->{'x'} - 1)) if ($self->{'x'} > 1); |
1375
|
3
|
|
|
|
|
5
|
$rsub = substr ($line, 2 * ($self->{'x'} - 1 + $todel)); |
1376
|
3
|
|
|
|
|
8
|
$self->{'scra'}->[$self->{'y'}] = $lsub . ($attr x $todel) . $rsub; |
1377
|
|
|
|
|
|
|
|
1378
|
3
|
|
|
|
|
14
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1379
|
|
|
|
|
|
|
} |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
sub _code_ED { # erase display |
1382
|
3
|
|
|
3
|
|
3
|
my $self = shift; |
1383
|
3
|
|
|
|
|
4
|
my $num = shift; |
1384
|
3
|
|
|
|
|
4
|
my ($row, $attr); |
1385
|
|
|
|
|
|
|
|
1386
|
3
|
100
|
|
|
|
8
|
$num = 0 if (not defined $num); |
1387
|
|
|
|
|
|
|
|
1388
|
3
|
|
|
|
|
5
|
$attr = DEFAULT_ATTR_PACKED; |
1389
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
# Wipe-cursor-to-end is the same as clear-whole-screen if cursor at top left |
1391
|
|
|
|
|
|
|
# |
1392
|
3
|
50
|
66
|
|
|
24
|
$num = 2 if (($num == 0) && ($self->{'x'} == 1) && ($self->{'y'} == 1)); |
|
|
|
33
|
|
|
|
|
1393
|
|
|
|
|
|
|
|
1394
|
3
|
100
|
|
|
|
10
|
if ($num == 0) { # 0 = cursor to end |
|
|
100
|
|
|
|
|
|
1395
|
1
|
|
|
|
|
8
|
$self->{'scrt'}->[$self->{'y'}] = |
1396
|
|
|
|
|
|
|
substr ( |
1397
|
|
|
|
|
|
|
$self->{'scrt'}->[$self->{'y'}], |
1398
|
|
|
|
|
|
|
0, |
1399
|
|
|
|
|
|
|
$self->{'x'} - 1 |
1400
|
|
|
|
|
|
|
) . ("\0" x ($self->{'cols'} + 1 - $self->{'x'})); |
1401
|
1
|
|
|
|
|
7
|
$self->{'scra'}->[$self->{'y'}] = |
1402
|
|
|
|
|
|
|
substr ( |
1403
|
|
|
|
|
|
|
$self->{'scra'}->[$self->{'y'}], |
1404
|
|
|
|
|
|
|
0, |
1405
|
|
|
|
|
|
|
2 * ($self->{'x'} - 1) |
1406
|
|
|
|
|
|
|
) . ($attr x ($self->{'cols'} + 1 - $self->{'x'})); |
1407
|
1
|
|
|
|
|
3
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1408
|
1
|
|
|
|
|
4
|
for ( |
1409
|
|
|
|
|
|
|
$row = $self->{'y'} + 1; |
1410
|
|
|
|
|
|
|
$row <= $self->{'rows'}; |
1411
|
|
|
|
|
|
|
$row ++ |
1412
|
|
|
|
|
|
|
) { |
1413
|
2
|
|
|
|
|
5
|
$self->{'scrt'}->[$row] = "\0" x $self->{'cols'}; |
1414
|
2
|
|
|
|
|
6
|
$self->{'scra'}->[$row] = $attr x $self->{'cols'}; |
1415
|
2
|
|
|
|
|
5
|
$self->callback_call ('ROWCHANGE', $row, 0); |
1416
|
|
|
|
|
|
|
} |
1417
|
|
|
|
|
|
|
} elsif ($num == 1) { # 1 = start to cursor |
1418
|
1
|
|
|
|
|
4
|
for ( |
1419
|
|
|
|
|
|
|
$row = 1; |
1420
|
|
|
|
|
|
|
$row < $self->{'y'}; |
1421
|
|
|
|
|
|
|
$row ++ |
1422
|
|
|
|
|
|
|
) { |
1423
|
1
|
|
|
|
|
3
|
$self->{'scrt'}->[$row] = "\0" x $self->{'cols'}; |
1424
|
1
|
|
|
|
|
3
|
$self->{'scra'}->[$row] = $attr x $self->{'cols'}; |
1425
|
1
|
|
|
|
|
3
|
$self->callback_call ('ROWCHANGE', $row, 0); |
1426
|
|
|
|
|
|
|
} |
1427
|
1
|
|
|
|
|
5
|
$self->{'scrt'}->[$self->{'y'}] = |
1428
|
|
|
|
|
|
|
("\0" x $self->{'x'}) . |
1429
|
|
|
|
|
|
|
substr ($self->{'scrt'}->[$self->{'y'}], $self->{'x'}); |
1430
|
1
|
|
|
|
|
5
|
$self->{'scra'}->[$self->{'y'}] = |
1431
|
|
|
|
|
|
|
($attr x $self->{'x'}) . |
1432
|
|
|
|
|
|
|
substr ($self->{'scra'}->[$self->{'y'}], 2 * $self->{'x'}); |
1433
|
1
|
|
|
|
|
4
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1434
|
|
|
|
|
|
|
} else { # 2 = whole display |
1435
|
1
|
|
|
|
|
5
|
$self->callback_call ('CLEAR', 0, 0); |
1436
|
1
|
|
|
|
|
5
|
for ($row = 1; $row <= $self->{'rows'}; $row ++) { |
1437
|
4
|
|
|
|
|
12
|
$self->{'scrt'}->[$row] = "\0" x $self->{'cols'}; |
1438
|
4
|
|
|
|
|
15
|
$self->{'scra'}->[$row] = $attr x $self->{'cols'}; |
1439
|
|
|
|
|
|
|
} |
1440
|
|
|
|
|
|
|
} |
1441
|
|
|
|
|
|
|
} |
1442
|
|
|
|
|
|
|
|
1443
|
|
|
|
|
|
|
sub _code_EL { # erase line |
1444
|
3
|
|
|
3
|
|
4
|
my $self = shift; |
1445
|
3
|
|
|
|
|
4
|
my $num = shift; |
1446
|
3
|
|
|
|
|
4
|
my $attr; |
1447
|
|
|
|
|
|
|
|
1448
|
3
|
100
|
|
|
|
7
|
$num = 0 if (not defined $num); |
1449
|
|
|
|
|
|
|
|
1450
|
3
|
|
|
|
|
5
|
$attr = DEFAULT_ATTR_PACKED; |
1451
|
|
|
|
|
|
|
|
1452
|
3
|
100
|
|
|
|
12
|
if ($num == 0) { # 0 = cursor to end of line |
|
|
100
|
|
|
|
|
|
1453
|
1
|
|
|
|
|
9
|
$self->{'scrt'}->[$self->{'y'}] = |
1454
|
|
|
|
|
|
|
substr ( |
1455
|
|
|
|
|
|
|
$self->{'scrt'}->[$self->{'y'}], |
1456
|
|
|
|
|
|
|
0, |
1457
|
|
|
|
|
|
|
$self->{'x'} - 1 |
1458
|
|
|
|
|
|
|
) . ("\0" x ($self->{'cols'} + 1 - $self->{'x'})); |
1459
|
1
|
|
|
|
|
7
|
$self->{'scra'}->[$self->{'y'}] = |
1460
|
|
|
|
|
|
|
substr ( |
1461
|
|
|
|
|
|
|
$self->{'scra'}->[$self->{'y'}], |
1462
|
|
|
|
|
|
|
0, |
1463
|
|
|
|
|
|
|
2 * ($self->{'x'} - 1) |
1464
|
|
|
|
|
|
|
) . ($attr x ($self->{'cols'} + 1 - $self->{'x'})); |
1465
|
1
|
|
|
|
|
3
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1466
|
|
|
|
|
|
|
} elsif ($num == 1) { # 1 = start of line to cursor |
1467
|
1
|
|
|
|
|
8
|
$self->{'scrt'}->[$self->{'y'}] = |
1468
|
|
|
|
|
|
|
("\0" x $self->{'x'}) . |
1469
|
|
|
|
|
|
|
substr ($self->{'scrt'}->[$self->{'y'}], $self->{'x'}); |
1470
|
1
|
|
|
|
|
23
|
$self->{'scra'}->[$self->{'y'}] = |
1471
|
|
|
|
|
|
|
($attr x $self->{'x'}) . |
1472
|
|
|
|
|
|
|
substr ($self->{'scra'}->[$self->{'y'}], 2 * $self->{'x'}); |
1473
|
1
|
|
|
|
|
5
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1474
|
|
|
|
|
|
|
} else { # 2 = whole line |
1475
|
1
|
|
|
|
|
5
|
$self->{'scrt'}->[$self->{'y'}] = "\0" x $self->{'cols'}; |
1476
|
1
|
|
|
|
|
10
|
$self->{'scra'}->[$self->{'y'}] = $attr x $self->{'cols'}; |
1477
|
1
|
|
|
|
|
4
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1478
|
|
|
|
|
|
|
} |
1479
|
|
|
|
|
|
|
} |
1480
|
|
|
|
|
|
|
|
1481
|
|
|
|
|
|
|
sub _code_ESC { # start escape sequence |
1482
|
258
|
|
|
258
|
|
370
|
my $self = shift; |
1483
|
258
|
100
|
66
|
|
|
652
|
if ((defined $self->{'_buf'}) && ($self->{'_inesc'} =~ /OSC|_ST/)) { |
1484
|
|
|
|
|
|
|
# Some sequences are terminated with an ST |
1485
|
3
|
|
|
|
|
6
|
$self->{'_buf'} .= "\033"; |
1486
|
3
|
|
|
|
|
7
|
$self->_process_escseq (); |
1487
|
3
|
|
|
|
|
12
|
return; |
1488
|
|
|
|
|
|
|
} |
1489
|
255
|
|
|
|
|
366
|
$self->{'_buf'} = ''; # set ESC buffer |
1490
|
255
|
|
|
|
|
966
|
$self->{'_inesc'} = 'ESC'; # ...for ESC, not CSI |
1491
|
|
|
|
|
|
|
} |
1492
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
sub _code_LF { # line feed |
1494
|
184
|
|
|
184
|
|
244
|
my $self = shift; |
1495
|
184
|
100
|
|
|
|
417
|
$self->_code_CR () # cursor to start of line |
1496
|
|
|
|
|
|
|
if ($self->{'opts'}->{'LFTOCRLF'} != 0); |
1497
|
184
|
|
|
|
|
473
|
$self->callback_call ('LINEFEED', $self->{'y'}, 0); |
1498
|
184
|
|
|
|
|
346
|
$self->_move_down (); |
1499
|
|
|
|
|
|
|
} |
1500
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
sub _code_NEL { # newline |
1502
|
2
|
|
|
2
|
|
3
|
my $self = shift; |
1503
|
2
|
|
|
|
|
9
|
$self->_code_CR (); # cursor always to start |
1504
|
2
|
|
|
|
|
17
|
$self->_code_LF (); # standard line feed |
1505
|
|
|
|
|
|
|
} |
1506
|
|
|
|
|
|
|
|
1507
|
|
|
|
|
|
|
sub _code_HT { # horizontal tab to next tab stop |
1508
|
53
|
|
|
53
|
|
52
|
my $self = shift; |
1509
|
53
|
|
|
|
|
57
|
my ($newx, $spaces, $width); |
1510
|
|
|
|
|
|
|
|
1511
|
53
|
50
|
33
|
|
|
129
|
if ( |
1512
|
|
|
|
|
|
|
($self->{'opts'}->{'LINEWRAP'} != 0) |
1513
|
|
|
|
|
|
|
&& ($self->{'x'} >= $self->{'cols'}) |
1514
|
|
|
|
|
|
|
) { |
1515
|
0
|
|
|
|
|
0
|
$self->callback_call ('LINEFEED', $self->{'y'}, 0); |
1516
|
0
|
|
|
|
|
0
|
$self->{'x'} = 1; |
1517
|
0
|
|
|
|
|
0
|
$self->_move_down; |
1518
|
|
|
|
|
|
|
} |
1519
|
|
|
|
|
|
|
|
1520
|
53
|
|
|
|
|
62
|
$newx = $self->{'x'} + 1; |
1521
|
53
|
|
100
|
|
|
190
|
while ($newx < $self->{'cols'} && not $self->{'_tabstops'}->[$newx]) { |
1522
|
335
|
|
|
|
|
1119
|
$newx++; |
1523
|
|
|
|
|
|
|
} |
1524
|
|
|
|
|
|
|
|
1525
|
53
|
|
|
|
|
71
|
$width = ($self->{'cols'} + 1) - $self->{'x'}; |
1526
|
53
|
|
|
|
|
56
|
$spaces = $newx - $self->{'x'}; |
1527
|
53
|
50
|
|
|
|
95
|
$spaces = $width + 1 if ($spaces > $width); |
1528
|
|
|
|
|
|
|
|
1529
|
53
|
50
|
|
|
|
6089
|
if ($spaces > 0) { |
1530
|
53
|
|
|
|
|
64
|
$self->{'x'} += $spaces; |
1531
|
53
|
100
|
|
|
|
402
|
$self->{'x'} = $self->{'cols'} if ($self->{'x'} > $self->{'cols'}); |
1532
|
|
|
|
|
|
|
} |
1533
|
|
|
|
|
|
|
} |
1534
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
sub _code_HTS { # set tab stop at current column |
1536
|
13
|
|
|
13
|
|
14
|
my $self = shift; |
1537
|
13
|
|
|
|
|
33
|
$self->{'_tabstops'}->[$self->{'x'}] = 1; |
1538
|
|
|
|
|
|
|
} |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
sub _code_ICH { # insert blank characters |
1541
|
3
|
|
|
3
|
|
5
|
my $self = shift; |
1542
|
3
|
|
|
|
|
5
|
my $num = shift; |
1543
|
3
|
|
|
|
|
5
|
my ($width, $toins, $line, $lsub, $rsub, $attr); |
1544
|
|
|
|
|
|
|
|
1545
|
3
|
100
|
|
|
|
8
|
$num = 1 if (not defined $num); |
1546
|
3
|
50
|
|
|
|
7
|
$num = 1 if ($num < 1); |
1547
|
|
|
|
|
|
|
|
1548
|
3
|
|
|
|
|
6
|
$width = $self->{'cols'} + 1 - $self->{'x'}; |
1549
|
3
|
|
|
|
|
6
|
$toins = $num; |
1550
|
3
|
100
|
|
|
|
7
|
$toins = $width if ($toins > $width); |
1551
|
|
|
|
|
|
|
|
1552
|
3
|
|
|
|
|
8
|
$line = $self->{'scrt'}->[$self->{'y'}]; |
1553
|
3
|
|
|
|
|
4
|
($lsub, $rsub) = ("", ""); |
1554
|
3
|
100
|
|
|
|
11
|
$lsub = substr ($line, 0, $self->{'x'} - 1) if ($self->{'x'} > 1); |
1555
|
3
|
|
|
|
|
8
|
$rsub = substr ($line, $self->{'x'} - 1, $width - $toins); |
1556
|
3
|
|
|
|
|
10
|
$self->{'scrt'}->[$self->{'y'}] = $lsub . ("\0" x $toins) . $rsub; |
1557
|
|
|
|
|
|
|
|
1558
|
3
|
|
|
|
|
7
|
$attr = DEFAULT_ATTR_PACKED; |
1559
|
3
|
|
|
|
|
5
|
$line = $self->{'scra'}->[$self->{'y'}]; |
1560
|
3
|
|
|
|
|
6
|
($lsub, $rsub) = ("", ""); |
1561
|
3
|
100
|
|
|
|
18
|
$lsub = substr ($line, 0, 2 * ($self->{'x'} - 1)) if ($self->{'x'} > 1); |
1562
|
3
|
|
|
|
|
10
|
$rsub = substr ($line, 2 * ($self->{'x'} - 1), 2 * ($width - $toins)); |
1563
|
3
|
|
|
|
|
8
|
$self->{'scra'}->[$self->{'y'}] = $lsub . ($attr x $toins) . $rsub; |
1564
|
|
|
|
|
|
|
|
1565
|
3
|
|
|
|
|
22
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1566
|
|
|
|
|
|
|
} |
1567
|
|
|
|
|
|
|
|
1568
|
|
|
|
|
|
|
sub _code_IL { # insert blank lines |
1569
|
8
|
|
|
8
|
|
13
|
my $self = shift; |
1570
|
8
|
|
|
|
|
11
|
my $lines = shift; |
1571
|
8
|
|
|
|
|
10
|
my ($attr, $scrb, $row); |
1572
|
|
|
|
|
|
|
|
1573
|
8
|
100
|
|
|
|
22
|
$lines = 1 if (not defined $lines); |
1574
|
8
|
50
|
|
|
|
19
|
$lines = 1 if ($lines < 1); |
1575
|
|
|
|
|
|
|
|
1576
|
8
|
|
|
|
|
12
|
$attr = DEFAULT_ATTR_PACKED; |
1577
|
|
|
|
|
|
|
|
1578
|
8
|
|
|
|
|
12
|
$scrb = $self->{'srb'}; |
1579
|
8
|
50
|
|
|
|
21
|
$scrb = $self->{'rows'} if ($self->{'y'} > $self->{'srb'}); |
1580
|
8
|
100
|
|
|
|
45
|
$scrb = $self->{'srt'} - 1 if ($self->{'y'} < $self->{'srt'}); |
1581
|
|
|
|
|
|
|
|
1582
|
8
|
|
|
|
|
27
|
for ($row = $scrb; $row >= ($self->{'y'} + $lines); $row --) { |
1583
|
6
|
|
|
|
|
19
|
$self->{'scrt'}->[$row] = $self->{'scrt'}->[$row - $lines]; |
1584
|
6
|
|
|
|
|
14
|
$self->{'scra'}->[$row] = $self->{'scra'}->[$row - $lines]; |
1585
|
6
|
|
|
|
|
16
|
$self->callback_call ('ROWCHANGE', $row, 0); |
1586
|
|
|
|
|
|
|
} |
1587
|
|
|
|
|
|
|
|
1588
|
8
|
|
100
|
|
|
55
|
for ( |
1589
|
|
|
|
|
|
|
$row = $self->{'y'}; |
1590
|
|
|
|
|
|
|
($row <= $scrb) && ($row < ($self->{'y'} + $lines)); |
1591
|
|
|
|
|
|
|
$row ++ |
1592
|
|
|
|
|
|
|
) { |
1593
|
14
|
|
|
|
|
37
|
$self->{'scrt'}->[$row] = "\000" x $self->{'cols'}; |
1594
|
14
|
|
|
|
|
29
|
$self->{'scra'}->[$row] = $attr x $self->{'cols'}; |
1595
|
14
|
|
|
|
|
32
|
$self->callback_call ('ROWCHANGE', $row, 0); |
1596
|
|
|
|
|
|
|
} |
1597
|
|
|
|
|
|
|
} |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
sub _code_PM { # privacy message (ignored) |
1600
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1601
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = ''; |
1602
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = 'PM_ST'; |
1603
|
|
|
|
|
|
|
} |
1604
|
|
|
|
|
|
|
|
1605
|
|
|
|
|
|
|
sub _code_APC { # application program command (ignored) |
1606
|
1
|
|
|
1
|
|
3
|
my $self = shift; |
1607
|
1
|
|
|
|
|
2
|
$self->{'_buf'} = ''; |
1608
|
1
|
|
|
|
|
2
|
$self->{'_inesc'} = 'APC_ST'; |
1609
|
|
|
|
|
|
|
} |
1610
|
|
|
|
|
|
|
|
1611
|
|
|
|
|
|
|
sub _code_OSC { # operating system command |
1612
|
2
|
|
|
2
|
|
3
|
my $self = shift; |
1613
|
2
|
|
|
|
|
3
|
$self->{'_buf'} = ''; # restart buffering |
1614
|
2
|
|
|
|
|
4
|
$self->{'_inesc'} = 'OSC'; # ...for OSC, not ESC or CSI |
1615
|
|
|
|
|
|
|
} |
1616
|
|
|
|
|
|
|
|
1617
|
|
|
|
|
|
|
sub _code_RIS { # reset |
1618
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1619
|
0
|
|
|
|
|
0
|
$self->reset (); |
1620
|
|
|
|
|
|
|
} |
1621
|
|
|
|
|
|
|
|
1622
|
|
|
|
|
|
|
sub _toggle_mode { # set/reset modes |
1623
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1624
|
0
|
|
|
|
|
0
|
my ($flag, @modes) = @_; |
1625
|
|
|
|
|
|
|
|
1626
|
0
|
|
|
|
|
0
|
foreach my $mode (@modes) { |
1627
|
0
|
|
|
|
|
0
|
my $name = $self->{'_modeseq'}->{$mode}; |
1628
|
0
|
|
|
|
|
0
|
my $func = undef; |
1629
|
0
|
0
|
|
|
|
0
|
$func = $self->{'_funcs'}->{$name} if (defined $name); |
1630
|
0
|
0
|
|
|
|
0
|
if (not defined $func) { # unsupported seq. |
1631
|
0
|
0
|
|
|
|
0
|
$self->callback_call ( |
1632
|
|
|
|
|
|
|
'UNKNOWN', |
1633
|
|
|
|
|
|
|
$name, |
1634
|
|
|
|
|
|
|
"\033[${mode}" . ($flag ? "h" : "l") |
1635
|
|
|
|
|
|
|
); |
1636
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
1637
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
1638
|
0
|
|
|
|
|
0
|
return; |
1639
|
|
|
|
|
|
|
} |
1640
|
0
|
|
|
|
|
0
|
$self->{'_buf'} = undef; |
1641
|
0
|
|
|
|
|
0
|
$self->{'_inesc'} = ''; |
1642
|
0
|
|
|
|
|
0
|
&{$func} ($self, $flag); |
|
0
|
|
|
|
|
0
|
|
1643
|
0
|
|
|
|
|
0
|
return; |
1644
|
|
|
|
|
|
|
} |
1645
|
|
|
|
|
|
|
} |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
sub _code_RM { # reset mode |
1648
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1649
|
0
|
|
|
|
|
0
|
$self->_toggle_mode(0, @_); |
1650
|
|
|
|
|
|
|
} |
1651
|
|
|
|
|
|
|
|
1652
|
|
|
|
|
|
|
sub _code_SM { # set mode |
1653
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
1654
|
0
|
|
|
|
|
0
|
$self->_toggle_mode(1, @_); |
1655
|
|
|
|
|
|
|
} |
1656
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
sub _code_SGR { # set graphic rendition |
1658
|
30
|
|
|
30
|
|
38
|
my $self = shift; |
1659
|
30
|
|
|
|
|
58
|
my (@parms) = (@_); |
1660
|
30
|
|
|
|
|
49
|
my ($val, $fg, $bg, $bo, $fa, $st, $ul, $bl, $rv); |
1661
|
|
|
|
|
|
|
|
1662
|
30
|
|
|
|
|
79
|
($fg, $bg, $bo, $fa, $st, $ul, $bl, $rv) = |
1663
|
|
|
|
|
|
|
$self->attr_unpack ($self->{'attr'}); |
1664
|
|
|
|
|
|
|
|
1665
|
30
|
100
|
|
|
|
94
|
@parms = (0) if ($#parms < 0); # ESC [ m = ESC [ 0 m |
1666
|
|
|
|
|
|
|
|
1667
|
30
|
|
|
|
|
75
|
while (defined ($val = shift @parms)) { |
1668
|
37
|
100
|
66
|
|
|
473
|
if ($val == 0) { # reset all attributes |
|
|
100
|
66
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1669
|
5
|
|
|
|
|
23
|
($fg, $bg, $bo, $fa, $st, $ul, $bl, $rv) = DEFAULT_ATTR; |
1670
|
|
|
|
|
|
|
} elsif ($val == 1) { # bold ON |
1671
|
4
|
|
|
|
|
14
|
($bo, $fa) = (1, 0); |
1672
|
|
|
|
|
|
|
} elsif ($val == 2) { # faint ON |
1673
|
3
|
|
|
|
|
9
|
($bo, $fa) = (0, 1); |
1674
|
|
|
|
|
|
|
} elsif ($val == 4) { # underline ON |
1675
|
2
|
|
|
|
|
6
|
$ul = 1; |
1676
|
|
|
|
|
|
|
} elsif ($val == 5) { # blink ON |
1677
|
2
|
|
|
|
|
6
|
$bl = 1; |
1678
|
|
|
|
|
|
|
} elsif ($val == 7) { # reverse video ON |
1679
|
2
|
|
|
|
|
5
|
$rv = 1; |
1680
|
|
|
|
|
|
|
} elsif ($val == 21) { # normal intensity |
1681
|
1
|
|
|
|
|
4
|
($bo, $fa) = (0, 0); |
1682
|
|
|
|
|
|
|
} elsif ($val == 22) { # normal intensity |
1683
|
1
|
|
|
|
|
5
|
($bo, $fa) = (0, 0); |
1684
|
|
|
|
|
|
|
} elsif ($val == 24) { # underline OFF |
1685
|
0
|
|
|
|
|
0
|
$ul = 0; |
1686
|
|
|
|
|
|
|
} elsif ($val == 25) { # blink OFF |
1687
|
0
|
|
|
|
|
0
|
$bl = 0; |
1688
|
|
|
|
|
|
|
} elsif ($val == 27) { # reverse video OFF |
1689
|
0
|
|
|
|
|
0
|
$rv = 0; |
1690
|
|
|
|
|
|
|
} elsif (($val >= 30) && ($val <= 37)) {# set foreground colour |
1691
|
7
|
|
|
|
|
20
|
$fg = $val - 30; |
1692
|
|
|
|
|
|
|
} elsif ($val == 38) { # underline on, default fg |
1693
|
1
|
|
|
|
|
4
|
($ul, $fg) = (1, 7); |
1694
|
|
|
|
|
|
|
} elsif ($val == 39) { # underline off, default fg |
1695
|
1
|
|
|
|
|
3
|
($ul, $fg) = (0, 7); |
1696
|
|
|
|
|
|
|
} elsif (($val >= 40) && ($val <= 47)) {# set background colour |
1697
|
7
|
|
|
|
|
25
|
$bg = $val - 40; |
1698
|
|
|
|
|
|
|
} elsif ($val == 49) { # default background |
1699
|
1
|
|
|
|
|
4
|
$bg = 0; |
1700
|
|
|
|
|
|
|
} |
1701
|
|
|
|
|
|
|
} |
1702
|
|
|
|
|
|
|
|
1703
|
30
|
|
|
|
|
77
|
$self->{'attr'} = $self->attr_pack ($fg, $bg, $bo, $fa, $st, $ul, $bl, $rv); |
1704
|
|
|
|
|
|
|
} |
1705
|
|
|
|
|
|
|
|
1706
|
|
|
|
|
|
|
sub _code_VPA { # move to row (current column) |
1707
|
1
|
|
|
1
|
|
4
|
my $self = shift; |
1708
|
1
|
|
|
|
|
3
|
my $row = shift; |
1709
|
1
|
50
|
|
|
|
5
|
$row = 1 if (not defined $row); |
1710
|
1
|
50
|
|
|
|
6
|
return if ($self->{'y'} == $row); |
1711
|
1
|
|
|
|
|
3
|
$self->{'y'} = $row; |
1712
|
1
|
50
|
|
|
|
4
|
$self->{'y'} = 1 if ($self->{'y'} < 1); |
1713
|
1
|
50
|
|
|
|
5
|
$self->{'y'} = $self->{'rows'} if ($self->{'y'} > $self->{'rows'}); |
1714
|
|
|
|
|
|
|
} |
1715
|
|
|
|
|
|
|
|
1716
|
|
|
|
|
|
|
sub _code_DECALN { # fill screen with E's |
1717
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
1718
|
1
|
|
|
|
|
2
|
my ($row, $attr); |
1719
|
|
|
|
|
|
|
|
1720
|
1
|
|
|
|
|
2
|
$attr = DEFAULT_ATTR_PACKED; |
1721
|
|
|
|
|
|
|
|
1722
|
1
|
|
|
|
|
4
|
for ($row = 1; $row <= $self->{'rows'}; $row ++) { |
1723
|
3
|
|
|
|
|
8
|
$self->{'scrt'}->[$row] = 'E' x $self->{'cols'}; |
1724
|
3
|
|
|
|
|
44
|
$self->{'scra'}->[$row] = $attr x $self->{'cols'}; |
1725
|
3
|
|
|
|
|
9
|
$self->callback_call ('ROWCHANGE', $self->{'y'}, 0); |
1726
|
|
|
|
|
|
|
} |
1727
|
|
|
|
|
|
|
|
1728
|
1
|
|
|
|
|
2
|
$self->{'x'} = 1; |
1729
|
1
|
|
|
|
|
2
|
$self->{'y'} = 1; |
1730
|
|
|
|
|
|
|
} |
1731
|
|
|
|
|
|
|
|
1732
|
|
|
|
|
|
|
sub _code_DECSC { # save state |
1733
|
2
|
|
|
2
|
|
4
|
my $self = shift; |
1734
|
2
|
|
|
|
|
2
|
my @state; |
1735
|
|
|
|
|
|
|
|
1736
|
2
|
|
|
|
|
3
|
@state = @{$self->{'_decsc'}}; |
|
2
|
|
|
|
|
7
|
|
1737
|
2
|
|
|
|
|
13
|
push ( |
1738
|
|
|
|
|
|
|
@state, |
1739
|
|
|
|
|
|
|
[ |
1740
|
|
|
|
|
|
|
$self->{'x'}, |
1741
|
|
|
|
|
|
|
$self->{'y'}, |
1742
|
|
|
|
|
|
|
$self->{'attr'}, |
1743
|
|
|
|
|
|
|
$self->{'ti'}, |
1744
|
|
|
|
|
|
|
$self->{'ic'}, |
1745
|
|
|
|
|
|
|
$self->{'cursor'} |
1746
|
|
|
|
|
|
|
] |
1747
|
|
|
|
|
|
|
); |
1748
|
2
|
|
|
|
|
6
|
$self->{'_decsc'} = [ @state ]; |
1749
|
|
|
|
|
|
|
} |
1750
|
|
|
|
|
|
|
|
1751
|
|
|
|
|
|
|
sub _code_DECRC { # restore most recently saved state |
1752
|
2
|
|
|
2
|
|
50
|
my $self = shift; |
1753
|
2
|
|
|
|
|
4
|
my @state; |
1754
|
|
|
|
|
|
|
my $ref; |
1755
|
|
|
|
|
|
|
|
1756
|
2
|
|
|
|
|
3
|
@state = @{$self->{'_decsc'}}; |
|
2
|
|
|
|
|
6
|
|
1757
|
2
|
50
|
|
|
|
8
|
return if ($#state < 0); |
1758
|
|
|
|
|
|
|
|
1759
|
2
|
|
|
|
|
3
|
$ref = pop @state; |
1760
|
|
|
|
|
|
|
|
1761
|
|
|
|
|
|
|
( |
1762
|
2
|
|
|
|
|
10
|
$self->{'x'}, |
1763
|
|
|
|
|
|
|
$self->{'y'}, |
1764
|
|
|
|
|
|
|
$self->{'attr'}, |
1765
|
|
|
|
|
|
|
$self->{'ti'}, |
1766
|
|
|
|
|
|
|
$self->{'ic'}, |
1767
|
|
|
|
|
|
|
$self->{'cursor'} |
1768
|
|
|
|
|
|
|
) = @$ref; |
1769
|
|
|
|
|
|
|
|
1770
|
2
|
|
|
|
|
7
|
$self->{'_decsc'} = [ @state ]; |
1771
|
|
|
|
|
|
|
} |
1772
|
|
|
|
|
|
|
|
1773
|
|
|
|
|
|
|
sub _code_CUPSV { # save cursor position |
1774
|
2
|
|
|
2
|
|
4
|
my $self = shift; |
1775
|
2
|
|
|
|
|
2
|
my @state; |
1776
|
|
|
|
|
|
|
|
1777
|
2
|
|
|
|
|
3
|
@state = @{$self->{'_cupsv'}}; |
|
2
|
|
|
|
|
5
|
|
1778
|
2
|
|
|
|
|
7
|
push ( |
1779
|
|
|
|
|
|
|
@state, |
1780
|
|
|
|
|
|
|
[ |
1781
|
|
|
|
|
|
|
$self->{'x'}, |
1782
|
|
|
|
|
|
|
$self->{'y'} |
1783
|
|
|
|
|
|
|
] |
1784
|
|
|
|
|
|
|
); |
1785
|
2
|
|
|
|
|
6
|
$self->{'_cupsv'} = [ @state ]; |
1786
|
|
|
|
|
|
|
} |
1787
|
|
|
|
|
|
|
|
1788
|
|
|
|
|
|
|
sub _code_CUPRS { # restore cursor position |
1789
|
2
|
|
|
2
|
|
38
|
my $self = shift; |
1790
|
2
|
|
|
|
|
4
|
my @state; |
1791
|
|
|
|
|
|
|
my $ref; |
1792
|
|
|
|
|
|
|
|
1793
|
2
|
|
|
|
|
3
|
@state = @{$self->{'_cupsv'}}; |
|
2
|
|
|
|
|
6
|
|
1794
|
2
|
50
|
|
|
|
6
|
return if ($#state < 0); |
1795
|
|
|
|
|
|
|
|
1796
|
2
|
|
|
|
|
2
|
$ref = pop @state; |
1797
|
|
|
|
|
|
|
|
1798
|
|
|
|
|
|
|
( |
1799
|
2
|
|
|
|
|
6
|
$self->{'x'}, |
1800
|
|
|
|
|
|
|
$self->{'y'} |
1801
|
|
|
|
|
|
|
) = @$ref; |
1802
|
|
|
|
|
|
|
|
1803
|
2
|
|
|
|
|
5
|
$self->{'_cupsv'} = [ @state ]; |
1804
|
|
|
|
|
|
|
} |
1805
|
|
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
sub _code_XON { # resume character processing |
1807
|
2
|
|
|
2
|
|
3
|
my $self = shift; |
1808
|
2
|
|
|
|
|
8
|
$self->{'_xon'} = 1; |
1809
|
|
|
|
|
|
|
} |
1810
|
|
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
sub _code_XOFF { # stop character processing |
1812
|
2
|
|
|
2
|
|
3
|
my $self = shift; |
1813
|
2
|
100
|
|
|
|
10
|
return if ($self->{'opts'}->{'IGNOREXOFF'}); |
1814
|
1
|
|
|
|
|
5
|
$self->{'_xon'} = 0; |
1815
|
|
|
|
|
|
|
} |
1816
|
|
|
|
|
|
|
|
1817
|
|
|
|
|
|
|
1; |
1818
|
|
|
|
|
|
|
__END__ |