special_input_device 0.0.0

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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/ext/special_input_device/_screen.c +25 -0
  3. data/ext/special_input_device/_screen.h +16 -0
  4. data/ext/special_input_device/_system_time.c +10 -0
  5. data/ext/special_input_device/_system_time.h +6 -0
  6. data/ext/special_input_device/_vendor__interception.c +331 -0
  7. data/ext/special_input_device/_vendor__interception.h +196 -0
  8. data/ext/special_input_device/color.c +25 -0
  9. data/ext/special_input_device/color.h +10 -0
  10. data/ext/special_input_device/extconf.rb +6 -0
  11. data/ext/special_input_device/interception_connector.c +75 -0
  12. data/ext/special_input_device/interception_connector.h +13 -0
  13. data/ext/special_input_device/keyboard.c +152 -0
  14. data/ext/special_input_device/mouse.c +1137 -0
  15. data/ext/special_input_device/point.c +17 -0
  16. data/ext/special_input_device/point.h +10 -0
  17. data/ext/special_input_device/rectangle.c +25 -0
  18. data/ext/special_input_device/rectangle.h +10 -0
  19. data/ext/special_input_device/ruby_macro.h +84 -0
  20. data/ext/special_input_device/screen.c +302 -0
  21. data/ext/special_input_device/special_input_device.c +40 -0
  22. data/ext/special_input_device/special_input_device.h +42 -0
  23. data/ext/special_input_device/win32error.c +69 -0
  24. data/ext/special_input_device/win32error.h +8 -0
  25. data/ext/special_input_device/window.c +1108 -0
  26. data/lib/special_input_device/attributes_equal_checker.rb +13 -0
  27. data/lib/special_input_device/color.rb +156 -0
  28. data/lib/special_input_device/image.rb +170 -0
  29. data/lib/special_input_device/image/bmp.rb +89 -0
  30. data/lib/special_input_device/image/error/damaged_image_error.rb +4 -0
  31. data/lib/special_input_device/image/error/image_error.rb +3 -0
  32. data/lib/special_input_device/image/error/unsupported_image_format_error.rb +4 -0
  33. data/lib/special_input_device/key_code.rb +268 -0
  34. data/lib/special_input_device/point.rb +48 -0
  35. data/lib/special_input_device/rectangle.rb +187 -0
  36. data/lib/special_input_device/special_input_device.rb +67 -0
  37. data/lib/special_input_device/table_2d.rb +157 -0
  38. data/stab/keyboard.rb +35 -0
  39. data/stab/mouse.rb +189 -0
  40. data/stab/screen.rb +56 -0
  41. data/stab/win32_error.rb +20 -0
  42. data/stab/window.rb +398 -0
  43. metadata +85 -0
