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 module derelict.cocoa.cocoa;
33 
34 import dplug.core.sharedlib;
35 import dplug.core.nogc;
36 
37 import derelict.cocoa.runtime;
38 import derelict.cocoa.foundation;
39 import derelict.cocoa.appkit;
40 import derelict.cocoa.coreimage;
41 
42 
43 version(OSX)
44     enum libNames = "/System/Library/Frameworks/Cocoa.framework/Cocoa";
45 else
46     enum libNames = "";
47 
48 
49 class DerelictCocoaLoader : SharedLibLoader
50 {
51     public
52     {
53         this() nothrow @nogc
54         {
55             super(libNames);
56         }
57 
58         override void loadSymbols() nothrow @nogc
59         {
60             // Runtime
61             bindFunc(cast(void**)&objc_registerClassPair, "objc_registerClassPair");
62             bindFunc(cast(void**)&varclass_addIvar, "class_addIvar");
63             bindFunc(cast(void**)&varclass_addMethod, "class_addMethod");
64             bindFunc(cast(void**)&varobjc_allocateClassPair, "objc_allocateClassPair");
65             bindFunc(cast(void**)&objc_disposeClassPair, "objc_disposeClassPair");
66             bindFunc(cast(void**)&varobjc_getClass, "objc_getClass");
67             bindFunc(cast(void**)&varobjc_lookUpClass, "objc_lookUpClass");
68 
69             bindFunc(cast(void**)&objc_msgSend, "objc_msgSend");
70             bindFunc(cast(void**)&objc_msgSendSuper, "objc_msgSendSuper");
71             bindFunc(cast(void**)&objc_msgSend_stret, "objc_msgSend_stret");
72             version(X86) bindFunc(cast(void**)&objc_msgSend_fpret, "objc_msgSend_fpret");
73 
74             bindFunc(cast(void**)&varobject_getClassName, "object_getClassName");
75             bindFunc(cast(void**)&object_getInstanceVariable, "object_getInstanceVariable");
76             bindFunc(cast(void**)&object_setInstanceVariable, "object_setInstanceVariable");
77             bindFunc(cast(void**)&varsel_registerName, "sel_registerName");
78 
79             bindFunc(cast(void**)&varclass_getInstanceMethod, "class_getInstanceMethod");
80             bindFunc(cast(void**)&method_setImplementation, "method_setImplementation");
81 
82             bindFunc(cast(void**)&class_addProtocol, "class_addProtocol");
83             bindFunc(cast(void**)&objc_getProtocol, "objc_getProtocol");
84             bindFunc(cast(void**)&objc_allocateProtocol, "objc_allocateProtocol"); // min 10.7
85             bindFunc(cast(void**)&objc_registerProtocol, "objc_registerProtocol"); // min 10.7
86             bindFunc(cast(void**)&class_conformsToProtocol, "class_conformsToProtocol"); // min 10.5
87             bindFunc(cast(void**)&protocol_addMethodDescription, "protocol_addMethodDescription"); // min 10.7
88 
89             // Foundation
90             bindFunc(cast(void**)&NSLog, "NSLog");
91             bindFunc(cast(void**)&NSAllocateMemoryPages, "NSAllocateMemoryPages");
92             bindFunc(cast(void**)&NSDeallocateMemoryPages, "NSDeallocateMemoryPages");
93 
94             // MAYDO: load from proper global variables
95             NSRunLoopCommonModes = NSString.stringWith("kCFRunLoopCommonModes"w);
96 
97             // For debugging purpose
98             //NSLog(NSString.stringWith("%@\n")._id, NSDefaultRunLoopMode._id);
99             //NSLog(NSString.stringWith("%@\n")._id, NSRunLoopCommonModes._id);
100 
101             // Appkit
102             bindFunc(cast(void**)&NSApplicationLoad, "NSApplicationLoad");
103 
104             // Core Image
105             // MAYDO load from proper global variables
106             kCIFormatARGB8 = 23;
107             kCIFormatRGBA16 = 27;
108             kCIFormatRGBAf = 34;
109             kCIFormatRGBAh = 31;
110         }
111     }
112 }
113 
114 
115 private __gshared DerelictCocoaLoader DerelictCocoa;
116 
117 private __gshared loaderCounterCocoa = 0;
118 
119 // Call this each time a new owner uses Cocoa functions
120 // TODO: hold a mutex, because this isn't thread-safe
121 // Corrolary: how to protect that mutex creation?
122 void acquireCocoaFunctions() nothrow @nogc
123 {
124     if (DerelictCocoa is null)  // You only live once
125     {
126         DerelictCocoa = mallocEmplace!DerelictCocoaLoader();
127         DerelictCocoa.load();
128     }
129 }
130 
131 // Call this each time a new owner releases a Cocoa functions
132 // TODO: hold a mutex, because this isn't thread-safe
133 // Corrolary: how to protect that mutex creation?
134 void releaseCocoaFunctions() nothrow @nogc
135 {
136     /*if (--loaderCounterCocoa == 0)
137     {
138         DerelictCocoa.unload();
139         DerelictCocoa.destroyFree();
140     }*/
141 }
142 
143 unittest
144 {
145     version(OSX)
146     {
147         acquireCocoaFunctions();
148         releaseCocoaFunctions();
149     }
150 }