jarib-win32console 1.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ #################################################################
2
+ #
3
+ # To compile and install, do this:
4
+ #
5
+ # Make sure your compiling environment is in your path.
6
+ # In the case of MSVC, this involves running vcvars32.bat first
7
+ # which is located in the bin directory of MS Visual C++.
8
+ #
9
+ # Then:
10
+ #
11
+ # > ruby extconf.rb
12
+ # > nmake Makefile
13
+ # > nmake install
14
+ #
15
+ #
16
+ ##################################################################
17
+ require 'mkmf'
18
+ create_makefile('Console')
@@ -0,0 +1,372 @@
1
+ # Win32::Console: an object implementing the Win32 API Console functions
2
+ # Copyright (C) 2003 Gonzalo Garramuno (ggarramuno@aol.com)
3
+ #
4
+ # Original Win32API_Console was:
5
+ # Copyright (C) 2001 Michael L. Semon (mlsemon@sega.net)
6
+
7
+ begin
8
+ # If Console.so is available, use that. Otherwise, we define
9
+ # equivalent functions in ruby (a tad slower)
10
+ # That dll should define everything in an identical interface
11
+ # to all the ruby code that the rescue below defines.
12
+
13
+ require "Console.so"
14
+ STDERR.print "Using faster, DLL Console.so\n" if $DEBUG
15
+
16
+ rescue Exception
17
+
18
+ STDERR.print "Using slower, non-DLL Console.rb\n" if $DEBUG
19
+
20
+ require 'Win32/Console/constants.rb'
21
+ require 'Win32/Console/api.rb'
22
+
23
+ end # rescue
24
+
25
+ module Win32
26
+ class Console
27
+
28
+ VERSION = '1.0'
29
+
30
+ include Win32::Console::Constants
31
+
32
+ def initialize( t = nil )
33
+ if t and ( t == STD_INPUT_HANDLE or t == STD_OUTPUT_HANDLE or
34
+ t == STD_ERROR_HANDLE )
35
+ @handle = API.GetStdHandle( t )
36
+ else
37
+ param1 = GENERIC_READ | GENERIC_WRITE
38
+ param2 = FILE_SHARE_READ | FILE_SHARE_WRITE
39
+ @handle = API.CreateConsoleScreenBuffer( param1, param2,
40
+ CONSOLE_TEXTMODE_BUFFER )
41
+ end
42
+ end
43
+
44
+ def Display
45
+ return API.SetConsoleActiveScreenBuffer(@handle)
46
+ end
47
+
48
+ def Select(type)
49
+ return API.SetStdHandle(type,@handle)
50
+ end
51
+
52
+ def Title(title = nil)
53
+ if title
54
+ return API.SetConsoleTitle(title)
55
+ else
56
+ return API.GetConsoleTitle()
57
+ end
58
+ end
59
+
60
+ def WriteChar(s, col, row)
61
+ API.WriteConsoleOutputCharacter( @handle, s, col, row )
62
+ end
63
+
64
+ def ReadChar(size, col, row)
65
+ buffer = ' ' * size
66
+ if API.ReadConsoleOutputCharacter( @handle, buffer, size, col, row )
67
+ return buffer
68
+ else
69
+ return nil
70
+ end
71
+ end
72
+
73
+ def WriteAttr(attr, col, row)
74
+ API.WriteConsoleOutputAttribute( @handle, attr, col, row )
75
+ end
76
+
77
+ def ReadAttr(size, col, row)
78
+ x = API.ReadConsoleOutputAttribute( @handle, size, col, row )
79
+ return x.unpack('c'*size)
80
+ end
81
+
82
+ def Cursor(*t)
83
+ col, row, size, visi = t
84
+ if col
85
+ row = -1 if !row
86
+ if col < 0 or row < 0
87
+ curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle)
88
+ col = curr_col if col < 0
89
+ row = curr_row if row < 0
90
+ end
91
+ API.SetConsoleCursorPosition( @handle, col, row )
92
+ if size and visi
93
+ curr_size, curr_visi = API.GetConsoleCursorInfo( @handle )
94
+ size = curr_size if size < 0
95
+ visi = curr_visi if visi < 0
96
+ size = 1 if size < 1
97
+ size = 99 if size > 99
98
+ API.SetConsoleCursorInfo( @handle, size, visi )
99
+ end
100
+ else
101
+ d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle)
102
+ curr_size, curr_visi = API.GetConsoleCursorInfo( @handle )
103
+ return [ curr_col, curr_row, curr_size, curr_visi ]
104
+ end
105
+ end
106
+
107
+ def Write(s)
108
+ API.WriteConsole( @handle, s )
109
+ end
110
+
111
+ def WriteFile(s)
112
+ API.WriteFile( @handle, s)
113
+ end
114
+
115
+ def ReadRect( left, top, right, bottom )
116
+ col = right - left + 1
117
+ row = bottom - top + 1
118
+ size = col * row
119
+ buffer = ' ' * size * 4
120
+ if API.ReadConsoleOutput( @handle, buffer, col, row, 0, 0,
121
+ left, top, right, bottom )
122
+ #return buffer.unpack('US'*size) # for unicode
123
+ return buffer.unpack('axS'*size) # for ascii
124
+ else
125
+ return nil
126
+ end
127
+ end
128
+
129
+ def WriteRect( buffer, left, top, right, bottom )
130
+ col = right - left + 1
131
+ row = bottom - top + 1
132
+ API.WriteConsoleOutput( @handle, buffer, col, row, 0, 0,
133
+ left, top, right, bottom )
134
+ end
135
+
136
+ def Scroll( left1, top1, right1, bottom1,
137
+ col, row, char, attr,
138
+ left2, top2, right2, bottom2 )
139
+ API.ScrollConsoleScreenBuffer(@handle, left1, top1, right1, bottom1,
140
+ col, row, char, attr,
141
+ left2, top2, right2, bottom2)
142
+ end
143
+
144
+ def MaxWindow(flag = nil)
145
+ if !flag
146
+ info = API.GetConsoleScreenBufferInfo(@handle)
147
+ return info[9], info[10]
148
+ else
149
+ return API.GetLargestConsoleWindowSize(@handle)
150
+ end
151
+ end
152
+
153
+ def Info()
154
+ return API.GetConsoleScreenBufferInfo( @handle )
155
+ end
156
+
157
+ def GetEvents()
158
+ return API.GetNumberOfConsoleInputEvents(@handle)
159
+ end
160
+
161
+ def Flush()
162
+ return API.FlushConsoleInputBuffer(@handle)
163
+ end
164
+
165
+ def InputChar(number = nil)
166
+ number = 1 unless number
167
+ buffer = ' ' * number
168
+ if API.ReadConsole(@handle, buffer, number) == number
169
+ return buffer
170
+ else
171
+ return nil
172
+ end
173
+ end
174
+
175
+ def Input()
176
+ API.ReadConsoleInput(@handle)
177
+ end
178
+
179
+ def PeekInput()
180
+ API.PeekConsoleInput(@handle)
181
+ end
182
+
183
+ def Mode(mode = nil)
184
+ if mode
185
+ mode = mode.pack('L') if mode === Array
186
+ API.SetConsoleMode(@handle, mode)
187
+ else
188
+ begin
189
+ x = API.GetConsoleMode(@handle)
190
+ return x
191
+ rescue
192
+ return 9999
193
+ end
194
+ end
195
+ end
196
+
197
+ def WriteInput(*t)
198
+ API.WriteConsoleInput(@handle, *t)
199
+ end
200
+
201
+ def Attr(*attr)
202
+ if attr.size > 0
203
+ API.SetConsoleTextAttribute( @handle, attr[0] )
204
+ else
205
+ info = API.GetConsoleScreenBufferInfo( @handle )
206
+ return info[4]
207
+ end
208
+ end
209
+
210
+ def Size(*t)
211
+ if t.size == 0
212
+ col, row = API.GetConsoleScreenBufferInfo(@handle )
213
+ return [col, row]
214
+ else
215
+ row = -1 if !t[1]
216
+ col = -1 if !t[0]
217
+ if col < 0 or row < 0
218
+ curr_col, curr_row = Size()
219
+ col = curr_col if col < 0
220
+ row = curr_row if row < 0
221
+ end
222
+ API.SetConsoleScreenBufferSize(@handle, row, col)
223
+ end
224
+ end
225
+
226
+ def Window(*t)
227
+ if t.size != 5
228
+ info = API.GetConsoleScreenBufferInfo( @handle )
229
+ return info[5..8]
230
+ else
231
+ API.SetConsoleWindowInfo(@handle, t[0], t[1], t[2], t[3], t[4])
232
+ end
233
+ end
234
+
235
+ def FillAttr(attr, number = 1, col = -1, row = -1)
236
+ if col < 0 or row < 0
237
+ d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle)
238
+ col = curr_col if col < 0
239
+ row = curr_row if row < 0
240
+ end
241
+ API.FillConsoleOutputAttribute(@handle, attr, number, col, row)
242
+ end
243
+
244
+ def FillChar(char, number, col = -1, row = -1)
245
+ if col < 0 or row < 0
246
+ d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle)
247
+ col = curr_col if col < 0
248
+ row = curr_row if row < 0
249
+ end
250
+ API.FillConsoleOutputCharacter(@handle, char[0], number, col, row)
251
+ end
252
+
253
+ def Cls()
254
+ attr = ATTR_NORMAL
255
+ x, y = Size()
256
+ left, top, right , bottom = Window()
257
+ vx = right - left
258
+ vy = bottom - top
259
+ FillChar(' ', x*y, 0, 0)
260
+ FillAttr(attr, x*y, 0, 0)
261
+ Cursor(0,0)
262
+ Window(1,0,0,vx,vy)
263
+ end
264
+
265
+ def Console.Free()
266
+ API.FreeConsole()
267
+ end
268
+
269
+ def Console.Alloc()
270
+ API.AllocConsole()
271
+ end
272
+
273
+ def Console.MouseButtons()
274
+ API.GetNumberOfConsoleMouseButtons()
275
+ end
276
+
277
+ def Console.InputCP(codepage=nil)
278
+ if codepage
279
+ API.SetConsoleCP(codepage)
280
+ else
281
+ return API.GetConsoleCP()
282
+ end
283
+ end
284
+
285
+ def Console.OutputCP(codepage=nil)
286
+ if codepage
287
+ API.SetConsoleOutputCP(codepage)
288
+ else
289
+ return API.GetConsoleOutputCP()
290
+ end
291
+ end
292
+
293
+ def Console.GenerateCtrlEvent( type=nil, pid=nil )
294
+ type = API.constant('CTRL_C_EVENT') if type == nil
295
+ pid = 0 if pid == nil
296
+ API.GenerateConsoleCtrlEvent(type, pid)
297
+ end
298
+
299
+ end
300
+ end
301
+
302
+
303
+ FG_BLACK = 0
304
+ FG_BLUE = Win32::Console::API.constant("FOREGROUND_BLUE")
305
+ FG_LIGHTBLUE = Win32::Console::API.constant("FOREGROUND_BLUE")|
306
+ Win32::Console::API.constant("FOREGROUND_INTENSITY")
307
+ FG_RED = Win32::Console::API.constant("FOREGROUND_RED")
308
+ FG_LIGHTRED = Win32::Console::API.constant("FOREGROUND_RED")|
309
+ Win32::Console::API.constant("FOREGROUND_INTENSITY")
310
+ FG_GREEN = Win32::Console::API.constant("FOREGROUND_GREEN")
311
+ FG_LIGHTGREEN = Win32::Console::API.constant("FOREGROUND_GREEN")|
312
+ Win32::Console::API.constant("FOREGROUND_INTENSITY")
313
+ FG_MAGENTA = Win32::Console::API.constant("FOREGROUND_RED")|
314
+ Win32::Console::API.constant("FOREGROUND_BLUE")
315
+ FG_LIGHTMAGENTA = Win32::Console::API.constant("FOREGROUND_RED")|
316
+ Win32::Console::API.constant("FOREGROUND_BLUE")|
317
+ Win32::Console::API.constant("FOREGROUND_INTENSITY")
318
+ FG_CYAN = Win32::Console::API.constant("FOREGROUND_GREEN")|
319
+ Win32::Console::API.constant("FOREGROUND_BLUE")
320
+ FG_LIGHTCYAN = Win32::Console::API.constant("FOREGROUND_GREEN")|
321
+ Win32::Console::API.constant("FOREGROUND_BLUE")|
322
+ Win32::Console::API.constant("FOREGROUND_INTENSITY")
323
+ FG_BROWN = Win32::Console::API.constant("FOREGROUND_RED")|
324
+ Win32::Console::API.constant("FOREGROUND_GREEN")
325
+ FG_YELLOW = Win32::Console::API.constant("FOREGROUND_RED")|
326
+ Win32::Console::API.constant("FOREGROUND_GREEN")|
327
+ Win32::Console::API.constant("FOREGROUND_INTENSITY")
328
+ FG_GRAY = Win32::Console::API.constant("FOREGROUND_RED")|
329
+ Win32::Console::API.constant("FOREGROUND_GREEN")|
330
+ Win32::Console::API.constant("FOREGROUND_BLUE")
331
+ FG_WHITE = Win32::Console::API.constant("FOREGROUND_RED")|
332
+ Win32::Console::API.constant("FOREGROUND_GREEN")|
333
+ Win32::Console::API.constant("FOREGROUND_BLUE")|
334
+ Win32::Console::API.constant("FOREGROUND_INTENSITY")
335
+
336
+ BG_BLACK = 0
337
+ BG_BLUE = Win32::Console::API.constant("BACKGROUND_BLUE")
338
+ BG_LIGHTBLUE = Win32::Console::API.constant("BACKGROUND_BLUE")|
339
+ Win32::Console::API.constant("BACKGROUND_INTENSITY")
340
+ BG_RED = Win32::Console::API.constant("BACKGROUND_RED")
341
+ BG_LIGHTRED = Win32::Console::API.constant("BACKGROUND_RED")|
342
+ Win32::Console::API.constant("BACKGROUND_INTENSITY")
343
+ BG_GREEN = Win32::Console::API.constant("BACKGROUND_GREEN")
344
+ BG_LIGHTGREEN = Win32::Console::API.constant("BACKGROUND_GREEN")|
345
+ Win32::Console::API.constant("BACKGROUND_INTENSITY")
346
+ BG_MAGENTA = Win32::Console::API.constant("BACKGROUND_RED")|
347
+ Win32::Console::API.constant("BACKGROUND_BLUE")
348
+ BG_LIGHTMAGENTA = Win32::Console::API.constant("BACKGROUND_RED")|
349
+ Win32::Console::API.constant("BACKGROUND_BLUE")|
350
+ Win32::Console::API.constant("BACKGROUND_INTENSITY")
351
+ BG_CYAN = Win32::Console::API.constant("BACKGROUND_GREEN")|
352
+ Win32::Console::API.constant("BACKGROUND_BLUE")
353
+ BG_LIGHTCYAN = Win32::Console::API.constant("BACKGROUND_GREEN")|
354
+ Win32::Console::API.constant("BACKGROUND_BLUE")|
355
+ Win32::Console::API.constant("BACKGROUND_INTENSITY")
356
+ BG_BROWN = Win32::Console::API.constant("BACKGROUND_RED")|
357
+ Win32::Console::API.constant("BACKGROUND_GREEN")
358
+ BG_YELLOW = Win32::Console::API.constant("BACKGROUND_RED")|
359
+ Win32::Console::API.constant("BACKGROUND_GREEN")|
360
+ Win32::Console::API.constant("BACKGROUND_INTENSITY")
361
+ BG_GRAY = Win32::Console::API.constant("BACKGROUND_RED")|
362
+ Win32::Console::API.constant("BACKGROUND_GREEN")|
363
+ Win32::Console::API.constant("BACKGROUND_BLUE")
364
+ BG_WHITE = Win32::Console::API.constant("BACKGROUND_RED")|
365
+ Win32::Console::API.constant("BACKGROUND_GREEN")|
366
+ Win32::Console::API.constant("BACKGROUND_BLUE")|
367
+ Win32::Console::API.constant("BACKGROUND_INTENSITY")
368
+
369
+ ATTR_NORMAL = FG_GRAY | BG_BLACK
370
+ ATTR_INVERSE = FG_BLACK | BG_GRAY
371
+
372
+ include Win32::Console::Constants
@@ -0,0 +1,349 @@
1
+ # encoding: binary
2
+ #
3
+ # Win32::Console::ANSI
4
+ #
5
+ # Copyright 2004 - Gonzalo Garramuno
6
+ # Licensed under GNU General Public License or Perl's Artistic License
7
+ #
8
+ # Based on Perl's Win32::Console::ANSI
9
+ # Copyright (c) 2003 Jean-Louis Morel <jl_morel@bribes.org>
10
+ # Licensed under GNU General Public License or Perl's Artistic License
11
+ #
12
+ require "Win32/Console"
13
+
14
+
15
+ module Kernel
16
+
17
+ # Kernel#putc is equivalent to $stdout.putc, but
18
+ # it doesn't use $stdout.putc. We redefine it to do that
19
+ # so that it will buffer the escape sequences properly.
20
+ # See Win32::Console::ANSI::IO#putc
21
+ remove_method :putc
22
+ def putc(int)
23
+ $stdout.putc(int)
24
+ end
25
+
26
+ end
27
+
28
+ module Win32
29
+ class Console
30
+ module ANSI
31
+
32
+ class IO < IO
33
+
34
+ VERSION = '0.05'
35
+ DEBUG = nil
36
+
37
+ require "win32/registry"
38
+
39
+ include Win32::Console::Constants
40
+
41
+ # @todo: encode is another perl module
42
+ EncodeOk = false
43
+
44
+ # Retrieving the codepages
45
+ cpANSI = nil
46
+ Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Nls\CodePage' ) { |reg|
47
+ cpANSI = reg['ACP']
48
+ }
49
+
50
+ STDERR.puts "Unable to read Win codepage #{cpANSI}" if DEBUG && !cpANSI
51
+
52
+
53
+ cpANSI = 'cp'+(cpANSI ? cpANSI : '1252') # Windows codepage
54
+ OEM = Win32::Console::OutputCP()
55
+ cpOEM = 'cp' + OEM.to_s # DOS codepage
56
+ @@cp = cpANSI + cpOEM
57
+
58
+ STDERR.puts "EncodeOk=#{EncodeOk} cpANSI=#{cpANSI} "+
59
+ "cpOEM=#{cpOEM}" if DEBUG
60
+
61
+ @@color = { 30 => 0, # black foreground
62
+ 31 => FOREGROUND_RED, # red foreground
63
+ 32 => FOREGROUND_GREEN, # green foreground
64
+ 33 => FOREGROUND_RED|FOREGROUND_GREEN, # yellow foreground
65
+ 34 => FOREGROUND_BLUE, # blue foreground
66
+ 35 => FOREGROUND_BLUE|FOREGROUND_RED, # magenta foreground
67
+ 36 => FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan foreground
68
+ 37 => FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE, # white foreground
69
+ 40 => 0, # black background
70
+ 41 => BACKGROUND_RED, # red background
71
+ 42 => BACKGROUND_GREEN, # green background
72
+ 43 => BACKGROUND_RED|BACKGROUND_GREEN, # yellow background
73
+ 44 => BACKGROUND_BLUE, # blue background
74
+ 45 => BACKGROUND_BLUE|BACKGROUND_RED, # magenta background
75
+ 46 => BACKGROUND_BLUE|BACKGROUND_GREEN, # cyan background
76
+ 47 => BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE, # white background
77
+ }
78
+
79
+ def initialize
80
+ super(1,'w')
81
+ @Out = Win32::Console.new(STD_OUTPUT_HANDLE)
82
+ @x = @y = 0 # to save cursor position
83
+ @foreground = 7
84
+ @background = 0
85
+ @bold =
86
+ @underline =
87
+ @revideo =
88
+ @concealed = nil
89
+ @conv = 1 # char conversion by default
90
+ @buffer = []
91
+ STDERR.puts "Console Mode=#{@Out.Mode}" if DEBUG
92
+ end
93
+
94
+ # this redefined #putc buffers escape sequences but passes
95
+ # other values to #write as normal.
96
+ def putc(int)
97
+ if @buffer.empty?
98
+ unless int == ?\e
99
+ write(int.chr)
100
+ else
101
+ @buffer << int
102
+ end
103
+ else
104
+ @buffer << int
105
+ case int
106
+ when ?m, ?J, ?L, ?M, ?@, ?P, ?A, ?B, ?C, ?D,
107
+ ?E, ?F, ?G, ?H, ?f, ?s, ?u, ?U, ?K, ?X
108
+ write(@buffer.pack("c*"))
109
+ @buffer.clear
110
+ end
111
+ end
112
+ end
113
+
114
+ # #write checks if $stdout is going to the console
115
+ # or if it's being redirected.
116
+ # When to the console, it passes the string to
117
+ # _PrintString to be parsed for escape codes.
118
+ #
119
+ # When redirected, it passes to WriteFile to allow escape
120
+ # codes and all to be output. The application that is
121
+ # handling the redirected IO should handle coloring.
122
+ # For Ruby applications, this means requiring Win32Conole again.
123
+ def write(*s)
124
+ if redirected?
125
+ s.each{ |x| @Out.WriteFile(x.dup.to_s) }
126
+ else
127
+ s.each{ |x| _PrintString(x) }
128
+ end
129
+ end
130
+
131
+ # returns true if outputs is being redirected.
132
+ def redirected?
133
+ @Out.Mode > 31
134
+ end
135
+
136
+ private
137
+
138
+ def _PrintString(t)
139
+ s = t.dup.to_s
140
+ while s != ''
141
+ if s.sub!( /([^\e]*)?\e([\[\(])([0-9\;\=]*)([a-zA-Z@])(.*)/s,'\5')
142
+ @Out.Write((_conv("#$1")))
143
+ if $2 == '['
144
+ case $4
145
+ when 'm' # ESC[#;#;....;#m Set display attributes
146
+ attributs = $3.split(';')
147
+ attributs.push(nil) unless attributs # ESC[m == ESC[;m ==...==ESC[0m
148
+ attributs.each do |attr|
149
+ atv = attr.to_i
150
+ case atv
151
+ when 0 # ESC[0m reset
152
+ @foreground = 7
153
+ @background = 0
154
+ @bold =
155
+ @underline =
156
+ @revideo =
157
+ @concealed = nil
158
+ when 1
159
+ @bold = 1
160
+ when 21
161
+ @bold = nil
162
+ when 4
163
+ @underline = 1
164
+ when 24
165
+ @underline = nil
166
+ when 7
167
+ @revideo = 1
168
+ when 27
169
+ @revideo = nil
170
+ when 8
171
+ @concealed = 1
172
+ when 28
173
+ @concealed = nil
174
+ when 30..37
175
+ @foreground = atv - 30
176
+ when 40..47
177
+ @background = atv - 40
178
+ end
179
+ end
180
+
181
+ if @revideo
182
+ attribut = @@color[40+@foreground] |
183
+ @@color[30+@background]
184
+ else
185
+ attribut = @@color[30+@foreground] |
186
+ @@color[40+@background]
187
+ end
188
+ attribut |= FOREGROUND_INTENSITY if @bold
189
+ attribut |= BACKGROUND_INTENSITY if @underline
190
+ @Out.Attr(attribut)
191
+ when 'J'
192
+ if !$3 or $3 == '' # ESC[0J from cursor to end of display
193
+ info = @Out.Info()
194
+ s = ' ' * ((info[1]-info[3]-1)*info[0]+info[0]-info[2]-1)
195
+ @Out.WriteChar(s, info[2], info[3])
196
+ @Out.Cursor(info[2], info[3])
197
+ elsif $3 == '1' # ESC[1J erase from start to cursor.
198
+ info = @Out.Info()
199
+ s = ' ' * (info[3]*info[0]+info[2]+1)
200
+ @Out.WriteChar(s, 0, 0)
201
+ @Out.Cursor(info[2], info[3])
202
+ elsif $3 == '2' # ESC[2J Clear screen and home cursor
203
+ @Out.Cls()
204
+ @Out.Cursor(0, 0)
205
+ else
206
+ STDERR.print "\e#$2#$3#$4" if DEBUG # if ESC-code not implemented
207
+ end
208
+ when 'K'
209
+ info = @Out.Info()
210
+ if !$3 or $3 == '' # ESC[0K Clear to end of line
211
+ s = ' ' * (info[7]-info[2]+1)
212
+ @Out.Write(s)
213
+ @Out.Cursor(info[2], info[3])
214
+ elsif $3=='1' # ESC[1K Clear from start of line to cursor
215
+ s = ' '*(info[2]+1)
216
+ @Out.WriteChar(s, 0, info[3])
217
+ @Out.Cursor(info[2], info[3])
218
+ elsif $3=='2' # ESC[2K Clear whole line.
219
+ s = ' '* info[0]
220
+ @Out.WriteChar(s, 0, info[3])
221
+ @Out.Cursor(info[2], info[3])
222
+ end
223
+ when 'L' # ESC[#L Insert # blank lines.
224
+ n = $3 == ''? 1 : $3.to_i # ESC[L == ESC[1L
225
+ info = @Out.Info()
226
+ @Out.Scroll(0, info[3], info[0]-1, info[1]-1,
227
+ 0, info[3] + n.to_i,
228
+ ' '[0], @Out.Attr(),
229
+ 0, 0, 10000, 10000)
230
+ @Out.Cursor(info[2], info[3])
231
+ when 'M' # ESC[#M Delete # line.
232
+ n = $3 == ''? 1 : $3.to_i # ESC[M == ESC[1M
233
+ info = @Out.Info();
234
+ @Out.Scroll(0, info[3]+n, info[0]-1, info[1]-1,
235
+ 0, info[3],
236
+ ' '[0], @Out.Attr(),
237
+ 0, 0, 10000, 10000)
238
+ @Out.Cursor(info[2], info[3])
239
+ when 'P' # ESC[#P Delete # characters.
240
+ n = $3 == ''? 1 : $3.to_i # ESC[P == ESC[1P
241
+ info = @Out.Info()
242
+ n = info[0]-info[2] if info[2]+n > info[0]-1
243
+ @Out.Scroll(info[2]+n, info[3] , info[0]-1, info[3],
244
+ info[2], info[3],
245
+ ' '[0], @Out.Attr(),
246
+ 0, 0, 10000, 10000)
247
+ s = ' ' * n
248
+ @Out.Cursor(info[0]-n, info[3])
249
+ @Out.Write(s)
250
+ @Out.Cursor(info[2], info[3])
251
+ when '@' # ESC[#@ Insert # blank Characters
252
+ s = ' ' * $3.to_i
253
+ info = @Out.Info()
254
+ s << @Out.ReadChar(info[7]-info[2]+1, info[2], info[3])
255
+ s = s[0..-($3.to_i)]
256
+ @Out.Write(s);
257
+ @Out.Cursor(info[2], info[3])
258
+ when 'A' # ESC[#A Moves cursor up # lines
259
+ (x, y) = @Out.Cursor()
260
+ n = $3 == ''? 1 : $3.to_i; # ESC[A == ESC[1A
261
+ @Out.Cursor(x, y-n)
262
+ when 'B' # ESC[#B Moves cursor down # lines
263
+ (x, y) = @Out.Cursor()
264
+ n = $3 == ''? 1 : $3.to_i; # ESC[B == ESC[1B
265
+ @Out.Cursor(x, y+n)
266
+ when 'C' # ESC[#C Moves cursor forward # spaces
267
+ (x, y) = @Out.Cursor()
268
+ n = $3 == ''? 1 : $3.to_i; # ESC[C == ESC[1C
269
+ @Out.Cursor(x+n, y)
270
+ when 'D' # ESC[#D Moves cursor back # spaces
271
+ (x, y) = @Out.Cursor()
272
+ n = $3 == ''? 1 : $3.to_i; # ESC[D == ESC[1D
273
+ @Out.Cursor(x-n, y)
274
+ when 'E' # ESC[#E Moves cursor down # lines, column 1.
275
+ x, y = @Out.Cursor()
276
+ n = $3 == ''? 1 : $3.to_i; # ESC[E == ESC[1E
277
+ @Out.Cursor(0, y+n)
278
+ when 'F' # ESC[#F Moves cursor up # lines, column 1.
279
+ x, y = @Out.Cursor()
280
+ n = $3 == ''? 1 : $3.to_i; # ESC[F == ESC[1F
281
+ @Out.Cursor(0, y-n)
282
+ when 'G' # ESC[#G Moves cursor column # in current row.
283
+ x, y = @Out.Cursor()
284
+ n = $3 == ''? 1 : $3.to_i; # ESC[G == ESC[1G
285
+ @Out.Cursor(n-1, y)
286
+ when 'f' # ESC[#;#f Moves cursor to line #, column #
287
+ y, x = $3.split(';')
288
+ x = 1 unless x # ESC[;5H == ESC[1;5H ...etc
289
+ y = 1 unless y
290
+ @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console
291
+ when 'H' # ESC[#;#H Moves cursor to line #, column #
292
+ y, x = $3.split(';')
293
+ x = 1 unless x # ESC[;5H == ESC[1;5H ...etc
294
+ y = 1 unless y
295
+ @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console
296
+ when 's' # ESC[s Saves cursor position for recall later
297
+ (@x, @y) = @Out.Cursor()
298
+ when 'u' # ESC[u Return to saved cursor position
299
+ @Out.Cursor(@x, @y)
300
+ when 'U' # ESC(U no mapping
301
+ @conv = nil
302
+ when 'K' # ESC(K mapping if it exist
303
+ @Out.OutputCP(OEM) # restore original codepage
304
+ @conv = 1
305
+ when 'X' # ESC(#X codepage **EXPERIMENTAL**
306
+ @conv = nil
307
+ @Out.OutputCP($3)
308
+ else
309
+ STDERR.puts "\e#$2#$3#$4 not implemented" if DEBUG # ESC-code not implemented
310
+ end
311
+ end
312
+ else
313
+ @Out.Write(_conv(s))
314
+ s=''
315
+ end
316
+ end
317
+ end
318
+
319
+ def _conv(s)
320
+ if @concealed
321
+ s.gsub!( /\S/,' ')
322
+ elsif @conv
323
+ if EncodeOk
324
+ from_to(s, cpANSI, cpOEM)
325
+ elsif @@cp == 'cp1252cp850' # WinLatin1 --> DOSLatin1
326
+ s.tr!("���������������������������������������������������������������������������������������������������ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁��������������������������������������������","???�??????????????????????????��������ρ��݁�����������������������������������������󁨁������ǎ����Ԑ�ҁӁށցׁ؁с������噞����ꚁ��ᅁ���Ƅ�������������Ё������䔁����������")
327
+ elsif @@cp == 'cp1252cp437' # WinLatin1 --> DOSLatinUS
328
+ s.tr!("���������������������������������������������������������������������������������������������������ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁��������������������������������������������", "??????????????????????????????������?�????������???�����??��?��??��������?��????����?�???????��????�?????�??�ᅁ��?�������������?������?���?�����??�")
329
+ elsif @@cp == 'cp1250cp852' # WinLatin2 --> DOSLatin2
330
+ s.tr!("���������������������������������������������������������������������������������������������������ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁��������������������������������������������",
331
+ "??????????��?��??????????��?������������ρ�?����?��������?����?���???����������񖁾�聵���Ǝ���������Ӂ��ցׁҁс�Ձ��⊙����ށ�뚁�݁�ꁠ��DŽ���������؁���ԁЁ�偢�����������������" )
332
+ elsif @@cp == 'cp1251cp855' # WinCyrillic --> DOSCyrillic
333
+ s.tr!("���������������������������������������������������������������������������������������������������ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁��������������������������������������������",
334
+ "��?�??????�?����?????????�?����������??���?���?��?�??��????������������쁭������􁸁��ǁсӁՁׁ݁���聫�����������������������끬������󁷁��ƁЁҁԁց؁���灪������������������")
335
+ end
336
+ end
337
+ return s
338
+ end
339
+
340
+ end
341
+
342
+ # end print overloading
343
+
344
+ end
345
+ end
346
+ end
347
+
348
+ $stdout = Win32::Console::ANSI::IO.new()
349
+