win32console 1.3.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,119 @@
1
+ === 1.3.0.beta
2
+
3
+ * Enhancements
4
+ * Usage of Hoe and rake-compiler to ease releasing and extension
5
+ compilation.
6
+
7
+ * Bugfixes:
8
+ * Works with Ruby 1.9
9
+
10
+ * Known issues:
11
+ * win32console no longer automatically translate encoding to the console
12
+ output enconding. Please use Iconv to convert from your encoding (eg. UTF8)
13
+ to current console output:
14
+
15
+ current_cp = Win32::Console::OutputCP()
16
+ Iconv.iconv("cp#{current_cp}", "utf-8", utf_string)
17
+
18
+ A working example can be seen here: http://gist.github.com/265593
19
+
20
+ === 1.2.0 / 2008-11-22
21
+
22
+ * Enhancements
23
+ * Better code organization and clenaup
24
+
25
+ * Bugfixes:
26
+ * Removed license conflicting ANSI Term code and functionality.
27
+
28
+ === 1.1.0 / 2008-03-17
29
+
30
+ * Enhancements:
31
+ * Added Kernel#putc
32
+ Redefined Kernel#putc to wrap Win32::Console::ANSI::IO#putc
33
+
34
+ * Added #putc to Win32::Console::ANSI::IO
35
+ This putc buffers escape sequences so that they will be handled properly
36
+
37
+ * Added #redirected? to Win32::Console::ANSI::IO
38
+ Checks the mode of the console to see if IO is being redirected or not
39
+
40
+ * Added Win32::Console::API#WriteFile
41
+ to both the Ruby and compiled versions
42
+
43
+ * Added Win32::Console#WriteFile
44
+ This is a wrapper around Win32::Console::API#WriteFile
45
+
46
+ * Split Win32::Console::Constants and Win32::Console::API out into
47
+ seperate files. These two classes were in 'Win32/Console.rb'
48
+ I moved them into 'Win32/Console/constants.rb' and 'Win32/Console/api.rb'
49
+ respectively.
50
+
51
+ * Cleaned up indentation
52
+ indentations was a mixture of tabs and spaces. I made everything indented
53
+ with 2 spaces.
54
+
55
+ * Bugfixes:
56
+ * Fixed "Invalid Handle" error in compiled version of GetConsoleMode
57
+ I'm actually not sure of the source of this error.
58
+ It may be expected behavior when output is being redirected.
59
+ I worked around it by rescuing the exception in Win32::Console#Mode and
60
+ returning 9999. I picked that arbitrary value, because it is
61
+ higher than 31, which is what I think is the highest value Mode would
62
+ return if output isn't being redirected.
63
+ [Gordon Thiesfeld]
64
+
65
+ * Modified Win32::Console::ANSI::IO#write to check for redirection.
66
+ If output is redirected, it uses WriteFile instead of WriteConosle.
67
+ It also skips the parsing step, and passes the escape sequences through.
68
+ [Gordon Thiesfeld]
69
+
70
+ * Modified Win32::Console::ANSI::IO#_PrintString
71
+ Didn't change behavior, just tried to make it more idiomatic ruby.
72
+ I didn't make all of the changes I wanted to, because I wasn't sure
73
+ how to test them all.
74
+ [Gordon Thiesfeld]
75
+
76
+ * Modified all Win32::Console::API methods
77
+ [Gordon Thiesfeld]
78
+
79
+ It was assigning Win32API functions to class variables. I switched them to instance variables. I also changed the idiom it was using to instantiate the objects.
80
+ For instance, instead of:
81
+
82
+ if @@m_AllocConsole == nil
83
+ @@m_AllocConsole = Win32API.new( "kernel32", "AllocConsole",
84
+ [], 'l' )
85
+
86
+ It is now:
87
+
88
+ @AllocConsole ||= Win32API.new( "kernel32", "AllocConsole", [], 'l' )
89
+
90
+ * Non-string arguments passed to Win32::Console::ANSI#write caused error
91
+ fix by Ivan Evtuhovich (evtuhovich at gmail dot com).
92
+
93
+ === 1.0.8 / 2006-06-05
94
+
95
+ * New features:
96
+ * First public release of win32console gem by Justin Bailey.
97
+
98
+ === 1.0
99
+
100
+ * New features:
101
+ * Added .dup to _printString function to avoid mangling outside
102
+ string references. Removed the other (later) .dup call.
103
+
104
+ * Bugfixes:
105
+ * Turned of some exceptions that were conflicting with using the module
106
+ with pipes or redirections.
107
+
108
+ === 0.8
109
+
110
+ * Enhancements:
111
+ * Added ruby docs, and sample test suite.
112
+
113
+ * Bugfixes:
114
+ * Fixed bugs in reading routines,
115
+
116
+ === 0.5
117
+
118
+ New features:
119
+ * First public release.
data/Manifest.txt ADDED
@@ -0,0 +1,22 @@
1
+ History.txt
2
+ Manifest.txt
3
+ Rakefile
4
+ README.txt
5
+ ext/Console_ext/Console.c
6
+ ext/Console_ext/extconf.rb
7
+ extra/Console.rdoc
8
+ extra/Console_ANSI.rdoc
9
+ lib/win32console.rb
10
+ lib/Win32/Console.rb
11
+ lib/Win32/Console/ANSI.rb
12
+ lib/Win32/Console/api.rb
13
+ lib/Win32/Console/constants.rb
14
+ tasks/gem.rake
15
+ tasks/native.rake
16
+ test/test_cursor.rb
17
+ test/test_mouse.rb
18
+ test/test_readinput.rb
19
+ test/test_readoutput.rb
20
+ test/test_sendevent.rb
21
+ test/test_title.rb
22
+ test/test_write.rb
data/README.txt ADDED
@@ -0,0 +1,63 @@
1
+ = Win32::Console
2
+
3
+ * http://rubyforge.org/projects/winconsole
4
+ * http://github.com/luislavena/win32console
5
+ * http://rdoc.info/projects/luislavena/win32console
6
+
7
+ == DESCRIPTION
8
+
9
+ Win32::Console allows controling the windows command line terminal
10
+ thru an OO-interface. This allows you to query the terminal (find
11
+ its size, characters, attributes, etc). The interface and functionality
12
+ should be identical to Perl's counterpart.
13
+
14
+ A port of Perl's Win32::Console and Win32::Console::ANSI modules.
15
+
16
+ This gem packages Gonzalo Garramuno's Win32::Console project, and includes
17
+ a compiled binary for speed. The Win32::Console project's home can be
18
+ found at:
19
+
20
+ http://rubyforge.org/projects/win32console
21
+
22
+ == FEATURES
23
+
24
+ Win32::Console::ANSI is a class derived from IO that seamlessly
25
+ translates ANSI Esc control character codes into Windows' command.exe
26
+ or cmd.exe equivalents.
27
+
28
+ To ease usage, you can use in combination with term-ansicolor gem and avoid
29
+ writing ANSI codes manually.
30
+
31
+ == EXAMPLES
32
+
33
+ To output a simple bolded string, try this script:
34
+
35
+ require 'rubygems'
36
+ require 'win32console'
37
+ include Win32::Console::ANSI
38
+ include Term::ANSIColor
39
+
40
+ puts bold << "bolded text" << clear << " and no longer bold."
41
+
42
+ == INSTALL
43
+
44
+ gem install win32console
45
+
46
+ == DEVELOPERS:
47
+
48
+ After checking out the source, run:
49
+
50
+ $ rake newb
51
+
52
+ This task will install any missing dependencies, run the tests/specs,
53
+ and generate the RDoc.
54
+
55
+ == LICENSE
56
+
57
+ This program is FREE; you can redistribute, modify, disassemble, or even
58
+ reverse engineer this software at your will. Keep in mind, however, that
59
+ NOTHING IS GUARANTEED to work and everything you do is AT YOUR OWN RISK - I
60
+ will not take responsibility for any damage, loss of money and/or health
61
+ that may arise from the use of this program!
62
+
63
+ This is distributed under the terms of Larry Wall's Artistic License.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ #
2
+ # NOTE: Keep this file clean.
3
+ # Add your customizations inside tasks directory.
4
+ # Thank You.
5
+ #
6
+
7
+ # load rakefile extensions (tasks)
8
+ Dir['tasks/*.rake'].sort.each { |f| load f }
9
+
10
+ =begin
11
+ require 'rubygems'
12
+ require 'rake/clean'
13
+ require 'rake/gempackagetask'
14
+ require 'rake/extensiontask'
15
+
16
+ spec = Gem::Specification.new do |s|
17
+ s.name = 'win32console'
18
+ s.version = '1.2.0'
19
+ s.platform = Gem::Platform::RUBY
20
+ s.has_rdoc = true
21
+ s.extra_rdoc_files = %w[ README.txt README_GEM.txt INSTALL.txt HISTORY.txt HISTORY_GEM.txt ]
22
+ s.summary = 'A library giving the Win32 console ANSI escape sequence support.'
23
+ s.description = s.summary
24
+ s.author = 'Original Library by Gonzalo Garramuno, Gem by Justin Bailey'
25
+ s.email = 'ggarra @nospam@ advancedsl.com.ar, jgbailey @nospan@ gmail.com'
26
+ s.homepage = 'http://rubyforge.org/projects/winconsole'
27
+ s.rubyforge_project = 'http://rubyforge.org/projects/winconsole'
28
+ s.description = <<EOS
29
+ This gem packages Gonzalo Garramuno's Win32::Console project, and includes a compiled binary for speed. The Win32::Console project's home can be found at:
30
+
31
+ http://rubyforge.org/projects/win32console
32
+
33
+ The gem project can be found at
34
+
35
+ http://rubyforge.org/projects/winconsole
36
+ EOS
37
+
38
+ s.require_path = 'lib'
39
+ s.extensions = %w[ ext/Console/extconf.rb ]
40
+ s.files = FileList[ '{doc,ext,lib,test}/**/*.{rdoc,c,cpp,rb}', 'Rakefile', *s.extra_rdoc_files ]
41
+
42
+ s.rdoc_options << '--title' << 'Win32Console Gem -- Gem for Win32::Console Project' <<
43
+ '--main' << 'README_GEM.txt' <<
44
+ '--line-numbers'
45
+ end
46
+
47
+ Rake::GemPackageTask.new(spec) do |pkg|
48
+ pkg.need_tar = true
49
+ pkg.gem_spec = spec
50
+ end
51
+
52
+ Rake::ExtensionTask.new('Console', spec) do |ext|
53
+ end
54
+ =end
@@ -0,0 +1,1216 @@
1
+ #include <windows.h>
2
+ #include "ruby.h"
3
+
4
+ /* Workaround deprecated RString accessors */
5
+ #ifndef RSTRING_PTR
6
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
7
+ #endif
8
+ #ifndef RSTRING_LEN
9
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
10
+ #endif
11
+
12
+ VALUE rb_mWin32;
13
+ VALUE rb_mConsole;
14
+ VALUE rb_mAPI;
15
+ VALUE rb_mConstants;
16
+
17
+ /* old RUBY_METHOD_FUNC() definition doesn't match to prototypes in those days. */
18
+ #ifndef ANYARGS
19
+ #undef RUBY_METHOD_FUNC
20
+ #define RUBY_METHOD_FUNC(func) ((VALUE (*)())func)
21
+ #endif
22
+
23
+
24
+ #define RB_DEF_S_METHOD(klass,method,func,argtype) \
25
+ rb_define_singleton_method(klass,method,RUBY_METHOD_FUNC(func), argtype)
26
+
27
+ #define RB_DEF_API_METHOD(name,argtype) \
28
+ RB_DEF_S_METHOD(rb_mAPI,#name,RUBY_METHOD_FUNC(rb_##name), argtype)
29
+
30
+ #define RB_DEF_METHOD(klass,method,func,argtype) \
31
+ rb_define_method(klass,method,RUBY_METHOD_FUNC(func), argtype)
32
+
33
+ VALUE
34
+ rb_getWin32Error()
35
+ {
36
+ LPVOID lpMsgBuf;
37
+ if (!FormatMessage(
38
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
39
+ FORMAT_MESSAGE_FROM_SYSTEM |
40
+ FORMAT_MESSAGE_IGNORE_INSERTS,
41
+ NULL,
42
+ GetLastError(),
43
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
44
+ (LPTSTR) &lpMsgBuf,
45
+ 0,
46
+ NULL ))
47
+ {
48
+ // Handle the error.
49
+ return Qnil;
50
+ }
51
+
52
+ VALUE t = rb_str_new2( (LPCTSTR) lpMsgBuf );
53
+
54
+ // Free the buffer.
55
+ LocalFree( lpMsgBuf );
56
+
57
+ // Raise exception
58
+ rb_raise(rb_eRuntimeError, RSTRING_PTR(t));
59
+ return Qnil;
60
+
61
+ }
62
+
63
+
64
+ static VALUE rb_GetStdHandle(VALUE self, VALUE handle)
65
+ {
66
+ unsigned long x;
67
+ if ( FIXNUM_P( handle ) )
68
+ {
69
+ x = NUM2ULONG( handle );
70
+ }
71
+ else
72
+ {
73
+ Check_Type( handle, T_BIGNUM );
74
+ x = rb_big2ulong(handle);
75
+ }
76
+ unsigned long h = PtrToUlong( GetStdHandle( x ) );
77
+ return ULONG2NUM(h);
78
+ }
79
+
80
+
81
+ static VALUE rb_AllocConsole(VALUE self)
82
+ {
83
+ if (AllocConsole()) return INT2FIX(1);
84
+ return rb_getWin32Error();
85
+ }
86
+
87
+
88
+ static VALUE rb_FreeConsole(VALUE self)
89
+ {
90
+ if (FreeConsole()) return INT2FIX(1);
91
+ return rb_getWin32Error();
92
+ }
93
+
94
+ static VALUE rb_GenerateConsoleCtrlEvent(VALUE self, VALUE event, VALUE pgid)
95
+ {
96
+ unsigned int e = NUM2UINT(event);
97
+ if ( e != CTRL_C_EVENT && e != CTRL_BREAK_EVENT )
98
+ rb_raise(rb_eArgError, "Wrong event: only CTRL_C_EVENT or "
99
+ "CTRL_BREAK_EVENT accepted.");
100
+ if ( GenerateConsoleCtrlEvent(e, NUM2UINT(pgid)) )
101
+ return INT2FIX(1);
102
+ return rb_getWin32Error();
103
+ }
104
+
105
+ static VALUE rb_GetConsoleMode(VALUE self, VALUE hConsoleOutput)
106
+ {
107
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
108
+ DWORD mode;
109
+ if (GetConsoleMode(handle,&mode))
110
+ return UINT2NUM(mode);
111
+ return rb_getWin32Error();
112
+ }
113
+
114
+ static VALUE rb_GetConsoleTitle(VALUE self)
115
+ {
116
+ char title[1024];
117
+ if (GetConsoleTitle((char*)&title,1024))
118
+ return rb_str_new2( title );
119
+ return rb_getWin32Error();
120
+ }
121
+
122
+
123
+
124
+
125
+ static VALUE rb_GetNumberOfConsoleMouseButtons( VALUE self )
126
+ {
127
+ DWORD mb;
128
+ if (GetNumberOfConsoleMouseButtons( &mb ))
129
+ return INT2FIX(mb);
130
+ return rb_getWin32Error();
131
+ }
132
+
133
+
134
+
135
+ static VALUE rb_GetNumberOfConsoleInputEvents( VALUE self, VALUE hConsoleOutput )
136
+ {
137
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
138
+ DWORD events;
139
+ if (GetNumberOfConsoleInputEvents(handle, &events))
140
+ return INT2FIX(events);
141
+ return rb_getWin32Error();
142
+ }
143
+
144
+
145
+ static VALUE
146
+ rb_CreateConsoleScreenBuffer( VALUE self, VALUE dwDesiredAccess,
147
+ VALUE dwShareMode, VALUE dwFlags )
148
+ {
149
+ if (CreateConsoleScreenBuffer( NUM2UINT(dwDesiredAccess),
150
+ NUM2UINT( dwShareMode),
151
+ NULL,
152
+ NUM2UINT( dwFlags),
153
+ NULL
154
+ ))
155
+ return INT2FIX(1);
156
+ return rb_getWin32Error();
157
+ }
158
+
159
+
160
+ static VALUE rb_GetConsoleCP( VALUE self )
161
+ {
162
+ unsigned int h = GetConsoleCP();
163
+ return UINT2NUM(h);
164
+ }
165
+
166
+ static VALUE rb_GetConsoleOutputCP( VALUE self )
167
+ {
168
+ unsigned int h = GetConsoleOutputCP();
169
+ return UINT2NUM(h);
170
+ }
171
+
172
+ static VALUE rb_SetConsoleMode( VALUE self, VALUE hConsoleOutput,
173
+ VALUE Mode )
174
+ {
175
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
176
+ if ( SetConsoleMode( handle, NUM2UINT( Mode ) ) )
177
+ return INT2FIX(1);
178
+ return rb_getWin32Error();
179
+ }
180
+
181
+ static VALUE rb_SetConsoleCP( VALUE self, VALUE wCodePageID )
182
+ {
183
+ if ( SetConsoleCP( NUM2UINT( wCodePageID ) ) )
184
+ return INT2FIX(1);
185
+ return rb_getWin32Error();
186
+ }
187
+
188
+ static VALUE rb_SetConsoleOutputCP( VALUE self, VALUE wCodePageID )
189
+ {
190
+ if ( SetConsoleOutputCP( NUM2UINT( wCodePageID ) ) )
191
+ return INT2FIX(1);
192
+ return rb_getWin32Error();
193
+ }
194
+
195
+ static VALUE rb_GetConsoleWindow( VALUE self )
196
+ {
197
+ unsigned long h = PtrToUlong( GetConsoleOutputCP() );
198
+ return ULONG2NUM(h);
199
+ }
200
+
201
+ static VALUE rb_WriteConsole( VALUE self, VALUE hConsoleOutput,
202
+ VALUE lpBuffer )
203
+ {
204
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
205
+ DWORD nNumberOfCharsToWrite = RSTRING_LEN(lpBuffer);
206
+
207
+ DWORD lpNumberOfCharsWritten;
208
+
209
+ WriteConsole( handle, RSTRING_PTR(lpBuffer),
210
+ nNumberOfCharsToWrite,
211
+ &lpNumberOfCharsWritten, NULL );
212
+ return UINT2NUM( lpNumberOfCharsWritten );
213
+ }
214
+
215
+ static VALUE rb_WriteFile( VALUE self, VALUE hConsoleOutput,
216
+ VALUE lpBuffer )
217
+ {
218
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
219
+ DWORD nNumberOfBytesToWrite = RSTRING_LEN(lpBuffer);
220
+
221
+ DWORD lpNumberOfBytesWritten;
222
+
223
+ WriteFile( handle, RSTRING_PTR(lpBuffer),
224
+ nNumberOfBytesToWrite,
225
+ &lpNumberOfBytesWritten, NULL );
226
+ return UINT2NUM( lpNumberOfBytesWritten );
227
+ }
228
+
229
+
230
+ static VALUE rb_GetLargestConsoleWindowSize( VALUE self, VALUE hConsoleOutput )
231
+ {
232
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
233
+ COORD size = GetLargestConsoleWindowSize( handle);
234
+
235
+ VALUE ret = rb_ary_new();
236
+ rb_ary_push( ret, UINT2NUM( size.X ) );
237
+ rb_ary_push( ret, UINT2NUM( size.Y ) );
238
+ return ret;
239
+ }
240
+
241
+ static VALUE rb_GetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput )
242
+ {
243
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
244
+
245
+ CONSOLE_CURSOR_INFO out;
246
+ if ( !GetConsoleCursorInfo( handle, &out ) )
247
+ return rb_getWin32Error();
248
+
249
+ VALUE ret = rb_ary_new();
250
+ rb_ary_push( ret, UINT2NUM( out.dwSize ) );
251
+ rb_ary_push( ret, UINT2NUM( out.bVisible ) );
252
+ return ret;
253
+ }
254
+
255
+ void rb_ParseEvent(VALUE ret, INPUT_RECORD *event )
256
+ {
257
+ switch(event->EventType) {
258
+ case KEY_EVENT:
259
+ {
260
+ KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event->Event);
261
+ rb_ary_push(ret, UINT2NUM(KEY_EVENT));
262
+ rb_ary_push(ret, UINT2NUM(kevent->bKeyDown));
263
+ rb_ary_push(ret, UINT2NUM(kevent->wRepeatCount));
264
+ rb_ary_push(ret, UINT2NUM(kevent->wVirtualKeyCode));
265
+ rb_ary_push(ret, UINT2NUM(kevent->wVirtualScanCode));
266
+ #ifdef UNICODE
267
+ rb_ary_push(ret, UINT2NUM(kevent->uChar.UnicodeChar));
268
+ #else
269
+ rb_ary_push(ret, UINT2NUM(kevent->uChar.AsciiChar));
270
+ #endif
271
+ rb_ary_push(ret, UINT2NUM(kevent->dwControlKeyState));
272
+ break;
273
+ }
274
+ case MOUSE_EVENT:
275
+ {
276
+ MOUSE_EVENT_RECORD * mevent=(MOUSE_EVENT_RECORD *)&(event->Event);
277
+ rb_ary_push(ret, UINT2NUM(MOUSE_EVENT) );
278
+ rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.X) );
279
+ rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.Y) );
280
+ rb_ary_push(ret, UINT2NUM(mevent->dwButtonState) );
281
+ rb_ary_push(ret, UINT2NUM(mevent->dwControlKeyState) );
282
+ rb_ary_push(ret, UINT2NUM(mevent->dwEventFlags) );
283
+ break;
284
+ }
285
+ case WINDOW_BUFFER_SIZE_EVENT:
286
+ {
287
+ WINDOW_BUFFER_SIZE_RECORD* wevent=
288
+ (WINDOW_BUFFER_SIZE_RECORD *)&(event->Event);
289
+ rb_ary_push(ret, UINT2NUM(WINDOW_BUFFER_SIZE_EVENT) );
290
+ rb_ary_push(ret, UINT2NUM(wevent->dwSize.X) );
291
+ rb_ary_push(ret, UINT2NUM(wevent->dwSize.Y) );
292
+ }
293
+ break;
294
+ case MENU_EVENT:
295
+ {
296
+ MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event->Event);
297
+ rb_ary_push(ret, UINT2NUM(MENU_EVENT) );
298
+ rb_ary_push(ret, UINT2NUM(mevent->dwCommandId) );
299
+ }
300
+ break;
301
+ case FOCUS_EVENT:
302
+ {
303
+ FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event->Event);
304
+ rb_ary_push(ret, UINT2NUM(FOCUS_EVENT) );
305
+ rb_ary_push(ret, UINT2NUM(mevent->bSetFocus) );
306
+ }
307
+ break;
308
+ }
309
+ }
310
+
311
+ static VALUE rb_PeekConsoleInput( VALUE self, VALUE hConsoleOutput )
312
+ {
313
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
314
+
315
+ DWORD nofread;
316
+ INPUT_RECORD event;
317
+ if (!PeekConsoleInput(handle,&event,1,&nofread))
318
+ return rb_getWin32Error();
319
+
320
+ VALUE ret = rb_ary_new();
321
+ rb_ParseEvent( ret, &event );
322
+ return ret;
323
+ }
324
+
325
+ static VALUE rb_ReadConsole( VALUE self, VALUE hConsoleOutput,
326
+ VALUE buffer, VALUE numread )
327
+ {
328
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
329
+ DWORD nofread;
330
+ Check_Type( buffer, T_STRING );
331
+ int to_read = NUM2INT(numread);
332
+ if ( RSTRING_LEN(buffer) > to_read )
333
+ rb_raise(rb_eArgError, "String is too small to read that many characters.");
334
+ if (ReadConsole(handle,(void *)RSTRING_PTR(buffer), to_read,
335
+ &nofread,NULL))
336
+ return UINT2NUM(nofread);
337
+ return rb_getWin32Error();
338
+ }
339
+
340
+ static VALUE rb_ReadConsoleInput( VALUE self, VALUE hConsoleOutput )
341
+ {
342
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
343
+ DWORD nofread;
344
+ INPUT_RECORD event;
345
+ if (!ReadConsoleInput(handle,&event,1,&nofread))
346
+ return rb_getWin32Error();
347
+
348
+ VALUE ret = rb_ary_new();
349
+ rb_ParseEvent( ret, &event );
350
+ return ret;
351
+ }
352
+
353
+
354
+
355
+ static VALUE rb_ReadConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput,
356
+ VALUE charbuf, VALUE len,
357
+ VALUE x, VALUE y )
358
+ {
359
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
360
+ COORD coords;
361
+ DWORD nofread;
362
+ coords.X= NUM2UINT( x );
363
+ coords.Y= NUM2UINT( y );
364
+ int l = NUM2INT(len);
365
+ if ( (unsigned long)RSTRING_LEN(charbuf) < l*sizeof(TCHAR) )
366
+ rb_raise(rb_eArgError, "String is too small to read that many characters.");
367
+ if (ReadConsoleOutputCharacter(handle,RSTRING_PTR(charbuf),l,
368
+ coords,&nofread))
369
+ return UINT2NUM( nofread );
370
+ return rb_getWin32Error();
371
+ }
372
+
373
+
374
+ static VALUE rb_ReadConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput,
375
+ VALUE len, VALUE x, VALUE y )
376
+ {
377
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
378
+ COORD coords;
379
+ DWORD nofread;
380
+ unsigned short abuffer[80*999*sizeof(unsigned short)];
381
+ char cbuffer[80*999];
382
+ unsigned i = 0;
383
+
384
+ coords.X= NUM2UINT( x );
385
+ coords.Y= NUM2UINT( y );
386
+ if (ReadConsoleOutputAttribute(handle, abuffer, NUM2UINT(len),
387
+ coords,&nofread))
388
+ {
389
+ for(i=0;i<nofread;++i) {
390
+ cbuffer[i]=(char)abuffer[i];
391
+ }
392
+ return rb_str_new( cbuffer, nofread );
393
+ }
394
+ return rb_getWin32Error();
395
+ }
396
+
397
+
398
+ static VALUE rb_ReadConsoleOutput( VALUE self, VALUE hConsoleOutput,
399
+ VALUE buffer, VALUE srcwid, VALUE srcht,
400
+ VALUE startx, VALUE starty,
401
+ VALUE l, VALUE t, VALUE r, VALUE b )
402
+ {
403
+ COORD coords;
404
+ COORD size;
405
+ SMALL_RECT from;
406
+ size.X= NUM2UINT( srcwid );
407
+ size.Y= NUM2UINT( srcht );
408
+ coords.X= NUM2INT( startx );
409
+ coords.Y= NUM2INT( starty );
410
+ from.Left = NUM2INT( l );
411
+ from.Top = NUM2INT( t );
412
+ from.Right = NUM2INT( r );
413
+ from.Bottom = NUM2INT( b );
414
+ Check_Type( buffer, T_STRING );
415
+ if ( (unsigned long)RSTRING_LEN(buffer) < (sizeof(CHAR_INFO)*size.X*size.Y) )
416
+ rb_raise(rb_eArgError, "string buffer is too small for reading that many characters.");
417
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
418
+ if (!ReadConsoleOutput(handle,(CHAR_INFO *)RSTRING_PTR(buffer),size,coords,&from))
419
+ return rb_getWin32Error();
420
+
421
+ VALUE ret = rb_ary_new();
422
+ rb_ary_push( ret, INT2FIX(from.Left) );
423
+ rb_ary_push( ret, INT2FIX(from.Top) );
424
+ rb_ary_push( ret, INT2FIX(from.Right) );
425
+ rb_ary_push( ret, INT2FIX(from.Bottom) );
426
+ return ret;
427
+ }
428
+
429
+
430
+
431
+ static VALUE rb_GetConsoleScreenBufferInfo( VALUE self, VALUE hConsoleOutput )
432
+ {
433
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
434
+
435
+ CONSOLE_SCREEN_BUFFER_INFO out;
436
+
437
+ if ( !GetConsoleScreenBufferInfo( handle, &out ) )
438
+ return rb_getWin32Error();
439
+
440
+ VALUE ret = rb_ary_new();
441
+ rb_ary_push( ret, UINT2NUM( out.dwSize.X ) );
442
+ rb_ary_push( ret, UINT2NUM( out.dwSize.Y ) );
443
+ rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.X ) );
444
+ rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.Y ) );
445
+
446
+ rb_ary_push( ret, UINT2NUM( out.wAttributes ) );
447
+
448
+ rb_ary_push( ret, INT2FIX( out.srWindow.Left ) );
449
+ rb_ary_push( ret, INT2FIX( out.srWindow.Top ) );
450
+ rb_ary_push( ret, INT2FIX( out.srWindow.Right ) );
451
+ rb_ary_push( ret, INT2FIX( out.srWindow.Bottom ) );
452
+
453
+ rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.X ) );
454
+ rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.Y ) );
455
+
456
+
457
+ return ret;
458
+ }
459
+
460
+
461
+ #define strEQ(x,y) strcmp(x,y) == 0
462
+
463
+ DWORD c_constant(char *name)
464
+ {
465
+ switch (*name) {
466
+ case 'A':
467
+ break;
468
+ case 'B':
469
+ if (strEQ(name, "BACKGROUND_BLUE"))
470
+ #ifdef BACKGROUND_BLUE
471
+ return BACKGROUND_BLUE;
472
+ #else
473
+ goto not_there;
474
+ #endif
475
+ if (strEQ(name, "BACKGROUND_GREEN"))
476
+ #ifdef BACKGROUND_GREEN
477
+ return BACKGROUND_GREEN;
478
+ #else
479
+ goto not_there;
480
+ #endif
481
+ if (strEQ(name, "BACKGROUND_INTENSITY"))
482
+ #ifdef BACKGROUND_INTENSITY
483
+ return BACKGROUND_INTENSITY;
484
+ #else
485
+ goto not_there;
486
+ #endif
487
+ if (strEQ(name, "BACKGROUND_RED"))
488
+ #ifdef BACKGROUND_RED
489
+ return BACKGROUND_RED;
490
+ #else
491
+ goto not_there;
492
+ #endif
493
+ break;
494
+ case 'C':
495
+ if (strEQ(name, "CAPSLOCK_ON"))
496
+ #ifdef CAPSLOCK_ON
497
+ return CAPSLOCK_ON;
498
+ #else
499
+ goto not_there;
500
+ #endif
501
+ if (strEQ(name, "CONSOLE_TEXTMODE_BUFFER"))
502
+ #ifdef CONSOLE_TEXTMODE_BUFFER
503
+ return CONSOLE_TEXTMODE_BUFFER;
504
+ #else
505
+ goto not_there;
506
+ #endif
507
+ if (strEQ(name, "CTRL_BREAK_EVENT"))
508
+ #ifdef CTRL_BREAK_EVENT
509
+ return CTRL_BREAK_EVENT;
510
+ #else
511
+ goto not_there;
512
+ #endif
513
+ if (strEQ(name, "CTRL_C_EVENT"))
514
+ #ifdef CTRL_C_EVENT
515
+ return CTRL_C_EVENT;
516
+ #else
517
+ goto not_there;
518
+ #endif
519
+ break;
520
+
521
+ case 'D':
522
+ break;
523
+ case 'E':
524
+ if (strEQ(name, "ENABLE_ECHO_INPUT"))
525
+ #ifdef ENABLE_ECHO_INPUT
526
+ return ENABLE_ECHO_INPUT;
527
+ #else
528
+ goto not_there;
529
+ #endif
530
+ if (strEQ(name, "ENABLE_LINE_INPUT"))
531
+ #ifdef ENABLE_LINE_INPUT
532
+ return ENABLE_LINE_INPUT;
533
+ #else
534
+ goto not_there;
535
+ #endif
536
+ if (strEQ(name, "ENABLE_MOUSE_INPUT"))
537
+ #ifdef ENABLE_MOUSE_INPUT
538
+ return ENABLE_MOUSE_INPUT;
539
+ #else
540
+ goto not_there;
541
+ #endif
542
+ if (strEQ(name, "ENABLE_PROCESSED_INPUT"))
543
+ #ifdef ENABLE_PROCESSED_INPUT
544
+ return ENABLE_PROCESSED_INPUT;
545
+ #else
546
+ goto not_there;
547
+ #endif
548
+ if (strEQ(name, "ENABLE_PROCESSED_OUTPUT"))
549
+ #ifdef ENABLE_PROCESSED_OUTPUT
550
+ return ENABLE_PROCESSED_OUTPUT;
551
+ #else
552
+ goto not_there;
553
+ #endif
554
+ if (strEQ(name, "ENABLE_WINDOW_INPUT"))
555
+ #ifdef ENABLE_WINDOW_INPUT
556
+ return ENABLE_WINDOW_INPUT;
557
+ #else
558
+ goto not_there;
559
+ #endif
560
+ if (strEQ(name, "ENABLE_WRAP_AT_EOL_OUTPUT"))
561
+ #ifdef ENABLE_WRAP_AT_EOL_OUTPUT
562
+ return ENABLE_WRAP_AT_EOL_OUTPUT;
563
+ #else
564
+ goto not_there;
565
+ #endif
566
+ if (strEQ(name, "ENHANCED_KEY"))
567
+ #ifdef ENHANCED_KEY
568
+ return ENHANCED_KEY;
569
+ #else
570
+ goto not_there;
571
+ #endif
572
+ break;
573
+ case 'F':
574
+ if (strEQ(name, "FILE_SHARE_READ"))
575
+ #ifdef FILE_SHARE_READ
576
+ return FILE_SHARE_READ;
577
+ #else
578
+ goto not_there;
579
+ #endif
580
+ if (strEQ(name, "FILE_SHARE_WRITE"))
581
+ #ifdef FILE_SHARE_WRITE
582
+ return FILE_SHARE_WRITE;
583
+ #else
584
+ goto not_there;
585
+ #endif
586
+ if (strEQ(name, "FOREGROUND_BLUE"))
587
+ #ifdef FOREGROUND_BLUE
588
+ return FOREGROUND_BLUE;
589
+ #else
590
+ goto not_there;
591
+ #endif
592
+ if (strEQ(name, "FOREGROUND_GREEN"))
593
+ #ifdef FOREGROUND_GREEN
594
+ return FOREGROUND_GREEN;
595
+ #else
596
+ goto not_there;
597
+ #endif
598
+ if (strEQ(name, "FOREGROUND_INTENSITY"))
599
+ #ifdef FOREGROUND_INTENSITY
600
+ return FOREGROUND_INTENSITY;
601
+ #else
602
+ goto not_there;
603
+ #endif
604
+ if (strEQ(name, "FOREGROUND_RED"))
605
+ #ifdef FOREGROUND_RED
606
+ return FOREGROUND_RED;
607
+ #else
608
+ goto not_there;
609
+ #endif
610
+ break;
611
+ case 'G':
612
+ if (strEQ(name, "GENERIC_READ"))
613
+ #ifdef GENERIC_READ
614
+ return GENERIC_READ;
615
+ #else
616
+ goto not_there;
617
+ #endif
618
+ if (strEQ(name, "GENERIC_WRITE"))
619
+ #ifdef GENERIC_WRITE
620
+ return GENERIC_WRITE;
621
+ #else
622
+ goto not_there;
623
+ #endif
624
+ break;
625
+ case 'H':
626
+ break;
627
+ case 'I':
628
+ break;
629
+ case 'J':
630
+ break;
631
+ case 'K':
632
+ if (strEQ(name, "KEY_EVENT"))
633
+ #ifdef KEY_EVENT
634
+ return KEY_EVENT;
635
+ #else
636
+ goto not_there;
637
+ #endif
638
+ break;
639
+ case 'L':
640
+ if (strEQ(name, "LEFT_ALT_PRESSED"))
641
+ #ifdef LEFT_ALT_PRESSED
642
+ return LEFT_ALT_PRESSED;
643
+ #else
644
+ goto not_there;
645
+ #endif
646
+ if (strEQ(name, "LEFT_CTRL_PRESSED"))
647
+ #ifdef LEFT_CTRL_PRESSED
648
+ return LEFT_CTRL_PRESSED;
649
+ #else
650
+ goto not_there;
651
+ #endif
652
+ break;
653
+ case 'M':
654
+ break;
655
+ case 'N':
656
+ if (strEQ(name, "NUMLOCK_ON"))
657
+ #ifdef NUMLOCK_ON
658
+ return NUMLOCK_ON;
659
+ #else
660
+ goto not_there;
661
+ #endif
662
+ break;
663
+ case 'O':
664
+ break;
665
+ case 'P':
666
+ break;
667
+ case 'Q':
668
+ break;
669
+ case 'R':
670
+ if (strEQ(name, "RIGHT_ALT_PRESSED"))
671
+ #ifdef RIGHT_ALT_PRESSED
672
+ return RIGHT_ALT_PRESSED;
673
+ #else
674
+ goto not_there;
675
+ #endif
676
+ if (strEQ(name, "RIGHT_CTRL_PRESSED"))
677
+ #ifdef RIGHT_CTRL_PRESSED
678
+ return RIGHT_CTRL_PRESSED;
679
+ #else
680
+ goto not_there;
681
+ #endif
682
+ break;
683
+ case 'S':
684
+ if (strEQ(name, "SCROLLLOCK_ON"))
685
+ #ifdef SCROLLLOCK_ON
686
+ return SCROLLLOCK_ON;
687
+ #else
688
+ goto not_there;
689
+ #endif
690
+ if (strEQ(name, "SHIFT_PRESSED"))
691
+ #ifdef SHIFT_PRESSED
692
+ return SHIFT_PRESSED;
693
+ #else
694
+ goto not_there;
695
+ #endif
696
+ if (strEQ(name, "STD_ERROR_HANDLE"))
697
+ #ifdef STD_ERROR_HANDLE
698
+ return STD_ERROR_HANDLE;
699
+ #else
700
+ goto not_there;
701
+ #endif
702
+ if (strEQ(name, "STD_INPUT_HANDLE"))
703
+ #ifdef STD_INPUT_HANDLE
704
+ return STD_INPUT_HANDLE;
705
+ #else
706
+ goto not_there;
707
+ #endif
708
+ if (strEQ(name, "STD_OUTPUT_HANDLE"))
709
+ #ifdef STD_OUTPUT_HANDLE
710
+ return STD_OUTPUT_HANDLE;
711
+ #else
712
+ goto not_there;
713
+ #endif
714
+ break;
715
+ case 'T':
716
+ break;
717
+ case 'U':
718
+ break;
719
+ case 'V':
720
+ break;
721
+ case 'W':
722
+ break;
723
+ case 'X':
724
+ break;
725
+ case 'Y':
726
+ break;
727
+ case 'Z':
728
+ break;
729
+ }
730
+ rb_raise(rb_eArgError, "Not such constant.");
731
+ return 0;
732
+
733
+ not_there:
734
+ rb_raise(rb_eArgError, "Not defined.");
735
+ return 0;
736
+ }
737
+
738
+ VALUE rb_constant( VALUE self, VALUE name )
739
+ {
740
+ Check_Type( name, T_STRING );
741
+ return ULONG2NUM( c_constant( RSTRING_PTR(name) ) );
742
+ }
743
+
744
+
745
+ void define_constants()
746
+ {
747
+ #define DEF_SELF_CONST(NAME) \
748
+ rb_define_const(rb_mConstants, #NAME, ULONG2NUM( (ULONG)NAME ) );
749
+
750
+ DEF_SELF_CONST( STD_INPUT_HANDLE );
751
+ DEF_SELF_CONST( STD_OUTPUT_HANDLE );
752
+ DEF_SELF_CONST( STD_ERROR_HANDLE );
753
+ DEF_SELF_CONST( INVALID_HANDLE_VALUE );
754
+ DEF_SELF_CONST( GENERIC_READ );
755
+ DEF_SELF_CONST( GENERIC_WRITE );
756
+ DEF_SELF_CONST( FILE_SHARE_READ );
757
+ DEF_SELF_CONST( FILE_SHARE_WRITE );
758
+ DEF_SELF_CONST( CONSOLE_TEXTMODE_BUFFER );
759
+
760
+ DEF_SELF_CONST( FOREGROUND_BLUE );
761
+ DEF_SELF_CONST( FOREGROUND_GREEN );
762
+ DEF_SELF_CONST( FOREGROUND_RED );
763
+ DEF_SELF_CONST( FOREGROUND_INTENSITY );
764
+ DEF_SELF_CONST( BACKGROUND_BLUE );
765
+ DEF_SELF_CONST( BACKGROUND_GREEN );
766
+ DEF_SELF_CONST( BACKGROUND_RED );
767
+ DEF_SELF_CONST( BACKGROUND_INTENSITY );
768
+
769
+ DEF_SELF_CONST( ENABLE_PROCESSED_INPUT );
770
+ DEF_SELF_CONST( ENABLE_LINE_INPUT );
771
+ DEF_SELF_CONST( ENABLE_ECHO_INPUT );
772
+ DEF_SELF_CONST( ENABLE_WINDOW_INPUT );
773
+ DEF_SELF_CONST( ENABLE_MOUSE_INPUT );
774
+ DEF_SELF_CONST( ENABLE_PROCESSED_OUTPUT );
775
+ DEF_SELF_CONST( ENABLE_WRAP_AT_EOL_OUTPUT );
776
+
777
+ DEF_SELF_CONST( KEY_EVENT );
778
+ DEF_SELF_CONST( MOUSE_EVENT );
779
+ DEF_SELF_CONST( WINDOW_BUFFER_SIZE_EVENT );
780
+ DEF_SELF_CONST( MENU_EVENT );
781
+ DEF_SELF_CONST( FOCUS_EVENT );
782
+
783
+ DEF_SELF_CONST( CAPSLOCK_ON );
784
+ DEF_SELF_CONST( ENHANCED_KEY );
785
+ DEF_SELF_CONST( NUMLOCK_ON );
786
+ DEF_SELF_CONST( SHIFT_PRESSED );
787
+ DEF_SELF_CONST( LEFT_CTRL_PRESSED );
788
+ DEF_SELF_CONST( RIGHT_CTRL_PRESSED );
789
+ DEF_SELF_CONST( LEFT_ALT_PRESSED );
790
+ DEF_SELF_CONST( RIGHT_ALT_PRESSED );
791
+ DEF_SELF_CONST( SCROLLLOCK_ON );
792
+
793
+ DEF_SELF_CONST( MOUSE_WHEELED );
794
+ DEF_SELF_CONST( DOUBLE_CLICK );
795
+ DEF_SELF_CONST( MOUSE_MOVED );
796
+
797
+ DEF_SELF_CONST( FROM_LEFT_1ST_BUTTON_PRESSED );
798
+ DEF_SELF_CONST( FROM_LEFT_2ND_BUTTON_PRESSED );
799
+ DEF_SELF_CONST( FROM_LEFT_3RD_BUTTON_PRESSED );
800
+ DEF_SELF_CONST( FROM_LEFT_4TH_BUTTON_PRESSED );
801
+ DEF_SELF_CONST( RIGHTMOST_BUTTON_PRESSED );
802
+
803
+ DEF_SELF_CONST( CTRL_C_EVENT );
804
+ DEF_SELF_CONST( CTRL_BREAK_EVENT );
805
+ DEF_SELF_CONST( CTRL_CLOSE_EVENT );
806
+ DEF_SELF_CONST( CTRL_LOGOFF_EVENT );
807
+ DEF_SELF_CONST( CTRL_SHUTDOWN_EVENT );
808
+ }
809
+
810
+
811
+ VALUE
812
+ rb_FillConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput,
813
+ VALUE wAttribute, VALUE nLength,
814
+ VALUE col, VALUE row )
815
+ {
816
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
817
+
818
+ COORD dwWriteCoord;
819
+ dwWriteCoord.X = NUM2UINT(col);
820
+ dwWriteCoord.Y = NUM2UINT(row);
821
+ DWORD numChars;
822
+ if (FillConsoleOutputAttribute( handle, NUM2UINT(wAttribute),
823
+ NUM2ULONG(nLength), dwWriteCoord,
824
+ &numChars ))
825
+ return ULONG2NUM(numChars);
826
+ return rb_getWin32Error();
827
+ }
828
+
829
+ VALUE
830
+ rb_SetConsoleScreenBufferSize( VALUE self, VALUE hConsoleOutput,
831
+ VALUE x, VALUE y )
832
+ {
833
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
834
+ COORD size;
835
+ size.X=NUM2UINT(x);
836
+ size.Y=NUM2UINT(y);
837
+ if (SetConsoleScreenBufferSize(handle, size))
838
+ return NUM2UINT(1);
839
+ return rb_getWin32Error();
840
+ }
841
+
842
+ VALUE
843
+ rb_SetConsoleTitle( VALUE self, VALUE title )
844
+ {
845
+ Check_Type( title, T_STRING );
846
+ if (SetConsoleTitle(RSTRING_PTR( title )))
847
+ return NUM2UINT(1);
848
+ return rb_getWin32Error();
849
+ }
850
+
851
+ VALUE
852
+ rb_SetStdHandle( VALUE self, VALUE fd, VALUE hConsoleOutput )
853
+ {
854
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
855
+ if (SetStdHandle(NUM2UINT(fd), handle))
856
+ return NUM2UINT(1);
857
+ return rb_getWin32Error();
858
+ }
859
+
860
+ VALUE
861
+ rb_SetConsoleWindowInfo( VALUE self, VALUE hConsoleOutput, VALUE bAbsolute,
862
+ VALUE left, VALUE top, VALUE right, VALUE bottom )
863
+ {
864
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
865
+
866
+ SMALL_RECT rect;
867
+ rect.Left = NUM2INT( left );
868
+ rect.Top = NUM2INT( top );
869
+ rect.Right = NUM2INT( right );
870
+ rect.Bottom = NUM2INT( bottom );
871
+ if (SetConsoleWindowInfo( handle, NUM2INT( bAbsolute ), &rect ))
872
+ return UINT2NUM(1);
873
+ return rb_getWin32Error();
874
+ }
875
+
876
+
877
+
878
+ VALUE
879
+ rb_SetConsoleCursorPosition( VALUE self, VALUE hConsoleOutput,
880
+ VALUE col, VALUE row )
881
+ {
882
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
883
+
884
+ COORD dwWriteCoord;
885
+ dwWriteCoord.X = NUM2UINT(col);
886
+ dwWriteCoord.Y = NUM2UINT(row);
887
+ // Cannot call rb_getWin32Error as this function fails when
888
+ // setting cursor to last column/row.
889
+ if ( !SetConsoleCursorPosition( handle, dwWriteCoord ) )
890
+ return Qnil;
891
+ return INT2FIX(1);
892
+ }
893
+
894
+ VALUE
895
+ rb_SetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput,
896
+ VALUE size, VALUE visib )
897
+ {
898
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
899
+ CONSOLE_CURSOR_INFO c;
900
+ c.dwSize = NUM2UINT(size);
901
+ c.bVisible = NUM2UINT(visib);
902
+ if ( !SetConsoleCursorInfo( handle, &c ) )
903
+ return rb_getWin32Error();
904
+ return INT2FIX(1);
905
+ }
906
+
907
+
908
+
909
+ VALUE
910
+ rb_SetConsoleActiveScreenBuffer( VALUE self, VALUE hConsoleOutput )
911
+ {
912
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
913
+
914
+ if ( !SetConsoleActiveScreenBuffer( handle ) )
915
+ return rb_getWin32Error();
916
+ return INT2FIX(1);
917
+ }
918
+
919
+ VALUE
920
+ rb_SetConsoleTextAttribute( VALUE self, VALUE hConsoleOutput,
921
+ VALUE wAttributes )
922
+ {
923
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
924
+
925
+ if ( !SetConsoleTextAttribute( handle, NUM2UINT(wAttributes) ) )
926
+ return Qnil; // no getWin32Error to allow piping/redirecting
927
+ return INT2FIX(1);
928
+ }
929
+
930
+
931
+
932
+ VALUE
933
+ rb_ScrollConsoleScreenBuffer( VALUE self, VALUE hConsoleOutput, VALUE left1,
934
+ VALUE top1, VALUE right1, VALUE bottom1,
935
+ VALUE col, VALUE row, VALUE cChar, VALUE attr,
936
+ VALUE left2, VALUE top2, VALUE right2,
937
+ VALUE bottom2)
938
+ {
939
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
940
+
941
+ SMALL_RECT scroll, clip;
942
+ scroll.Left = NUM2INT( left1 );
943
+ scroll.Right = NUM2INT( right1 );
944
+ scroll.Top = NUM2INT( top1 );
945
+ scroll.Bottom = NUM2INT( bottom1 );
946
+ clip.Left = NUM2INT( left2 );
947
+ clip.Right = NUM2INT( right2 );
948
+ clip.Top = NUM2INT( top2 );
949
+ clip.Bottom = NUM2INT( bottom2 );
950
+ CHAR_INFO fill;
951
+ #ifdef UNICODE
952
+ fill.Char.UnicodeChar = NUM2CHR( cChar );
953
+ #else
954
+ fill.Char.AsciiChar = NUM2CHR( cChar );
955
+ #endif
956
+ fill.Attributes = NUM2INT(attr);
957
+ COORD origin;
958
+ origin.X = NUM2UINT( col );
959
+ origin.Y = NUM2UINT( row );
960
+
961
+ if ( ScrollConsoleScreenBuffer( handle, &scroll, &clip, origin,
962
+ &fill ) )
963
+ return INT2FIX(1);
964
+ return rb_getWin32Error();
965
+ }
966
+
967
+
968
+ VALUE
969
+ rb_FillConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput,
970
+ VALUE cCharacter, VALUE nLength,
971
+ VALUE col, VALUE row )
972
+ {
973
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
974
+
975
+ COORD dwWriteCoord;
976
+ dwWriteCoord.X = NUM2UINT(col);
977
+ dwWriteCoord.Y = NUM2UINT(row);
978
+ DWORD numChars;
979
+ if (FillConsoleOutputCharacter( handle, NUM2CHR(cCharacter),
980
+ NUM2ULONG(nLength), dwWriteCoord,
981
+ &numChars ))
982
+ return ULONG2NUM(numChars);
983
+ return rb_getWin32Error();
984
+ }
985
+
986
+
987
+ VALUE
988
+ rb_WriteConsoleInput(int argc, VALUE *argv, VALUE self)
989
+ {
990
+ if (argc < 3)
991
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
992
+
993
+ HANDLE handle = ULongToPtr( NUM2ULONG( argv[0] ) );
994
+ WORD type = NUM2INT( argv[1] );
995
+ DWORD written;
996
+ INPUT_RECORD event;
997
+ event.EventType = type;
998
+ switch(event.EventType) {
999
+ case KEY_EVENT:
1000
+ {
1001
+ KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event.Event);
1002
+ kevent->bKeyDown=(BOOL)NUM2UINT( argv[2] );
1003
+ kevent->wRepeatCount=NUM2UINT( argv[3] );
1004
+ kevent->wVirtualKeyCode=NUM2UINT( argv[4] );
1005
+ kevent->wVirtualScanCode=NUM2UINT( argv[5] );
1006
+ #ifdef UNICODE
1007
+ if (argc < 7)
1008
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1009
+ kevent->uChar.UnicodeChar=NUM2UINT( argv[6] );
1010
+ #else
1011
+ if (argc < 8)
1012
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1013
+ kevent->uChar.AsciiChar=NUM2UINT( argv[7] );
1014
+ #endif
1015
+ break;
1016
+ }
1017
+ case MOUSE_EVENT:
1018
+ {
1019
+ if (argc < 7)
1020
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1021
+
1022
+ MOUSE_EVENT_RECORD* mevent=(MOUSE_EVENT_RECORD *)&(event.Event);
1023
+ mevent->dwMousePosition.X=NUM2UINT( argv[2] );
1024
+ mevent->dwMousePosition.Y=NUM2UINT( argv[3] );
1025
+ mevent->dwButtonState=NUM2UINT( argv[4] );
1026
+ mevent->dwControlKeyState=NUM2UINT( argv[5] );
1027
+ mevent->dwEventFlags=NUM2UINT( argv[6] );
1028
+ break;
1029
+ }
1030
+ case WINDOW_BUFFER_SIZE_EVENT:
1031
+ {
1032
+ if (argc < 4)
1033
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1034
+ WINDOW_BUFFER_SIZE_RECORD* mevent=
1035
+ (WINDOW_BUFFER_SIZE_RECORD *)&(event.Event);
1036
+ mevent->dwSize.X = NUM2UINT( argv[2] );
1037
+ mevent->dwSize.Y = NUM2UINT( argv[3] );
1038
+ }
1039
+ break;
1040
+ case MENU_EVENT:
1041
+ {
1042
+ if (argc < 3)
1043
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1044
+ MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event.Event);
1045
+ mevent->dwCommandId = argv[2];
1046
+ }
1047
+ break;
1048
+ case FOCUS_EVENT:
1049
+ {
1050
+ if (argc < 3)
1051
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1052
+ FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event.Event);
1053
+ mevent->bSetFocus = NUM2UINT( argv[2] );
1054
+ }
1055
+ default:
1056
+ rb_raise( rb_eArgError, "Unknown type of event.");
1057
+ break;
1058
+ }
1059
+ if (WriteConsoleInput(handle,&event,1,&written))
1060
+ return INT2FIX(1);
1061
+ return rb_getWin32Error();
1062
+ }
1063
+
1064
+ VALUE
1065
+ rb_WriteConsoleOutput(VALUE self, VALUE h, VALUE buffer,
1066
+ VALUE srcwid, VALUE srcht, VALUE startx,
1067
+ VALUE starty, VALUE l, VALUE t, VALUE r, VALUE b)
1068
+ {
1069
+ COORD coords;
1070
+ COORD size;
1071
+ SMALL_RECT to;
1072
+
1073
+ HANDLE handle = ULongToPtr( NUM2ULONG( h ) );
1074
+ Check_Type( buffer, T_STRING );
1075
+ size.X=NUM2UINT( srcwid );
1076
+ size.Y=NUM2UINT( srcht );
1077
+ coords.X=NUM2INT( startx );
1078
+ coords.Y=NUM2INT( starty );
1079
+ to.Left = NUM2INT( l );
1080
+ to.Top = NUM2INT( t );
1081
+ to.Right = NUM2INT( r );
1082
+ to.Bottom = NUM2INT( b );
1083
+ if (WriteConsoleOutput(handle,(CHAR_INFO *)RSTRING_PTR(buffer),
1084
+ size,coords,&to)) {
1085
+ VALUE ret = rb_ary_new();
1086
+ rb_ary_push( ret, INT2FIX( to.Left ) );
1087
+ rb_ary_push( ret, INT2FIX( to.Top ) );
1088
+ rb_ary_push( ret, INT2FIX( to.Right ) );
1089
+ rb_ary_push( ret, INT2FIX( to.Bottom ) );
1090
+ return ret;
1091
+ }
1092
+ return rb_getWin32Error();
1093
+ }
1094
+
1095
+
1096
+ VALUE
1097
+ rb_WriteConsoleOutputAttribute(VALUE self, VALUE h, VALUE s,
1098
+ VALUE x, VALUE y)
1099
+ {
1100
+
1101
+ HANDLE handle = ULongToPtr( NUM2ULONG( h ) );
1102
+ Check_Type( s, T_STRING );
1103
+
1104
+ unsigned short buffer[80*999*sizeof(unsigned short)];
1105
+ DWORD written;
1106
+ DWORD towrite = RSTRING_LEN(s);
1107
+ unsigned i = 0;
1108
+
1109
+ for(i=0; i<towrite; i++) {
1110
+ buffer[i] = (unsigned short)(RSTRING_PTR(s)[i]);
1111
+ }
1112
+ COORD coords;
1113
+ coords.X=NUM2INT( x );
1114
+ coords.Y=NUM2INT( y );
1115
+ if (WriteConsoleOutputAttribute(handle,(const unsigned short *)&buffer,
1116
+ towrite,coords,&written)) {
1117
+ return UINT2NUM( written );
1118
+ }
1119
+ return rb_getWin32Error();
1120
+ }
1121
+
1122
+
1123
+ VALUE
1124
+ rb_WriteConsoleOutputCharacter(VALUE self, VALUE h, VALUE s,
1125
+ VALUE x, VALUE y)
1126
+ {
1127
+
1128
+ HANDLE handle = ULongToPtr( NUM2ULONG( h ) );
1129
+ Check_Type( s, T_STRING );
1130
+
1131
+ DWORD written;
1132
+ COORD coords;
1133
+ coords.X=NUM2INT( x );
1134
+ coords.Y=NUM2INT( y );
1135
+ if (WriteConsoleOutputCharacter(handle,(LPCTSTR)RSTRING_PTR(s),
1136
+ RSTRING_LEN(s),coords,&written)) {
1137
+ return UINT2NUM( written );
1138
+ }
1139
+ return rb_getWin32Error();
1140
+ }
1141
+
1142
+
1143
+ void Init_Console_ext(void)
1144
+ {
1145
+ rb_mWin32 = rb_define_module("Win32");
1146
+ rb_define_const(rb_mKernel, "Win32", rb_mWin32);
1147
+
1148
+ rb_mConsole = rb_define_class_under(rb_mWin32, "Console", rb_cObject);
1149
+
1150
+ // Handle Constants
1151
+ rb_mConstants = rb_define_module_under(rb_mConsole,"Constants");
1152
+ define_constants();
1153
+
1154
+ // Handle API
1155
+ rb_mAPI = rb_define_class_under(rb_mConsole, "API", rb_cObject);
1156
+
1157
+ RB_DEF_API_METHOD(constant, 1); //OK
1158
+
1159
+ RB_DEF_API_METHOD(AllocConsole, 0);
1160
+
1161
+ RB_DEF_API_METHOD(CreateConsoleScreenBuffer, 3); //OK
1162
+
1163
+ RB_DEF_API_METHOD(FillConsoleOutputAttribute, 5); //OK
1164
+ RB_DEF_API_METHOD(FillConsoleOutputCharacter, 5); //OK
1165
+ // RB_DEF_API_METHOD(FillConsoleInputBuffer, 1); // Does not exist anymore
1166
+
1167
+ RB_DEF_API_METHOD(FreeConsole, 0);
1168
+
1169
+ RB_DEF_API_METHOD(GenerateConsoleCtrlEvent, 2);
1170
+
1171
+ RB_DEF_API_METHOD(GetConsoleCP, 0); //OK
1172
+ RB_DEF_API_METHOD(GetConsoleCursorInfo, 1); //OK
1173
+ RB_DEF_API_METHOD(GetConsoleMode, 1);
1174
+ RB_DEF_API_METHOD(GetConsoleOutputCP, 0);
1175
+ RB_DEF_API_METHOD(GetConsoleScreenBufferInfo, 1); //OK
1176
+ RB_DEF_API_METHOD(GetConsoleTitle, 0);
1177
+ RB_DEF_API_METHOD(GetConsoleWindow, 0);
1178
+ RB_DEF_API_METHOD(GetLargestConsoleWindowSize, 1);
1179
+ RB_DEF_API_METHOD(GetNumberOfConsoleInputEvents, 1);
1180
+ RB_DEF_API_METHOD(GetNumberOfConsoleMouseButtons, 0);
1181
+
1182
+ RB_DEF_API_METHOD(GetStdHandle, 1); //OK
1183
+
1184
+ RB_DEF_API_METHOD(PeekConsoleInput, 1); //OK
1185
+ RB_DEF_API_METHOD(ReadConsole, 3); //OK
1186
+ RB_DEF_API_METHOD(ReadConsoleInput, 1); //OK
1187
+
1188
+ RB_DEF_API_METHOD(ReadConsoleOutput, 10); // OK
1189
+ RB_DEF_API_METHOD(ReadConsoleOutputAttribute, 4); // OK
1190
+ RB_DEF_API_METHOD(ReadConsoleOutputCharacter, 5); // OK
1191
+
1192
+
1193
+ RB_DEF_API_METHOD(ScrollConsoleScreenBuffer, 13); //OK
1194
+
1195
+ RB_DEF_API_METHOD(SetConsoleActiveScreenBuffer, 1);
1196
+ RB_DEF_API_METHOD(SetConsoleCP, 1);
1197
+ RB_DEF_API_METHOD(SetConsoleCursorPosition, 3);
1198
+ RB_DEF_API_METHOD(SetConsoleCursorInfo, 3);
1199
+ RB_DEF_API_METHOD(SetConsoleMode, 2); //OK
1200
+ RB_DEF_API_METHOD(SetConsoleOutputCP, 1);
1201
+ RB_DEF_API_METHOD(SetConsoleScreenBufferSize, 3);
1202
+ RB_DEF_API_METHOD(SetConsoleTextAttribute, 2);
1203
+ RB_DEF_API_METHOD(SetConsoleTitle, 1); //OK
1204
+ RB_DEF_API_METHOD(SetConsoleWindowInfo, 6);
1205
+
1206
+ RB_DEF_API_METHOD(SetStdHandle, 2);
1207
+
1208
+ RB_DEF_API_METHOD(WriteConsole, 2);
1209
+ RB_DEF_API_METHOD(WriteFile, 2);
1210
+
1211
+ RB_DEF_API_METHOD(WriteConsoleInput, -1);
1212
+ RB_DEF_API_METHOD(WriteConsoleOutput, 10);
1213
+ RB_DEF_API_METHOD(WriteConsoleOutputAttribute, 4);
1214
+ RB_DEF_API_METHOD(WriteConsoleOutputCharacter, 4);
1215
+
1216
+ }