accessibility_core 0.1.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.yardopts +2 -0
  2. data/History.markdown +33 -0
  3. data/README.markdown +11 -0
  4. data/Rakefile +18 -49
  5. data/ext/accessibility/bridge/{ext/accessibility/bridge/bridge.c → bridge.c} +136 -56
  6. data/ext/accessibility/bridge/bridge.h +132 -0
  7. data/ext/accessibility/bridge/{ext/accessibility/bridge/extconf.rb → extconf.rb} +1 -1
  8. data/ext/accessibility/core/core.c +21 -3
  9. data/ext/accessibility/core/extconf.rb +7 -1
  10. data/ext/accessibility/extras/extconf.rb +28 -0
  11. data/ext/accessibility/extras/extras.c +842 -0
  12. data/ext/accessibility/extras/extras.h +1 -0
  13. data/ext/accessibility/highlighter/extconf.rb +9 -2
  14. data/ext/accessibility/highlighter/highlighter.c +291 -1
  15. data/{ext/accessibility/bridge/lib → lib}/accessibility/bridge.rb +3 -3
  16. data/{ext/accessibility/bridge/lib → lib}/accessibility/bridge/common.rb +0 -0
  17. data/{ext/accessibility/bridge/lib → lib}/accessibility/bridge/macruby.rb +17 -0
  18. data/{ext/accessibility/bridge/lib → lib}/accessibility/bridge/mri.rb +10 -7
  19. data/lib/accessibility/core.rb +1 -1
  20. data/lib/accessibility/core/macruby.rb +1 -1
  21. data/lib/accessibility/core/version.rb +1 -1
  22. data/lib/accessibility/extras.rb +5 -0
  23. data/lib/accessibility/extras/common.rb +19 -0
  24. data/lib/accessibility/highlighter.rb +8 -0
  25. data/lib/accessibility/highlighter/macruby.rb +85 -0
  26. data/test/helper.rb +18 -28
  27. metadata +33 -56
  28. data/ext/accessibility/bridge/lib/accessibility/bridge/version.rb +0 -6
  29. data/ext/accessibility/bridge/test/array_test.rb +0 -31
  30. data/ext/accessibility/bridge/test/boxed_test.rb +0 -23
  31. data/ext/accessibility/bridge/test/cfrange_test.rb +0 -21
  32. data/ext/accessibility/bridge/test/cgpoint_test.rb +0 -54
  33. data/ext/accessibility/bridge/test/cgrect_test.rb +0 -60
  34. data/ext/accessibility/bridge/test/cgsize_test.rb +0 -54
  35. data/ext/accessibility/bridge/test/helper.rb +0 -19
  36. data/ext/accessibility/bridge/test/nsstring_test.rb +0 -22
  37. data/ext/accessibility/bridge/test/nsurl_test.rb +0 -17
  38. data/ext/accessibility/bridge/test/object_test.rb +0 -19
  39. data/ext/accessibility/bridge/test/range_test.rb +0 -16
  40. data/ext/accessibility/bridge/test/string_test.rb +0 -35
  41. data/ext/accessibility/bridge/test/uri_test.rb +0 -15
  42. data/ext/accessibility/core/bridge.h +0 -1
data/.yardopts CHANGED
@@ -6,3 +6,5 @@
6
6
  --readme README.markdown
7
7
  --hide-void-return
8
8
  lib/**/*.rb
9
+ ext/**/*{.m,.c}
10
+
@@ -1,13 +1,46 @@
1
+ # 0.3.1 - Fix it up
2
+
3
+ * Fix C extensions being installed to the wrong location
4
+ * Fix Accessibility module not always being defined at the appropriate time
5
+
6
+ # 0.3.0 - Merge accessibility\_bridge
7
+
8
+ * Merge in `accessibility_bridge` v0.2.0
9
+
10
+ - Add the `Battery` module for collecting information about the battery status
11
+ - Add the `Accessibility::Highilghter` module to highlight rectangles on the screen
12
+ - Add `NSScreen.wakeup` method as a freedom patch to wake sleeping screens
13
+
14
+ - Add a 99% drop-in replacement for `NSRunningApplication`
15
+ - Add a 20% drop-in replacement for `NSWorkspace` to complement `NSRunningApplication`
16
+ - Add a 66% drop-in replacement for `NSProcessInfo` for collecting process info
17
+ - Add a 66% drop-in-replacement for `NSHost` for collecting host info
18
+ - Add a 20% drop-in replacement for `NSScreen` to help the highlighter
19
+ - Add a 33% drop-in replacement for `NSColor` to help the highlighter
20
+
21
+ - Various bugs fixed (wrapping strings, URLs, rectangles...)
22
+ - Various memory leaks plugged
23
+
24
+ __NOTE__: Percentages are somewhat arbitrary based on my personal usage.
25
+
26
+
27
+ # 0.2.0 - Update accessibility\_bridge
28
+
29
+ * Update bridge dependency to v0.2.0
30
+
31
+
1
32
  # 0.1.2 - Fix some bridging stuff
