mouse 3.0.0 → 4.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/History.markdown +8 -0
- data/README.markdown +14 -1
- data/Rakefile +12 -13
- data/ext/mouse/extconf.rb +13 -18
- data/ext/mouse/mouse.c +613 -497
- data/ext/mouse/mouser.c +321 -333
- data/ext/mouse/mouser.h +53 -54
- data/lib/mouse.rb +2 -0
- data/lib/mouse/version.rb +2 -2
- metadata +39 -59
- metadata.gz.sig +1 -0
data/ext/mouse/mouser.c
CHANGED
@@ -6,11 +6,10 @@
|
|
6
6
|
// Copyright (c) 2012 Mark Rada. All rights reserved.
|
7
7
|
//
|
8
8
|
|
9
|
-
#include <ApplicationServices/ApplicationServices.h>
|
10
9
|
#include "mouser.h"
|
11
10
|
|
12
|
-
static const
|
13
|
-
static const
|
11
|
+
static const double FPS = 240;
|
12
|
+
static const double QUANTUM = 1000000 / 240; // should be FPS, but GCC sucks
|
14
13
|
static const double DEFAULT_DURATION = 0.2; // seconds
|
15
14
|
static const double DEFAULT_MAGNIFICATION = 1.0; // factor
|
16
15
|
|
@@ -19,640 +18,629 @@ static const double DEFAULT_MAGNIFICATION = 1.0; // factor
|
|
19
18
|
#define POST(event) CGEventPost(kCGHIDEventTap, event)
|
20
19
|
#define CHANGE(event,type) CGEventSetType(event, type)
|
21
20
|
|
22
|
-
#define CLOSE_ENOUGH(a,b) ((
|
23
|
-
#define NOW (CFDateCreate(nil,CFAbsoluteTimeGetCurrent()))
|
21
|
+
#define CLOSE_ENOUGH(a, b) ((fabs(a.x - b.x) < 1.0) && (fabs(a.y - b.y) < 1.0))
|
22
|
+
#define NOW (CFDateCreate(nil, CFAbsoluteTimeGetCurrent()))
|
24
23
|
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
#define POSTRELEASE(x) do { \
|
32
|
-
CGEventRef _event = x; \
|
33
|
-
POST(_event); \
|
34
|
-
RELEASE(_event); \
|
35
|
-
} while(false);
|
24
|
+
#define POSTRELEASE(x) { \
|
25
|
+
CGEventRef const _event = x; \
|
26
|
+
POST(_event); \
|
27
|
+
CFRelease(_event); \
|
28
|
+
}
|
36
29
|
|
37
30
|
|
38
31
|
static
|
39
32
|
void
|
40
|
-
mouse_sleep(uint_t quanta)
|
33
|
+
mouse_sleep(const uint_t quanta)
|
41
34
|
{
|
42
|
-
|
35
|
+
usleep(quanta * (uint_t)QUANTUM);
|
43
36
|
}
|
44
37
|
|
45
38
|
CGPoint
|
46
39
|
mouse_current_position()
|
47
40
|
{
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
41
|
+
CGEventRef const event = CGEventCreate(nil);
|
42
|
+
const CGPoint point = CGEventGetLocation(event);
|
43
|
+
CFRelease(event);
|
44
|
+
return point;
|
52
45
|
}
|
53
46
|
|
54
47
|
// Executes a linear mouse movement animation. It can be a simple cursor
|
55
48
|
// move or a drag depending on what is passed to `type`.
|
56
49
|
static
|
57
50
|
void
|
58
|
-
mouse_animate(
|
59
|
-
|
60
|
-
|
61
|
-
CGPoint
|
62
|
-
|
63
|
-
double duration
|
64
|
-
)
|
51
|
+
mouse_animate(const CGEventType type,
|
52
|
+
const CGMouseButton button,
|
53
|
+
const CGPoint start_point,
|
54
|
+
const CGPoint end_point,
|
55
|
+
const double duration)
|
65
56
|
{
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
57
|
+
CGPoint current_point = start_point;
|
58
|
+
const double xstep = (end_point.x - start_point.x) / (duration * FPS);
|
59
|
+
const double ystep = (end_point.y - start_point.y) / (duration * FPS);
|
60
|
+
CFDateRef const start = NOW;
|
61
|
+
double remaining = 0.0;
|
62
|
+
CFDateRef current_time = NULL;
|
72
63
|
|
73
|
-
|
74
|
-
|
75
|
-
|
64
|
+
while (!CLOSE_ENOUGH(current_point, end_point)) {
|
65
|
+
remaining = end_point.x - current_point.x;
|
66
|
+
current_point.x += fabs(xstep) > fabs(remaining) ? remaining : xstep;
|
76
67
|
|
77
|
-
|
78
|
-
|
68
|
+
remaining = end_point.y - current_point.y;
|
69
|
+
current_point.y += fabs(ystep) > fabs(remaining) ? remaining : ystep;
|
79
70
|
|
80
|
-
|
71
|
+
POSTRELEASE(NEW_EVENT(type, current_point, button));
|
81
72
|
|
82
|
-
|
83
|
-
|
73
|
+
mouse_sleep(1);
|
74
|
+
current_time = NOW;
|
84
75
|
|
85
|
-
|
86
|
-
|
87
|
-
|
76
|
+
// this is a safety
|
77
|
+
const double boundary = duration + 1;
|
78
|
+
if (CFDateGetTimeIntervalSinceDate(current_time, start) > boundary)
|
79
|
+
break;
|
88
80
|
|
89
|
-
|
90
|
-
|
81
|
+
CFRelease(current_time);
|
82
|
+
current_time = NULL;
|
91
83
|
|
92
|
-
|
93
|
-
|
84
|
+
current_point = mouse_current_position();
|
85
|
+
}
|
94
86
|
|
95
|
-
|
96
|
-
|
97
|
-
|
87
|
+
CFRelease(start);
|
88
|
+
if (current_time)
|
89
|
+
CFRelease(current_time);
|
98
90
|
}
|
99
91
|
|
100
92
|
|
101
93
|
void
|
102
|
-
mouse_move_to2(CGPoint point, double duration)
|
94
|
+
mouse_move_to2(const CGPoint point, const double duration)
|
103
95
|
{
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
duration
|
110
|
-
);
|
96
|
+
mouse_animate(kCGEventMouseMoved,
|
97
|
+
kCGMouseButtonLeft,
|
98
|
+
mouse_current_position(),
|
99
|
+
point,
|
100
|
+
duration);
|
111
101
|
}
|
112
102
|
|
113
103
|
void
|
114
|
-
mouse_move_to(CGPoint point)
|
104
|
+
mouse_move_to(const CGPoint point)
|
115
105
|
{
|
116
|
-
|
106
|
+
mouse_move_to2(point, DEFAULT_DURATION);
|
117
107
|
}
|
118
108
|
|
119
109
|
|
120
110
|
void
|
121
|
-
mouse_drag_to2(CGPoint point, double duration)
|
111
|
+
mouse_drag_to2(const CGPoint point, const double duration)
|
122
112
|
{
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
kCGMouseButtonLeft
|
127
|
-
));
|
128
|
-
|
113
|
+
POSTRELEASE(NEW_EVENT(kCGEventLeftMouseDown,
|
114
|
+
mouse_current_position(),
|
115
|
+
kCGMouseButtonLeft));
|
129
116
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
duration
|
136
|
-
);
|
117
|
+
mouse_animate(kCGEventLeftMouseDragged,
|
118
|
+
kCGMouseButtonLeft,
|
119
|
+
mouse_current_position(),
|
120
|
+
point,
|
121
|
+
duration);
|
137
122
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
kCGMouseButtonLeft
|
142
|
-
));
|
123
|
+
POSTRELEASE(NEW_EVENT(kCGEventLeftMouseUp,
|
124
|
+
mouse_current_position(),
|
125
|
+
kCGMouseButtonLeft));
|
143
126
|
}
|
144
127
|
|
145
128
|
void
|
146
|
-
mouse_drag_to(CGPoint point)
|
129
|
+
mouse_drag_to(const CGPoint point)
|
147
130
|
{
|
148
|
-
|
131
|
+
mouse_drag_to2(point, DEFAULT_DURATION);
|
149
132
|
}
|
150
133
|
|
151
134
|
|
152
|
-
#define SCROLL(vval, hval)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
} \
|
165
|
-
} while (false);
|
135
|
+
#define SCROLL(vval, hval) { \
|
136
|
+
const size_t steps = round(FPS * duration); \
|
137
|
+
double current = 0.0; \
|
138
|
+
\
|
139
|
+
for (size_t step = 0; step < steps; step++) { \
|
140
|
+
const double done = (double)(step+1) / (double)steps; \
|
141
|
+
const double scroll = round((done - current) * amount); \
|
142
|
+
POSTRELEASE(CGEventCreateScrollWheelEvent(nil, units, 2, vval, hval)); \
|
143
|
+
mouse_sleep(2); \
|
144
|
+
current += scroll / (double)amount; \
|
145
|
+
} \
|
146
|
+
}
|
166
147
|
|
167
148
|
void
|
168
|
-
mouse_scroll3(int amount,
|
149
|
+
mouse_scroll3(const int amount,
|
150
|
+
const CGScrollEventUnit units,
|
151
|
+
const double duration)
|
169
152
|
{
|
170
|
-
|
153
|
+
SCROLL(scroll, 0);
|
171
154
|
}
|
172
155
|
|
173
156
|
void
|
174
|
-
mouse_scroll2(int amount,
|
157
|
+
mouse_scroll2(const int amount,
|
158
|
+
const CGScrollEventUnit units)
|
175
159
|
{
|
176
|
-
|
160
|
+
mouse_scroll3(amount, units, DEFAULT_DURATION);
|
177
161
|
}
|
178
162
|
|
179
163
|
void
|
180
|
-
mouse_scroll(int amount)
|
164
|
+
mouse_scroll(const int amount)
|
181
165
|
{
|
182
|
-
|
166
|
+
mouse_scroll2(amount, kCGScrollEventUnitLine);
|
183
167
|
}
|
184
168
|
|
185
169
|
void
|
186
|
-
mouse_horizontal_scroll3(int amount,
|
170
|
+
mouse_horizontal_scroll3(const int amount,
|
171
|
+
const CGScrollEventUnit units,
|
172
|
+
const double duration)
|
187
173
|
{
|
188
|
-
|
174
|
+
SCROLL(0, scroll);
|
189
175
|
}
|
190
176
|
|
191
177
|
void
|
192
|
-
mouse_horizontal_scroll2(int amount,
|
178
|
+
mouse_horizontal_scroll2(const int amount,
|
179
|
+
const CGScrollEventUnit units)
|
193
180
|
{
|
194
|
-
|
181
|
+
mouse_horizontal_scroll3(amount, units, DEFAULT_DURATION);
|
195
182
|
}
|
196
183
|
|
197
184
|
void
|
198
|
-
mouse_horizontal_scroll(int amount)
|
185
|
+
mouse_horizontal_scroll(const int amount)
|
199
186
|
{
|
200
|
-
|
187
|
+
mouse_horizontal_scroll2(amount, kCGScrollEventUnitLine);
|
201
188
|
}
|
202
189
|
|
203
190
|
void
|
204
|
-
mouse_click_down3(CGPoint point, uint_t sleep_quanta)
|
191
|
+
mouse_click_down3(const CGPoint point, const uint_t sleep_quanta)
|
205
192
|
{
|
206
|
-
|
207
|
-
|
193
|
+
POSTRELEASE(NEW_EVENT(kCGEventLeftMouseDown, point, kCGMouseButtonLeft));
|
194
|
+
mouse_sleep(sleep_quanta);
|
208
195
|
}
|
209
196
|
|
210
197
|
void
|
211
|
-
mouse_click_down2(CGPoint point)
|
198
|
+
mouse_click_down2(const CGPoint point)
|
212
199
|
{
|
213
|
-
|
200
|
+
mouse_click_down3(point, FPS / 10);
|
214
201
|
}
|
215
202
|
|
216
203
|
void
|
217
204
|
mouse_click_down()
|
218
205
|
{
|
219
|
-
|
206
|
+
mouse_click_down2(mouse_current_position());
|
220
207
|
}
|
221
208
|
|
222
209
|
|
223
210
|
void
|
224
|
-
mouse_click_up2(CGPoint point)
|
211
|
+
mouse_click_up2(const CGPoint point)
|
225
212
|
{
|
226
|
-
|
213
|
+
POSTRELEASE(NEW_EVENT(kCGEventLeftMouseUp, point, kCGMouseButtonLeft));
|
227
214
|
}
|
228
215
|
|
229
216
|
void
|
230
217
|
mouse_click_up()
|
231
218
|
{
|
232
|
-
|
219
|
+
mouse_click_up2(mouse_current_position());
|
233
220
|
}
|
234
221
|
|
235
222
|
|
236
223
|
void
|
237
|
-
mouse_click2(CGPoint point)
|
224
|
+
mouse_click2(const CGPoint point)
|
238
225
|
{
|
239
|
-
|
240
|
-
|
226
|
+
mouse_click_down2(point);
|
227
|
+
mouse_click_up2(point);
|
241
228
|
}
|
242
229
|
|
243
230
|
void
|
244
231
|
mouse_click()
|
245
232
|
{
|
246
|
-
|
233
|
+
mouse_click2(mouse_current_position());
|
247
234
|
}
|
248
235
|
|
249
236
|
|
250
237
|
void
|
251
|
-
mouse_secondary_click_down3(CGPoint point, uint_t sleep_quanta)
|
238
|
+
mouse_secondary_click_down3(const CGPoint point, const uint_t sleep_quanta)
|
252
239
|
{
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
POSTRELEASE(base_event);
|
259
|
-
mouse_sleep(sleep_quanta);
|
240
|
+
CGEventRef const base_event = NEW_EVENT(kCGEventRightMouseDown,
|
241
|
+
point,
|
242
|
+
kCGMouseButtonRight);
|
243
|
+
POSTRELEASE(base_event);
|
244
|
+
mouse_sleep(sleep_quanta);
|
260
245
|
}
|
261
246
|
|
262
247
|
void
|
263
|
-
mouse_secondary_click_down2(CGPoint point)
|
248
|
+
mouse_secondary_click_down2(const CGPoint point)
|
264
249
|
{
|
265
|
-
|
250
|
+
mouse_secondary_click_down3(point, FPS / 10);
|
266
251
|
}
|
267
252
|
|
268
253
|
void
|
269
254
|
mouse_secondary_click_down()
|
270
255
|
{
|
271
|
-
|
256
|
+
mouse_secondary_click_down2(mouse_current_position());
|
272
257
|
}
|
273
258
|
|
274
259
|
|
275
260
|
void
|
276
|
-
mouse_secondary_click_up2(CGPoint point)
|
261
|
+
mouse_secondary_click_up2(const CGPoint point)
|
277
262
|
{
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
);
|
283
|
-
POSTRELEASE(base_event);
|
263
|
+
CGEventRef const base_event = NEW_EVENT(kCGEventRightMouseUp,
|
264
|
+
point,
|
265
|
+
kCGMouseButtonRight);
|
266
|
+
POSTRELEASE(base_event);
|
284
267
|
}
|
285
268
|
|
286
269
|
void
|
287
270
|
mouse_secondary_click_up()
|
288
271
|
{
|
289
|
-
|
272
|
+
mouse_secondary_click_up2(mouse_current_position());
|
290
273
|
}
|
291
274
|
|
292
275
|
|
293
276
|
void
|
294
|
-
mouse_secondary_click3(CGPoint point, uint_t sleep_quanta)
|
277
|
+
mouse_secondary_click3(const CGPoint point, const uint_t sleep_quanta)
|
295
278
|
{
|
296
|
-
|
297
|
-
|
279
|
+
mouse_secondary_click_down3(point, sleep_quanta);
|
280
|
+
mouse_secondary_click_up2(point);
|
298
281
|
}
|
299
282
|
|
300
283
|
void
|
301
|
-
mouse_secondary_click2(CGPoint point)
|
284
|
+
mouse_secondary_click2(const CGPoint point)
|
302
285
|
{
|
303
|
-
|
304
|
-
|
286
|
+
mouse_secondary_click_down2(point);
|
287
|
+
mouse_secondary_click_up2(point);
|
305
288
|
}
|
306
289
|
|
307
290
|
void
|
308
291
|
mouse_secondary_click()
|
309
292
|
{
|
310
|
-
|
311
|
-
|
293
|
+
mouse_secondary_click_down();
|
294
|
+
mouse_secondary_click_up();
|
312
295
|
}
|
313
296
|
|
314
297
|
|
315
298
|
void
|
316
|
-
mouse_arbitrary_click_down3(
|
317
|
-
|
318
|
-
|
319
|
-
uint_t sleep_quanta
|
320
|
-
)
|
299
|
+
mouse_arbitrary_click_down3(const CGEventMouseSubtype button,
|
300
|
+
const CGPoint point,
|
301
|
+
const uint_t sleep_quanta)
|
321
302
|
{
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
POSTRELEASE(base_event);
|
328
|
-
mouse_sleep(sleep_quanta);
|
303
|
+
CGEventRef const base_event = NEW_EVENT(kCGEventOtherMouseDown,
|
304
|
+
point,
|
305
|
+
button);
|
306
|
+
POSTRELEASE(base_event);
|
307
|
+
mouse_sleep(sleep_quanta);
|
329
308
|
}
|
330
309
|
|
331
310
|
void
|
332
|
-
mouse_arbitrary_click_down2(CGEventMouseSubtype button,
|
311
|
+
mouse_arbitrary_click_down2(const CGEventMouseSubtype button,
|
312
|
+
const CGPoint point)
|
333
313
|
{
|
334
|
-
|
314
|
+
mouse_arbitrary_click_down3(button, point, FPS / 10);
|
335
315
|
}
|
336
316
|
|
337
317
|
void
|
338
|
-
mouse_arbitrary_click_down(CGEventMouseSubtype button)
|
318
|
+
mouse_arbitrary_click_down(const CGEventMouseSubtype button)
|
339
319
|
{
|
340
|
-
|
320
|
+
mouse_arbitrary_click_down2(button, mouse_current_position());
|
341
321
|
}
|
342
322
|
|
343
323
|
|
344
|
-
void mouse_arbitrary_click_up2(CGEventMouseSubtype button,
|
324
|
+
void mouse_arbitrary_click_up2(const CGEventMouseSubtype button,
|
325
|
+
const CGPoint point)
|
345
326
|
{
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
);
|
351
|
-
POSTRELEASE(base_event);
|
327
|
+
CGEventRef const base_event = NEW_EVENT(kCGEventOtherMouseUp,
|
328
|
+
point,
|
329
|
+
button);
|
330
|
+
POSTRELEASE(base_event);
|
352
331
|
}
|
353
332
|
|
354
|
-
void mouse_arbitrary_click_up(CGEventMouseSubtype button)
|
333
|
+
void mouse_arbitrary_click_up(const CGEventMouseSubtype button)
|
355
334
|
{
|
356
|
-
|
335
|
+
mouse_arbitrary_click_up2(button, mouse_current_position());
|
357
336
|
}
|
358
337
|
|
359
338
|
|
360
339
|
void
|
361
|
-
mouse_arbitrary_click3(CGEventMouseSubtype button,
|
340
|
+
mouse_arbitrary_click3(const CGEventMouseSubtype button,
|
341
|
+
const CGPoint point,
|
342
|
+
const uint_t sleep_quanta)
|
362
343
|
{
|
363
|
-
|
364
|
-
|
344
|
+
mouse_arbitrary_click_down3(button, point, sleep_quanta);
|
345
|
+
mouse_arbitrary_click_up2(button, point);
|
365
346
|
}
|
366
347
|
|
367
348
|
void
|
368
|
-
mouse_arbitrary_click2(CGEventMouseSubtype button,
|
349
|
+
mouse_arbitrary_click2(const CGEventMouseSubtype button,
|
350
|
+
const CGPoint point)
|
369
351
|
{
|
370
|
-
|
371
|
-
|
352
|
+
mouse_arbitrary_click_down2(button, point);
|
353
|
+
mouse_arbitrary_click_up2(button, point);
|
372
354
|
}
|
373
355
|
|
374
356
|
void
|
375
|
-
mouse_arbitrary_click(CGEventMouseSubtype button)
|
357
|
+
mouse_arbitrary_click(const CGEventMouseSubtype button)
|
376
358
|
{
|
377
|
-
|
378
|
-
|
359
|
+
mouse_arbitrary_click_down(button);
|
360
|
+
mouse_arbitrary_click_up(button);
|
379
361
|
}
|
380
362
|
|
381
363
|
|
382
364
|
void
|
383
|
-
mouse_middle_click2(CGPoint point)
|
365
|
+
mouse_middle_click2(const CGPoint point)
|
384
366
|
{
|
385
|
-
|
367
|
+
mouse_arbitrary_click2(kCGMouseButtonCenter, point);
|
386
368
|
}
|
387
369
|
|
388
370
|
void
|
389
371
|
mouse_middle_click()
|
390
372
|
{
|
391
|
-
|
373
|
+
mouse_middle_click2(mouse_current_position());
|
392
374
|
}
|
393
375
|
|
394
376
|
|
395
377
|
void
|
396
|
-
mouse_multi_click2(size_t num_clicks, CGPoint point)
|
378
|
+
mouse_multi_click2(const size_t num_clicks, const CGPoint point)
|
397
379
|
{
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
380
|
+
CGEventRef const base_event = NEW_EVENT(kCGEventLeftMouseDown,
|
381
|
+
point,
|
382
|
+
kCGMouseButtonLeft);
|
383
|
+
CGEventSetIntegerValueField(base_event,
|
384
|
+
kCGMouseEventClickState,
|
385
|
+
num_clicks);
|
404
386
|
|
405
|
-
|
406
|
-
|
387
|
+
CHANGE(base_event, kCGEventLeftMouseDown);
|
388
|
+
POST(base_event);
|
407
389
|
|
408
|
-
|
409
|
-
|
390
|
+
CHANGE(base_event, kCGEventLeftMouseUp);
|
391
|
+
POSTRELEASE(base_event);
|
410
392
|
}
|
411
393
|
|
412
394
|
void
|
413
|
-
mouse_multi_click(size_t num_clicks)
|
395
|
+
mouse_multi_click(const size_t num_clicks)
|
414
396
|
{
|
415
|
-
|
397
|
+
mouse_multi_click2(num_clicks, mouse_current_position());
|
416
398
|
}
|
417
399
|
|
418
400
|
|
419
401
|
void
|
420
|
-
mouse_double_click2(CGPoint point)
|
402
|
+
mouse_double_click2(const CGPoint point)
|
421
403
|
{
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
404
|
+
// some apps still expect to receive the single click event first
|
405
|
+
// and then the double click event
|
406
|
+
mouse_multi_click2(1, point);
|
407
|
+
mouse_multi_click2(2, point);
|
426
408
|
}
|
427
409
|
|
428
410
|
void
|
429
411
|
mouse_double_click()
|
430
412
|
{
|
431
|
-
|
413
|
+
mouse_double_click2(mouse_current_position());
|
432
414
|
}
|
433
415
|
|
434
416
|
|
435
417
|
void
|
436
|
-
mouse_triple_click2(CGPoint point)
|
418
|
+
mouse_triple_click2(const CGPoint point)
|
437
419
|
{
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
420
|
+
// some apps still expect to receive the single click event first
|
421
|
+
// and then the double and triple click events
|
422
|
+
mouse_double_click2(point);
|
423
|
+
mouse_multi_click2(3, point);
|
442
424
|
}
|
443
425
|
|
444
426
|
void
|
445
427
|
mouse_triple_click()
|
446
428
|
{
|
447
|
-
|
429
|
+
mouse_triple_click2(mouse_current_position());
|
448
430
|
}
|
449
431
|
|
450
432
|
|
451
433
|
static
|
452
434
|
void
|
453
|
-
mouse_gesture(CGPoint point,
|
435
|
+
mouse_gesture(const CGPoint point,
|
436
|
+
const uint_t sleep_quanta,
|
437
|
+
void (^ const gesture_block)(void))
|
454
438
|
{
|
455
|
-
|
439
|
+
POSTRELEASE(NEW_EVENT(kCGEventMouseMoved, point, kCGMouseButtonLeft));
|
456
440
|
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
);
|
463
|
-
POST(gesture);
|
441
|
+
NEW_GESTURE(gesture);
|
442
|
+
CGEventSetIntegerValueField(gesture,
|
443
|
+
kCGEventGestureType,
|
444
|
+
kCGGestureTypeGestureStarted);
|
445
|
+
POST(gesture);
|
464
446
|
|
465
|
-
|
447
|
+
gesture_block();
|
466
448
|
|
467
|
-
|
468
|
-
|
449
|
+
CGEventSetIntegerValueField(gesture,
|
450
|
+
kCGEventGestureType,
|
451
|
+
kCGGestureTypeGestureEnded);
|
452
|
+
POSTRELEASE(gesture);
|
469
453
|
|
470
|
-
|
454
|
+
mouse_sleep(sleep_quanta);
|
471
455
|
}
|
472
456
|
|
473
457
|
void
|
474
|
-
mouse_smart_magnify2(CGPoint point)
|
458
|
+
mouse_smart_magnify2(const CGPoint point)
|
475
459
|
{
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
460
|
+
mouse_gesture(point, (FPS / 2), ^(void)
|
461
|
+
{
|
462
|
+
NEW_GESTURE(event);
|
463
|
+
CGEventSetIntegerValueField(event,
|
464
|
+
kCGEventGestureType,
|
465
|
+
kCGGestureTypeSmartMagnify);
|
466
|
+
POSTRELEASE(event);
|
480
467
|
});
|
481
468
|
}
|
482
469
|
|
483
470
|
void
|
484
471
|
mouse_smart_magnify()
|
485
472
|
{
|
486
|
-
|
473
|
+
mouse_smart_magnify2(mouse_current_position());
|
487
474
|
}
|
488
475
|
|
489
476
|
void
|
490
|
-
|
491
|
-
CGSwipeDirection direction,
|
492
|
-
CGPoint point,
|
493
|
-
double duration
|
494
|
-
)
|
477
|
+
mouse_swipe2(const CGSwipeDirection direction, const CGPoint point)
|
495
478
|
{
|
496
|
-
|
497
|
-
|
498
|
-
|
479
|
+
uint16_t axis = 0;
|
480
|
+
CGFloat distance = 1.0;
|
481
|
+
CGGestureMotion motion = kCGGestureMotionNone;
|
499
482
|
|
500
|
-
|
501
|
-
{
|
483
|
+
switch (direction) {
|
502
484
|
case kCGSwipeDirectionUp:
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
485
|
+
axis = kCGEventGestureSwipePositionY;
|
486
|
+
distance = -(distance);
|
487
|
+
motion = kCGGestureMotionVertical;
|
488
|
+
break;
|
507
489
|
case kCGSwipeDirectionDown:
|
508
|
-
|
509
|
-
|
510
|
-
|
490
|
+
axis = kCGEventGestureSwipePositionY;
|
491
|
+
motion = kCGGestureMotionVertical;
|
492
|
+
break;
|
511
493
|
case kCGSwipeDirectionLeft:
|
512
|
-
|
513
|
-
|
514
|
-
|
494
|
+
axis = kCGEventGestureSwipePositionX;
|
495
|
+
motion = kCGGestureMotionHorizontal;
|
496
|
+
break;
|
515
497
|
case kCGSwipeDirectionRight:
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
498
|
+
axis = kCGEventGestureSwipePositionX;
|
499
|
+
distance = -(distance);
|
500
|
+
motion = kCGGestureMotionHorizontal;
|
501
|
+
break;
|
520
502
|
default:
|
521
|
-
|
503
|
+
return;
|
522
504
|
}
|
523
505
|
|
524
|
-
|
525
|
-
|
506
|
+
mouse_gesture(point, (FPS / 10), ^(void)
|
507
|
+
{
|
508
|
+
NEW_GESTURE(swipe);
|
526
509
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
510
|
+
CGEventSetIntegerValueField(swipe, kCGEventGestureType, kCGGestureTypeSwipe);
|
511
|
+
CGEventSetIntegerValueField(swipe, kCGEventGestureSwipeMotion, motion);
|
512
|
+
CGEventSetIntegerValueField(swipe, kCGEventGestureSwipeDirection, direction);
|
513
|
+
CGEventSetIntegerValueField(swipe, kCGEventGesturePhase, kCGGesturePhaseBegan);
|
514
|
+
CGEventSetDoubleValueField( swipe, kCGEventGestureSwipeProgress, distance);
|
515
|
+
CGEventSetDoubleValueField( swipe, axis, distance);
|
533
516
|
|
534
|
-
|
535
|
-
|
536
|
-
|
517
|
+
// TODO: animation steps don't seem to do anything...
|
518
|
+
// kCGGesturePhaseChanged
|
519
|
+
// kCGGesturePhaseEnded
|
537
520
|
|
538
|
-
|
521
|
+
POSTRELEASE(swipe);
|
539
522
|
});
|
540
523
|
}
|
541
524
|
|
542
525
|
void
|
543
|
-
|
526
|
+
mouse_swipe(const CGSwipeDirection direction)
|
544
527
|
{
|
545
|
-
|
528
|
+
mouse_swipe2(direction, mouse_current_position());
|
546
529
|
}
|
547
530
|
|
548
531
|
void
|
549
|
-
|
532
|
+
mouse_pinch4(const CGPinchDirection direction,
|
533
|
+
const double magnification,
|
534
|
+
const CGPoint point,
|
535
|
+
const double duration)
|
550
536
|
{
|
551
|
-
|
552
|
-
}
|
537
|
+
double _magnification = magnification;
|
553
538
|
|
554
|
-
|
555
|
-
mouse_pinch4(
|
556
|
-
CGPinchDirection direction,
|
557
|
-
double magnification,
|
558
|
-
CGPoint point,
|
559
|
-
double duration
|
560
|
-
)
|
561
|
-
{
|
562
|
-
switch (direction)
|
563
|
-
{
|
539
|
+
switch (direction) {
|
564
540
|
case kCGPinchExpand:
|
565
|
-
|
541
|
+
break;
|
566
542
|
case kCGPinchContract:
|
567
|
-
|
568
|
-
|
543
|
+
_magnification = -(magnification);
|
544
|
+
break;
|
569
545
|
default:
|
570
|
-
|
546
|
+
return;
|
571
547
|
}
|
572
548
|
|
573
|
-
|
574
|
-
|
575
|
-
|
549
|
+
mouse_gesture(point, FPS / 10, ^(void)
|
550
|
+
{
|
551
|
+
NEW_GESTURE(pinch);
|
552
|
+
CGEventSetIntegerValueField(pinch,
|
553
|
+
kCGEventGestureType,
|
554
|
+
kCGGestureTypePinch);
|
576
555
|
|
577
|
-
|
578
|
-
|
579
|
-
|
556
|
+
const size_t steps = FPS / duration;
|
557
|
+
const double step_size = _magnification / steps;
|
558
|
+
const double step_period = (duration / steps) * 1000000;
|
580
559
|
|
581
|
-
|
560
|
+
CGEventSetDoubleValueField(pinch, kCGEventGesturePinchValue, step_size);
|
582
561
|
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
562
|
+
for (size_t i = 0; i < steps; i++) {
|
563
|
+
POST(pinch);
|
564
|
+
usleep(step_period);
|
565
|
+
}
|
587
566
|
|
588
|
-
|
567
|
+
CFRelease(pinch);
|
589
568
|
});
|
590
569
|
}
|
591
570
|
|
592
571
|
void
|
593
|
-
mouse_pinch3(CGPinchDirection direction,
|
572
|
+
mouse_pinch3(const CGPinchDirection direction,
|
573
|
+
const double magnification,
|
574
|
+
const CGPoint point)
|
594
575
|
{
|
595
|
-
|
576
|
+
mouse_pinch4(direction, magnification, point, DEFAULT_DURATION);
|
596
577
|
}
|
597
578
|
|
598
579
|
void
|
599
|
-
mouse_pinch2(CGPinchDirection direction,
|
580
|
+
mouse_pinch2(const CGPinchDirection direction,
|
581
|
+
const double magnification)
|
600
582
|
{
|
601
|
-
|
583
|
+
mouse_pinch3(direction, magnification, mouse_current_position());
|
602
584
|
}
|
603
585
|
|
604
586
|
void
|
605
|
-
mouse_pinch(CGPinchDirection direction)
|
587
|
+
mouse_pinch(const CGPinchDirection direction)
|
606
588
|
{
|
607
|
-
|
589
|
+
mouse_pinch2(direction, DEFAULT_MAGNIFICATION);
|
608
590
|
}
|
609
591
|
|
610
592
|
void
|
611
|
-
mouse_rotate3(
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
double duration
|
616
|
-
)
|
593
|
+
mouse_rotate3(const CGRotateDirection direction,
|
594
|
+
const double angle,
|
595
|
+
const CGPoint point,
|
596
|
+
const double duration)
|
617
597
|
{
|
618
|
-
|
619
|
-
|
598
|
+
double _angle = angle;
|
599
|
+
|
600
|
+
switch (direction) {
|
620
601
|
case kCGRotateClockwise:
|
621
|
-
|
622
|
-
|
602
|
+
_angle = -(angle);
|
603
|
+
break;
|
623
604
|
case kCGRotateCounterClockwise:
|
624
|
-
|
605
|
+
break;
|
625
606
|
default:
|
626
|
-
|
607
|
+
return;
|
627
608
|
}
|
628
609
|
|
629
|
-
|
630
|
-
|
631
|
-
|
610
|
+
mouse_gesture(point, (FPS / 10), ^(void)
|
611
|
+
{
|
612
|
+
NEW_GESTURE(rotation);
|
613
|
+
CGEventSetIntegerValueField(rotation,
|
614
|
+
kCGEventGestureType,
|
615
|
+
kCGGestureTypeRotation);
|
632
616
|
|
633
|
-
|
634
|
-
|
635
|
-
|
617
|
+
const size_t steps = FPS / duration;
|
618
|
+
const double step_size = _angle / steps;
|
619
|
+
const double step_period = (duration / steps) * 1000000;
|
636
620
|
|
637
|
-
|
621
|
+
CGEventSetDoubleValueField(rotation,
|
622
|
+
kCGEventGestureRotationValue,
|
623
|
+
step_size);
|
638
624
|
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
625
|
+
for (size_t i = 0; i < steps; i++) {
|
626
|
+
POST(rotation);
|
627
|
+
usleep(step_period);
|
628
|
+
}
|
643
629
|
|
644
|
-
|
630
|
+
CFRelease(rotation);
|
645
631
|
});
|
646
632
|
}
|
647
633
|
|
648
634
|
void
|
649
|
-
mouse_rotate2(CGRotateDirection direction,
|
635
|
+
mouse_rotate2(const CGRotateDirection direction,
|
636
|
+
const double angle,
|
637
|
+
const CGPoint point)
|
650
638
|
{
|
651
|
-
|
639
|
+
mouse_rotate3(direction, angle, point, DEFAULT_DURATION);
|
652
640
|
}
|
653
641
|
|
654
642
|
void
|
655
|
-
mouse_rotate(CGRotateDirection direction, double angle)
|
643
|
+
mouse_rotate(const CGRotateDirection direction, const double angle)
|
656
644
|
{
|
657
|
-
|
645
|
+
mouse_rotate2(direction, angle, mouse_current_position());
|
658
646
|
}
|