rum 0.0.1-universal-darwin-10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/CHANGELOG +3 -0
  2. data/README +30 -0
  3. data/Rakefile +134 -0
  4. data/bin/rum-client +124 -0
  5. data/doc/basic.rb +10 -0
  6. data/doc/doc.html +602 -0
  7. data/doc/example.rb +59 -0
  8. data/doc/reference.rb +415 -0
  9. data/doc/resources/bg.png +0 -0
  10. data/doc/resources/bottom.png +0 -0
  11. data/doc/resources/build.rb +235 -0
  12. data/doc/resources/doc.haml +167 -0
  13. data/doc/resources/emacs-auto-completion.png +0 -0
  14. data/doc/resources/flash.png +0 -0
  15. data/doc/resources/highlight.css +94 -0
  16. data/doc/resources/intro.rb +17 -0
  17. data/doc/resources/left.png +0 -0
  18. data/doc/resources/logo.png +0 -0
  19. data/doc/resources/screen.css +420 -0
  20. data/doc/resources/screenshot.png +0 -0
  21. data/doc/resources/top.png +0 -0
  22. data/ext/mac/keyboard_hook/English.lproj/InfoPlist.strings +0 -0
  23. data/ext/mac/keyboard_hook/Event.h +17 -0
  24. data/ext/mac/keyboard_hook/Event.m +18 -0
  25. data/ext/mac/keyboard_hook/EventTap.h +11 -0
  26. data/ext/mac/keyboard_hook/EventTap.m +77 -0
  27. data/ext/mac/keyboard_hook/Info.plist +26 -0
  28. data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/TemplateIcon.icns +0 -0
  29. data/ext/mac/keyboard_hook/KeyboardHook.xcodeproj/project.pbxproj +323 -0
  30. data/ext/mac/keyboard_hook/KeyboardHook_Prefix.pch +7 -0
  31. data/ext/mac/keyboard_hook/version.plist +16 -0
  32. data/ext/windows/keyboard_hook/extconf.rb +2 -0
  33. data/ext/windows/keyboard_hook/keyboard_hook.c +126 -0
  34. data/ext/windows/system/autohotkey_stuff.c +255 -0
  35. data/ext/windows/system/autohotkey_stuff.h +2 -0
  36. data/ext/windows/system/clipboard_watcher.c +58 -0
  37. data/ext/windows/system/clipboard_watcher.h +2 -0
  38. data/ext/windows/system/extconf.rb +3 -0
  39. data/ext/windows/system/input_box.c +239 -0
  40. data/ext/windows/system/input_box.h +4 -0
  41. data/ext/windows/system/system.c +273 -0
  42. data/lib/rum.rb +4 -0
  43. data/lib/rum/apps.rb +4 -0
  44. data/lib/rum/barrel.rb +157 -0
  45. data/lib/rum/barrel/emacs.rb +44 -0
  46. data/lib/rum/barrel/emacs_client.rb +74 -0
  47. data/lib/rum/core.rb +125 -0
  48. data/lib/rum/dsl.rb +109 -0
  49. data/lib/rum/gui.rb +93 -0
  50. data/lib/rum/help.rb +128 -0
  51. data/lib/rum/hotkey_core.rb +479 -0
  52. data/lib/rum/mac.rb +18 -0
  53. data/lib/rum/mac/app.rb +4 -0
  54. data/lib/rum/mac/apps.rb +19 -0
  55. data/lib/rum/mac/gui.rb +26 -0
  56. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Info.plist +28 -0
  57. data/lib/rum/mac/gui/CocoaDialog.app/Contents/MacOS/CocoaDialog +0 -0
  58. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Info.plist +28 -0
  59. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/InfoPlist.strings +0 -0
  60. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/classes.nib +51 -0
  61. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/info.nib +16 -0
  62. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Inputbox.nib/keyedobjects.nib +0 -0
  63. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/classes.nib +7 -0
  64. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/info.nib +21 -0
  65. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/info.nib.orig +21 -0
  66. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/objects.nib +0 -0
  67. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/MainMenu.nib/objects.nib.orig +0 -0
  68. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/classes.nib +27 -0
  69. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/info.nib +16 -0
  70. data/lib/rum/mac/gui/CocoaDialog.app/Contents/Resources/Msgbox.nib/keyedobjects.nib +0 -0
  71. data/lib/rum/mac/gui/Growl.framework/Growl +0 -0
  72. data/lib/rum/mac/gui/Growl.framework/Versions/A/Growl +0 -0
  73. data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/Growl.h +6 -0
  74. data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h +780 -0
  75. data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h +575 -0
  76. data/lib/rum/mac/gui/Growl.framework/Versions/A/Headers/GrowlDefines.h +348 -0
  77. data/lib/rum/mac/gui/Growl.framework/Versions/A/Resources/Info.plist +24 -0
  78. data/lib/rum/mac/gui/growl.rb +54 -0
  79. data/lib/rum/mac/irb/completion.rb +207 -0
  80. data/lib/rum/mac/keyboard_hook.rb +73 -0
  81. data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/KeyboardHook +0 -0
  82. data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/KeyboardHook +0 -0
  83. data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/English.lproj/InfoPlist.strings +0 -0
  84. data/lib/rum/mac/keyboard_hook/KeyboardHook.framework/Versions/A/Resources/Info.plist +22 -0
  85. data/lib/rum/mac/layouts.rb +146 -0
  86. data/lib/rum/mac/system.rb +45 -0
  87. data/lib/rum/remote.rb +48 -0
  88. data/lib/rum/server.rb +92 -0
  89. data/lib/rum/windows.rb +23 -0
  90. data/lib/rum/windows/app.rb +72 -0
  91. data/lib/rum/windows/apps.rb +25 -0
  92. data/lib/rum/windows/gui.rb +116 -0
  93. data/lib/rum/windows/keyboard.rb +80 -0
  94. data/lib/rum/windows/keyboard_hook.rb +20 -0
  95. data/lib/rum/windows/layouts.rb +232 -0
  96. data/lib/rum/windows/system.rb +310 -0
  97. data/lib/rum/windows/system_foreign_functions.rb +129 -0
  98. data/rum.gemspec +14 -0
  99. metadata +166 -0
