special_input_device 0.0.0 → 0.0.1

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/ext/special_input_device/color.c +25 -6
  3. data/ext/special_input_device/color.h +5 -1
  4. data/ext/special_input_device/extconf.rb +2 -2
  5. data/ext/special_input_device/image.c +728 -0
  6. data/ext/special_input_device/image.h +8 -0
  7. data/ext/special_input_device/{interception_connector.c → interception.c} +7 -3
  8. data/ext/special_input_device/{interception_connector.h → interception.h} +0 -0
  9. data/ext/special_input_device/keyboard.c +4 -4
  10. data/ext/special_input_device/mouse.c +26 -28
  11. data/ext/special_input_device/ruby_macro.h +11 -3
  12. data/ext/special_input_device/screen.c +54 -164
  13. data/ext/special_input_device/special_input_device.c +2 -2
  14. data/ext/special_input_device/special_input_device.h +2 -1
  15. data/ext/special_input_device/win32error.c +0 -2
  16. data/ext/special_input_device/window.c +82 -105
  17. data/lib/special_input_device/color.rb +2 -3
  18. data/lib/special_input_device/image.rb +2 -61
  19. data/lib/special_input_device/point.rb +0 -1
  20. data/lib/special_input_device/special_input_device.rb +0 -1
  21. metadata +7 -15
  22. data/lib/special_input_device/image/bmp.rb +0 -89
  23. data/lib/special_input_device/image/error/damaged_image_error.rb +0 -4
  24. data/lib/special_input_device/image/error/image_error.rb +0 -3
  25. data/lib/special_input_device/image/error/unsupported_image_format_error.rb +0 -4
  26. data/lib/special_input_device/table_2d.rb +0 -157
  27. data/stab/keyboard.rb +0 -35
  28. data/stab/mouse.rb +0 -189
  29. data/stab/screen.rb +0 -56
  30. data/stab/win32_error.rb +0 -20
  31. data/stab/window.rb +0 -398
@@ -0,0 +1,8 @@
1
+ #ifndef SPECIAL_INPUT_DEVICE_IMAGE_H
2
+ #define SPECIAL_INPUT_DEVICE_IMAGE_H
3
+
4
+ VALUE ruby___image_new(UINT cWidth, UINT cHeight);
5
+
6
+ VALUE ruby___image_new_from_bitmap(HBITMAP cHBitmap);
7
+
8
+ #endif //SPECIAL_INPUT_DEVICE_IMAGE_H
@@ -26,7 +26,9 @@ InterceptionDevice ruby___interception_find_keyboard() {
26
26
  MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
27
27
  return cData->keyboard;
28
28
  }
29
- rb_raise(rb_eRuntimeError, "Can not find any keyboard connected.");
29
+ rb_raise(rb_eRuntimeError, "Can not find any keyboard connected. Make sure you have at least one keyboard connected"
30
+ " and interception driver has been installed. Otherwise, you may try to use other mode instead of"
31
+ " interception mode.");
30
32
  }
31
33
 
32
34
  InterceptionDevice ruby___interception_find_mouse() {
@@ -40,12 +42,14 @@ InterceptionDevice ruby___interception_find_mouse() {
40
42
  MAXIMUM_HARDWARE_IDENTIFIER_LENGTH))
41
43
  return cData->mouse;
42
44
  }
43
- rb_raise(rb_eRuntimeError, "Can not find any mouse connected.");
45
+ rb_raise(rb_eRuntimeError, "Can not find any mouse connected. Make sure you have at least one keyboard connected"
46
+ " and interception driver has been installed. Otherwise, you may try to use other mode instead of"
47
+ " interception mode.");
44
48
  }
45
49
 
46
50
  static VOID callback_interception_free(SID_INTERCEPTION_DATA *cData) {
47
51
  interceptionDestroyContext(cData->context);
48
- free(cData);
52
+ xfree(cData);
49
53
  }
50
54
 
