1 /*
2 
3 Boost Software License - Version 1.0 - August 17th, 2003
4 
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 
27 */
28 module derelict.sdl.macinit.runtime;
29 
30 version(DigitalMars) version(OSX) version = darwin;
31 
32 version (darwin):
33 
34 import derelict.sdl.macinit.string;
35 import derelict.util.compat;
36 
37 import derelict.sdl.macinit.NSGeometry;
38 import derelict.util.loader;
39 import derelict.util.exception;
40 
41 package:
42 
43 alias objc_ivar* Ivar;
44 alias objc_method* Method;
45 alias objc_object Protocol;
46 
47 alias objc_selector* SEL;
48 alias objc_class* Class;
49 alias objc_object* id;
50 
51 alias extern (C) id function(id, SEL, ...) IMP;
52 
53 struct objc_selector
54 {
55 	void* sel_id;
56 	char* sel_types;
57 }
58 
59 struct objc_object
60 {
61     Class isa;
62 }
63 
64 struct objc_super
65 {
66     id receiver;
67     Class clazz;
68 }
69 
70 struct objc_class
71 {
72     Class isa;
73     Class super_class;
74     CCPTR name;
75     int versionn;
76     int info;
77     int instance_size;
78     objc_ivar_list* ivars;
79     objc_method_list** methodLists;
80     objc_cache* cache;
81     objc_protocol_list* protocols;
82 }
83 
84 struct objc_ivar
85 {
86     CCPTR ivar_name;
87     CCPTR ivar_type;
88     int ivar_offset;
89 
90     version (X86_64)
91         int space;
92 }
93 
94 struct objc_ivar_list
95 {
96     int ivar_count;
97 
98     version (X86_64)
99         int space;
100 
101     /* variable length structure */
102     objc_ivar ivar_list[1];
103 }
104 
105 struct objc_method
106 {
107     SEL method_name;
108     CCPTR method_types;
109     IMP method_imp;
110 }
111 
112 struct objc_method_list
113 {
114     objc_method_list* obsolete;
115 
116     int method_count;
117 
118     version (X86_64)
119         int space;
120 
121     /* variable length structure */
122     objc_method method_list[1];
123 }
124 
125 struct objc_cache
126 {
127     uint mask /* total = mask + 1 */;
128     uint occupied;
129     Method buckets[1];
130 }
131 
132 struct objc_protocol_list
133 {
134     objc_protocol_list* next;
135     long count;
136     Protocol* list[1];
137 }
138 
139 // Objective-C runtime bindings from the Cocoa framework
140 extern (C)
141 {
142     mixin(gsharedString!() ~ "
143     Class function (Class superclass, CCPTR name, size_t extraBytes) c_objc_allocateClassPair;
144     Class function (Class superclass) objc_registerClassPair;
145     id function (CCPTR name) c_objc_getClass;
146     id function (id theReceiver, SEL theSelector, ...) c_objc_msgSend;
147     SEL function (CCPTR str) c_sel_registerName;
148 
149     bool function () NSApplicationLoad;
150 
151     void function (Class myClass) objc_addClass;
152     void function (Class arg0, objc_method_list* arg1) class_addMethods;
153     bool function (Class c13ls, SEL name, IMP imp, CCPTR types) class_addMethod;");
154 }
155 
156 void load (void delegate(void**, string, bool doThrow = true) bindFunc)
157 {
158     bindFunc(cast(void**)&c_objc_getClass, "objc_getClass");
159     bindFunc(cast(void**)&c_objc_msgSend, "objc_msgSend");
160     bindFunc(cast(void**)&c_sel_registerName, "sel_registerName");
161     
162     bindFunc(cast(void**)&NSApplicationLoad, "NSApplicationLoad");
163     
164     try
165     {
166         /* 
167          * These methods are expected to not be found in > Leopard, they have
168          * been deprecated in favor of objc_{allocate|register}ClassPair and
169          * class_addMethod.
170          */
171         bindFunc(cast(void**)&objc_addClass, "objc_addClass");
172         bindFunc(cast(void**)&class_addMethods, "class_addMethods");
173     }
174     
175     catch (Exception e)
176     {
177         bindFunc(cast(void**)&class_addMethod, "class_addMethod");
178         bindFunc(cast(void**)&c_objc_allocateClassPair, "objc_allocateClassPair");
179         bindFunc(cast(void**)&objc_registerClassPair, "objc_registerClassPair");
180     }    
181 }
182 
183 Class objc_allocateClassPair (string name) (Class superclass, size_t extraBytes)
184 {
185     return c_objc_allocateClassPair(superclass, name.ptr, extraBytes);
186 }
187 
188 id objc_getClass (string name) ()
189 {
190     return c_objc_getClass(name.ptr);
191 }
192 
193 SEL sel_registerName (string str) ()
194 {
195     return c_sel_registerName(str.ptr);
196 }
197 
198 id objc_msgSend (ARGS...)(id theReceiver, SEL theSelector, ARGS args)
199 {
200     // the dmd import generator can't handle this
201     //alias extern (C) id function (id, SEL, ARGS) fp;
202 	//return (cast(fp)&c_objc_msgSend)(theReceiver, theSelector, args);
203 	 
204 	return c_objc_msgSend(theReceiver, theSelector, args);
205 }