rubyosa19 0.5.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.
@@ -0,0 +1,34 @@
1
+ /**********************************************************************
2
+
3
+ ruby.h -
4
+
5
+ $Author$
6
+ created at: Sun 10 12:06:15 Jun JST 2007
7
+
8
+ Copyright (C) 2007-2008 Yukihiro Matsumoto
9
+
10
+ **********************************************************************/
11
+
12
+ #ifndef RUBY_H
13
+ #define RUBY_H 1
14
+
15
+ #define HAVE_RUBY_DEFINES_H 1
16
+ #define HAVE_RUBY_ENCODING_H 1
17
+ #define HAVE_RUBY_INTERN_H 1
18
+ #define HAVE_RUBY_IO_H 1
19
+ #define HAVE_RUBY_MISSING_H 1
20
+ #define HAVE_RUBY_ONIGURUMA_H 1
21
+ #define HAVE_RUBY_RE_H 1
22
+ #define HAVE_RUBY_REGEX_H 1
23
+ #define HAVE_RUBY_RUBY_H 1
24
+ #define HAVE_RUBY_ST_H 1
25
+ #define HAVE_RUBY_UTIL_H 1
26
+ #define HAVE_RUBY_VERSION_H 1
27
+ #define HAVE_RUBY_VM_H 1
28
+ #ifdef _WIN32
29
+ #define HAVE_RUBY_WIN32_H 1
30
+ #endif
31
+
32
+ #include "ruby/ruby.h"
33
+
34
+ #endif /* RUBY_H */
@@ -0,0 +1,717 @@
1
+ /*
2
+ * Copyright (c) 2006-2007, Apple Inc. All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions
6
+ * are met:
7
+ * 1. Redistributions of source code must retain the above copyright
8
+ * notice, this list of conditions and the following disclaimer.
9
+ * 2. Redistributions in binary form must reproduce the above copyright
10
+ * notice, this list of conditions and the following disclaimer in the
11
+ * documentation and/or other materials provided with the distribution.
12
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
13
+ * its contributors may be used to endorse or promote products derived
14
+ * from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
17
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
20
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ * POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ #include "rbosa.h"
30
+ #include <ruby/st.h>
31
+
32
+ static VALUE mOSA;
33
+ static VALUE cOSAElement;
34
+ static VALUE cOSAElementList;
35
+ static VALUE cOSAElementRecord;
36
+ static VALUE mOSAEventDispatcher;
37
+
38
+ static ID sClasses;
39
+ static ID sApp;
40
+
41
+ static void
42
+ rbosa_element_free (void *ptr)
43
+ {
44
+ AEDisposeDesc (ptr);
45
+ free (ptr);
46
+ }
47
+
48
+ static VALUE
49
+ __rbosa_class_from_desc_data (VALUE app, AEDesc res)
50
+ {
51
+ DescType data;
52
+ Size datasize;
53
+ VALUE classes, klass;
54
+
55
+ classes = rb_ivar_get (app, sClasses);
56
+ if (NIL_P (classes))
57
+ return Qnil;
58
+ klass = Qnil;
59
+
60
+ datasize = AEGetDescDataSize (&res);
61
+ /* This should always be a four-byte code. */
62
+ if (datasize != sizeof (DescType))
63
+ return Qnil;
64
+
65
+ if (AEGetDescData (&res, &data, datasize) == noErr) {
66
+ char dtStr[5];
67
+
68
+ *(DescType *)dtStr = CFSwapInt32HostToBig (data);
69
+ klass = rb_hash_aref (classes, rb_str_new (dtStr, 4));
70
+ }
71
+
72
+ return klass;
73
+ }
74
+
75
+ static VALUE
76
+ rbosa_element_make (VALUE klass, AEDesc *desc, VALUE app)
77
+ {
78
+ AEDesc * newDesc;
79
+ VALUE new_klass, obj;
80
+
81
+ newDesc = (AEDesc *)malloc (sizeof (AEDesc));
82
+ if (newDesc == NULL)
83
+ rb_fatal ("cannot allocate memory");
84
+ memcpy (newDesc, desc, sizeof (AEDesc));
85
+ new_klass = Qnil;
86
+
87
+ /* Let's replace the klass here according to the type of the descriptor,
88
+ * if the basic class OSA::Element was given.
89
+ */
90
+ if (klass == cOSAElement) {
91
+ if (newDesc->descriptorType == 'list') {
92
+ klass = cOSAElementList;
93
+ }
94
+ else if (newDesc->descriptorType == 'reco') {
95
+ klass = cOSAElementRecord;
96
+ }
97
+ else if (newDesc->descriptorType == 'type') {
98
+ new_klass = __rbosa_class_from_desc_data (app, *newDesc);
99
+ }
100
+ else if (newDesc->descriptorType == 'obj ' && !NIL_P (app)) {
101
+ AEDesc res;
102
+ OSErr err;
103
+
104
+ if ((err = AEGetParamDesc ((AppleEvent *)newDesc, 'want', '****', &res)) == noErr)
105
+ new_klass = __rbosa_class_from_desc_data (app, res);
106
+ }
107
+ }
108
+
109
+ if (!NIL_P (new_klass))
110
+ klass = new_klass;
111
+
112
+ obj = Data_Wrap_Struct (klass, NULL, rbosa_element_free, newDesc);
113
+
114
+ rb_ivar_set (obj, sApp, NIL_P (app) ? obj : app);
115
+
116
+ return obj;
117
+ }
118
+
119
+ static AEDesc *
120
+ rbosa_element_aedesc (VALUE element)
121
+ {
122
+ AEDesc * desc;
123
+
124
+ if (!rb_obj_is_kind_of (element, cOSAElement))
125
+ rb_raise (rb_eArgError, "Invalid argument of type '%s' (required: OSA::Element)", rb_class2name (rb_class_of (element)));
126
+
127
+ Data_Get_Struct (element, AEDesc, desc);
128
+
129
+ return desc;
130
+ }
131
+
132
+ static VALUE
133
+ rbosa_element_new (VALUE self, VALUE type, VALUE value)
134
+ {
135
+ FourCharCode ffc_type;
136
+ OSErr error;
137
+ const char * c_value;
138
+ unsigned c_value_size;
139
+ AEDesc desc;
140
+
141
+ ffc_type = RVAL2FOURCHAR (type);
142
+
143
+ if (NIL_P (value)) {
144
+ c_value = NULL;
145
+ c_value_size = 0;
146
+ }
147
+ else if (rb_obj_is_kind_of (value, rb_cInteger)) {
148
+ FourCharCode code;
149
+
150
+ code = NUM2INT (value);
151
+ c_value = (const char *)&code;
152
+ c_value_size = sizeof (FourCharCode);
153
+ }
154
+ else if (ffc_type == 'alis') {
155
+ AliasHandle alias;
156
+
157
+ rbobj_to_alias_handle (value, &alias);
158
+
159
+ c_value = (const char *)*alias;
160
+ c_value_size = GetHandleSize ((Handle)alias);
161
+ }
162
+ else {
163
+ Check_Type (value, T_STRING);
164
+ c_value = RSTRING_PTR(value);
165
+ c_value_size = RSTRING_LEN(value);
166
+ }
167
+
168
+ error = AECreateDesc (ffc_type, c_value, c_value_size, &desc);
169
+ if (error != noErr)
170
+ rb_raise (rb_eArgError, "Cannot create Apple Event descriptor from type '%s' value '%s' : %s (%d)",
171
+ RVAL2CSTR (type), c_value, error_code_to_string (error), error);
172
+
173
+ return rbosa_element_make (self, &desc, Qnil);
174
+ }
175
+
176
+ static VALUE
177
+ rbosa_element_new_os (VALUE self, VALUE desired_class, VALUE container, VALUE key_form, VALUE key_data)
178
+ {
179
+ OSErr error;
180
+ AEDesc obj_specifier;
181
+
182
+ error = CreateObjSpecifier (RVAL2FOURCHAR (desired_class),
183
+ rbosa_element_aedesc (container),
184
+ RVAL2FOURCHAR (key_form),
185
+ rbosa_element_aedesc (key_data),
186
+ false,
187
+ &obj_specifier);
188
+
189
+ if (error != noErr)
190
+ rb_raise (rb_eArgError, "Cannot create Apple Event object specifier for desired class '%s' : %s (%d)",
191
+ RVAL2CSTR (desired_class), error_code_to_string (error), error);
192
+
193
+ return rbosa_element_make (self, &obj_specifier, Qnil);
194
+ }
195
+
196
+ static VALUE
197
+ rbosa_element_dup (VALUE self, VALUE element)
198
+ {
199
+ AEDesc * desc;
200
+ AEDesc new_desc;
201
+ OSErr error;
202
+
203
+ desc = rbosa_element_aedesc (element);
204
+ error = AEDuplicateDesc (desc, &new_desc);
205
+ if (error != noErr)
206
+ rb_raise (rb_eArgError, "Cannot duplicate element : %s (%d)",
207
+ error_code_to_string (error), error);
208
+
209
+ return rbosa_element_make (self, &new_desc, Qnil);
210
+ }
211
+
212
+ static void
213
+ __rbosa_raise_potential_app_error (AEDesc *reply)
214
+ {
215
+ OSErr error;
216
+ AEDesc errorNumDesc;
217
+ AEDesc errorStringDesc;
218
+ int errorNum;
219
+ const char * errorMsg;
220
+ char exception[128];
221
+
222
+ if (AEGetParamDesc (reply, keyErrorNumber, typeSInt32, &errorNumDesc) != noErr)
223
+ return;
224
+
225
+ if (AEGetDescData (&errorNumDesc, &errorNum, sizeof errorNum) != noErr) {
226
+ AEDisposeDesc (&errorNumDesc);
227
+ return;
228
+ }
229
+
230
+ /* The reply is an application error. */
231
+
232
+ errorMsg = error_code_to_string(errorNum);
233
+ if (errorMsg == NULL)
234
+ errorMsg = "Unknown error";
235
+
236
+ exception[0] = '\0';
237
+ error = AEGetParamDesc (reply, keyErrorString, typeChar, &errorStringDesc);
238
+ if (error == noErr) {
239
+ Size size;
240
+
241
+ size = AEGetDescDataSize (&errorStringDesc);
242
+ if (size > 0) {
243
+ char *msg;
244
+
245
+ msg = (char *)malloc (size + 1);
246
+ if (msg != NULL) {
247
+ if (AEGetDescData (&errorStringDesc, msg, size) == noErr) {
248
+ msg[size] = '\0';
249
+ snprintf (exception, sizeof exception, "application returned error: %s (%d), with message: %s", errorMsg, errorNum, msg);
250
+ }
251
+ free (msg);
252
+ }
253
+ }
254
+ AEDisposeDesc (&errorStringDesc);
255
+ }
256
+
257
+ if (exception[0] == '\0')
258
+ snprintf (exception, sizeof exception, "application returned error: %s (%d)", errorMsg, errorNum);
259
+
260
+ AEDisposeDesc (&errorNumDesc);
261
+
262
+ rb_raise (rb_eRuntimeError, exception);
263
+ }
264
+
265
+ static VALUE
266
+ rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE params, VALUE need_retval)
267
+ {
268
+ OSErr error;
269
+ AppleEvent ae;
270
+ AppleEvent reply;
271
+ VALUE rb_timeout;
272
+ SInt32 timeout;
273
+ VALUE rb_reply;
274
+ unsigned has_direct_param;
275
+
276
+ error = AECreateAppleEvent (RVAL2FOURCHAR (event_class),
277
+ RVAL2FOURCHAR (event_id),
278
+ rbosa_element_aedesc (self),
279
+ kAutoGenerateReturnID,
280
+ kAnyTransactionID,
281
+ &ae);
282
+ if (error != noErr)
283
+ rb_raise (rb_eArgError, "Cannot create Apple Event '%s%s' : %s (%d)",
284
+ RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error);
285
+
286
+ has_direct_param = 0;
287
+ if (!NIL_P (params)) {
288
+ unsigned i;
289
+
290
+ for (i = 0; i < RARRAY_LEN(params); i++) {
291
+ VALUE ary;
292
+ VALUE type;
293
+ VALUE element;
294
+ FourCharCode code;
295
+
296
+ ary = RARRAY_PTR(params)[i];
297
+ if (NIL_P (ary) || RARRAY_LEN(ary) != 2)
298
+ continue;
299
+
300
+ type = RARRAY_PTR(ary)[0];
301
+ element = RARRAY_PTR(ary)[1];
302
+ code = RVAL2FOURCHAR (type);
303
+
304
+ if (code == '----')
305
+ has_direct_param = 1;
306
+
307
+ error = AEPutParamDesc (&ae, RVAL2FOURCHAR (type), rbosa_element_aedesc (element));
308
+ if (error != noErr) {
309
+ AEDisposeDesc (&ae);
310
+ rb_raise (rb_eArgError, "Cannot add Apple Event parameter '%s' : %s (%d)",
311
+ RVAL2CSTR (type), error_code_to_string (error), error);
312
+ }
313
+ }
314
+ }
315
+
316
+ rb_timeout = rb_iv_get (mOSA, "@timeout");
317
+ timeout = NIL_P (rb_timeout) ? kAEDefaultTimeout : NUM2INT (rb_timeout);
318
+
319
+ if (has_direct_param == 0)
320
+ AEPutAttributePtr (&ae, 'subj', typeNull, NULL, 0);
321
+
322
+ error = AESend (&ae, &reply, (RVAL2CBOOL(need_retval) ? kAEWaitReply : kAENoReply) | kAECanInteract | kAECanSwitchLayer,
323
+ kAENormalPriority, timeout, NULL, NULL);
324
+
325
+ AEDisposeDesc (&ae);
326
+
327
+ if (error != noErr)
328
+ rb_raise (rb_eRuntimeError, "Cannot send Apple Event '%s%s' : %s (%d)",
329
+ RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error);
330
+
331
+ __rbosa_raise_potential_app_error (&reply);
332
+
333
+ if (RTEST (need_retval)) {
334
+ AEDesc replyObject;
335
+
336
+ AEGetParamDesc (&reply, keyDirectObject, typeWildCard, &replyObject);
337
+
338
+ rb_reply = rbosa_element_make (cOSAElement, &replyObject, self);
339
+ }
340
+ else {
341
+ rb_reply = Qnil;
342
+ }
343
+
344
+ AEDisposeDesc (&reply);
345
+
346
+ return rb_reply;
347
+ }
348
+
349
+ static VALUE
350
+ rbosa_element_type (VALUE self)
351
+ {
352
+ AEDesc *desc;
353
+ char dtStr[5];
354
+
355
+ desc = rbosa_element_aedesc (self);
356
+ *(DescType*)dtStr = CFSwapInt32HostToBig (desc->descriptorType);
357
+
358
+ return rb_str_new (dtStr, 4);
359
+ }
360
+
361
+ static VALUE
362
+ rbosa_element_data (int argc, VALUE *argv, VALUE self)
363
+ {
364
+ VALUE coerce_type;
365
+ AEDesc coerced_desc;
366
+ AEDesc * desc;
367
+ OSErr error;
368
+ void * data;
369
+ Size datasize;
370
+ VALUE retval;
371
+ bool to_4cc;
372
+
373
+ rb_scan_args (argc, argv, "01", &coerce_type);
374
+ to_4cc = false;
375
+
376
+ desc = rbosa_element_aedesc (self);
377
+
378
+ if (!NIL_P (coerce_type)) {
379
+ FourCharCode code;
380
+
381
+ code = RVAL2FOURCHAR (coerce_type);
382
+ error = AECoerceDesc (desc, code, &coerced_desc);
383
+ if (error != noErr)
384
+ rb_raise (rb_eRuntimeError, "Cannot coerce desc to type %s : %s (%d)",
385
+ RVAL2CSTR (coerce_type), error_code_to_string (error), error);
386
+
387
+ desc = &coerced_desc;
388
+ to_4cc = code == 'type';
389
+ }
390
+
391
+ datasize = AEGetDescDataSize (desc);
392
+ data = (void *)malloc (datasize);
393
+ if (data == NULL)
394
+ rb_fatal ("cannot allocate memory");
395
+
396
+ error = AEGetDescData (desc, data, datasize);
397
+ if (error == noErr) {
398
+ if (to_4cc)
399
+ *(DescType*)data = CFSwapInt32HostToBig (*(DescType*)data);
400
+ retval = rb_str_new (data, datasize);
401
+ }
402
+ else {
403
+ retval = Qnil;
404
+ }
405
+
406
+ if (!NIL_P (coerce_type))
407
+ AEDisposeDesc (&coerced_desc);
408
+ free (data);
409
+
410
+ if (error != noErr)
411
+ rb_raise (rb_eRuntimeError, "Cannot get desc data : %s (%d)",
412
+ error_code_to_string (error), error);
413
+
414
+ return retval;
415
+ }
416
+
417
+ static VALUE
418
+ __rbosa_insertion_loc_new (VALUE rcv, FourCharCode code)
419
+ {
420
+ AEDesc * self_desc;
421
+ AEDesc rec;
422
+ AEDesc pos_desc;
423
+ AEDesc new_desc;
424
+
425
+ self_desc = rbosa_element_aedesc (rcv);
426
+ AECreateList (NULL, 0, true, &rec);
427
+ AEPutParamDesc (&rec, keyAEObject, self_desc);
428
+ AECreateDesc (code, NULL, 0, &pos_desc);
429
+ AEPutParamPtr (&rec, keyAEPosition, typeEnumerated, &pos_desc, 4);
430
+ AECoerceDesc (&rec, typeInsertionLoc, &new_desc);
431
+ AEDisposeDesc (&rec);
432
+
433
+ return rbosa_element_make (cOSAElement, &new_desc, Qnil);
434
+ }
435
+
436
+ static VALUE
437
+ rbosa_element_after (VALUE self)
438
+ {
439
+ return __rbosa_insertion_loc_new (self, kAEAfter);
440
+ }
441
+
442
+ static VALUE
443
+ rbosa_element_before (VALUE self)
444
+ {
445
+ return __rbosa_insertion_loc_new (self, kAEBefore);
446
+ }
447
+
448
+ static VALUE
449
+ rbosa_element_eql (VALUE self, VALUE other)
450
+ {
451
+ AEDesc * self_desc;
452
+ AEDesc * other_desc;
453
+ Size data_size;
454
+ void * self_data;
455
+ void * other_data;
456
+ OSErr error;
457
+ Boolean ok;
458
+
459
+ if (!rb_obj_is_kind_of (other, rb_class_real (rb_class_of (self))))
460
+ return Qfalse;
461
+
462
+ self_desc = rbosa_element_aedesc (self);
463
+ other_desc = rbosa_element_aedesc (other);
464
+
465
+ if (self_desc == other_desc)
466
+ return Qtrue;
467
+
468
+ if (self_desc->descriptorType != other_desc->descriptorType)
469
+ return Qfalse;
470
+
471
+ data_size = AEGetDescDataSize (self_desc);
472
+ if (data_size != AEGetDescDataSize (other_desc))
473
+ return Qfalse;
474
+
475
+ self_data = (void *)malloc (data_size);
476
+ other_data = (void *)malloc (data_size);
477
+ ok = 0;
478
+
479
+ if (self_data == NULL || other_data == NULL)
480
+ rb_fatal ("cannot allocate memory");
481
+
482
+ error = AEGetDescData (self_desc, self_data, data_size);
483
+ if (error != noErr)
484
+ goto bails;
485
+
486
+ error = AEGetDescData (other_desc, other_data, data_size);
487
+ if (error != noErr)
488
+ goto bails;
489
+
490
+ ok = memcmp (self_data, other_data, data_size) == 0;
491
+
492
+ bails:
493
+ free (self_data);
494
+ free (other_data);
495
+
496
+ return CBOOL2RVAL (ok);
497
+ }
498
+
499
+ static VALUE
500
+ rbosa_element_inspect (VALUE self)
501
+ {
502
+ Handle h;
503
+ char buf[1024];
504
+
505
+ if (AEPrintDescToHandle (rbosa_element_aedesc (self), &h) != noErr) {
506
+ snprintf (buf, sizeof buf, "<%s:%p>", rb_obj_classname (self), (void *)self);
507
+ }
508
+ else {
509
+ snprintf (buf, sizeof buf, "<%s:%p desc=\"%s\">", rb_obj_classname (self), (void *)self, *h);
510
+ DisposeHandle (h);
511
+ }
512
+
513
+ return CSTR2RVAL (buf);
514
+ }
515
+
516
+ static long
517
+ __rbosa_elementlist_count (AEDescList *list)
518
+ {
519
+ OSErr error;
520
+ long count;
521
+
522
+ error = AECountItems (list, &count);
523
+ if (error != noErr)
524
+ rb_raise (rb_eRuntimeError, "Cannot count items : %s (%d)",
525
+ error_code_to_string (error), error);
526
+
527
+ return count;
528
+ }
529
+
530
+ static void
531
+ __rbosa_elementlist_add (AEDescList *list, VALUE element, long pos)
532
+ {
533
+ OSErr error;
534
+
535
+ error = AEPutDesc (list, pos, rbosa_element_aedesc (element));
536
+ if (error != noErr)
537
+ rb_raise (rb_eRuntimeError, "Cannot add given descriptor : %s (%d)",
538
+ error_code_to_string (error), error);
539
+ }
540
+
541
+ static VALUE
542
+ rbosa_elementlist_new (int argc, VALUE *argv, VALUE self)
543
+ {
544
+ OSErr error;
545
+ AEDescList list;
546
+ VALUE ary;
547
+ int i;
548
+
549
+ rb_scan_args (argc, argv, "01", &ary);
550
+
551
+ if (!NIL_P (ary))
552
+ Check_Type (ary, T_ARRAY);
553
+
554
+ error = AECreateList (NULL, 0, false, &list);
555
+ if (error != noErr)
556
+ rb_raise (rb_eRuntimeError, "Cannot create Apple Event descriptor list : %s (%d)",
557
+ error_code_to_string (error), error);
558
+
559
+ if (!NIL_P (ary)) {
560
+ for (i = 0; i < RARRAY_LEN(ary); i++)
561
+ __rbosa_elementlist_add (&list, RARRAY_PTR(ary)[i], i + 1);
562
+ }
563
+
564
+ return rbosa_element_make (self, &list, Qnil);
565
+ }
566
+
567
+ static VALUE
568
+ rbosa_elementlist_add (VALUE self, VALUE element)
569
+ {
570
+ AEDescList * list;
571
+
572
+ list = (AEDescList *)rbosa_element_aedesc (self);
573
+ __rbosa_elementlist_add (list, __rbosa_elementlist_count (list) + 1, element);
574
+
575
+ return self;
576
+ }
577
+
578
+ static VALUE
579
+ __rbosa_elementlist_get (VALUE self, long index, AEKeyword *keyword)
580
+ {
581
+ OSErr error;
582
+ AEDesc desc;
583
+
584
+ error = AEGetNthDesc ((AEDescList *)rbosa_element_aedesc (self),
585
+ index + 1,
586
+ typeWildCard,
587
+ keyword,
588
+ &desc);
589
+
590
+ if (error != noErr)
591
+ rb_raise (rb_eRuntimeError, "Cannot get desc at index %d : %s (%d)",
592
+ index, error_code_to_string (error), error);
593
+
594
+ return rbosa_element_make (cOSAElement, &desc, rb_ivar_get (self, sApp));
595
+ }
596
+
597
+ static VALUE
598
+ rbosa_elementlist_get (VALUE self, VALUE index)
599
+ {
600
+ AEKeyword keyword;
601
+ return __rbosa_elementlist_get (self, FIX2INT (index), &keyword);
602
+ }
603
+
604
+ static VALUE
605
+ rbosa_elementlist_size (VALUE self)
606
+ {
607
+ return INT2FIX (__rbosa_elementlist_count ((AEDescList *)rbosa_element_aedesc (self)));
608
+ }
609
+
610
+ static int
611
+ __rbosa_elementrecord_set (VALUE key, VALUE value, AEDescList *list)
612
+ {
613
+ OSErr error;
614
+
615
+ error = AEPutKeyDesc (list, RVAL2FOURCHAR (key), rbosa_element_aedesc (value));
616
+ if (error != noErr)
617
+ rb_raise (rb_eRuntimeError, "Cannot set value %p for key %p of record %p: %s (%d)",
618
+ value, key, list, error_code_to_string (error), error);
619
+
620
+ return ST_CONTINUE;
621
+ }
622
+
623
+ static VALUE
624
+ rbosa_elementrecord_new (int argc, VALUE *argv, VALUE self)
625
+ {
626
+ OSErr error;
627
+ AEDescList list;
628
+ VALUE hash;
629
+
630
+ rb_scan_args (argc, argv, "01", &hash);
631
+
632
+ if (!NIL_P (hash))
633
+ Check_Type (hash, T_HASH);
634
+
635
+ error = AECreateList (NULL, 0, true, &list);
636
+ if (error != noErr)
637
+ rb_raise (rb_eRuntimeError, "Cannot create Apple Event descriptor list : %s (%d)",
638
+ error_code_to_string (error), error);
639
+
640
+ if (!NIL_P (hash))
641
+ rb_hash_foreach (hash, __rbosa_elementrecord_set, (VALUE)&list);
642
+
643
+ return rbosa_element_make (self, &list, Qnil);
644
+ }
645
+
646
+ static VALUE
647
+ rbosa_elementrecord_to_a (VALUE self)
648
+ {
649
+ long i, count;
650
+ VALUE ary;
651
+
652
+ count = FIX2INT (rbosa_elementlist_size (self));
653
+ ary = rb_ary_new ();
654
+ for (i = 0; i < count; i++) {
655
+ AEKeyword keyword;
656
+ char keyStr[5];
657
+ VALUE val;
658
+
659
+ val = __rbosa_elementlist_get (self, i, &keyword);
660
+ *(AEKeyword *)keyStr = CFSwapInt32HostToBig (keyword);
661
+ keyStr[4] = '\0';
662
+ rb_ary_push (ary, rb_ary_new3 (2, CSTR2RVAL (keyStr), val));
663
+ }
664
+
665
+ return ary;
666
+ }
667
+
668
+ #define rbosa_define_param(name,default_value) \
669
+ do { \
670
+ rb_define_attr (CLASS_OF (mOSA), name, 1, 1); \
671
+ if (default_value == Qtrue || default_value == Qfalse) \
672
+ rb_define_alias (CLASS_OF (mOSA), name"?", name); \
673
+ rb_iv_set (mOSA, "@"name, default_value); \
674
+ } \
675
+ while (0)
676
+
677
+ void
678
+ Init_osa (void)
679
+ {
680
+ sClasses = rb_intern ("@classes");
681
+ sApp = rb_intern ("@app");
682
+
683
+ mOSA = rb_define_module ("OSA");
684
+ rb_define_module_function (mOSA, "__scripting_info__", rbosa_scripting_info, 1);
685
+ rb_define_module_function (mOSA, "__remote_processes__", rbosa_remote_processes, 1);
686
+ rb_define_module_function (mOSA, "__four_char_code__", rbosa_four_char_code, 1);
687
+
688
+ cOSAElement = rb_define_class_under (mOSA, "Element", rb_cObject);
689
+ rb_define_singleton_method (cOSAElement, "__new__", rbosa_element_new, 2);
690
+ rb_define_singleton_method (cOSAElement, "__new_object_specifier__", rbosa_element_new_os, 4);
691
+ rb_define_singleton_method (cOSAElement, "__duplicate__", rbosa_element_dup, 1);
692
+ rb_define_method (cOSAElement, "__type__", rbosa_element_type, 0);
693
+ rb_define_method (cOSAElement, "__data__", rbosa_element_data, -1);
694
+ rb_define_method (cOSAElement, "before", rbosa_element_before, 0);
695
+ rb_define_method (cOSAElement, "after", rbosa_element_after, 0);
696
+ rb_define_method (cOSAElement, "==", rbosa_element_eql, 1);
697
+ rb_define_method (cOSAElement, "inspect", rbosa_element_inspect, 0);
698
+
699
+ cOSAElementList = rb_define_class_under (mOSA, "ElementList", cOSAElement);
700
+ rb_define_singleton_method (cOSAElementList, "__new__", rbosa_elementlist_new, -1);
701
+ rb_define_method (cOSAElementList, "[]", rbosa_elementlist_get, 1);
702
+ rb_define_method (cOSAElementList, "size", rbosa_elementlist_size, 0);
703
+ rb_define_alias (cOSAElementList, "length", "size");
704
+ rb_define_method (cOSAElementList, "add", rbosa_elementlist_add, 1);
705
+
706
+ cOSAElementRecord = rb_define_class_under (mOSA, "ElementRecord", cOSAElement);
707
+ rb_define_singleton_method (cOSAElementRecord, "__new__", rbosa_elementrecord_new, -1);
708
+ rb_define_method (cOSAElementRecord, "to_a", rbosa_elementrecord_to_a, 0);
709
+
710
+ mOSAEventDispatcher = rb_define_module_under (mOSA, "EventDispatcher");
711
+ rb_define_method (mOSAEventDispatcher, "__send_event__", rbosa_app_send_event, 4);
712
+
713
+ rbosa_define_param ("timeout", INT2NUM (kAEDefaultTimeout));
714
+ rbosa_define_param ("lazy_events", Qtrue);
715
+ rbosa_define_param ("utf8_strings", Qfalse);
716
+ rbosa_define_param ("wait_reply", Qnil);
717
+ }