51
55
  static VALUE ruby__alloc(VALUE self) {
@@ -1,5 +1,5 @@
1
1
  #include "special_input_device.h"
2
- #include "interception_connector.h"
2
+ #include "interception.h"
3
3
 
4
4
  /*
5
5
  * @overload hold(key_code)
@@ -32,7 +32,7 @@ static VALUE ruby__hold(VALUE self, VALUE keyCode) {
32
32
  cInput.ki.wScan = (WORD) cScanCode;
33
33
  cInput.ki.wVk = cKeyCode;
34
34
  if (SendInput(1, &cInput, sizeof(INPUT)) == 0)
35
- RAISE_WIN32_ERROR;
35
+ RAISE_WIN32_ERROR();
36
36
  break;
37
37
  }
38
38
  default: {
@@ -83,7 +83,7 @@ static VALUE ruby__press(VALUE self, VALUE keyCode) {
83
83
  cInput[1].ki.wScan = (WORD) cScanCode;
84
84
  cInput[1].ki.wVk = cKeyCode;
85
85
  if (SendInput(2, cInput, sizeof(INPUT)) == 0)
86
- RAISE_WIN32_ERROR;
86
+ RAISE_WIN32_ERROR();
87
87
  break;
88
88
  }
89
89
  default: {
@@ -125,7 +125,7 @@ static VALUE ruby__release(VALUE self, VALUE keyCode) {
125
125
  cInput.ki.wScan = (WORD) cScanCode;
126
126
  cInput.ki.wVk = cKeyCode;
127
127
  if (SendInput(1, &cInput, sizeof(INPUT)) == 0)
128
- RAISE_WIN32_ERROR;
128
+ RAISE_WIN32_ERROR();
129
129
  break;
130
130
  }
131
131
  default: {
@@ -1,6 +1,6 @@
1
1
  #include "special_input_device.h"
2
2
  #include "_screen.h"
3
- #include "interception_connector.h"
3
+ #include "interception.h"
4
4
  #include "point.h"
5
5
 
6
6
  //<editor-fold desc="cursor">
@@ -16,9 +16,8 @@ static VALUE ruby__lock(VALUE self) {
16
16
  interceptionSetFilter(cContext, interceptionIsMouse, INTERCEPTION_FILTER_MOUSE_ALL);
17
17
  break;
18
18
  }
19
- case MODE_WIN_API: {
19
+ case MODE_WIN_API:
20
20
  rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
21
- }
22
21
  default: {
23
22
  PCHAR cModeName = ruby___special_input_device_get_mode_name();
24
23
  rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
@@ -38,9 +37,8 @@ static VALUE ruby__unlock(VALUE self) {
38
37
  interceptionSetFilter(cContext, interceptionIsMouse, INTERCEPTION_FILTER_MOUSE_NONE);
39
38
  break;
40
39
  }
41
- case MODE_WIN_API: {
40
+ case MODE_WIN_API:
42
41
  rb_raise(rb_eRuntimeError, "WinAPI mode does not support lock mouse function.");
43
- }
44
42
  default: {
45
43
  PCHAR cModeName = ruby___special_input_device_get_mode_name();
46
44
  rb_raise(rb_eRuntimeError, "Undefined mode '%s'.", cModeName);
@@ -56,7 +54,7 @@ static VALUE ruby__unlock(VALUE self) {
56
54
  static VALUE ruby__cursor_position(VALUE self) {
57
55
  POINT cPoint;
58
56
  if (!GetCursorPos(&cPoint))
59
- RAISE_WIN32_ERROR;
57
+ RAISE_WIN32_ERROR();
60
58
  return ruby___point_new_from_point(&cPoint);
61
59
  }
62
60
 
@@ -96,7 +94,7 @@ static VALUE ruby__move_relatively(VALUE self, VALUE x, VALUE y) {
96
94
  input.mi.mouseData = 0;
97
95
  input.mi.time = 0;
98
96
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
99
- RAISE_WIN32_ERROR;
97
+ RAISE_WIN32_ERROR();
100
98
  break;
101
99
  }
102
100
  default: {
@@ -145,7 +143,7 @@ static VALUE ruby__move_to_primary(VALUE self, VALUE x, VALUE y) {
145
143
  input.mi.mouseData = 0;
146
144
  input.mi.time = 0;
147
145
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
148
- RAISE_WIN32_ERROR;
146
+ RAISE_WIN32_ERROR();
149
147
  break;
150
148
  }
151
149
  default: {
@@ -195,7 +193,7 @@ static VALUE ruby__move_to_virtual(VALUE self, VALUE x, VALUE y) {
195
193
  input.mi.mouseData = 0;
196
194
  input.mi.time = 0;
197
195
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
198
- RAISE_WIN32_ERROR;
196
+ RAISE_WIN32_ERROR();
199
197
  break;
200
198
  }
201
199
  default: {
@@ -254,7 +252,7 @@ static VALUE ruby__left_click(VALUE self) {
254
252
  input[1].mi.mouseData = 0;
255
253
  input[1].mi.time = 0;
256
254
  if (SendInput(2, input, sizeof(INPUT)) == 0)
257
- RAISE_WIN32_ERROR;
255
+ RAISE_WIN32_ERROR();
258
256
  break;
259
257
  }
260
258
  default: {
@@ -296,7 +294,7 @@ static VALUE ruby__left_down(VALUE self) {
296
294
  input.mi.mouseData = 0;
297
295
  input.mi.time = 0;
298
296
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
299
- RAISE_WIN32_ERROR;
297
+ RAISE_WIN32_ERROR();
300
298
  break;
301
299
  }
302
300
  default: {
@@ -338,7 +336,7 @@ static VALUE ruby__left_up(VALUE self) {
338
336
  input.mi.mouseData = 0;
339
337
  input.mi.time = 0;
340
338
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
341
- RAISE_WIN32_ERROR;
339
+ RAISE_WIN32_ERROR();
342
340
  break;
343
341
  }
344
342
  default: {
@@ -397,7 +395,7 @@ static VALUE ruby__right_click(VALUE self) {
397
395
  input[1].mi.mouseData = 0;
398
396
  input[1].mi.time = 0;
399
397
  if (SendInput(2, input, sizeof(INPUT)) == 0)
400
- RAISE_WIN32_ERROR;
398
+ RAISE_WIN32_ERROR();
401
399
  break;
402
400
  }
403
401
  default: {
@@ -439,7 +437,7 @@ static VALUE ruby__right_down(VALUE self) {
439
437
  input.mi.mouseData = 0;
440
438
  input.mi.time = 0;
441
439
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
442
- RAISE_WIN32_ERROR;
440
+ RAISE_WIN32_ERROR();
443
441
  break;
444
442
  }
445
443
  default: {
@@ -481,7 +479,7 @@ static VALUE ruby__right_up(VALUE self) {
481
479
  input.mi.mouseData = 0;
482
480
  input.mi.time = 0;
483
481
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
484
- RAISE_WIN32_ERROR;
482
+ RAISE_WIN32_ERROR();
485
483
  break;
486
484
  }
487
485
  default: {
@@ -540,7 +538,7 @@ static VALUE ruby__middle_click(VALUE self) {
540
538
  input[1].mi.mouseData = 0;
541
539
  input[1].mi.time = 0;
542
540
  if (SendInput(2, input, sizeof(INPUT)) == 0)
543
- RAISE_WIN32_ERROR;
541
+ RAISE_WIN32_ERROR();
544
542
  break;
545
543
  }
546
544
  default: {
@@ -582,7 +580,7 @@ static VALUE ruby__middle_down(VALUE self) {
582
580
  input.mi.mouseData = 0;
583
581
  input.mi.time = 0;
584
582
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
585
- RAISE_WIN32_ERROR;
583
+ RAISE_WIN32_ERROR();
586
584
  break;
587
585
  }
588
586
  default: {
@@ -624,7 +622,7 @@ static VALUE ruby__middle_up(VALUE self) {
624
622
  input.mi.mouseData = 0;
625
623
  input.mi.time = 0;
626
624
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
627
- RAISE_WIN32_ERROR;
625
+ RAISE_WIN32_ERROR();
628
626
  break;
629
627
  }
630
628
  default: {
@@ -683,7 +681,7 @@ static VALUE ruby__x1_click(VALUE self) {
683
681
  input[1].mi.mouseData = XBUTTON1;
684
682
  input[1].mi.time = 0;
685
683
  if (SendInput(2, input, sizeof(INPUT)) == 0)
686
- RAISE_WIN32_ERROR;
684
+ RAISE_WIN32_ERROR();
687
685
  break;
688
686
  }
689
687
  default: {
@@ -725,7 +723,7 @@ static VALUE ruby__x1_down(VALUE self) {
725
723
  input.mi.mouseData = XBUTTON1;
726
724
  input.mi.time = 0;
727
725
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
728
- RAISE_WIN32_ERROR;
726
+ RAISE_WIN32_ERROR();
729
727
  break;
730
728
  }
731
729
  default: {
@@ -767,7 +765,7 @@ static VALUE ruby__x1_up(VALUE self) {
767
765
  input.mi.mouseData = XBUTTON1;
768
766
  input.mi.time = 0;
769
767
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
770
- RAISE_WIN32_ERROR;
768
+ RAISE_WIN32_ERROR();
771
769
  break;
772
770
  }
773
771
  default: {
@@ -822,7 +820,7 @@ static VALUE ruby__x2_click(VALUE self) {
822
820
  input[1].mi.mouseData = XBUTTON2;
823
821
  input[1].mi.time = 0;
824
822
  if (SendInput(2, input, sizeof(INPUT)) == 0)
825
- RAISE_WIN32_ERROR;
823
+ RAISE_WIN32_ERROR();
826
824
  break;
827
825
  }
828
826
  default: {
@@ -864,7 +862,7 @@ static VALUE ruby__x2_down(VALUE self) {
864
862
  input.mi.mouseData = XBUTTON2;
865
863
  input.mi.time = 0;
866
864
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
867
- RAISE_WIN32_ERROR;
865
+ RAISE_WIN32_ERROR();
868
866
  break;
869
867
  }
870
868
  default: {
@@ -906,7 +904,7 @@ static VALUE ruby__x2_up(VALUE self) {
906
904
  input.mi.mouseData = XBUTTON2;
907
905
  input.mi.time = 0;
908
906
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
909
- RAISE_WIN32_ERROR;
907
+ RAISE_WIN32_ERROR();
910
908
  break;
911
909
  }
912
910
  default: {
@@ -952,7 +950,7 @@ static VALUE ruby__scroll_wheel_backward(VALUE self) {
952
950
  input.mi.mouseData = (DWORD) -WHEEL_DELTA;
953
951
  input.mi.time = 0;
954
952
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
955
- RAISE_WIN32_ERROR;
953
+ RAISE_WIN32_ERROR();
956
954
  break;
957
955
  }
958
956
  default: {
@@ -994,7 +992,7 @@ static VALUE ruby__scroll_wheel_forward(VALUE self) {
994
992
  input.mi.mouseData = WHEEL_DELTA;
995
993
  input.mi.time = 0;
996
994
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
997
- RAISE_WIN32_ERROR;
995
+ RAISE_WIN32_ERROR();
998
996
  break;
999
997
  }
1000
998
  default: {
@@ -1037,7 +1035,7 @@ static VALUE ruby__scroll_wheel_to_left(VALUE self) {
1037
1035
  input.mi.mouseData = (DWORD) -WHEEL_DELTA;
1038
1036
  input.mi.time = 0;
1039
1037
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
1040
- RAISE_WIN32_ERROR;
1038
+ RAISE_WIN32_ERROR();
1041
1039
  break;
1042
1040
  }
1043
1041
  default: {
@@ -1083,7 +1081,7 @@ static VALUE ruby__scroll_wheel_to_right(VALUE self) {
1083
1081
  input.mi.mouseData = WHEEL_DELTA;
1084
1082
  input.mi.time = 0;
1085
1083
  if (SendInput(1, &input, sizeof(INPUT)) == 0)
1086
- RAISE_WIN32_ERROR;
1084
+ RAISE_WIN32_ERROR();
1087
1085
  break;
1088
1086
  }
1089
1087
  default: {
@@ -6,7 +6,7 @@
6
6
  // Hide error messages in CLion
7
7
  #ifdef CLION
8
8
 
9
- NORETURN(void _RUBY_KERNEL_RAISE();)
9
+ NORETURN(VOID _RUBY_KERNEL_RAISE();)
10
10
 
11
11
  # define RUBY_KERNEL_RAISE(exception) \
12
12
  (rb_funcall(rb_mKernel, rb_intern_const("raise"), 1, exception), _RUBY_KERNEL_RAISE())
@@ -56,14 +56,22 @@ VALUE __ruby_string_converter_temp_variable;
56
56
  StringValueCStr(string)
57
57
  #endif
58
58
 
59
+ // C Data
59
60
  #define NEW_DATA_OBJECT(_class, data_type, mark, free) \
60
61
  rb_data_object_zalloc((_class), sizeof(data_type), (RUBY_DATA_FUNC)(mark), (RUBY_DATA_FUNC)(free))
61
62
  #define NEW_SIMPLE_DATA_OBJECT(_class, data_type) NEW_DATA_OBJECT(_class, data_type, NULL, RUBY_DEFAULT_FREE)
63
+ #define GET_DATA_OBJECT(instance) rb_data_object_get(instance)
64
+ #define GET_SELF_DATA_OBJECT() rb_data_object_get(self)
62
65
 
66
+ // Console output
63
67
  #define RUBY_KERNEL_P(object) rb_funcall(rb_mKernel, rb_intern_const("p"), 1, object)
64
68
  #define RUBY_KERNEL_PUTS(object) rb_funcall(rb_mKernel, rb_intern_const("puts"), 1, object)
65
69
 
66
- #define RAISE_WIN32_ERROR RUBY_KERNEL_RAISE(ruby___win32error_new())
70
+ // Symbol
71
+ #define NEW_SYMBOL(symbol) rb_id2sym(rb_intern_const(symbol))
72
+
73
+ // Exception
74
+ #define RAISE_WIN32_ERROR() RUBY_KERNEL_RAISE(ruby___win32error_new())
67
75
  #define RAISE_WIN32_ERROR_FROM_CODE(code) RUBY_KERNEL_RAISE(ruby___win32error_new_from_code(code))
68
76
  #define RAISE_ARGUMENT_ERROR(expected) \
69
77
  rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected %s)", cCount, expected)
@@ -75,10 +83,10 @@ VALUE __ruby_string_converter_temp_variable;
75
83
  RAISE_TYPE_ERROR(object, rb_class2name(expected));\
76
84
  })
77
85
 
86
+ // Arguments
78
87
  #define VARIABLE_ARGUMENTS_C INT cCount, VALUE* cArguments, VALUE self
79
88
  #define VARIABLE_ARGUMENTS_RUBY VALUE self, VALUE arguments
80
89
  #define SCAN_ARGUMENTS(format, arguments...) rb_scan_args(cCount, cArguments, format, arguments)
81
-
82
90
  #define ARGUMENT_AT(index, defaultValue) cCount > index ? cArguments[index] : defaultValue
83
91
 
84
92
  #endif //SPECIAL_INPUT_DEVICE_RUBY_MACRO_H
@@ -1,6 +1,7 @@
1
1
  #include "special_input_device.h"
2
2
  #include "_screen.h"
3
3
  #include "color.h"
4
+ #include "image.h"
4
5
  #include "rectangle.h"
5
6
 
6
7
  /*
@@ -41,146 +42,38 @@ static VALUE ruby__virtual_screen(VALUE self) {
41
42
  * @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd144909.aspx Windows Dev Center - GetPixel function
42
43
  */
43
44
  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);