@@ -0,0 +1,2 @@
1
+ VALUE install_watcher(VALUE self);
2
+ VALUE evaluate_watcher(VALUE self, VALUE window);
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+ $LIBS << ' gdi32.lib' # needed for input_box.c
3
+ create_makefile("system")
@@ -0,0 +1,239 @@
1
+
2
+ /* Inspired by https://sourceforge.net/projects/cinputbox */
3
+
4
+ #define UNICODE
5
+ #include <windows.h>
6
+ #include <stdio.h>
7
+ #include "input_box.h"
8
+
9
+ #define IB_CLASS_NAME L"RumInputBox"
10
+ #define IB_WIDTH 300
11
+ #define IB_HEIGHT 130
12
+ #define IB_SPAN 10
13
+ #define IB_LEFT_OFFSET 6
14
+ #define IB_TOP_OFFSET 4
15
+ #define IB_BTN_WIDTH 60
16
+ #define IB_BTN_HEIGHT 20
17
+
18
+ typedef struct {
19
+ HWND main_window, text, ok, cancel, edit_control;
20
+ LPTSTR result_text;
21
+ INT max_chars, result;
22
+ HINSTANCE instance;
23
+ } InputBox;
24
+
25
+ HMODULE global_instance;
26
+
27
+ static void input_box_populate_window(InputBox *box, HWND blank_window)
28
+ {
29
+ NONCLIENTMETRICS metrics;
30
+ HFONT font;
31
+
32
+ box->main_window = blank_window;
33
+
34
+ box->text = CreateWindow(L"Static", L"",
35
+ WS_CHILD | WS_VISIBLE,
36
+ IB_LEFT_OFFSET, IB_TOP_OFFSET,
37
+ IB_WIDTH-IB_LEFT_OFFSET*2, IB_BTN_HEIGHT*2,
38
+ box->main_window, NULL,
39
+ box->instance, NULL);
40
+ box->edit_control = CreateWindow(L"Edit", L"",
41
+ (WS_CHILD | WS_VISIBLE | WS_BORDER |
42
+ ES_AUTOHSCROLL | ES_LEFT),
43
+ IB_LEFT_OFFSET,
44
+ IB_TOP_OFFSET + IB_BTN_HEIGHT*2,
45
+ IB_WIDTH-IB_LEFT_OFFSET*3, IB_BTN_HEIGHT,
46
+ box->main_window, NULL,
47
+ box->instance, NULL);
48
+ box->ok = CreateWindow(L"Button", L"OK",
49
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
50
+ IB_WIDTH/2 - IB_SPAN*2 - IB_BTN_WIDTH,
51
+ IB_HEIGHT - IB_TOP_OFFSET*4 - IB_BTN_HEIGHT*2,
52
+ IB_BTN_WIDTH, IB_BTN_HEIGHT,
53
+ box->main_window, (HMENU)IDOK,
54
+ box->instance, NULL);
55
+ box->cancel = CreateWindow(L"Button", L"Cancel",
56
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
57
+ IB_WIDTH/2 + IB_SPAN,
58
+ IB_HEIGHT - IB_TOP_OFFSET*4 - IB_BTN_HEIGHT*2,
59
+ IB_BTN_WIDTH, IB_BTN_HEIGHT,
60
+ box->main_window, (HMENU)IDCANCEL,
61
+ box->instance, NULL);
62
+
63
+ font = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
64
+
65
+ SendMessage(box->text,WM_SETFONT,(WPARAM)font,FALSE);
66
+ SendMessage(box->edit_control,WM_SETFONT,(WPARAM)font,FALSE);
67
+ SendMessage(box->ok,WM_SETFONT,(WPARAM)font,FALSE);
68
+ SendMessage(box->cancel,WM_SETFONT,(WPARAM)font,FALSE);
69
+ }
70
+
71
+ static void input_box_close(InputBox *box)
72
+ {
73
+ PostMessage(box->main_window, WM_CLOSE, 0, 0);
74
+ }
75
+
76
+ static void input_box_submit(InputBox *box)
77
+ {
78
+ int input_length = (int)SendMessage(box->edit_control, EM_LINELENGTH, 0, 0);
79
+ if (input_length){
80
+ // Provide the max number of chars to be copied as a word in the buffer.
81
+ *((LPWORD)box->result_text) = box->max_chars;
82
+ // Although undocumented, the copied string is null-terminated.
83
+ input_length = (WORD)SendMessage(box->edit_control, EM_GETLINE, 0,
84
+ (LPARAM)box->result_text);
85
+ }
86
+ box->result = input_length;
87
+ }
88
+
89
+ LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
90
+ {
91
+ InputBox *box = (InputBox*)GetWindowLong(hwnd, GWL_USERDATA);
92
+
93
+ switch(msg)
94
+ {
95
+ case WM_CREATE:
96
+ box = (InputBox *) ((CREATESTRUCT *)lParam)->lpCreateParams;
97
+ SetWindowLong(hwnd, GWL_USERDATA, (long)box);
98
+ input_box_populate_window(box, hwnd);
99
+ break;
100
+ case WM_COMMAND:
101
+ switch(LOWORD(wParam)) {
102
+ case IDOK:
103
+ input_box_submit(box);
104
+ case IDCANCEL:
105
+ input_box_close(box);
106
+ break;
107
+ }
108
+ break;
109
+ case WM_SETFOCUS:
110
+ SetFocus(box->edit_control);
111
+ break;
112
+ case WM_CLOSE:
113
+ DestroyWindow(hwnd);
114
+ break;
115
+ case WM_DESTROY:
116
+ PostQuitMessage(0);
117
+ break;
118
+ }
119
+ return DefWindowProc(hwnd, msg, wParam, lParam);
120
+ }
121
+
122
+ void input_box_register_window_class(HINSTANCE instance)
123
+ {
124
+ WNDCLASSEX wndInputBox;
125
+
126
+ wndInputBox.cbSize = sizeof(wndInputBox);
127
+ wndInputBox.style = CS_HREDRAW | CS_VREDRAW;
128
+ wndInputBox.lpszClassName = IB_CLASS_NAME;
129
+ wndInputBox.lpfnWndProc = window_proc;
130
+ wndInputBox.lpszMenuName = NULL;
131
+ wndInputBox.cbClsExtra = 0;
132
+ wndInputBox.cbWndExtra = 0;
133
+ wndInputBox.hInstance = instance;
134
+ wndInputBox.hIcon = LoadIcon(NULL, IDI_QUESTION);
135
+ wndInputBox.hIconSm = NULL;
136
+ wndInputBox.hCursor = LoadCursor(NULL, IDC_ARROW);
137
+ wndInputBox.hbrBackground = (HBRUSH)(COLOR_WINDOW);
138
+
139
+ if(!RegisterClassEx(&wndInputBox))
140
+ {
141
+ MessageBox(NULL, L"Window Registration Failed!", L"Error!",
142
+ MB_ICONEXCLAMATION | MB_OK);
143
+ }
144
+ }
145
+
146
+ void input_box_unregister_window_class(InputBox *box)
147
+ {
148
+ UnregisterClass(IB_CLASS_NAME, box->instance);
149
+ }
150
+
151
+ static void input_box_show(InputBox *box, LPCTSTR title, LPCTSTR text,
152
+ LPTSTR result_text, int max_chars)
153
+ {
154
+ box->result_text = result_text;
155
+ box->max_chars = max_chars;
156
+ box->result = 0;
157
+
158
+ SetWindowText(box->main_window, title);
159
+ SetWindowText(box->edit_control, result_text);
160
+ SetWindowText(box->text, text);
161
+ SendMessage(box->edit_control, EM_LIMITTEXT,
162
+ max_chars-1, // Leave room for the terminating null char.
163
+ 0);
164
+ SendMessage(box->edit_control, EM_SETSEL, 0, -1); // Select the whole text
165
+ ShowWindow(box->main_window, SW_SHOWNORMAL);
166
+ }
167
+
168
+ static void input_box_create(InputBox *box, HINSTANCE instance)
169
+ {
170
+ RECT rect;
171
+
172
+ GetWindowRect(GetDesktopWindow(), &rect);
173
+
174
+ box->instance = instance;
175
+ box->main_window = CreateWindowEx(WS_EX_TOPMOST,
176
+ IB_CLASS_NAME, L"",
177
+ (WS_BORDER | WS_CAPTION | WS_SYSMENU),
178
+ (rect.left + rect.right - IB_WIDTH)/2,
179
+ (rect.top + rect.bottom - IB_HEIGHT)/2,
180
+ IB_WIDTH, IB_HEIGHT,
181
+ GetForegroundWindow(), 0,
182
+ instance, box);
183
+ }
184
+
185
+
186
+
187
+ static void input_box_destroy(InputBox *box)
188
+ {
189
+ SendMessage(box->main_window, WM_DESTROY, 0, 0);
190
+ }
191
+
192
+
193
+ void input_box_initialize(HINSTANCE instance)
194
+ {
195
+ global_instance = instance;
196
+ input_box_register_window_class(instance);
197
+ }
198
+
199
+ int input_box(LPCTSTR text, LPCTSTR title,
200
+ LPTSTR result_text, int max_chars)
201
+ {
202
+ MSG msg;
203
+ InputBox box;
204
+
205
+ input_box_create(&box, global_instance);
206
+
207
+ input_box_show(&box, title, text, result_text, max_chars);
208
+
209
+ while(GetMessage(&msg, NULL, 0, 0) > 0)
210
+ {
211
+ if (msg.message == WM_KEYDOWN) {
212
+ switch (msg.wParam) {
213
+ case VK_RETURN:
214
+ input_box_submit(&box);
215
+ case VK_ESCAPE:
216
+ input_box_close(&box);
217
+ break;
218
+ default:
219
+ TranslateMessage(&msg);
220
+ }
221
+ } else {
222
+ TranslateMessage(&msg);
223
+ }
224
+ DispatchMessage(&msg);
225
+ }
226
+
227
+ input_box_destroy(&box);
228
+
229
+ return(box.result);
230
+ }
231
+
232
+ /* void input_box_demo() */
233
+ /* { */
234
+ /* input_box_initialize(GetModuleHandle(NULL)); */
235
+ /* #define chars 100 */
236
+ /* /\* UTF-16LE: 2 bytes per char. *\/ */
237
+ /* char buffer[chars*2] = {187, 3, 184, 3, 4, 4}; */
238
+ /* input_box(L"text", L"title", (LPTSTR)buffer, chars); */
239
+ /* } */
@@ -0,0 +1,4 @@
1
+ void input_box_initialize(HINSTANCE instance);
2
+
3
+ int input_box(LPCTSTR title, LPCTSTR query,
4
+ LPTSTR result_text, int max_chars);
@@ -0,0 +1,273 @@
1
+ #include "ruby.h"
2
+ #include <windows.h>
3
+ #include <winuser.h>
4
+ #include <tlhelp32.h>
5
+ #include "autohotkey_stuff.h"
6
+ #include "input_box.h"
7
+ #include "clipboard_watcher.h"
8
+
9
+ VALUE mSystem;
10
+ VALUE mDesktop;
11
+ VALUE mScreen;
12
+ VALUE mClipboard;
13
+ VALUE cWindow;
14
+
15
+ struct KeybdEventParams {
16
+ int vkcode;
17
+ int scancode;
18
+ DWORD flags;
19
+ };
20
+
21
+ struct InputBoxParams {
22
+ LPCTSTR text;
23
+ LPCTSTR title;
24
+ LPTSTR result_text;
25
+ int length;
26
+ };
27
+
28
+ struct MessageBoxParams {
29
+ LPCWSTR text;
30
+ LPCWSTR title;
31
+ };
32
+
33
+ static BOOL CALLBACK enum_windows_proc(HWND hwnd, LPARAM lParam)
34
+ {
35
+ rb_yield(LONG2NUM((DWORD)hwnd));
36
+ return TRUE;
37
+ }
38
+
39
+ static VALUE enum_windows(VALUE self) {
40
+ EnumWindows(enum_windows_proc, 0);
41
+ return Qnil;
42
+ }
43
+
44
+ static void call_keybd_event(struct KeybdEventParams *event) {
45
+ #ifdef DEBUG
46
+ printf("Sending key: vkcode: %d, scancode: %d\n", event.vkcode, event.scancode);
47
+ #endif
48
+ keybd_event(event->vkcode, event->scancode, event->flags, 0);
49
+ }
50
+
51
+ static VALUE f_keybd_event(int argc, VALUE* argv, VALUE self)
52
+ {
53
+ VALUE vkcode, down, scancode, extended;
54
+ struct KeybdEventParams event;
55
+ rb_scan_args(argc, argv, "22", &vkcode, &down, &scancode, &extended);
56
+
57
+ event.flags = 0;
58
+ if (down != Qtrue)
59
+ event.flags |= KEYEVENTF_KEYUP;
60
+ if ( !(extended == Qnil || extended == Qfalse) )
61
+ event.flags |= KEYEVENTF_EXTENDEDKEY;
62
+
63
+ event.vkcode = NUM2INT(vkcode);
64
+ event.scancode = (NIL_P(scancode) ? 0 : NUM2INT(scancode));
65
+ rb_thread_blocking_region(call_keybd_event, &event, 0, 0);
66
+ return Qnil;
67
+ }
68
+
69
+ /* Returns 'true' if successful, 'false' if not. */
70
+ static VALUE ForceWindowToFront(VALUE self)
71
+ {
72
+ HWND TargetWindow = (HWND)NUM2ULONG(rb_iv_get(self, "@handle"));
73
+ if (SetForegroundWindowEx(TargetWindow))
74
+ return Qtrue;
75
+ else
76
+ return Qfalse;
77
+ }
78
+
79
+ static DWORD process_id(VALUE window)
80
+ {
81
+ VALUE handle = rb_iv_get(window, "@handle");
82
+ HWND window_handle = (HWND)NUM2ULONG(handle);
83
+
84
+ DWORD process_id = 0;
85
+ GetWindowThreadProcessId(window_handle, &process_id);
86
+ return process_id;
87
+ }
88
+
89
+ static void process_module(VALUE window, MODULEENTRY32 *module) {
90
+ DWORD processID = process_id(window);
91
+
92
+ // Take a snapshot of the modules of this process
93
+ HANDLE moduleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
94
+
95
+ //Get the first module
96
+ module->dwSize = sizeof(MODULEENTRY32);
97
+ Module32First(moduleSnapshot, module);
98
+ }
99
+
100
+ static void get_exe_path(MODULEENTRY32 *module, char *buffer) {
101
+ strcpy(buffer, module->szExePath);
102
+ }
103
+
104
+ static void get_exe_name(MODULEENTRY32 *module, char *buffer) {
105
+ strcpy(buffer, module->szModule);
106
+ buffer[strlen(buffer) - 4] = '\0'; /* Remove .exe suffix */
107
+ }
108
+
109
+ static void access_window_process_data(VALUE window, void fn(MODULEENTRY32 *module, char *buffer), char *buffer) {
110
+ MODULEENTRY32 module = {0};
111
+ process_module(window, &module);
112
+ (*fn)(&module, buffer);
113
+ }
114
+
115
+ static VALUE exe_name(VALUE self)
116
+ {
117
+ char buffer[MAX_MODULE_NAME32 + 1];
118
+ access_window_process_data(self, &get_exe_name, buffer);
119
+ return rb_str_new2(buffer);
120
+ }
121
+
122
+ static VALUE exe_path(VALUE self)
123
+ {
124
+ char buffer[MAX_PATH];
125
+ access_window_process_data(self, &get_exe_path, buffer);
126
+ return rb_str_new2(buffer);
127
+ }
128
+
129
+ static LPRECT get_window_rect(VALUE window, LPRECT rect)
130
+ {
131
+ HWND window_handle = (HWND)NUM2ULONG(rb_iv_get(window, "@handle"));
132
+ GetWindowRect(window_handle, rect);
133
+ return rect;
134
+ }
135
+
136
+ static VALUE top(VALUE self)
137
+ {
138
+ RECT rect;
139
+ return LONG2NUM((get_window_rect(self, &rect)->top));
140
+ }
141
+
142
+
143
+ static VALUE right(VALUE self)
144
+ {
145
+ RECT rect;
146
+ return LONG2NUM((get_window_rect(self, &rect)->right));
147
+ }
148
+
149
+ static VALUE bottom(VALUE self)
150
+ {
151
+ RECT rect;
152
+ return LONG2NUM((get_window_rect(self, &rect)->bottom));
153
+ }
154
+
155
+ static VALUE left(VALUE self)
156
+ {
157
+ RECT rect;
158
+ return LONG2NUM((get_window_rect(self, &rect)->left));
159
+ }
160
+
161
+ static VALUE desktop_top(VALUE self)
162
+ {
163
+ RECT work_area;
164
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
165
+ return LONG2NUM(work_area.top);
166
+ }
167
+
168
+ static VALUE desktop_right(VALUE self)
169
+ {
170
+ RECT work_area;
171
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
172
+ return LONG2NUM(work_area.right);
173
+ }
174
+
175
+ static VALUE desktop_bottom(VALUE self)
176
+ {
177
+ RECT work_area;
178
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
179
+ return LONG2NUM(work_area.bottom);
180
+ }
181
+
182
+ static VALUE desktop_left(VALUE self)
183
+ {
184
+ RECT work_area;
185
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
186
+ return LONG2NUM(work_area.left);
187
+ }
188
+
189
+ static VALUE screen_width(VALUE self)
190
+ {
191
+ return INT2NUM(GetSystemMetrics(SM_CXSCREEN));
192
+ }
193
+
194
+ static VALUE screen_height(VALUE self)
195
+ {
196
+ return INT2NUM(GetSystemMetrics(SM_CYSCREEN));
197
+ }
198
+
199
+ static VALUE get_console_window(VALUE self)
200
+ {
201
+ /* Cast to ULONG_PTR to neutralize a compiler warning. */
202
+ return LONG2NUM((ULONG_PTR)GetConsoleWindow());
203
+ }
204
+
205
+ static VALUE call_message_box(struct MessageBoxParams *params)
206
+ {
207
+ int result = MessageBoxW(0, params->text, params->title,
208
+ MB_OKCANCEL | MB_TOPMOST | MB_SETFOREGROUND);
209
+ return result == IDOK ? Qtrue : Qfalse;
210
+ }
211
+
212
+ static VALUE message_box_internal(VALUE self, VALUE text, VALUE title)
213
+ {
214
+ struct MessageBoxParams params;
215
+ params.text = (LPCWSTR)RSTRING_PTR(text);
216
+ params.title = (LPCWSTR)RSTRING_PTR(title);
217
+ return rb_thread_blocking_region(call_message_box, &params, 0, 0);
218
+ }
219
+
220
+ static VALUE call_input_box(struct InputBoxParams *params)
221
+ {
222
+ return INT2FIX(input_box(params->text, params->title,
223
+ params->result_text, params->length));
224
+ }
225
+
226
+ static VALUE input_box_internal(VALUE self, VALUE text, VALUE title,
227
+ VALUE result_text)
228
+ {
229
+ struct InputBoxParams params;
230
+ params.text = RSTRING_PTR(text);
231
+ params.title = RSTRING_PTR(title);
232
+ params.result_text = RSTRING_PTR(result_text);
233
+ params.length = RSTRING_LEN(result_text)/2;
234
+
235
+ return rb_thread_blocking_region(call_input_box, &params, 0, 0);
236
+ }
237
+
238
+
239
+ void Init_system() {
240
+ input_box_initialize(GetModuleHandle(NULL));
241
+ autohotkey_stuff_initialize(GetCurrentThreadId());
242
+
243
+ mSystem = rb_define_module_under(rb_define_module("Rum"), "System");
244
+ mDesktop = rb_define_module_under(mSystem, "Desktop");
245
+ mScreen = rb_define_module_under(mSystem, "Screen");
246
+ mClipboard = rb_define_module_under(mSystem, "Clipboard");
247
+ cWindow = rb_define_class_under(mSystem, "Window", rb_cObject);
248
+
249
+ rb_define_method(mSystem, "enum_windows", enum_windows, 0);
250
+ rb_define_method(mSystem, "keybd_event", f_keybd_event, -1);
251
+ rb_define_method(mSystem, "get_console_window", get_console_window, 0);
252
+ rb_define_method(mSystem, "message_box_internal", message_box_internal, 2);
253
+ rb_define_method(mSystem, "input_box_internal", input_box_internal, 3);
254
+
255
+ rb_define_method(cWindow, "show", ForceWindowToFront, 0);
256
+ rb_define_method(cWindow, "exe_path", exe_path, 0);
257
+ rb_define_method(cWindow, "exe_name", exe_name, 0);
258
+ rb_define_method(cWindow, "left", left, 0);
259
+ rb_define_method(cWindow, "right", right, 0);
260
+ rb_define_method(cWindow, "top", top, 0);
261
+ rb_define_method(cWindow, "bottom", bottom, 0);
262
+
263
+ rb_define_module_function(mDesktop, "top", desktop_top, 0);
264
+ rb_define_module_function(mDesktop, "left", desktop_left, 0);
265
+ rb_define_module_function(mDesktop, "bottom", desktop_bottom, 0);
266
+ rb_define_module_function(mDesktop, "right", desktop_right, 0);
267
+
268
+ rb_define_module_function(mScreen, "width", screen_width, 0);
269
+ rb_define_module_function(mScreen, "height", screen_height, 0);
270
+
271
+ rb_define_method(mClipboard, "install_watcher", install_watcher, 0);
272
+ rb_define_method(mClipboard, "evaluate_watcher", evaluate_watcher, 2);
273
+ }