accessibility_core 0.1.2 → 0.3.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 (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
+ }