2
33
 
3
34
  * Update bridge dependency to get a fix
4
35
 
36
+
5
37
  # 0.1.1 - Fix the silly things release
6
38
 
7
39
  * Fix documentation not being generated
8
40
  * Fix C extension not being installed to the proper location
9
41
  * Remove redundant core extensions provided by `accessibility_bridge`
10
42
 
43
+
11
44
  # 0.1.0 - Initial Release
12
45
 
13
46
  * CRuby and MacRuby compatible
@@ -36,6 +36,17 @@ rake anymore.
36
36
  * bridging for `NSAttributedString`
37
37
  * more descriptive error handling for the C extension
38
38
 
39
+
40
+ ## Tests
41
+
42
+ Currently, the tests are all run as one task. You can run individual
43
+ test files if needed. This is not ideal, but not a high priority for
44
+ me right now.
45
+
46
+ To properly run tests, you must run them under CRuby and also under
47
+ MacRuby and get the same results.
48
+
49
+
39
50
  ## Copyright
40
51
 
41
52
  Copyright (c) 2012, Mark Rada
data/Rakefile CHANGED
@@ -1,42 +1,30 @@
1
- task :default => :test
2
-
3
- require 'rake/clean'
4
- CLEAN.include '*.plist', '*.gch'
5
-
6
- desc 'Run the Clang static analyzer'
7
- task :analyze do
8
- sh "clang --analyze ext/accessibility/core/core.c"
1
+ if defined? MACRUBY_REVISION
2
+ def on_macruby?
3
+ true
4
+ end
5
+ else
6
+ def on_macruby?
7
+ false
8
+ end
9
9
  end
10
10
 
11
- desc 'Startup an IRb console with accessibility-core loaded'
12
- task :console => [:compile] do
13
- sh 'irb -Ilib -raccessibility/core'
11
+ def on_mri?
12
+ !on_macruby?
14
13
  end
15
14
 
16
- desc 'Open the fixture app'
17
- task :run_fixture => :fixture do
18
- sh 'open test/fixture/Release/AXElementsTester.app'
19
- end
15
+ task :default => :test
20
16
 
21
- desc 'Build the test fixture'
22
- task :fixture do
23
- sh 'cd test/AXElementsTester && xcodebuild'
24
- end
17
+ # @todo restore the clang analyze task, don't forget to add rubyhdrdir
25
18
 
26
- desc 'Remove the built fixture app'
27
- task :clobber_fixture do
28
- $stdout.puts 'rm -rf test/fixture'
29
- rm_rf 'test/fixture'
19
+ desc 'Startup an IRb console with accessibility-core loaded'
20
+ task :console => 'compile:core' do
21
+ sh 'irb -Ilib -raccessibility/core'
30
22
  end
31
- task :clobber => :clobber_fixture
32
23
 
33
- require 'rake/testtask'
34
- Rake::TestTask.new do |t|
35
- t.libs << '.'
36
- t.pattern = 'test/*_test.rb'
24
+ desc 'Startup an IRb console with everything loaded'
25
+ task :console_complete => :compile do
26
+ sh 'irb -Ilib -raccessibility/core -raccessibility/bridge -raccessibility/extras -raccessibility/highlighter'
37
27
  end
38
- task :test => [:compile, :fixture]
39
-
40
28
 
41
29
  # Gem stuff
42
30
 
@@ -51,22 +39,3 @@ task :install => :gem do
51
39
  Gem::Installer.new("pkg/#{SPEC.file_name}").install
52
40
  end
53
41
 