45
+ INT cX = NUM2INT(x);
46
+ INT cY = NUM2INT(y);
47
+ HDC cScreenDC = GetDC(NULL);
48
+ COLORREF cColor = GetPixel(cScreenDC, cX, cY);
49
+ ReleaseDC(NULL, cScreenDC);
49
50
  return ruby___color_new_from_color_ref(cColor);
50
51
  }
51
52
 
52
53
  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);
54
+ INT x;
55
+ INT y;
56
+ INT width;
57
+ INT height;
58
+ HDC memoryDC;
59
+ HDC screenDC;
60
+ LPSTR bitmapFile;
61
+ HANDLE hBitmapFile;
62
+ } SID_SCREEN_CAPTURE_PARAMETER;
63
+
64
+ static VALUE ruby__capture_helper(VALUE arguments) {
65
+ SID_SCREEN_CAPTURE_PARAMETER *cParameter = GET_DATA_OBJECT(arguments);
66
+ HBITMAP cHBitmap;
67
+
68
+ cParameter->screenDC = GetDC(NULL);
69
+ cParameter->memoryDC = CreateCompatibleDC(cParameter->screenDC);
70
+ cHBitmap = CreateCompatibleBitmap(cParameter->screenDC, cParameter->width, cParameter->height);
71
+
72
+ SelectObject(cParameter->memoryDC, cHBitmap);
73
+ BitBlt(cParameter->memoryDC, 0, 0, cParameter->width, cParameter->height,
74
+ cParameter->screenDC, cParameter->x, cParameter->y, SRCCOPY);
75
+
76
+ return ruby___image_new_from_bitmap(cHBitmap);
184
77
  }
