1 /*
2 * Copyright (c) 2004-2015 Derelict Developers
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the names 'Derelict', 'DerelictSDL', nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /**
33     Dynamic bindings to the Cocoa framework.
34 */
35 module derelict.cocoa.cocoa;
36 
37 import dplug.core.sharedlib;
38 import dplug.core.nogc;
39 
40 import derelict.cocoa.runtime;
41 import derelict.cocoa.foundation;
42 import derelict.cocoa.appkit;
43 import derelict.cocoa.coreimage;
44 
45 
46 version(OSX)
47     enum libNames = "/System/Library/Frameworks/Cocoa.framework/Cocoa";
48 else
49     enum libNames = "";
50 
51 
52 class DerelictCocoaLoader : SharedLibLoader
53 {
54     public
55     {
56         this() nothrow @nogc
57         {
58             super(libNames);
59         }
60 
61         override void loadSymbols() nothrow @nogc
62         {
63             // Runtime
64             bindFunc(cast(void**)&objc_registerClassPair, "objc_registerClassPair");
65             bindFunc(cast(void**)&varclass_addIvar, "class_addIvar");
66             bindFunc(cast(void**)&varclass_addMethod, "class_addMethod");
67             bindFunc(cast(void**)&varobjc_allocateClassPair, "objc_allocateClassPair");
68             bindFunc(cast(void**)&objc_disposeClassPair, "objc_disposeClassPair");
69             bindFunc(cast(void**)&varobjc_getClass, "objc_getClass");
70             bindFunc(cast(void**)&varobjc_lookUpClass, "objc_lookUpClass");
71 
72             bindFunc(cast(void**)&objc_msgSend, "objc_msgSend");
73             bindFunc(cast(void**)&objc_msgSendSuper, "objc_msgSendSuper");
74             bindFunc(cast(void**)&objc_msgSend_stret, "objc_msgSend_stret");
75             version(X86) bindFunc(cast(void**)&objc_msgSend_fpret, "objc_msgSend_fpret");
76 
77             bindFunc(cast(void**)&varobject_getClassName, "object_getClassName");
78             bindFunc(cast(void**)&object_getInstanceVariable, "object_getInstanceVariable");
79             bindFunc(cast(void**)&object_setInstanceVariable, "object_setInstanceVariable");
80             bindFunc(cast(void**)&varsel_registerName, "sel_registerName");
81 
82             bindFunc(cast(void**)&varclass_getInstanceMethod, "class_getInstanceMethod");
83             bindFunc(cast(void**)&method_setImplementation, "method_setImplementation");
84 
85             bindFunc(cast(void**)&class_addProtocol, "class_addProtocol");
86             bindFunc(cast(void**)&objc_getProtocol, "objc_getProtocol");
87             bindFunc(cast(void**)&objc_allocateProtocol, "objc_allocateProtocol"); // min 10.7
88             bindFunc(cast(void**)&objc_registerProtocol, "objc_registerProtocol"); // min 10.7
89             bindFunc(cast(void**)&class_conformsToProtocol, "class_conformsToProtocol"); // min 10.5
90             bindFunc(cast(void**)&protocol_addMethodDescription, "protocol_addMethodDescription"); // min 10.7
91 
92             // Foundation
93             bindFunc(cast(void**)&NSLog, "NSLog");
94             bindFunc(cast(void**)&NSAllocateMemoryPages, "NSAllocateMemoryPages");
95             bindFunc(cast(void**)&NSDeallocateMemoryPages, "NSDeallocateMemoryPages");
96 
97             // MAYDO: load from proper global variables
98             NSRunLoopCommonModes = NSString.stringWith("kCFRunLoopCommonModes"w);
99 
100             // For debugging purpose
101             //NSLog(NSString.stringWith("%@\n")._id, NSDefaultRunLoopMode._id);
102             //NSLog(NSString.stringWith("%@\n")._id, NSRunLoopCommonModes._id);
103 
104             // Appkit
105             bindFunc(cast(void**)&NSApplicationLoad, "NSApplicationLoad");
106 
107             // Core Image
108             // MAYDO load from proper global variables
109             kCIFormatARGB8 = 23;
110             kCIFormatRGBA16 = 27;
111             kCIFormatRGBAf = 34;
112             kCIFormatRGBAh = 31;
113         }
114     }
115 }
116 
117 
118 private __gshared DerelictCocoaLoader DerelictCocoa;
119 
120 private __gshared loaderCounterCocoa = 0;
121 
122 // Call this each time a new owner uses Cocoa functions
123 // TODO: hold a mutex, because this isn't thread-safe
124 // Corrolary: how to protect that mutex creation?
125 void acquireCocoaFunctions() nothrow @nogc
126 {
127     if (DerelictCocoa is null)  // You only live once
128     {
129         DerelictCocoa = mallocNew!DerelictCocoaLoader();
130         DerelictCocoa.load();
131     }
132 }
133 
134 // Call this each time a new owner releases a Cocoa functions
135 // TODO: hold a mutex, because this isn't thread-safe
136 // Corrolary: how to protect that mutex creation?
137 void releaseCocoaFunctions() nothrow @nogc
138 {
139     /*if (--loaderCounterCocoa == 0)
140     {
141         DerelictCocoa.unload();
142         DerelictCocoa.destroyFree();
143     }*/
144 }
145 
146 unittest
147 {
148     version(OSX)
149     {
150         acquireCocoaFunctions();
151         releaseCocoaFunctions();
152     }
153 }