@@ -0,0 +1,17 @@
1
+ #include "special_input_device.h"
2
+
3
+ VALUE ruby___point_new(INT cX, INT cY) {
4
+ VALUE newPointArguments[2];
5
+ newPointArguments[0] = INT2NUM(cX);
6
+ newPointArguments[1] = INT2NUM(cY);
7
+ return rb_class_new_instance(2, newPointArguments, specialInputDevice_point);
8
+ }
9
+
10
+ inline VALUE ruby___point_new_from_point(LPPOINT cPoint) {
11
+ return ruby___point_new(cPoint->x, cPoint->y);
12
+ }
13
+
14
+ inline VOID ruby___point_to_point(VALUE point, LPPOINT cPoint) {
15
+ cPoint->x = NUM2LONG(rb_iv_get(point, "@x"));
16
+ cPoint->y = NUM2LONG(rb_iv_get(point, "@y"));
17
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef SPECIAL_INPUT_DEVICE_POINT_H
2
+ #define SPECIAL_INPUT_DEVICE_POINT_H
3
+
4
+ VALUE ruby___point_new(INT cX, INT cY);
5
+
6
+ VALUE ruby___point_new_from_point(LPPOINT cPoint);
7
+
8
+ VOID ruby___point_to_point(VALUE point, LPPOINT cPoint);
9
+
10
+ #endif //SPECIAL_INPUT_DEVICE_POINT_H
@@ -0,0 +1,25 @@
1
+ #include "special_input_device.h"
2
+
3
+ VALUE ruby___rectangle_new(INT left, INT top, INT right, INT bottom) {
4
+ VALUE newOriginArguments[2];
5
+ VALUE newEndPointArguments[2];
6
+ VALUE newRectangleArguments[2];
7
+ newOriginArguments[0] = INT2NUM(left);
8
+ newOriginArguments[1] = INT2NUM(top);
9
+ newEndPointArguments[0] = INT2NUM(right);
10
+ newEndPointArguments[1] = INT2NUM(bottom);
11
+ newRectangleArguments[0] = rb_class_new_instance(2, newOriginArguments, specialInputDevice_point);
12
+ newRectangleArguments[1] = rb_class_new_instance(2, newEndPointArguments, specialInputDevice_point);
13
+ return rb_class_new_instance(2, newRectangleArguments, specialInputDevice_rectangle);
14
+ }
15
+
16
+ inline VALUE ruby___rectangle_new_from_rect(LPRECT cRectangle) {
17
+ return ruby___rectangle_new(cRectangle->left, cRectangle->top, cRectangle->right, cRectangle->bottom);
18
+ }
19
+
20
+ inline VOID ruby___rectangle_to_rect(VALUE rectangle, LPRECT cRectangle) {
21
+ cRectangle->left = NUM2LONG(rb_funcall(rectangle, rb_intern_const("left"), 0));
22
+ cRectangle->top = NUM2LONG(rb_funcall(rectangle, rb_intern_const("top"), 0));
23
+ cRectangle->right = NUM2LONG(rb_funcall(rectangle, rb_intern_const("right"), 0));
24
+ cRectangle->bottom = NUM2LONG(rb_funcall(rectangle, rb_intern_const("bottom"), 0));
25
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef SPECIAL_INPUT_DEVICE_RECTANGLE_H
2
+ #define SPECIAL_INPUT_DEVICE_RECTANGLE_H
3
+
4
+ VALUE ruby___rectangle_new(INT left, INT top, INT right, INT bottom);
5
+
6
+ VALUE ruby___rectangle_new_from_rect(LPRECT cRectangle);
7
+
8
+ VOID ruby___rectangle_to_rect(VALUE rectangle, LPRECT cRectangle);
9
+
10
+ #endif //SPECIAL_INPUT_DEVICE_RECTANGLE_H
@@ -0,0 +1,84 @@
1
+ #ifndef SPECIAL_INPUT_DEVICE_RUBY_MACRO_H
2
+ #define SPECIAL_INPUT_DEVICE_RUBY_MACRO_H
3
+
4
+ #include "win32error.h"
5
+
6
+ // Hide error messages in CLion
7
+ #ifdef CLION
8
+
9
+ NORETURN(void _RUBY_KERNEL_RAISE();)
10
+
11
+ # define RUBY_KERNEL_RAISE(exception) \
12
+ (rb_funcall(rb_mKernel, rb_intern_const("raise"), 1, exception), _RUBY_KERNEL_RAISE())
13
+ # define RUBY_OBJECT_IS_A_qs(object, _class) rb_funcall(object, rb_intern_const("is_a?"), 1, _class)
14
+ # define RUBY_REGEXP_MATCH(regexp, string) rb_funcall(regexp, rb_intern_const("match"), 1, string)
15
+ # define RUBY_MODULE_CONST_GET(module, id) rb_funcall(module, rb_intern_const("const_get"), 1, id)
16
+ #else
17
+ # define RUBY_KERNEL_RAISE(exception) rb_exc_raise(exception)
18
+ # define RUBY_OBJECT_IS_A_qs(object, _class) rb_obj_is_kind_of(object, _class)
19
+ # define RUBY_REGEXP_MATCH(regexp, string) rb_reg_match(regexp, string)
20
+ # define RUBY_MODULE_CONST_GET(module, id) rb_const_get(module, id)
21
+ #endif
22
+
23
+ // Encoding
24
+ #define INTERNAL_ENCODING rb_utf8_encoding()
25
+ #ifdef UNICODE
26
+ # define EXTERNAL_ENCODING rb_enc_find("UTF-16LE")
27
+ VALUE __ruby_string_converter_temp_variable;
28
+ # define RUBY_LPTSTR_TO_VALUE(string, length) \
29
+ (\
30
+ __ruby_string_converter_temp_variable = rb_str_new((LPSTR) string, length * sizeof(WCHAR)),\
31
+ __ruby_string_converter_temp_variable = rb_enc_associate(__ruby_string_converter_temp_variable, EXTERNAL_ENCODING),\
32
+ rb_str_export_to_enc(__ruby_string_converter_temp_variable, INTERNAL_ENCODING)\
33
+ )
34
+ # define RUBY_LPCTSTR_TO_VALUE(string) \
35
+ RUBY_LPTSTR_TO_VALUE(string, (INT) wcslen(string))
36
+ # define RUBY_VALUE_TO_LPTSTR(string, _OUT_length) \
37
+ (\
38
+ __ruby_string_converter_temp_variable = rb_str_export_to_enc(string, EXTERNAL_ENCODING),\
39
+ _OUT_length = RSTRING_LEN(__ruby_string_converter_temp_variable) / sizeof(WCHAR),\
40
+ (LPTSTR) StringValuePtr(__ruby_string_converter_temp_variable)\
41
+ )
42
+ # define RUBY_VALUE_TO_LPCTSTR(string) \
43
+ (\
44
+ __ruby_string_converter_temp_variable = rb_str_export_to_enc(string, EXTERNAL_ENCODING),\
45
+ (LPCTSTR) StringValueCStr(__ruby_string_converter_temp_variable)\
46
+ )
47
+ #else
48
+ # define EXTERNAL_ENCODING rb_locale_encoding()
49
+ # define RUBY_LPTSTR_TO_VALUE(string, length) \
50
+ rb_enc_str_new(string, length, EXTERNAL_ENCODING);
51
+ # define RUBY_LPCTSTR_TO_VALUE(string) \
52
+ rb_enc_str_new_cstr(string, EXTERNAL_ENCODING);
53
+ # define RUBY_VALUE_TO_LPTSTR(string, _OUT_length) \
54
+ (_OUT_length = RSTRING_LEN(string), StringValuePtr())
55
+ # define RUBY_VALUE_TO_LPCTSTR(string) \
56
+ StringValueCStr(string)
57
+ #endif
58
+
59
+ #define NEW_DATA_OBJECT(_class, data_type, mark, free) \
60
+ rb_data_object_zalloc((_class), sizeof(data_type), (RUBY_DATA_FUNC)(mark), (RUBY_DATA_FUNC)(free))
61
+ #define NEW_SIMPLE_DATA_OBJECT(_class, data_type) NEW_DATA_OBJECT(_class, data_type, NULL, RUBY_DEFAULT_FREE)
62
+
63
+ #define RUBY_KERNEL_P(object) rb_funcall(rb_mKernel, rb_intern_const("p"), 1, object)
64
+ #define RUBY_KERNEL_PUTS(object) rb_funcall(rb_mKernel, rb_intern_const("puts"), 1, object)
65
+
66
+ #define RAISE_WIN32_ERROR RUBY_KERNEL_RAISE(ruby___win32error_new())
67
+ #define RAISE_WIN32_ERROR_FROM_CODE(code) RUBY_KERNEL_RAISE(ruby___win32error_new_from_code(code))
68
+ #define RAISE_ARGUMENT_ERROR(expected) \
69
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected %s)", cCount, expected)
70
+ #define RAISE_TYPE_ERROR(object, expected) \
71
+ rb_raise(rb_eTypeError, "Expecting %s, got %s", expected, rb_obj_classname(object))
72
+ #define CHECK_TYPE_ERROR(object, expected) \
73
+ ({\
74
+ if (!RTEST(RUBY_OBJECT_IS_A_qs(object, expected)))\
75
+ RAISE_TYPE_ERROR(object, rb_class2name(expected));\
76
+ })
77
+
78
+ #define VARIABLE_ARGUMENTS_C INT cCount, VALUE* cArguments, VALUE self
79
+ #define VARIABLE_ARGUMENTS_RUBY VALUE self, VALUE arguments
80
+ #define SCAN_ARGUMENTS(format, arguments...) rb_scan_args(cCount, cArguments, format, arguments)
81
+
82
+ #define ARGUMENT_AT(index, defaultValue) cCount > index ? cArguments[index] : defaultValue
83
+
84
+ #endif //SPECIAL_INPUT_DEVICE_RUBY_MACRO_H
@@ -0,0 +1,302 @@
1
+ #include "special_input_device.h"
2
+ #include "_screen.h"
3
+ #include "color.h"
4
+ #include "rectangle.h"
5
+
6
+ /*
7
+ * Returns the rectangle of primary screen. The rectangle is relative to primary screen itself so the upper-left corner
8
+ * of the rectangle is always (0, 0).
9
+ * @return [SpecialInputDevice::Rectangle] the rectangle of primary screen
10
+ * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385.aspx Windows Dev Center - GetSystemMetrics function
11
+ */
12
+ static VALUE ruby__primary_screen(VALUE self) {
13
+ return ruby___rectangle_new(0, 0, getPrimaryScreenWidth(), getPrimaryScreenHeight());
14
+ }
15
+
16
+ /*
17
+ * Returns the rectangle of virtual screen. The rectangle is relative to primary screen so the x and y of upper-left
18
+ * corner is always non-positive. Virtual screen is a area that contain all the screens and some position in virtual may
19
+ * not accessible.
20
+ * @return [SpecialInputDevice::Rectangle] the rectangle of virtual screen
21
+ * @see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385.aspx Windows Dev Center - GetSystemMetrics function
22
+ */
23
+ static VALUE ruby__virtual_screen(VALUE self) {
24
+ INT left = getVirtualScreenX();
25
+ INT top = getVirtualScreenY();
26
+ return ruby___rectangle_new(
27
+ left,
28
+ top,
29
+ getVirtualScreenWidth() + left,
30
+ getVirtualScreenHeight() + top
31
+ );
32
+ }
33
+
34
+ /*
35
+ * @overload color_at(x, y)
36
+ * Returns the color at the specific position on primary screen coordinate system.
37
+ * @param [Fixnum] x the x coordinate of the point for get color
38
+ * @param [Fixnum] y the y coordinate of the point for get color
39
+ * @return [SpecialInputDevice::Color] the color at the specified point at the screen
40
+ * @see SpecialInputDevice::Window#color_at
41
+ * @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd144909.aspx Windows Dev Center - GetPixel function
42
+ */
43
+ static VALUE ruby__color_at(VALUE self, VALUE x, VALUE y) {
44
+ INT cX = NUM2INT(x);
45
+ INT cY = NUM2INT(y);
46
+ HDC cHDC = GetDC(NULL);
47
+ COLORREF cColor = GetPixel(cHDC, cX, cY);
48
+ ReleaseDC(NULL, cHDC);
49
+ return ruby___color_new_from_color_ref(cColor);
50
+ }
51
+
52
+ typedef struct {
53
+ VALUE pipe;
54
+ DWORD cFileSize;
55
+ LPSTR cBitmapFile;
56
+ HANDLE cHBitmapFile;
57
+ } SID_SCREEN_CAPTURE_PARAMETER_THREAD;
58
+
59
+ static VALUE ruby__capture_helper_thread(SID_SCREEN_CAPTURE_PARAMETER_THREAD *cParameters) {
60
+ VALUE bitmapFile = rb_enc_str_new(cParameters->cBitmapFile, cParameters->cFileSize, rb_ascii8bit_encoding());
61
+ rb_funcall(cParameters->pipe, rb_intern_const("write"), 1, bitmapFile);
62
+ return Qnil;
63
+ }
64
+
65
+ typedef struct {
66
+ INT cX;
67
+ INT cY;
68
+ INT cWidth;
69
+ INT cHeight;
70
+ HDC cCompatibleDC;
71
+ HDC cHDC;
72
+ LPSTR cBitmapFile;
73
+ HANDLE cHBitmapFile;
74
+ } SID_SCREEN_CAPTURE_PARAMETER_PROTECT;
75
+
76
+ static VALUE ruby__capture_helper_protect(VALUE arguments) {
77
+ VALUE bmpClass;
78
+ VALUE pipesEncoding = rb_str_new_cstr("ASCII-8BIT");
79
+ VALUE pipes;
80
+ VALUE pipeIn;
81
+ VALUE pipeOut;
82
+
83
+ SID_SCREEN_CAPTURE_PARAMETER_PROTECT *cParameterProtect;
84
+ SID_SCREEN_CAPTURE_PARAMETER_THREAD cParameterThread;
85
+
86
+ WORD cBitPerPixel;
87
+ DWORD cPaletteSize;
88
+ DWORD cDataSize;
89
+ DWORD cFileSize;
90
+ BITMAP cBitmap;
91
+ HBITMAP cHBitmap;
92
+ BITMAPFILEHEADER cFileHeader;
93
+ BITMAPINFOHEADER cInfoHeader;
94
+ LPBITMAPFILEHEADER cPFileHeader;
95
+ LPBITMAPINFOHEADER cPInfoHeader;
96
+ LPSTR cPPalette;
97
+ LPSTR cPData;
98
+ HPALETTE cPalette = GetStockObject(DEFAULT_PALETTE);
99
+ HPALETTE cOldPalette = NULL;
100
+
101
+ Data_Get_Struct(arguments, SID_SCREEN_CAPTURE_PARAMETER_PROTECT, cParameterProtect);
102
+
103
+ cParameterProtect->cCompatibleDC = CreateCompatibleDC(NULL);
104
+ cParameterProtect->cHDC = GetDC(NULL);
105
+ cHBitmap = CreateCompatibleBitmap(cParameterProtect->cHDC, cParameterProtect->cWidth, cParameterProtect->cHeight);
106
+
107
+ SelectObject(cParameterProtect->cCompatibleDC, cHBitmap);
108
+ BitBlt(cParameterProtect->cCompatibleDC, 0, 0, cParameterProtect->cWidth, cParameterProtect->cHeight,
109
+ cParameterProtect->cHDC, cParameterProtect->cX, cParameterProtect->cY, SRCCOPY);
110
+ GetObject(cHBitmap, sizeof(BITMAP), (LPSTR) &cBitmap);
111
+
112
+ cBitPerPixel = (WORD) (GetDeviceCaps(cParameterProtect->cHDC, BITSPIXEL) *
113
+ GetDeviceCaps(cParameterProtect->cHDC, PLANES));
114
+ if (cBitPerPixel <= 1)
115
+ cBitPerPixel = 1;
116
+ else if (cBitPerPixel <= 4)
117
+ cBitPerPixel = 4;
118
+ else if (cBitPerPixel <= 8)
119
+ cBitPerPixel = 8;
120
+ else if (cBitPerPixel <= 24)
121
+ cBitPerPixel = 24;
122
+ else
123
+ cBitPerPixel = 32;
124
+
125
+ cPaletteSize = cBitPerPixel <= 8 ? (1 << cBitPerPixel) * sizeof(RGBQUAD) : 0;
126
+ cDataSize = (DWORD) (((cBitmap.bmWidth * cBitPerPixel + 31) / 32) * 4 * cBitmap.bmHeight);
127
+ cFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + cPaletteSize + cDataSize;
128
+
129
+ cFileHeader.bfType = 0x4D42;
130
+ cFileHeader.bfSize = cFileSize;
131
+ cFileHeader.bfReserved1 = 0;
132
+ cFileHeader.bfReserved2 = 0;
133
+ cFileHeader.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + (DWORD) sizeof(BITMAPINFOHEADER) + cPaletteSize;
134
+
135
+ cInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
136
+ cInfoHeader.biWidth = cBitmap.bmWidth;
137
+ cInfoHeader.biHeight = cBitmap.bmHeight;
138
+ cInfoHeader.biPlanes = 1;
139
+ cInfoHeader.biBitCount = cBitPerPixel;
140
+ cInfoHeader.biCompression = BI_RGB;
141
+ cInfoHeader.biSizeImage = 0;
142
+ cInfoHeader.biXPelsPerMeter = 0;
143
+ cInfoHeader.biYPelsPerMeter = 0;
144
+ cInfoHeader.biClrUsed = 0;
145
+ cInfoHeader.biClrImportant = 0;
146
+
147
+ cParameterProtect->cHBitmapFile = GlobalAlloc(GHND, cFileSize);
148
+ if (!cParameterProtect->cHBitmapFile)
149
+ RAISE_WIN32_ERROR;
150
+ cParameterProtect->cBitmapFile = (LPSTR) GlobalLock(cParameterProtect->cHBitmapFile);
151
+ if (!cParameterProtect->cBitmapFile)
152
+ RAISE_WIN32_ERROR;
153
+
154
+ cPFileHeader = (LPBITMAPFILEHEADER) cParameterProtect->cBitmapFile;
155
+ cPInfoHeader = (LPBITMAPINFOHEADER) (cPFileHeader + 1);
156
+ cPPalette = (LPSTR) (cPInfoHeader + 1);
157
+ cPData = cPPalette + cPaletteSize;
158
+
159
+ *cPFileHeader = cFileHeader;
160
+ *cPInfoHeader = cInfoHeader;
161
+ if (cPalette) {
162
+ cOldPalette = SelectPalette(cParameterProtect->cHDC, cPalette, FALSE);
163
+ RealizePalette(cParameterProtect->cHDC);
164
+ }
165
+ GetDIBits(cParameterProtect->cHDC, cHBitmap, 0, (UINT) cBitmap.bmHeight, cPData, (LPBITMAPINFO) cPInfoHeader,
166
+ DIB_RGB_COLORS);
167
+ if (cOldPalette) {
168
+ SelectPalette(cParameterProtect->cHDC, cOldPalette, TRUE);
169
+ RealizePalette(cParameterProtect->cHDC);
170
+ }
171
+
172
+ pipes = rb_funcall(rb_cIO, rb_intern_const("pipe"), 2, pipesEncoding, pipesEncoding);
173
+ pipeIn = rb_ary_entry(pipes, 1);
174
+ pipeOut = rb_ary_entry(pipes, 0);
175
+
176
+ cParameterThread.pipe = pipeIn;
177
+ cParameterThread.cFileSize = cFileSize;
178
+ cParameterThread.cBitmapFile = cParameterProtect->cBitmapFile;
179
+ cParameterThread.cHBitmapFile = cParameterProtect->cHBitmapFile;
180
+ rb_thread_create(ruby__capture_helper_thread, &cParameterThread);
181
+
182
+ bmpClass = RUBY_MODULE_CONST_GET(specialInputDevice_image, rb_intern_const("BMP"));
183
+ return rb_funcall(bmpClass, rb_intern_const("load"), 1, pipeOut);
184
+ }
185
+
186
+ /*
187
+ * @overload capture()
188
+ * Capture the whole screen.
189
+ * @overload capture(x, y, width, height)
190
+ * Capture a rectangle part of screen.
191
+ * @param [Integer] x the x-coordinate of the left edge
192
+ * @param [Integer] y the y-coordinate of the top edge
193
+ * @param [Integer] width the width of rectangle
194
+ * @param [Integer] height the height of rectangle
195
+ * @return [SpecialInputDevice::Image]
196
+ */
197
+ static VALUE ruby__capture(VARIABLE_ARGUMENTS_C) {
198
+ VALUE x;
199
+ VALUE y;
200
+ VALUE width;
201
+ VALUE height;
202
+ VALUE parameter;
203
+ SID_SCREEN_CAPTURE_PARAMETER_PROTECT *cParameter;
204
+ INT cError;
205
+ VALUE result;
206
+ parameter = Data_Make_Struct(rb_cData, SID_SCREEN_CAPTURE_PARAMETER_PROTECT, NULL, RUBY_DEFAULT_FREE,
207
+ cParameter);
208
+ switch (cCount) {
209
+ case 0: {
210
+ cParameter->cX = getVirtualScreenX();
211
+ cParameter->cY = getVirtualScreenY();
212
+ cParameter->cWidth = getVirtualScreenWidth();
213
+ cParameter->cHeight = getVirtualScreenHeight();
214
+ break;
215
+ }
216
+ case 4: {
217
+ SCAN_ARGUMENTS("4", &x, &y, &width, &height);
218
+ cParameter->cX = NUM2INT(x);
219
+ cParameter->cY = NUM2INT(y);
220
+ cParameter->cWidth = NUM2INT(width);
221
+ cParameter->cHeight = NUM2INT(height);
222
+ break;
223
+ }
224
+ default:
225
+ RAISE_ARGUMENT_ERROR("0, 4");
226
+ }
227
+ result = rb_protect(ruby__capture_helper_protect, parameter, &cError);
228
+ GlobalUnlock(cParameter->cHBitmapFile);
229
+ GlobalFree(cParameter->cHBitmapFile);
230
+ ReleaseDC(NULL, cParameter->cCompatibleDC);
231
+ ReleaseDC(NULL, cParameter->cHDC);
232
+ if (cError)
233
+ rb_jump_tag(cError);
234
+ return result;
235
+ }
236
+
237
+ /*
238
+ * @overload find_image(image, area: SpecialInputDevice::Screen.primary_screen, similarity: 1.0, _return: RETURN_METHOD::FIRST)
239
+ * @param [SpecialInputDevice::Image, String] image a picture to be search
240
+ * @param [SpecialInputDevice::Rectangle] area the searching area
241
+ * @param [Float] similarity minimum limit of similarity
242
+ * @param [Symbol] _return indicate the behavior of this method, see SpecialInputDevice::Image::RETURN_METHOD
243
+ * @return [NilClass, SpecialInputDevice::Rectangle] a rectangle contain the position and the size of the result
244
+ * @see SpecialInputDevice::Image#find
245
+ * @see SpecialInputDevice::Image::RETURN_METHOD
246
+ */
247
+ static VALUE ruby__find_image(VARIABLE_ARGUMENTS_C) {
248
+ VALUE image;
249
+ VALUE options;
250
+ ID keywords[1] = {
251
+ rb_intern_const("area")
252
+ };
253
+ VALUE option_values[sizeof(keywords)];
254
+ VALUE *area = option_values + 0;
255
+ VALUE x = Qnil;
256
+ VALUE y = Qnil;
257
+ VALUE capture;
258
+ VALUE captureArguments[4];
259
+ VALUE result;
260
+ SCAN_ARGUMENTS("1:", &image, &options);
261
+ rb_get_kwargs(options, keywords, 0, -2, option_values);
262
+ if (RTEST(RUBY_OBJECT_IS_A_qs(image, rb_cString)) || RTEST(RUBY_OBJECT_IS_A_qs(image, rb_cFile)))
263
+ image = rb_funcall(specialInputDevice_image, rb_intern_const("load"), 1, image);
264
+ else if (!RTEST(RUBY_OBJECT_IS_A_qs(image, specialInputDevice_image)))
265
+ RAISE_TYPE_ERROR(image, "String, File or SpecialInputDevice::Image");
266
+ if (*area == Qundef) {
267
+ capture = ruby__capture(0, captureArguments, self);
268
+ } else {
269
+ CHECK_TYPE_ERROR(*area, specialInputDevice_rectangle);
270
+ x = rb_funcall(*area, rb_intern_const("x"), 0);
271
+ y = rb_funcall(*area, rb_intern_const("y"), 0);
272
+ captureArguments[0] = x;
273
+ captureArguments[1] = y;
274
+ captureArguments[2] = rb_funcall(*area, rb_intern_const("width"), 0);
275
+ captureArguments[3] = rb_funcall(*area, rb_intern_const("height"), 0);
276
+ capture = ruby__capture(4, captureArguments, self);
277
+ }
278
+ // return capture;
279
+ rb_funcall(capture, rb_intern_const("save"), 1, rb_str_new_cstr("D:/2.bmp"));
280
+ result = rb_funcall(capture, rb_intern_const("find"), 2, image, options);
281
+ if (result != Qnil && *area != Qundef)
282
+ result = rb_funcall(result, rb_intern_const("move"), 2, x, y);
283
+ return result;
284
+ }
285
+
286
+ VOID Init_screen() {
287
+ #ifdef YARD
288
+ specialInputDevice = rb_define_module("SpecialInputDevice");
289
+ #endif
290
+ /*
291
+ * Document-module: SpecialInputDevice::Screen
292
+ *
293
+ * The <code>Screen</code> module provides an interface to receive the information for the screen and to simulate
294
+ * the signal form the touch screen.
295
+ */
296
+ VALUE specialInputDevice_screen = rb_define_module_under(specialInputDevice, "Screen");
297
+ rb_define_singleton_method(specialInputDevice_screen, "primary_screen", ruby__primary_screen, 0);
298
+ rb_define_singleton_method(specialInputDevice_screen, "virtual_screen", ruby__virtual_screen, 0);
299
+ rb_define_singleton_method(specialInputDevice_screen, "color_at", ruby__color_at, 2);
300
+ rb_define_singleton_method(specialInputDevice_screen, "capture", ruby__capture, -1);
301
+ rb_define_singleton_method(specialInputDevice_screen, "find_image", ruby__find_image, -1);
302
+ }