win32console 1.2.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,302 @@
1
+ #
2
+ # = NAME
3
+ #
4
+ # Win32::Console::ANSI - Ruby extension to emulate ANSI console on Win32 system.
5
+ #
6
+ # = SYNOPSIS
7
+ #
8
+ # require "Win32::Console::ANSI"
9
+ #
10
+ # puts "\e[1;34mThis text is bold blue.\e[0m"
11
+ # puts "This text is normal.""
12
+ # puts "\e[33;45;1mBold yellow on magenta.\e[0m"
13
+ # puts "This text is normal."
14
+ #
15
+ # With the Term::ANSIColor module one increases the readability:
16
+ #
17
+ # require "Win32::Console::ANSI"
18
+ # require "Term::ANSIColor"
19
+ #
20
+ # puts color 'bold blue'
21
+ # puts "This text is bold blue."
22
+ # puts color 'reset'
23
+ # puts "This text is normal."
24
+ # puts colored ("Bold yellow on magenta.", 'bold yellow on_magenta')
25
+ # puts "This text is normal."
26
+ #
27
+ # And even more with Term::ANSIScreen:
28
+ #
29
+ # require "Win32::Console::ANSI;
30
+ # require "Term::ANSIScreen qw/:color :cursor :screen/;
31
+ #
32
+ # locate 1, 1; puts "@ This is (1,1)", savepos;
33
+ # puts locate(24,60), "@ This is (24,60)"; loadpos;
34
+ # puts down(2), clline, "@ This is (3,16)";
35
+ # setscroll 1, 20;
36
+ # color 'black on white'; clline;
37
+ # puts "This line is black on white.";
38
+ # puts color 'reset'; puts "This text is normal.";
39
+ # puts colored ("This text is bold blue.", 'bold blue');
40
+ # puts "This text is normal.";
41
+ # puts colored ['bold blue'], "This text is bold blue.";
42
+ # puts "This text is normal.";
43
+ #
44
+ # = DESCRIPTION
45
+ #
46
+ # Windows NT/2000/XP does not support ANSI escape sequences in Win32 Console
47
+ # applications. This module emulates an ANSI console for the script which
48
+ # uses it.
49
+ #
50
+ #
51
+ # == Escape sequences for Cursor Movement
52
+ #
53
+ # * \e[#A
54
+ #
55
+ # CUU: CUrsor Up: Moves the cursor up by the specified number of lines without
56
+ # changing columns. If the cursor is already on the top line, this sequence
57
+ # is ignored. \e[A is equivalent to \e[1A.
58
+ #
59
+ # * \e[#B
60
+ #
61
+ # CUD: CUrsor Down: Moves the cursor down by the specified number of lines
62
+ # without changing columns. If the cursor is already on the bottom line,
63
+ # this sequence is ignored. \e[B is equivalent to \e[1B.
64
+ #
65
+ # * \e[#C
66
+ #
67
+ # CUF: CUrsor Forward: Moves the cursor forward by the specified number of
68
+ # columns without changing lines. If the cursor is already in the
69
+ # rightmost column, this sequence is ignored. \e[C is equivalent to \e[1C.
70
+ #
71
+ # * \e[#D
72
+ #
73
+ # CUB: CUrsor Backward: Moves the cursor back by the specified number of
74
+ # columns without changing lines. If the cursor is already in the leftmost
75
+ # column, this sequence is ignored. \e[D is equivalent to \e[1D.
76
+ #
77
+ # * \e[#E
78
+ #
79
+ # CNL: Cursor Next Line: Moves the cursor down the indicated # of rows, to
80
+ # column 1. \e[E is equivalent to \e[1E.
81
+ #
82
+ # * \e[#F
83
+ #
84
+ # CPL: Cursor Preceding Line: Moves the cursor up the indicated # of rows,
85
+ # to column 1. \e[F is equivalent to \e[1F.
86
+ #
87
+ # * \e[#G
88
+ #
89
+ # CHA: Cursor Horizontal Absolute: Moves the cursor to indicated column in
90
+ # current row. \e[G is equivalent to \e[1G.
91
+ #
92
+ # * \e[#;#H
93
+ #
94
+ # CUP: CUrsor Position: Moves the cursor to the specified position. The first #
95
+ # specifies the line number, the second # specifies the column.
96
+ # If you do not specify a position, the cursor moves to the
97
+ # home position: the upper-left corner of the screen (line 1, column 1).
98
+ #
99
+ # * \e[#;#f
100
+ #
101
+ # HVP: Horizontal and Vertical Position.
102
+ # Works the same way as the preceding escape sequence.
103
+ #
104
+ # * \e[s
105
+ #
106
+ # SCP: Save Cursor Position: Saves the current cursor position. You can move
107
+ # the cursor to the saved cursor position by using the Restore Cursor
108
+ # Position sequence.
109
+ #
110
+ # * \e[u
111
+ #
112
+ # RCP: Restore Cursor Position: Returns the cursor to the position stored
113
+ # by the Save Cursor Position sequence.
114
+ #
115
+ # == Escape sequences for Display Edition
116
+ #
117
+ # * \e[#J
118
+ #
119
+ # ED: Erase Display:
120
+ #
121
+ # * \e[0J
122
+ #
123
+ # Clears the screen from cursor to end of display. The cursor position is unchanged.
124
+ #
125
+ # * \e[1J
126
+ #
127
+ # Clears the screen from start to cursor. The cursor position is unchanged.
128
+ #
129
+ # * \e[2J
130
+ #
131
+ # Clears the screen and moves the cursor to the home position (line 1, column 1).
132
+ #
133
+ # \e[J is equivalent to \e[0J. (Some terminal/emulators respond to \e[J as if
134
+ # it were \e[2J. Here, the default is 0; it's the norm)
135
+ #
136
+ # * \e[#K
137
+ #
138
+ # EL: Erase Line:
139
+ #
140
+ # * \e[0K
141
+ #
142
+ # Clears all characters from the cursor position to the end of the line
143
+ # (including the character at the cursor position).
144
+ # The cursor position is unchanged.
145
+ #
146
+ # * \e[1K
147
+ #
148
+ # Clears all characters from start of line to the cursor position.
149
+ # (including the character at the cursor position).
150
+ # The cursor position is unchanged.
151
+ #
152
+ # * \e[2K
153
+ #
154
+ # Clears all characters of the whole line.
155
+ # The cursor position is unchanged.
156
+ #
157
+ # \e[K is equivalent to \e[0K.
158
+ #
159
+ # * \e[#L
160
+ #
161
+ # IL: Insert Lines: The cursor line and all lines below it move down # lines,
162
+ # leaving blank space. The cursor position is unchanged. The bottommost #
163
+ # lines are lost. \e[L is equivalent to \e[1L.
164
+ #
165
+ # * \e[#M
166
+ #
167
+ # DL: Delete Line: The block of # lines at and below the cursor are deleted;
168
+ # all lines below them move up # lines to fill in the gap, leaving # blank
169
+ # lines at the bottom of the screen. The cursor position is unchanged.
170
+ # \e[M is equivalent to \e[1M.
171
+ #
172
+ # * \e#\@
173
+ #
174
+ # ICH: Insert CHaracter: The cursor character and all characters to the right
175
+ # of it move right # columns, leaving behind blank space.
176
+ # The cursor position is unchanged. The rightmost # characters on the line are lost.
177
+ #
178
+ # * \e[#P
179
+ #
180
+ # DCH: Delete CHaracter: The block of # characters at and to the right of the
181
+ # cursor are deleted; all characters to the right of it move left # columns,
182
+ # leaving behind blank space. The cursor position is unchanged.
183
+ # \e[P is equivalent to \e[1P.
184
+ #
185
+ #
186
+ # == Escape sequences for Set Graphics Rendition
187
+ #
188
+ # * \e[#;...;#m
189
+ #
190
+ # SGM: Set Graphics Mode: Calls the graphics functions specified by the
191
+ # following values. These specified functions remain active until the next
192
+ # occurrence of this escape sequence. Graphics mode changes the colors and
193
+ # attributes of text (such as bold and underline) displayed on the
194
+ # screen.
195
+ #
196
+ # * Text attributes
197
+ #
198
+ # 0 All attributes off
199
+ # 1 Bold on
200
+ # 4 Underscore on
201
+ # 7 Reverse video on
202
+ # 8 Concealed on
203
+ #
204
+ # 21 Bold off
205
+ # 24 Underscore off
206
+ # 27 Reverse video off
207
+ # 28 Concealed off
208
+ #
209
+ # * Foreground colors
210
+ #
211
+ # 30 Black
212
+ # 31 Red
213
+ # 32 Green
214
+ # 33 Yellow
215
+ # 34 Blue
216
+ # 35 Magenta
217
+ # 36 Cyan
218
+ # 37 White
219
+ #
220
+ # * Background colors
221
+ #
222
+ # 40 Black
223
+ # 41 Red
224
+ # 42 Green
225
+ # 43 Yellow
226
+ # 44 Blue
227
+ # 45 Magenta
228
+ # 46 Cyan
229
+ # 47 White
230
+ #
231
+ # \e[m is equivalent to \e0m.
232
+ #
233
+ # == Escape sequences for Select Character Set
234
+ #
235
+ # * \e(U
236
+ #
237
+ # Select null mapping - straight to character from the codepage of the console.
238
+ #
239
+ # * \e(K
240
+ #
241
+ # Select Windows to DOS mapping, if the corresponding map exist; no effect
242
+ # otherwise. This is the default mapping (if the map exist, of course). It's
243
+ # useful becarequire "one types the script with a Windows-based editor (using a
244
+ # Windows codepage) and the script prints its messages on the console using
245
+ # another codepage: without translation, the characters with a code greatest
246
+ # than 127 are different and the printed messages may be not readable.
247
+ #
248
+ # The conversion is done by the module Encode if it is installed (it's a
249
+ # standard module with Perl5.8, not Ruby yet). Otherwise, the conversion is limited to the
250
+ # following couples:
251
+ #
252
+ # WinLatin1 (cp1252) to DOSLatin1 (cp850)
253
+ # WinLatin1 (cp1252) to DOSLatinUS (cp437)
254
+ # WinLatin2 (cp1250) to DOSLatin2 (cp852)
255
+ # WinCyrillic(cp1251) to DOSCyrillic (cp855)
256
+ #
257
+ # * \e(#X
258
+ #
259
+ # This escape sequence is I<not> standard! It's an experimental one, just for
260
+ # fun :-)
261
+ #
262
+ # If <i>and only if</i> the console uses an Unicode police, it is possible to
263
+ # change its codepage with this escape sequence. No effect with an ordinary
264
+ # "Raster Font". (For Windows NT/2000/XP the currently available Unicode
265
+ # console font is the Lucida Console TrueType font.)
266
+ # # is the number of the codepage needed, 855 for cp855 for instance.
267
+ #
268
+ #
269
+ # = LIMITATIONS
270
+ #
271
+ # * Due to DOS-console limitations, the blink mode (text attributes 5 and 25) is not implemented.
272
+ #
273
+ # = SEE ALSO
274
+ #
275
+ # <b>Win32::Console</b>, <b>Term::ANSIColor</b>, <b>Term::ANSIScreen</b>.
276
+ #
277
+ # = AUTHOR
278
+ #
279
+ # J-L Morel jl_morel@bribes.org
280
+ #
281
+ # Home page: http://www.bribes.org/perl/wANSIConsole.html
282
+ #
283
+ # Gonzalo Garramu�o GGarramuno@aol.com Ruby port
284
+ #
285
+ # = CREDITS
286
+ #
287
+ # Render unto C�sar the things which are C�sar's...
288
+ #
289
+ # This module requires the module Win32::Console. Thanks to Aldo Calpini.
290
+ #
291
+ # The method used to overload the print function is due to Matt Sergeant
292
+ # (see his module Win32::ASP).
293
+ #
294
+ # = COPYRIGHT
295
+ #
296
+ # Copyright (c) 2004 Gonzalo Garramu�o. All rights reserved.
297
+ # Copyright (c) 2003 J-L Morel. All rights reserved.
298
+ #
299
+ # This program is free software; you can redistribute it and/or modify it under
300
+ # the terms of the Artistic License.
301
+ #
302
+ #
data/ext/Console.cpp ADDED
@@ -0,0 +1,1218 @@
1
+
2
+ #include "windows.h"
3
+ #include "ruby.h"
4
+
5
+ #ifdef WIN32
6
+ #define CONSOLE_EXPORT __declspec(dllexport)
7
+ #else
8
+ #error Not compiling on Windows
9
+ #endif
10
+
11
+ VALUE rb_mWin32;
12
+ VALUE rb_mConsole;
13
+ VALUE rb_mAPI;
14
+ VALUE rb_mConstants;
15
+
16
+ /* old RUBY_METHOD_FUNC() definition doesn't match to prototypes in those days. */
17
+ #ifndef ANYARGS
18
+ #undef RUBY_METHOD_FUNC
19
+ #define RUBY_METHOD_FUNC(func) ((VALUE (*)())func)
20
+ #endif
21
+
22
+
23
+ #define RB_DEF_S_METHOD(klass,method,func,argtype) \
24
+ rb_define_singleton_method(klass,method,RUBY_METHOD_FUNC(func), argtype)
25
+
26
+ #define RB_DEF_API_METHOD(name,argtype) \
27
+ RB_DEF_S_METHOD(rb_mAPI,#name,RUBY_METHOD_FUNC(rb_##name), argtype)
28
+
29
+ #define RB_DEF_METHOD(klass,method,func,argtype) \
30
+ rb_define_method(klass,method,RUBY_METHOD_FUNC(func), argtype)
31
+
32
+ VALUE
33
+ rb_getWin32Error()
34
+ {
35
+ DWORD e = GetLastError();
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(t)->ptr);
59
+ return Qnil;
60
+
61
+ }
62
+
63
+
64
+ extern "C"
65
+ {
66
+
67
+ static VALUE rb_GetStdHandle(VALUE self, VALUE handle)
68
+ {
69
+ unsigned long x;
70
+ if ( FIXNUM_P( handle ) )
71
+ {
72
+ x = NUM2ULONG( handle );
73
+ }
74
+ else
75
+ {
76
+ Check_Type( handle, T_BIGNUM );
77
+ x = rb_big2ulong(handle);
78
+ }
79
+ unsigned long h = PtrToUlong( GetStdHandle( x ) );
80
+ return ULONG2NUM(h);
81
+ }
82
+
83
+
84
+ static VALUE rb_AllocConsole(VALUE self)
85
+ {
86
+ if (AllocConsole()) return INT2FIX(1);
87
+ return rb_getWin32Error();
88
+ }
89
+
90
+
91
+ static VALUE rb_FreeConsole(VALUE self)
92
+ {
93
+ if (FreeConsole()) return INT2FIX(1);
94
+ return rb_getWin32Error();
95
+ }
96
+
97
+ static VALUE rb_GenerateConsoleCtrlEvent(VALUE self, VALUE event, VALUE pgid)
98
+ {
99
+ unsigned int e = NUM2UINT(event);
100
+ if ( e != CTRL_C_EVENT && e != CTRL_BREAK_EVENT )
101
+ rb_raise(rb_eArgError, "Wrong event: only CTRL_C_EVENT or "
102
+ "CTRL_BREAK_EVENT accepted.");
103
+ if ( GenerateConsoleCtrlEvent(e, NUM2UINT(pgid)) )
104
+ return INT2FIX(1);
105
+ return rb_getWin32Error();
106
+ }
107
+
108
+ static VALUE rb_GetConsoleMode(VALUE self, VALUE hConsoleOutput)
109
+ {
110
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
111
+ DWORD mode;
112
+ if (GetConsoleMode(handle,&mode))
113
+ return UINT2NUM(mode);
114
+ return rb_getWin32Error();
115
+ }
116
+
117
+ static VALUE rb_GetConsoleTitle(VALUE self)
118
+ {
119
+ char title[1024];
120
+ if (GetConsoleTitle((char*)&title,1024))
121
+ return rb_str_new2( title );
122
+ return rb_getWin32Error();
123
+ }
124
+
125
+
126
+
127
+
128
+ static VALUE rb_GetNumberOfConsoleMouseButtons( VALUE self )
129
+ {
130
+ DWORD mb;
131
+ if (GetNumberOfConsoleMouseButtons( &mb ))
132
+ return INT2FIX(mb);
133
+ return rb_getWin32Error();
134
+ }
135
+
136
+
137
+
138
+ static VALUE rb_GetNumberOfConsoleInputEvents( VALUE self, VALUE hConsoleOutput )
139
+ {
140
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
141
+ DWORD events;
142
+ if (GetNumberOfConsoleInputEvents(handle, &events))
143
+ return INT2FIX(events);
144
+ return rb_getWin32Error();
145
+ }
146
+
147
+
148
+ static VALUE
149
+ rb_CreateConsoleScreenBuffer( VALUE self, VALUE dwDesiredAccess,
150
+ VALUE dwShareMode, VALUE dwFlags )
151
+ {
152
+ if (CreateConsoleScreenBuffer( NUM2UINT(dwDesiredAccess),
153
+ NUM2UINT( dwShareMode),
154
+ NULL,
155
+ NUM2UINT( dwFlags),
156
+ NULL
157
+ ))
158
+ return INT2FIX(1);
159
+ return rb_getWin32Error();
160
+ }
161
+
162
+
163
+ static VALUE rb_GetConsoleCP( VALUE self )
164
+ {
165
+ unsigned int h = GetConsoleCP();
166
+ return UINT2NUM(h);
167
+ }
168
+
169
+ static VALUE rb_GetConsoleOutputCP( VALUE self )
170
+ {
171
+ unsigned int h = GetConsoleOutputCP();
172
+ return UINT2NUM(h);
173
+ }
174
+
175
+ static VALUE rb_SetConsoleMode( VALUE self, VALUE hConsoleOutput,
176
+ VALUE Mode )
177
+ {
178
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
179
+ if ( SetConsoleMode( handle, NUM2UINT( Mode ) ) )
180
+ return INT2FIX(1);
181
+ return rb_getWin32Error();
182
+ }
183
+
184
+ static VALUE rb_SetConsoleCP( VALUE self, VALUE wCodePageID )
185
+ {
186
+ if ( SetConsoleCP( NUM2UINT( wCodePageID ) ) )
187
+ return INT2FIX(1);
188
+ return rb_getWin32Error();
189
+ }
190
+
191
+ static VALUE rb_SetConsoleOutputCP( VALUE self, VALUE wCodePageID )
192
+ {
193
+ if ( SetConsoleOutputCP( NUM2UINT( wCodePageID ) ) )
194
+ return INT2FIX(1);
195
+ return rb_getWin32Error();
196
+ }
197
+
198
+ static VALUE rb_GetConsoleWindow( VALUE self )
199
+ {
200
+ unsigned long h = PtrToUlong( GetConsoleOutputCP() );
201
+ return ULONG2NUM(h);
202
+ }
203
+
204
+ static VALUE rb_WriteConsole( VALUE self, VALUE hConsoleOutput,
205
+ VALUE lpBuffer )
206
+ {
207
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
208
+ DWORD nNumberOfCharsToWrite = RSTRING(lpBuffer)->len;
209
+
210
+ DWORD lpNumberOfCharsWritten;
211
+
212
+ WriteConsole( handle, RSTRING(lpBuffer)->ptr,
213
+ nNumberOfCharsToWrite,
214
+ &lpNumberOfCharsWritten, NULL );
215
+ return UINT2NUM( lpNumberOfCharsWritten );
216
+ }
217
+
218
+ static VALUE rb_WriteFile( VALUE self, VALUE hConsoleOutput,
219
+ VALUE lpBuffer )
220
+ {
221
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
222
+ DWORD nNumberOfBytesToWrite = RSTRING(lpBuffer)->len;
223
+
224
+ DWORD lpNumberOfBytesWritten;
225
+
226
+ WriteFile( handle, RSTRING(lpBuffer)->ptr,
227
+ nNumberOfBytesToWrite,
228
+ &lpNumberOfBytesWritten, NULL );
229
+ return UINT2NUM( lpNumberOfBytesWritten );
230
+ }
231
+
232
+
233
+ static VALUE rb_GetLargestConsoleWindowSize( VALUE self, VALUE hConsoleOutput )
234
+ {
235
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
236
+ COORD size = GetLargestConsoleWindowSize( handle);
237
+
238
+ VALUE ret = rb_ary_new();
239
+ rb_ary_push( ret, UINT2NUM( size.X ) );
240
+ rb_ary_push( ret, UINT2NUM( size.Y ) );
241
+ return ret;
242
+ }
243
+
244
+ static VALUE rb_GetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput )
245
+ {
246
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
247
+
248
+ CONSOLE_CURSOR_INFO out;
249
+ if ( !GetConsoleCursorInfo( handle, &out ) )
250
+ return rb_getWin32Error();
251
+
252
+ VALUE ret = rb_ary_new();
253
+ rb_ary_push( ret, UINT2NUM( out.dwSize ) );
254
+ rb_ary_push( ret, UINT2NUM( out.bVisible ) );
255
+ return ret;
256
+ }
257
+
258
+ void rb_ParseEvent(VALUE ret, INPUT_RECORD& event )
259
+ {
260
+ switch(event.EventType) {
261
+ case KEY_EVENT:
262
+ {
263
+ KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event.Event);
264
+ rb_ary_push(ret, UINT2NUM(KEY_EVENT));
265
+ rb_ary_push(ret, UINT2NUM(kevent->bKeyDown));
266
+ rb_ary_push(ret, UINT2NUM(kevent->wRepeatCount));
267
+ rb_ary_push(ret, UINT2NUM(kevent->wVirtualKeyCode));
268
+ rb_ary_push(ret, UINT2NUM(kevent->wVirtualScanCode));
269
+ #ifdef UNICODE
270
+ rb_ary_push(ret, UINT2NUM(kevent->uChar.UnicodeChar));
271
+ #else
272
+ rb_ary_push(ret, UINT2NUM(kevent->uChar.AsciiChar));
273
+ #endif
274
+ rb_ary_push(ret, UINT2NUM(kevent->dwControlKeyState));
275
+ break;
276
+ }
277
+ case MOUSE_EVENT:
278
+ {
279
+ MOUSE_EVENT_RECORD * mevent=(MOUSE_EVENT_RECORD *)&(event.Event);
280
+ rb_ary_push(ret, UINT2NUM(MOUSE_EVENT) );
281
+ rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.X) );
282
+ rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.Y) );
283
+ rb_ary_push(ret, UINT2NUM(mevent->dwButtonState) );
284
+ rb_ary_push(ret, UINT2NUM(mevent->dwControlKeyState) );
285
+ rb_ary_push(ret, UINT2NUM(mevent->dwEventFlags) );
286
+ break;
287
+ }
288
+ case WINDOW_BUFFER_SIZE_EVENT:
289
+ {
290
+ WINDOW_BUFFER_SIZE_RECORD* wevent=
291
+ (WINDOW_BUFFER_SIZE_RECORD *)&(event.Event);
292
+ rb_ary_push(ret, UINT2NUM(WINDOW_BUFFER_SIZE_EVENT) );
293
+ rb_ary_push(ret, UINT2NUM(wevent->dwSize.X) );
294
+ rb_ary_push(ret, UINT2NUM(wevent->dwSize.Y) );
295
+ }
296
+ break;
297
+ case MENU_EVENT:
298
+ {
299
+ MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event.Event);
300
+ rb_ary_push(ret, UINT2NUM(MENU_EVENT) );
301
+ rb_ary_push(ret, UINT2NUM(mevent->dwCommandId) );
302
+ }
303
+ break;
304
+ case FOCUS_EVENT:
305
+ {
306
+ FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event.Event);
307
+ rb_ary_push(ret, UINT2NUM(FOCUS_EVENT) );
308
+ rb_ary_push(ret, UINT2NUM(mevent->bSetFocus) );
309
+ }
310
+ break;
311
+ }
312
+ }
313
+
314
+ static VALUE rb_PeekConsoleInput( VALUE self, VALUE hConsoleOutput )
315
+ {
316
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
317
+
318
+ DWORD nofread;
319
+ INPUT_RECORD event;
320
+ if (!PeekConsoleInput(handle,&event,1,&nofread))
321
+ return rb_getWin32Error();
322
+
323
+ VALUE ret = rb_ary_new();
324
+ rb_ParseEvent( ret, event );
325
+ return ret;
326
+ }
327
+
328
+ static VALUE rb_ReadConsole( VALUE self, VALUE hConsoleOutput,
329
+ VALUE buffer, VALUE numread )
330
+ {
331
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
332
+ DWORD nofread;
333
+ Check_Type( buffer, T_STRING );
334
+ int to_read = NUM2INT(numread);
335
+ if ( RSTRING(buffer)->len > to_read )
336
+ rb_raise(rb_eArgError, "String is too small to read that many characters.");
337
+ if (ReadConsole(handle,(void *)RSTRING(buffer)->ptr, to_read,
338
+ &nofread,NULL))
339
+ return UINT2NUM(nofread);
340
+ return rb_getWin32Error();
341
+ }
342
+
343
+ static VALUE rb_ReadConsoleInput( VALUE self, VALUE hConsoleOutput )
344
+ {
345
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
346
+ DWORD nofread;
347
+ INPUT_RECORD event;
348
+ if (!ReadConsoleInput(handle,&event,1,&nofread))
349
+ return rb_getWin32Error();
350
+
351
+ VALUE ret = rb_ary_new();
352
+ rb_ParseEvent( ret, event );
353
+ return ret;
354
+ }
355
+
356
+
357
+
358
+ static VALUE rb_ReadConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput,
359
+ VALUE charbuf, VALUE len,
360
+ VALUE x, VALUE y )
361
+ {
362
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
363
+ COORD coords;
364
+ DWORD nofread;
365
+ coords.X= NUM2UINT( x );
366
+ coords.Y= NUM2UINT( y );
367
+ int l = NUM2INT(len);
368
+ if ( RSTRING(charbuf)->len < l*sizeof(TCHAR) )
369
+ rb_raise(rb_eArgError, "String is too small to read that many characters.");
370
+ if (ReadConsoleOutputCharacter(handle,RSTRING(charbuf)->ptr,l,
371
+ coords,&nofread))
372
+ return UINT2NUM( nofread );
373
+ return rb_getWin32Error();
374
+ }
375
+
376
+
377
+ static VALUE rb_ReadConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput,
378
+ VALUE len, VALUE x, VALUE y )
379
+ {
380
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
381
+ COORD coords;
382
+ DWORD nofread;
383
+ unsigned short abuffer[80*999*sizeof(unsigned short)];
384
+ char cbuffer[80*999];
385
+ coords.X= NUM2UINT( x );
386
+ coords.Y= NUM2UINT( y );
387
+ if (ReadConsoleOutputAttribute(handle, abuffer, NUM2UINT(len),
388
+ coords,&nofread))
389
+ {
390
+ for(unsigned i=0;i<nofread;++i) {
391
+ cbuffer[i]=(char)abuffer[i];
392
+ }
393
+ return rb_str_new( cbuffer, nofread );
394
+ }
395
+ return rb_getWin32Error();
396
+ }
397
+
398
+
399
+ static VALUE rb_ReadConsoleOutput( VALUE self, VALUE hConsoleOutput,
400
+ VALUE buffer, VALUE srcwid, VALUE srcht,
401
+ VALUE startx, VALUE starty,
402
+ VALUE l, VALUE t, VALUE r, VALUE b )
403
+ {
404
+ COORD coords;
405
+ COORD size;
406
+ SMALL_RECT from;
407
+ size.X= NUM2UINT( srcwid );
408
+ size.Y= NUM2UINT( srcht );
409
+ coords.X= NUM2INT( startx );
410
+ coords.Y= NUM2INT( starty );
411
+ from.Left = NUM2INT( l );
412
+ from.Top = NUM2INT( t );
413
+ from.Right = NUM2INT( r );
414
+ from.Bottom = NUM2INT( b );
415
+ Check_Type( buffer, T_STRING );
416
+ if ( RSTRING(buffer)->len < (sizeof(CHAR_INFO)*size.X*size.Y) )
417
+ rb_raise(rb_eArgError, "string buffer is too small for reading that many characters.");
418
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
419
+ if (!ReadConsoleOutput(handle,(CHAR_INFO *)RSTRING(buffer)->ptr,size,coords,&from))
420
+ return rb_getWin32Error();
421
+
422
+ VALUE ret = rb_ary_new();
423
+ rb_ary_push( ret, INT2FIX(from.Left) );
424
+ rb_ary_push( ret, INT2FIX(from.Top) );
425
+ rb_ary_push( ret, INT2FIX(from.Right) );
426
+ rb_ary_push( ret, INT2FIX(from.Bottom) );
427
+ return ret;
428
+ }
429
+
430
+
431
+
432
+ static VALUE rb_GetConsoleScreenBufferInfo( VALUE self, VALUE hConsoleOutput )
433
+ {
434
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
435
+
436
+ CONSOLE_SCREEN_BUFFER_INFO out;
437
+
438
+ if ( !GetConsoleScreenBufferInfo( handle, &out ) )
439
+ return rb_getWin32Error();
440
+
441
+ VALUE ret = rb_ary_new();
442
+ rb_ary_push( ret, UINT2NUM( out.dwSize.X ) );
443
+ rb_ary_push( ret, UINT2NUM( out.dwSize.Y ) );
444
+ rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.X ) );
445
+ rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.Y ) );
446
+
447
+ rb_ary_push( ret, UINT2NUM( out.wAttributes ) );
448
+
449
+ rb_ary_push( ret, INT2FIX( out.srWindow.Left ) );
450
+ rb_ary_push( ret, INT2FIX( out.srWindow.Top ) );
451
+ rb_ary_push( ret, INT2FIX( out.srWindow.Right ) );
452
+ rb_ary_push( ret, INT2FIX( out.srWindow.Bottom ) );
453
+
454
+ rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.X ) );
455
+ rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.Y ) );
456
+
457
+
458
+ return ret;
459
+ }
460
+
461
+
462
+ #define strEQ(x,y) strcmp(x,y) == 0
463
+
464
+ DWORD c_constant(char *name)
465
+ {
466
+ switch (*name) {
467
+ case 'A':
468
+ break;
469
+ case 'B':
470
+ if (strEQ(name, "BACKGROUND_BLUE"))
471
+ #ifdef BACKGROUND_BLUE
472
+ return BACKGROUND_BLUE;
473
+ #else
474
+ goto not_there;
475
+ #endif
476
+ if (strEQ(name, "BACKGROUND_GREEN"))
477
+ #ifdef BACKGROUND_GREEN
478
+ return BACKGROUND_GREEN;
479
+ #else
480
+ goto not_there;
481
+ #endif
482
+ if (strEQ(name, "BACKGROUND_INTENSITY"))
483
+ #ifdef BACKGROUND_INTENSITY
484
+ return BACKGROUND_INTENSITY;
485
+ #else
486
+ goto not_there;
487
+ #endif
488
+ if (strEQ(name, "BACKGROUND_RED"))
489
+ #ifdef BACKGROUND_RED
490
+ return BACKGROUND_RED;
491
+ #else
492
+ goto not_there;
493
+ #endif
494
+ break;
495
+ case 'C':
496
+ if (strEQ(name, "CAPSLOCK_ON"))
497
+ #ifdef CAPSLOCK_ON
498
+ return CAPSLOCK_ON;
499
+ #else
500
+ goto not_there;
501
+ #endif
502
+ if (strEQ(name, "CONSOLE_TEXTMODE_BUFFER"))
503
+ #ifdef CONSOLE_TEXTMODE_BUFFER
504
+ return CONSOLE_TEXTMODE_BUFFER;
505
+ #else
506
+ goto not_there;
507
+ #endif
508
+ if (strEQ(name, "CTRL_BREAK_EVENT"))
509
+ #ifdef CTRL_BREAK_EVENT
510
+ return CTRL_BREAK_EVENT;
511
+ #else
512
+ goto not_there;
513
+ #endif
514
+ if (strEQ(name, "CTRL_C_EVENT"))
515
+ #ifdef CTRL_C_EVENT
516
+ return CTRL_C_EVENT;
517
+ #else
518
+ goto not_there;
519
+ #endif
520
+ break;
521
+
522
+ case 'D':
523
+ break;
524
+ case 'E':
525
+ if (strEQ(name, "ENABLE_ECHO_INPUT"))
526
+ #ifdef ENABLE_ECHO_INPUT
527
+ return ENABLE_ECHO_INPUT;
528
+ #else
529
+ goto not_there;
530
+ #endif
531
+ if (strEQ(name, "ENABLE_LINE_INPUT"))
532
+ #ifdef ENABLE_LINE_INPUT
533
+ return ENABLE_LINE_INPUT;
534
+ #else
535
+ goto not_there;
536
+ #endif
537
+ if (strEQ(name, "ENABLE_MOUSE_INPUT"))
538
+ #ifdef ENABLE_MOUSE_INPUT
539
+ return ENABLE_MOUSE_INPUT;
540
+ #else
541
+ goto not_there;
542
+ #endif
543
+ if (strEQ(name, "ENABLE_PROCESSED_INPUT"))
544
+ #ifdef ENABLE_PROCESSED_INPUT
545
+ return ENABLE_PROCESSED_INPUT;
546
+ #else
547
+ goto not_there;
548
+ #endif
549
+ if (strEQ(name, "ENABLE_PROCESSED_OUTPUT"))
550
+ #ifdef ENABLE_PROCESSED_OUTPUT
551
+ return ENABLE_PROCESSED_OUTPUT;
552
+ #else
553
+ goto not_there;
554
+ #endif
555
+ if (strEQ(name, "ENABLE_WINDOW_INPUT"))
556
+ #ifdef ENABLE_WINDOW_INPUT
557
+ return ENABLE_WINDOW_INPUT;
558
+ #else
559
+ goto not_there;
560
+ #endif
561
+ if (strEQ(name, "ENABLE_WRAP_AT_EOL_OUTPUT"))
562
+ #ifdef ENABLE_WRAP_AT_EOL_OUTPUT
563
+ return ENABLE_WRAP_AT_EOL_OUTPUT;
564
+ #else
565
+ goto not_there;
566
+ #endif
567
+ if (strEQ(name, "ENHANCED_KEY"))
568
+ #ifdef ENHANCED_KEY
569
+ return ENHANCED_KEY;
570
+ #else
571
+ goto not_there;
572
+ #endif
573
+ break;
574
+ case 'F':
575
+ if (strEQ(name, "FILE_SHARE_READ"))
576
+ #ifdef FILE_SHARE_READ
577
+ return FILE_SHARE_READ;
578
+ #else
579
+ goto not_there;
580
+ #endif
581
+ if (strEQ(name, "FILE_SHARE_WRITE"))
582
+ #ifdef FILE_SHARE_WRITE
583
+ return FILE_SHARE_WRITE;
584
+ #else
585
+ goto not_there;
586
+ #endif
587
+ if (strEQ(name, "FOREGROUND_BLUE"))
588
+ #ifdef FOREGROUND_BLUE
589
+ return FOREGROUND_BLUE;
590
+ #else
591
+ goto not_there;
592
+ #endif
593
+ if (strEQ(name, "FOREGROUND_GREEN"))
594
+ #ifdef FOREGROUND_GREEN
595
+ return FOREGROUND_GREEN;
596
+ #else
597
+ goto not_there;
598
+ #endif
599
+ if (strEQ(name, "FOREGROUND_INTENSITY"))
600
+ #ifdef FOREGROUND_INTENSITY
601
+ return FOREGROUND_INTENSITY;
602
+ #else
603
+ goto not_there;
604
+ #endif
605
+ if (strEQ(name, "FOREGROUND_RED"))
606
+ #ifdef FOREGROUND_RED
607
+ return FOREGROUND_RED;
608
+ #else
609
+ goto not_there;
610
+ #endif
611
+ break;
612
+ case 'G':
613
+ if (strEQ(name, "GENERIC_READ"))
614
+ #ifdef GENERIC_READ
615
+ return GENERIC_READ;
616
+ #else
617
+ goto not_there;
618
+ #endif
619
+ if (strEQ(name, "GENERIC_WRITE"))
620
+ #ifdef GENERIC_WRITE
621
+ return GENERIC_WRITE;
622
+ #else
623
+ goto not_there;
624
+ #endif
625
+ break;
626
+ case 'H':
627
+ break;
628
+ case 'I':
629
+ break;
630
+ case 'J':
631
+ break;
632
+ case 'K':
633
+ if (strEQ(name, "KEY_EVENT"))
634
+ #ifdef KEY_EVENT
635
+ return KEY_EVENT;
636
+ #else
637
+ goto not_there;
638
+ #endif
639
+ break;
640
+ case 'L':
641
+ if (strEQ(name, "LEFT_ALT_PRESSED"))
642
+ #ifdef LEFT_ALT_PRESSED
643
+ return LEFT_ALT_PRESSED;
644
+ #else
645
+ goto not_there;
646
+ #endif
647
+ if (strEQ(name, "LEFT_CTRL_PRESSED"))
648
+ #ifdef LEFT_CTRL_PRESSED
649
+ return LEFT_CTRL_PRESSED;
650
+ #else
651
+ goto not_there;
652
+ #endif
653
+ break;
654
+ case 'M':
655
+ break;
656
+ case 'N':
657
+ if (strEQ(name, "NUMLOCK_ON"))
658
+ #ifdef NUMLOCK_ON
659
+ return NUMLOCK_ON;
660
+ #else
661
+ goto not_there;
662
+ #endif
663
+ break;
664
+ case 'O':
665
+ break;
666
+ case 'P':
667
+ break;
668
+ case 'Q':
669
+ break;
670
+ case 'R':
671
+ if (strEQ(name, "RIGHT_ALT_PRESSED"))
672
+ #ifdef RIGHT_ALT_PRESSED
673
+ return RIGHT_ALT_PRESSED;
674
+ #else
675
+ goto not_there;
676
+ #endif
677
+ if (strEQ(name, "RIGHT_CTRL_PRESSED"))
678
+ #ifdef RIGHT_CTRL_PRESSED
679
+ return RIGHT_CTRL_PRESSED;
680
+ #else
681
+ goto not_there;
682
+ #endif
683
+ break;
684
+ case 'S':
685
+ if (strEQ(name, "SCROLLLOCK_ON"))
686
+ #ifdef SCROLLLOCK_ON
687
+ return SCROLLLOCK_ON;
688
+ #else
689
+ goto not_there;
690
+ #endif
691
+ if (strEQ(name, "SHIFT_PRESSED"))
692
+ #ifdef SHIFT_PRESSED
693
+ return SHIFT_PRESSED;
694
+ #else
695
+ goto not_there;
696
+ #endif
697
+ if (strEQ(name, "STD_ERROR_HANDLE"))
698
+ #ifdef STD_ERROR_HANDLE
699
+ return STD_ERROR_HANDLE;
700
+ #else
701
+ goto not_there;
702
+ #endif
703
+ if (strEQ(name, "STD_INPUT_HANDLE"))
704
+ #ifdef STD_INPUT_HANDLE
705
+ return STD_INPUT_HANDLE;
706
+ #else
707
+ goto not_there;
708
+ #endif
709
+ if (strEQ(name, "STD_OUTPUT_HANDLE"))
710
+ #ifdef STD_OUTPUT_HANDLE
711
+ return STD_OUTPUT_HANDLE;
712
+ #else
713
+ goto not_there;
714
+ #endif
715
+ break;
716
+ case 'T':
717
+ break;
718
+ case 'U':
719
+ break;
720
+ case 'V':
721
+ break;
722
+ case 'W':
723
+ break;
724
+ case 'X':
725
+ break;
726
+ case 'Y':
727
+ break;
728
+ case 'Z':
729
+ break;
730
+ }
731
+ rb_raise(rb_eArgError, "Not such constant.");
732
+ return 0;
733
+
734
+ not_there:
735
+ rb_raise(rb_eArgError, "Not defined.");
736
+ return 0;
737
+ }
738
+
739
+ VALUE rb_constant( VALUE self, VALUE name )
740
+ {
741
+ Check_Type( name, T_STRING );
742
+ return ULONG2NUM( c_constant( RSTRING(name)->ptr ) );
743
+ }
744
+
745
+
746
+ void define_constants()
747
+ {
748
+ #define DEF_SELF_CONST(NAME) \
749
+ rb_define_const(rb_mConstants, #NAME, ULONG2NUM( (ULONG)NAME ) );
750
+
751
+ DEF_SELF_CONST( STD_INPUT_HANDLE );
752
+ DEF_SELF_CONST( STD_OUTPUT_HANDLE );
753
+ DEF_SELF_CONST( STD_ERROR_HANDLE );
754
+ DEF_SELF_CONST( INVALID_HANDLE_VALUE );
755
+ DEF_SELF_CONST( GENERIC_READ );
756
+ DEF_SELF_CONST( GENERIC_WRITE );
757
+ DEF_SELF_CONST( FILE_SHARE_READ );
758
+ DEF_SELF_CONST( FILE_SHARE_WRITE );
759
+ DEF_SELF_CONST( CONSOLE_TEXTMODE_BUFFER );
760
+
761
+ DEF_SELF_CONST( FOREGROUND_BLUE );
762
+ DEF_SELF_CONST( FOREGROUND_GREEN );
763
+ DEF_SELF_CONST( FOREGROUND_RED );
764
+ DEF_SELF_CONST( FOREGROUND_INTENSITY );
765
+ DEF_SELF_CONST( BACKGROUND_BLUE );
766
+ DEF_SELF_CONST( BACKGROUND_GREEN );
767
+ DEF_SELF_CONST( BACKGROUND_RED );
768
+ DEF_SELF_CONST( BACKGROUND_INTENSITY );
769
+
770
+ DEF_SELF_CONST( ENABLE_PROCESSED_INPUT );
771
+ DEF_SELF_CONST( ENABLE_LINE_INPUT );
772
+ DEF_SELF_CONST( ENABLE_ECHO_INPUT );
773
+ DEF_SELF_CONST( ENABLE_WINDOW_INPUT );
774
+ DEF_SELF_CONST( ENABLE_MOUSE_INPUT );
775
+ DEF_SELF_CONST( ENABLE_PROCESSED_OUTPUT );
776
+ DEF_SELF_CONST( ENABLE_WRAP_AT_EOL_OUTPUT );
777
+
778
+ DEF_SELF_CONST( KEY_EVENT );
779
+ DEF_SELF_CONST( MOUSE_EVENT );
780
+ DEF_SELF_CONST( WINDOW_BUFFER_SIZE_EVENT );
781
+ DEF_SELF_CONST( MENU_EVENT );
782
+ DEF_SELF_CONST( FOCUS_EVENT );
783
+
784
+ DEF_SELF_CONST( CAPSLOCK_ON );
785
+ DEF_SELF_CONST( ENHANCED_KEY );
786
+ DEF_SELF_CONST( NUMLOCK_ON );
787
+ DEF_SELF_CONST( SHIFT_PRESSED );
788
+ DEF_SELF_CONST( LEFT_CTRL_PRESSED );
789
+ DEF_SELF_CONST( RIGHT_CTRL_PRESSED );
790
+ DEF_SELF_CONST( LEFT_ALT_PRESSED );
791
+ DEF_SELF_CONST( RIGHT_ALT_PRESSED );
792
+ DEF_SELF_CONST( SCROLLLOCK_ON );
793
+
794
+ DEF_SELF_CONST( MOUSE_WHEELED );
795
+ DEF_SELF_CONST( DOUBLE_CLICK );
796
+ DEF_SELF_CONST( MOUSE_MOVED );
797
+
798
+ DEF_SELF_CONST( FROM_LEFT_1ST_BUTTON_PRESSED );
799
+ DEF_SELF_CONST( FROM_LEFT_2ND_BUTTON_PRESSED );
800
+ DEF_SELF_CONST( FROM_LEFT_3RD_BUTTON_PRESSED );
801
+ DEF_SELF_CONST( FROM_LEFT_4TH_BUTTON_PRESSED );
802
+ DEF_SELF_CONST( RIGHTMOST_BUTTON_PRESSED );
803
+
804
+ DEF_SELF_CONST( CTRL_C_EVENT );
805
+ DEF_SELF_CONST( CTRL_BREAK_EVENT );
806
+ DEF_SELF_CONST( CTRL_CLOSE_EVENT );
807
+ DEF_SELF_CONST( CTRL_LOGOFF_EVENT );
808
+ DEF_SELF_CONST( CTRL_SHUTDOWN_EVENT );
809
+ }
810
+
811
+
812
+ VALUE
813
+ rb_FillConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput,
814
+ VALUE wAttribute, VALUE nLength,
815
+ VALUE col, VALUE row )
816
+ {
817
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
818
+
819
+ COORD dwWriteCoord;
820
+ dwWriteCoord.X = NUM2UINT(col);
821
+ dwWriteCoord.Y = NUM2UINT(row);
822
+ DWORD numChars;
823
+ if (FillConsoleOutputAttribute( handle, NUM2UINT(wAttribute),
824
+ NUM2ULONG(nLength), dwWriteCoord,
825
+ &numChars ))
826
+ return ULONG2NUM(numChars);
827
+ return rb_getWin32Error();
828
+ }
829
+
830
+ VALUE
831
+ rb_SetConsoleScreenBufferSize( VALUE self, VALUE hConsoleOutput,
832
+ VALUE x, VALUE y )
833
+ {
834
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
835
+ COORD size;
836
+ size.X=NUM2UINT(x);
837
+ size.Y=NUM2UINT(y);
838
+ if (SetConsoleScreenBufferSize(handle, size))
839
+ return NUM2UINT(1);
840
+ return rb_getWin32Error();
841
+ }
842
+
843
+ VALUE
844
+ rb_SetConsoleTitle( VALUE self, VALUE title )
845
+ {
846
+ Check_Type( title, T_STRING );
847
+ if (SetConsoleTitle(RSTRING( title )->ptr))
848
+ return NUM2UINT(1);
849
+ return rb_getWin32Error();
850
+ }
851
+
852
+ VALUE
853
+ rb_SetStdHandle( VALUE self, VALUE fd, VALUE hConsoleOutput )
854
+ {
855
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
856
+ if (SetStdHandle(NUM2UINT(fd), handle))
857
+ return NUM2UINT(1);
858
+ return rb_getWin32Error();
859
+ }
860
+
861
+ VALUE
862
+ rb_SetConsoleWindowInfo( VALUE self, VALUE hConsoleOutput, VALUE bAbsolute,
863
+ VALUE left, VALUE top, VALUE right, VALUE bottom )
864
+ {
865
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
866
+
867
+ SMALL_RECT rect;
868
+ rect.Left = NUM2INT( left );
869
+ rect.Top = NUM2INT( top );
870
+ rect.Right = NUM2INT( right );
871
+ rect.Bottom = NUM2INT( bottom );
872
+ if (SetConsoleWindowInfo( handle, NUM2INT( bAbsolute ), &rect ))
873
+ return UINT2NUM(1);
874
+ return rb_getWin32Error();
875
+ }
876
+
877
+
878
+
879
+ VALUE
880
+ rb_SetConsoleCursorPosition( VALUE self, VALUE hConsoleOutput,
881
+ VALUE col, VALUE row )
882
+ {
883
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
884
+
885
+ COORD dwWriteCoord;
886
+ dwWriteCoord.X = NUM2UINT(col);
887
+ dwWriteCoord.Y = NUM2UINT(row);
888
+ // Cannot call rb_getWin32Error as this function fails when
889
+ // setting cursor to last column/row.
890
+ if ( !SetConsoleCursorPosition( handle, dwWriteCoord ) )
891
+ return Qnil;
892
+ return INT2FIX(1);
893
+ }
894
+
895
+ VALUE
896
+ rb_SetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput,
897
+ VALUE size, VALUE visib )
898
+ {
899
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
900
+ CONSOLE_CURSOR_INFO c;
901
+ c.dwSize = NUM2UINT(size);
902
+ c.bVisible = NUM2UINT(visib);
903
+ if ( !SetConsoleCursorInfo( handle, &c ) )
904
+ return rb_getWin32Error();
905
+ return INT2FIX(1);
906
+ }
907
+
908
+
909
+
910
+ VALUE
911
+ rb_SetConsoleActiveScreenBuffer( VALUE self, VALUE hConsoleOutput )
912
+ {
913
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
914
+
915
+ if ( !SetConsoleActiveScreenBuffer( handle ) )
916
+ return rb_getWin32Error();
917
+ return INT2FIX(1);
918
+ }
919
+
920
+ VALUE
921
+ rb_SetConsoleTextAttribute( VALUE self, VALUE hConsoleOutput,
922
+ VALUE wAttributes )
923
+ {
924
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
925
+
926
+ if ( !SetConsoleTextAttribute( handle, NUM2UINT(wAttributes) ) )
927
+ return Qnil; // no getWin32Error to allow piping/redirecting
928
+ return INT2FIX(1);
929
+ }
930
+
931
+
932
+
933
+ VALUE
934
+ rb_ScrollConsoleScreenBuffer( VALUE self, VALUE hConsoleOutput, VALUE left1,
935
+ VALUE top1, VALUE right1, VALUE bottom1,
936
+ VALUE col, VALUE row, VALUE cChar, VALUE attr,
937
+ VALUE left2, VALUE top2, VALUE right2,
938
+ VALUE bottom2)
939
+ {
940
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
941
+
942
+ SMALL_RECT scroll, clip;
943
+ scroll.Left = NUM2INT( left1 );
944
+ scroll.Right = NUM2INT( right1 );
945
+ scroll.Top = NUM2INT( top1 );
946
+ scroll.Bottom = NUM2INT( bottom1 );
947
+ clip.Left = NUM2INT( left2 );
948
+ clip.Right = NUM2INT( right2 );
949
+ clip.Top = NUM2INT( top2 );
950
+ clip.Bottom = NUM2INT( bottom2 );
951
+ CHAR_INFO fill;
952
+ #ifdef UNICODE
953
+ fill.Char.UnicodeChar = NUM2CHR( cChar );
954
+ #else
955
+ fill.Char.AsciiChar = NUM2CHR( cChar );
956
+ #endif
957
+ fill.Attributes = NUM2INT(attr);
958
+ COORD origin;
959
+ origin.X = NUM2UINT( col );
960
+ origin.Y = NUM2UINT( row );
961
+
962
+ if ( ScrollConsoleScreenBuffer( handle, &scroll, &clip, origin,
963
+ &fill ) )
964
+ return INT2FIX(1);
965
+ return rb_getWin32Error();
966
+ }
967
+
968
+
969
+ VALUE
970
+ rb_FillConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput,
971
+ VALUE cCharacter, VALUE nLength,
972
+ VALUE col, VALUE row )
973
+ {
974
+ HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) );
975
+
976
+ COORD dwWriteCoord;
977
+ dwWriteCoord.X = NUM2UINT(col);
978
+ dwWriteCoord.Y = NUM2UINT(row);
979
+ DWORD numChars;
980
+ if (FillConsoleOutputCharacter( handle, NUM2CHR(cCharacter),
981
+ NUM2ULONG(nLength), dwWriteCoord,
982
+ &numChars ))
983
+ return ULONG2NUM(numChars);
984
+ return rb_getWin32Error();
985
+ }
986
+
987
+
988
+ VALUE
989
+ rb_WriteConsoleInput(int argc, VALUE *argv, VALUE self)
990
+ {
991
+ if (argc < 3)
992
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
993
+
994
+ HANDLE handle = ULongToPtr( NUM2ULONG( argv[0] ) );
995
+ WORD type = NUM2INT( argv[1] );
996
+ DWORD written;
997
+ INPUT_RECORD event;
998
+ event.EventType = type;
999
+ switch(event.EventType) {
1000
+ case KEY_EVENT:
1001
+ {
1002
+ KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event.Event);
1003
+ kevent->bKeyDown=(BOOL)NUM2UINT( argv[2] );
1004
+ kevent->wRepeatCount=NUM2UINT( argv[3] );
1005
+ kevent->wVirtualKeyCode=NUM2UINT( argv[4] );
1006
+ kevent->wVirtualScanCode=NUM2UINT( argv[5] );
1007
+ #ifdef UNICODE
1008
+ if (argc < 7)
1009
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1010
+ kevent->uChar.UnicodeChar=NUM2UINT( argv[6] );
1011
+ #else
1012
+ if (argc < 8)
1013
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1014
+ kevent->uChar.AsciiChar=NUM2UINT( argv[7] );
1015
+ #endif
1016
+ break;
1017
+ }
1018
+ case MOUSE_EVENT:
1019
+ {
1020
+ if (argc < 7)
1021
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1022
+
1023
+ MOUSE_EVENT_RECORD* mevent=(MOUSE_EVENT_RECORD *)&(event.Event);
1024
+ mevent->dwMousePosition.X=NUM2UINT( argv[2] );
1025
+ mevent->dwMousePosition.Y=NUM2UINT( argv[3] );
1026
+ mevent->dwButtonState=NUM2UINT( argv[4] );
1027
+ mevent->dwControlKeyState=NUM2UINT( argv[5] );
1028
+ mevent->dwEventFlags=NUM2UINT( argv[6] );
1029
+ break;
1030
+ }
1031
+ case WINDOW_BUFFER_SIZE_EVENT:
1032
+ {
1033
+ if (argc < 4)
1034
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1035
+ WINDOW_BUFFER_SIZE_RECORD* mevent=
1036
+ (WINDOW_BUFFER_SIZE_RECORD *)&(event.Event);
1037
+ mevent->dwSize.X = NUM2UINT( argv[2] );
1038
+ mevent->dwSize.Y = NUM2UINT( argv[3] );
1039
+ }
1040
+ break;
1041
+ case MENU_EVENT:
1042
+ {
1043
+ if (argc < 3)
1044
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1045
+ MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event.Event);
1046
+ mevent->dwCommandId = argv[2];
1047
+ }
1048
+ break;
1049
+ case FOCUS_EVENT:
1050
+ {
1051
+ if (argc < 3)
1052
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
1053
+ FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event.Event);
1054
+ mevent->bSetFocus = NUM2UINT( argv[2] );
1055
+ }
1056
+ default:
1057
+ rb_raise( rb_eArgError, "Unknown type of event.");
1058
+ break;
1059
+ }
1060
+ if (WriteConsoleInput(handle,&event,1,&written))
1061
+ return INT2FIX(1);
1062
+ return rb_getWin32Error();
1063
+ }
1064
+
1065
+ VALUE
1066
+ rb_WriteConsoleOutput(VALUE self, VALUE h, VALUE buffer,
1067
+ VALUE srcwid, VALUE srcht, VALUE startx,
1068
+ VALUE starty, VALUE l, VALUE t, VALUE r, VALUE b)
1069
+ {
1070
+ COORD coords;
1071
+ COORD size;
1072
+ SMALL_RECT to;
1073
+
1074
+ HANDLE handle = ULongToPtr( NUM2ULONG( h ) );
1075
+ Check_Type( buffer, T_STRING );
1076
+ size.X=NUM2UINT( srcwid );
1077
+ size.Y=NUM2UINT( srcht );
1078
+ coords.X=NUM2INT( startx );
1079
+ coords.Y=NUM2INT( starty );
1080
+ to.Left = NUM2INT( l );
1081
+ to.Top = NUM2INT( t );
1082
+ to.Right = NUM2INT( r );
1083
+ to.Bottom = NUM2INT( b );
1084
+ if (WriteConsoleOutput(handle,(CHAR_INFO *)RSTRING(buffer)->ptr,
1085
+ size,coords,&to)) {
1086
+ VALUE ret = rb_ary_new();
1087
+ rb_ary_push( ret, INT2FIX( to.Left ) );
1088
+ rb_ary_push( ret, INT2FIX( to.Top ) );
1089
+ rb_ary_push( ret, INT2FIX( to.Right ) );
1090
+ rb_ary_push( ret, INT2FIX( to.Bottom ) );
1091
+ return ret;
1092
+ }
1093
+ return rb_getWin32Error();
1094
+ }
1095
+
1096
+
1097
+ VALUE
1098
+ rb_WriteConsoleOutputAttribute(VALUE self, VALUE h, VALUE s,
1099
+ VALUE x, VALUE y)
1100
+ {
1101
+
1102
+ HANDLE handle = ULongToPtr( NUM2ULONG( h ) );
1103
+ Check_Type( s, T_STRING );
1104
+
1105
+ unsigned short buffer[80*999*sizeof(unsigned short)];
1106
+ DWORD written;
1107
+ DWORD towrite = RSTRING(s)->len;
1108
+ for(unsigned i=0; i<towrite; i++) {
1109
+ buffer[i] = (unsigned short)(RSTRING(s)->ptr[i]);
1110
+ }
1111
+ COORD coords;
1112
+ coords.X=NUM2INT( x );
1113
+ coords.Y=NUM2INT( y );
1114
+ if (WriteConsoleOutputAttribute(handle,(const unsigned short *)&buffer,
1115
+ towrite,coords,&written)) {
1116
+ return UINT2NUM( written );
1117
+ }
1118
+ return rb_getWin32Error();
1119
+ }
1120
+
1121
+
1122
+ VALUE
1123
+ rb_WriteConsoleOutputCharacter(VALUE self, VALUE h, VALUE s,
1124
+ VALUE x, VALUE y)
1125
+ {
1126
+
1127
+ HANDLE handle = ULongToPtr( NUM2ULONG( h ) );
1128
+ Check_Type( s, T_STRING );
1129
+
1130
+ DWORD written;
1131
+ COORD coords;
1132
+ coords.X=NUM2INT( x );
1133
+ coords.Y=NUM2INT( y );
1134
+ if (WriteConsoleOutputCharacter(handle,(LPCTSTR)RSTRING(s)->ptr,
1135
+ RSTRING(s)->len,coords,&written)) {
1136
+ return UINT2NUM( written );
1137
+ }
1138
+ return rb_getWin32Error();
1139
+ }
1140
+
1141
+
1142
+ CONSOLE_EXPORT void
1143
+ Init_Console(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
+ }
1217
+
1218
+ }