54
-
55
- # C extensions!
56
-
57
- require 'rake/extensiontask'
58
-
59
- Rake::ExtensionTask.new('core', SPEC) do |ext|
60
- ext.ext_dir = 'ext/accessibility/core'
61
- ext.lib_dir = 'lib/accessibility'
62
- end
63
-
64
- #Rake::ExtensionTask.new('highlighter', SPEC) do |ext|
65
- # ext.ext_dir = 'ext/accessibility/highlighter'
66
- # ext.lib_dir = 'lib/accessibility/core'
67
- #end
68
-
69
- # Rake::ExtensionTask.new('running_application', SPEC) do |ext|
70
- # ext.ext_dir = 'ext/accessibility/running_application'
71
- # ext.lib_dir = 'lib/accessibility/core'
72
- # end
@@ -1,8 +1,13 @@
1
- #include "ruby.h"
2
- #import <Cocoa/Cocoa.h>
1
+ #include "bridge.h"
2
+ #include "ruby/encoding.h"
3
+
4
+
5
+ void
6
+ spin(double seconds)
7
+ {
8
+ CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, false);
9
+ }
3
10
 
4
- #ifndef ACCESSIBILITY_BRIDGE
5
- #define ACCESSIBILITY_BRIDGE 1
6
11
 
7
12
  #ifdef NOT_MACRUBY
8
13
 
@@ -13,6 +18,7 @@ VALUE rb_cCGSize;
13
18
  VALUE rb_cCGRect;
14
19
  VALUE rb_mURI; // URI module
15
20
  VALUE rb_cURI; // URI::Generic class
21
+ VALUE rb_cScreen;
16
22
 
17
23
  ID sel_x;
18
24
  ID sel_y;
@@ -27,24 +33,23 @@ ID sel_to_s;
27
33
  ID sel_parse;
28
34
 
29
35
 
30
- #define WRAP_ARRAY(wrapper) do { \
31
- CFIndex length = CFArrayGetCount(array); \
32
- VALUE ary = rb_ary_new2(length); \
33
- \
34
- for (CFIndex idx = 0; idx < length; idx++) \
35
- rb_ary_store( \
36
- ary, \
37
- idx, \
38
- wrapper(CFArrayGetValueAtIndex(array, idx)) \
39
- ); \
40
- return ary; \
41
- } while (false);
36
+ void
37
+ cf_finalizer(void* obj)
38
+ {
39
+ CFRelease((CFTypeRef)obj);
40
+ }
41
+
42
+ void
43
+ objc_finalizer(void* obj)
44
+ {
45
+ [(id)obj release];
46
+ }
42
47
 
43
48
 
44
49
  VALUE
45
50
  wrap_unknown(CFTypeRef obj)