185
78
 
186
79
  /*
@@ -195,40 +88,37 @@ static VALUE ruby__capture_helper_protect(VALUE arguments) {
195
88
  * @return [SpecialInputDevice::Image]
196
89
  */
197
90
  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);
91
+ VALUE x;
92
+ VALUE y;
93
+ VALUE width;
94
+ VALUE height;
95
+ VALUE parameter;
96
+ SID_SCREEN_CAPTURE_PARAMETER *cParameter;
97
+ INT cError;
98
+ VALUE result;
99
+ parameter = Data_Make_Struct(rb_cData, SID_SCREEN_CAPTURE_PARAMETER, NULL, RUBY_DEFAULT_FREE, cParameter);
208
100
  switch (cCount) {
209
- case 0: {
210
- cParameter->cX = getVirtualScreenX();
211
- cParameter->cY = getVirtualScreenY();
212
- cParameter->cWidth = getVirtualScreenWidth();
213
- cParameter->cHeight = getVirtualScreenHeight();
101
+ case 0:
102
+ cParameter->x = getVirtualScreenX();
103
+ cParameter->y = getVirtualScreenY();
104
+ cParameter->width = getVirtualScreenWidth();
105
+ cParameter->height = getVirtualScreenHeight();
214
106
  break;
215
- }
216
- case 4: {
107
+ case 4:
217
108
  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);
109
+ cParameter->x = NUM2INT(x);
110
+ cParameter->y = NUM2INT(y);
111
+ cParameter->width = NUM2INT(width);
112
+ cParameter->height = NUM2INT(height);
222
113
  break;
223
- }
224
114
  default:
225
115
  RAISE_ARGUMENT_ERROR("0, 4");
226
116
  }
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);
117
+ result = rb_protect(ruby__capture_helper, parameter, &cError);
118
+ GlobalUnlock(cParameter->hBitmapFile);
119
+ GlobalFree(cParameter->hBitmapFile);
120
+ ReleaseDC(NULL, cParameter->memoryDC);
121
+ ReleaseDC(NULL, cParameter->screenDC);
232
122
  if (cError)
233
123
  rb_jump_tag(cError);
234
124
  return result;
@@ -277,7 +167,7 @@ static VALUE ruby__find_image(VARIABLE_ARGUMENTS_C) {
277
167
  }
278
168
  // return capture;
279
169
  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);
170
+ result = rb_funcall(capture, rb_intern_const("find"), 2, image, options);
281
171
  if (result != Qnil && *area != Qundef)
282
172
  result = rb_funcall(result, rb_intern_const("move"), 2, x, y);
283
173
  return result;
@@ -20,9 +20,8 @@ VOID Init_special_input_device() {
20
20
  Init_win32error();
21
21
 
22
22
  specialInputDevice_attributesEqualChecker = rb_define_module_under(specialInputDevice, "AttributesEqualChecker");
23
- specialInputDevice_table2d = rb_define_class_under(specialInputDevice, "Table2D", rb_cObject);
24
23
  specialInputDevice_color = rb_define_class_under(specialInputDevice, "Color", rb_cObject);
25
- specialInputDevice_image = rb_define_class_under(specialInputDevice, "Image", specialInputDevice_table2d);
24
+ specialInputDevice_image = rb_define_class_under(specialInputDevice, "Image", rb_cData);
26
25
  specialInputDevice_point = rb_define_class_under(specialInputDevice, "Point", rb_cObject);
27
26
  specialInputDevice_rectangle = rb_define_class_under(specialInputDevice, "Rectangle", rb_cObject);
28
27
  rb_eval_string(""
@@ -32,6 +31,7 @@ VOID Init_special_input_device() {
32
31
  " raise LoadError.new('Cannot load the library of SpecialInputDevice. Reinstall may solve this problem.')\n"
33
32
  "end\n");
34
33
 
34
+ Init_image();
35
35
  Init_keyboard();
36
36
  Init_mouse();
37
37
  Init_screen();
@@ -14,7 +14,6 @@ typedef enum {
14
14
 
15
15
  VALUE specialInputDevice;
16
16
  VALUE specialInputDevice_attributesEqualChecker;
17
- VALUE specialInputDevice_table2d;
18
17
  VALUE specialInputDevice_color;
19
18
  VALUE specialInputDevice_image;
20
19
  VALUE specialInputDevice_point;
@@ -29,6 +28,8 @@ PCHAR ruby___special_input_device_get_mode_name();
29
28
 
30
29
  VOID Init_special_input_device();
31
30
 
31
+ VOID Init_image();
32
+
32
33
  VOID Init_interception();
33
34
 
34
35
  VOID Init_keyboard();
@@ -14,9 +14,7 @@ VALUE ruby___win32error_new_from_code(DWORD cCode) {
14
14
  /*
15
15
  * @!scope class
16
16
  * @overload new(code = nil)
17
- * Returns a new instance of <code>Win32Error</code>.
18
17
  * @param [Integer] code the error code
19
- * @return [SpecialInputDevice::Window] a new instance of <code>Win32Error</code>
20
18
  */
21
19
 
22
20
  static VALUE ruby_initialize(VARIABLE_ARGUMENTS_C) {