1 /**
2 Dynamic bindings to the Cocoa framework.
3
4 Copyright: Guillaume Piolat 2016.
5 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
6 */
7 module derelict.cocoa.cocoa;
8
9 import dplug.core.sharedlib;
10 import dplug.core.nogc;
11
12 import derelict.cocoa.runtime;
13 import derelict.cocoa.foundation;
14 import derelict.cocoa.appkit;
15 import derelict.cocoa.coreimage;
16
17
18 version(OSX)
19 enum libNames = "/System/Library/Frameworks/Cocoa.framework/Cocoa";
20 else
21 enum libNames = "";
22
23 version(X86)
24 version = AnyX86;
25 version(X86_64)
26 version = AnyX86;
27
28 class DerelictCocoaLoader : SharedLibLoader
29 {
30 public
31 {
32 this() nothrow @nogc
33 {
34 super(libNames);
35 }
36
37 override void loadSymbols() nothrow @nogc
38 {
39 // Runtime
40 bindFunc(cast(void**)&objc_registerClassPair, "objc_registerClassPair");
41 bindFunc(cast(void**)&varclass_addIvar, "class_addIvar");
42 bindFunc(cast(void**)&varclass_addMethod, "class_addMethod");
43 bindFunc(cast(void**)&varobjc_allocateClassPair, "objc_allocateClassPair");
44 bindFunc(cast(void**)&objc_disposeClassPair, "objc_disposeClassPair");
45 bindFunc(cast(void**)&varobjc_getClass, "objc_getClass");
46 bindFunc(cast(void**)&varobjc_lookUpClass, "objc_lookUpClass");
47
48 bindFunc(cast(void**)&objc_msgSend, "objc_msgSend");
49 bindFunc(cast(void**)&objc_msgSendSuper, "objc_msgSendSuper");
50 version(AnyX86) bindFunc(cast(void**)&objc_msgSend_stret, "objc_msgSend_stret");
51 version(X86) bindFunc(cast(void**)&objc_msgSend_fpret, "objc_msgSend_fpret");
52
53 bindFunc(cast(void**)&varobject_getClassName, "object_getClassName");
54 bindFunc(cast(void**)&object_getInstanceVariable, "object_getInstanceVariable");
55 bindFunc(cast(void**)&object_setInstanceVariable, "object_setInstanceVariable");
56 bindFunc(cast(void**)&varsel_registerName, "sel_registerName");
57
58 bindFunc(cast(void**)&varclass_getInstanceMethod, "class_getInstanceMethod");
59 bindFunc(cast(void**)&method_setImplementation, "method_setImplementation");
60
61 bindFunc(cast(void**)&class_addProtocol, "class_addProtocol");
62 bindFunc(cast(void**)&objc_getProtocol, "objc_getProtocol");
63 bindFunc(cast(void**)&objc_allocateProtocol, "objc_allocateProtocol"); // min 10.7
64 bindFunc(cast(void**)&objc_registerProtocol, "objc_registerProtocol"); // min 10.7
65 bindFunc(cast(void**)&class_conformsToProtocol, "class_conformsToProtocol"); // min 10.5
66 bindFunc(cast(void**)&protocol_addMethodDescription, "protocol_addMethodDescription"); // min 10.7
67
68 // Foundation
69 bindFunc(cast(void**)&NSLog, "NSLog");
70 bindFunc(cast(void**)&NSAllocateMemoryPages, "NSAllocateMemoryPages");
71 bindFunc(cast(void**)&NSDeallocateMemoryPages, "NSDeallocateMemoryPages");
72
73 // MAYDO: load from proper global variables
74 NSRunLoopCommonModes = NSString.stringWith("kCFRunLoopCommonModes"w);
75
76 kCAContentsFormatRGBA8Uint = NSString.stringWith("RGBA8"w); // value from Big Sur
77
78 // For debugging purpose
79 //NSLog(NSString.stringWith("%@\n")._id, NSDefaultRunLoopMode._id);
80 //NSLog(NSString.stringWith("%@\n")._id, NSRunLoopCommonModes._id);
81
82 // Appkit
83 bindFunc(cast(void**)&NSApplicationLoad, "NSApplicationLoad");
84
85 // Core Image
86 // MAYDO load from proper global variables
87 kCIFormatARGB8 = 23;
88 kCIFormatRGBA16 = 27;
89 kCIFormatRGBAf = 34;
90 kCIFormatRGBAh = 31;
91 }
92 }
93 }
94
95
96 private __gshared DerelictCocoaLoader DerelictCocoa;
97
98 private __gshared loaderCounterCocoa = 0;
99
100 // Call this each time a new owner uses Cocoa functions
101 // TODO: hold a mutex, because this isn't thread-safe
102 // Corrolary: how to protect that mutex creation?
103 void acquireCocoaFunctions() nothrow @nogc
104 {
105 if (DerelictCocoa is null) // You only live once
106 {
107 DerelictCocoa = mallocNew!DerelictCocoaLoader();
108 DerelictCocoa.load();
109 }
110 }
111
112 // Call this each time a new owner releases a Cocoa functions
113 // TODO: hold a mutex, because this isn't thread-safe
114 // Corrolary: how to protect that mutex creation?
115 void releaseCocoaFunctions() nothrow @nogc
116 {
117 /*if (--loaderCounterCocoa == 0)
118 {
119 DerelictCocoa.unload();
120 DerelictCocoa.destroyFree();
121 }*/
122 }
123
124 unittest
125 {
126 version(OSX)
127 {
128 acquireCocoaFunctions();
129 releaseCocoaFunctions();
130 }
131 }