46
51
  {
47
- // TODO: this will leak, can we use something like alloca?
52
+ // TODO: this will leak...
48
53
  CFStringRef description = CFCopyDescription(obj);
49
54
  rb_raise(
50
55
  rb_eRuntimeError,
@@ -99,6 +104,7 @@ unwrap_size(VALUE size)
99
104
  }
100
105
 
101
106
 
107
+
102
108
  VALUE
103
109
  wrap_rect(CGRect rect)
104
110
  {
@@ -107,6 +113,13 @@ wrap_rect(CGRect rect)
107
113
  return rb_struct_new(rb_cCGRect, point, size);
108
114
  }
109
115
 
116
+
117
+ VALUE
118
+ coerce_to_rect(VALUE obj)
119
+ {
120
+ return rb_funcall(obj, sel_to_rect, 0);
121
+ }
122
+
110
123
  CGRect
111
124
  unwrap_rect(VALUE rect)
112
125
  {
@@ -180,8 +193,7 @@ wrap_value(AXValueRef value)
180
193
  switch (AXValueGetType(value))
181
194
  {
182
195
  case kAXValueIllegalType:
183
- // TODO better error message
184
- rb_raise(rb_eArgError, "herped when you should have derped");
196
+ rb_raise(rb_eArgError, "cannot wrap %s objects", rb_class2name(CLASS_OF(value)));
185
197
  case kAXValueCGPointType:
186
198
  return wrap_value_point(value);
187
199
  case kAXValueCGSizeType:
@@ -196,7 +208,7 @@ wrap_value(AXValueRef value)
196
208
  // TODO better error message
197
209
  rb_raise(
198
210
  rb_eRuntimeError,
199
- "Could not wrap You've found a bug in something...not sure who to blame"
211
+ "Either accessibility_core is out of date or your system has had a serious error"
200
212
  );
201
213
  }
202
214
 
@@ -223,17 +235,10 @@ unwrap_value(VALUE value)
223
235
  VALUE wrap_array_values(CFArrayRef array) { WRAP_ARRAY(wrap_value) }
224
236
 
225
237
 
226
- static
227
- void
228
- ref_finalizer(void* obj)
229
- {
230
- CFRelease((CFTypeRef)obj);
231
- }
232
-
233
238
  VALUE
234
239
  wrap_ref(AXUIElementRef ref)
235
240
  {
236
- return Data_Wrap_Struct(rb_cElement, NULL, ref_finalizer, (void*)ref);
241
+ return Data_Wrap_Struct(rb_cElement, NULL, cf_finalizer, (void*)ref);
237
242
  }
238
243
 
239
244
  AXUIElementRef
@@ -253,14 +258,38 @@ wrap_string(CFStringRef string)
253
258
  {
254
259
  // flying by the seat of our pants here, this hasn't failed yet
255
260
  // but probably will one day when I'm not looking
256
- const char* name = CFStringGetCStringPtr(string, kCFStringEncodingMacRoman);
257
- if (name)
258
- return rb_str_new(name, CFStringGetLength(string));
259
- else
260
- // use rb_external_str_new() ? assume always UTF-8?
261
- rb_raise(rb_eRuntimeError, "NEED TO IMPLEMNET STRING COPYING");
261
+ VALUE ruby_string;
262
+ CFIndex length = CFStringGetLength(string);
263
+ char* name = (char*)CFStringGetCStringPtr(string, kCFStringEncodingMacRoman);
264
+
265
+ if (name) {
266
+ ruby_string = rb_usascii_str_new(name, length);
267
+ }
268
+ else {
269
+ // currently we will always assume UTF-8
270
+ // perhaps we could use CFStringGetSystemEncoding in the future?
271
+ name = malloc(length+1);
272
+ CFStringGetCString(
273
+ string,
274
+ name,
275
+ length+1,
276
+ kCFStringEncodingUTF8
277
+ );
278
+ ruby_string = rb_enc_str_new(name, length, rb_utf8_encoding());
279
+ free(name);
280
+ }
281
+
282
+ return ruby_string;
283
+ }
262
284
 
263
- return Qnil; // unreachable
285
+ VALUE
286
+ wrap_nsstring(NSString* string)
287
+ {
288
+ return rb_enc_str_new(
289
+ [string UTF8String],
290
+ [string length],
291
+ rb_utf8_encoding()
292
+ );
264
293
  }
265
294
 
266
295
  CFStringRef
@@ -279,7 +308,18 @@ unwrap_string(VALUE string)
279
308
  /* ); */
280
309
  }
281
310
 
282
- VALUE wrap_array_strings(CFArrayRef array) { WRAP_ARRAY(wrap_string) }
311
+ NSString*
312
+ unwrap_nsstring(VALUE string)
313
+ {
314
+ return (NSString*)unwrap_string(string);
315
+ }
316
+
317
+ VALUE wrap_array_strings(CFArrayRef array) { WRAP_ARRAY(wrap_string); }
318
+ VALUE wrap_array_nsstrings(NSArray* ary)
319
+ {
320
+ CFArrayRef array = (CFArrayRef)ary;
321
+ WRAP_ARRAY(wrap_string);
322
+ }
283
323
 
284
324
 
285
325
  #define WRAP_NUM(type, cookie, macro) do { \
@@ -358,12 +398,23 @@ unwrap_number(VALUE number)
358
398
  VALUE wrap_array_numbers(CFArrayRef array) { WRAP_ARRAY(wrap_number) }
359
399
 
360
400
 
401
+
361
402
  VALUE
362
403
  wrap_url(CFURLRef url)
363
404
  {
405
+ // @note CFURLGetString does not need to be CFReleased since it is a Get
364
406
  return rb_funcall(rb_mURI, sel_parse, 1, wrap_string(CFURLGetString(url)));
365
407
  }
366
408
 
409
+ VALUE
410
+ wrap_nsurl(NSURL* url)
411
+ {
412
+ NSString* str = [url absoluteString];
413
+ VALUE rb_str = wrap_nsstring(str);
414
+ [str release];
415
+ return rb_funcall(rb_mURI, sel_parse, 1, rb_str);
416
+ }
417
+
367
418
  CFURLRef
368
419
  unwrap_url(VALUE url)
369
420
  {
@@ -387,6 +438,12 @@ wrap_date(CFDateRef date)
387
438
  return rb_time_new((time_t)time, 0);
388
439
  }
389
440
 
441
+ VALUE
442
+ wrap_nsdate(NSDate* date)
443
+ {
444
+ return wrap_date((CFDateRef)date);
445
+ }
446
+
390
447
  CFDateRef
391
448
  unwrap_date(VALUE date)
392
449
  {
@@ -446,20 +503,41 @@ to_ruby(CFTypeRef obj)
446
503
  CFTypeRef
447
504
  to_ax(VALUE obj)
448
505
  {
449
- // TODO we can better optimize this when running under MacRuby
506
+ switch (TYPE(obj))
507
+ {
508
+ case T_STRING:
509
+ return unwrap_string(obj);
510
+ case T_FIXNUM:
511
+ return unwrap_number(obj);
512
+ case T_STRUCT:
513
+ return unwrap_value(obj);
514
+ case T_FLOAT:
515
+ return unwrap_number(obj);
516
+ case T_TRUE:
517
+ case T_FALSE:
518
+ return unwrap_boolean(obj);
519
+ }
520
+
450
521
  VALUE type = CLASS_OF(obj);
451
- if (type == rb_cElement) return unwrap_ref(obj);
452
- else if (type == rb_cString) return unwrap_string(obj);
453
- else if (type == rb_cFixnum) return unwrap_number(obj);
454
- else if (type == rb_cCGPoint) return unwrap_value(obj);
455
- else if (type == rb_cCGSize) return unwrap_value(obj);
456
- else if (type == rb_cCGRect) return unwrap_value(obj);
457
- else if (type == rb_cRange) return unwrap_value(obj);
458
- else if (type == rb_cFloat) return unwrap_number(obj);
459
- else if (type == rb_cTime) return unwrap_date(obj);
460
- else if (type == rb_cURI) return unwrap_url(obj);
461
- else if (obj == Qtrue || obj == Qfalse) return unwrap_boolean(obj);
462
- else return unwrap_unknown(obj);
522
+ if (type == rb_cTime)
523
+ return unwrap_date(obj);
524
+ else if (type == rb_cRange)
525
+ return unwrap_value_range(obj);
526
+
527
+ if (rb_obj_is_kind_of(obj, rb_cURI))
528
+ return unwrap_url(obj);
529
+
530
+ // give up if we get this far
531
+ return unwrap_unknown(obj);
532
+ }
533
+
534
+
535
+ static
536
+ VALUE
537
+ rb_spin(VALUE self, VALUE seconds)
538
+ {
539
+ spin(NUM2DBL(seconds));
540
+ return self;
463
541
  }
464
542
 
465
543
  #endif
@@ -481,12 +559,14 @@ Init_bridge()
481
559
  sel_to_s = rb_intern("to_s");
482
560
  sel_parse = rb_intern("parse");
483
561
 
484
- rb_cCGPoint = rb_const_get(rb_cObject, rb_intern("CGPoint"));
485
- rb_cCGSize = rb_const_get(rb_cObject, rb_intern("CGSize"));
486
- rb_cCGRect = rb_const_get(rb_cObject, rb_intern("CGRect"));
487
- rb_mURI = rb_const_get(rb_cObject, rb_intern("URI"));
488
- rb_cURI = rb_const_get(rb_mURI, rb_intern("Generic"));
489
- #endif
490
- }
562
+ rb_mAccessibility = rb_define_module("Accessibility");
563
+ rb_cElement = rb_define_class_under(rb_mAccessibility, "Element", rb_cObject);
564
+ rb_cCGPoint = rb_const_get(rb_cObject, rb_intern("CGPoint"));
565
+ rb_cCGSize = rb_const_get(rb_cObject, rb_intern("CGSize"));
566
+ rb_cCGRect = rb_const_get(rb_cObject, rb_intern("CGRect"));
567
+ rb_mURI = rb_const_get(rb_cObject, rb_intern("URI"));
568
+ rb_cURI = rb_const_get(rb_mURI, rb_intern("Generic"));
491
569
 
570
+ rb_define_method(rb_cObject, "spin", rb_spin, 1); // semi-private method
492
571
  #endif
572
+ }