1 /*
2 * Copyright (c) 2015 Guillaume Piolat
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 CoreServices framework.
34 */
35 module derelict.carbon.coreservices;
36 
37 import core.stdc.config;
38 
39 import dplug.core.sharedlib;
40 
41 import derelict.carbon.corefoundation;
42 
43 import dplug.core.nogc;
44 
45 version(OSX)
46     enum libNames = "/System/Library/Frameworks/CoreServices.framework/CoreServices";
47 else
48     enum libNames = "";
49 
50 
51 class DerelictCoreServicesLoader : SharedLibLoader
52 {
53     public
54     {
55         nothrow @nogc:
56         this()
57         {
58             super(libNames);
59         }
60 
61         override void loadSymbols()
62         {
63             bindFunc(cast(void**)&SetComponentInstanceStorage, "SetComponentInstanceStorage");
64             bindFunc(cast(void**)&GetComponentInstanceStorage, "GetComponentInstanceStorage");
65             bindFunc(cast(void**)&GetComponentInfo, "GetComponentInfo");
66         }
67     }
68 }
69 
70 private __gshared DerelictCoreServicesLoader DerelictCoreServices;
71 
72 private __gshared loaderCounterCS = 0;
73 
74 // Call this each time a novel owner uses these functions
75 // TODO: hold a mutex, because this isn't thread-safe
76 void acquireCoreServicesFunctions() nothrow @nogc
77 {
78     if (DerelictCoreServices is null)  // You only live once
79     {
80         DerelictCoreServices = mallocNew!DerelictCoreServicesLoader();
81         DerelictCoreServices.load();
82     }
83 }
84 
85 // Call this each time a novel owner releases a Cocoa functions
86 // TODO: hold a mutex, because this isn't thread-safe
87 void releaseCoreServicesFunctions() nothrow @nogc
88 {
89     /*if (--loaderCounterCS == 0)
90     {
91         DerelictCoreServices.unload();
92         DerelictCoreServices.destroyFree();
93     }*/
94 }
95 
96 unittest
97 {
98     version(OSX)
99     {
100         acquireCoreServicesFunctions();
101         releaseCoreServicesFunctions();
102     }
103 }
104 
105 enum : int
106 {
107     typeSInt16                 = CCONST('s', 'h', 'o', 'r'),
108     typeUInt16                 = CCONST('u', 's', 'h', 'r'),
109     typeSInt32                 = CCONST('l', 'o', 'n', 'g'),
110     typeUInt32                 = CCONST('m', 'a', 'g', 'n'),
111     typeSInt64                 = CCONST('c', 'o', 'm', 'p'),
112     typeUInt64                 = CCONST('u', 'c', 'o', 'm'),
113     typeIEEE32BitFloatingPoint = CCONST('s', 'i', 'n', 'g'),
114     typeIEEE64BitFloatingPoint = CCONST('d', 'o', 'u', 'b'),
115     type128BitFloatingPoint    = CCONST('l', 'd', 'b', 'l'),
116     typeDecimalStruct          = CCONST('d', 'e', 'c', 'm'),
117     typeChar                   = CCONST('T', 'E', 'X', 'T'),
118 }
119 
120 // <CarbonCore/MacErrors.h>
121 enum : int
122 {
123     badComponentInstance = cast(int)0x80008001,
124     badComponentSelector = cast(int)0x80008002
125 }
126 
127 enum
128 {
129     coreFoundationUnknownErr      = -4960,
130 }
131 
132 
133 // <CarbonCore/Components.h>
134 
135 // LP64 => "long and pointers are 64-bit"
136 static if (size_t.sizeof == 8 && c_long.sizeof == 8)
137     private enum __LP64__ = 1;
138 else
139     private enum __LP64__ = 0;
140 
141 alias Component = void*;
142 alias ComponentResult = int;
143 
144 alias ComponentInstance = void*;
145 
146 struct ComponentParameters
147 {
148     UInt8               flags;
149     UInt8               paramSize;
150     SInt16              what;
151     static if (__LP64__)
152         UInt32          padding;
153     c_long[1]           params;
154 }
155 
156 static if (__LP64__)
157 {
158     static assert(ComponentParameters.sizeof == 16);
159 }
160 
161 enum : int
162 {
163     kComponentOpenSelect          = -1,
164     kComponentCloseSelect         = -2,
165     kComponentCanDoSelect         = -3,
166     kComponentVersionSelect       = -4,
167     kComponentRegisterSelect      = -5,
168     kComponentTargetSelect        = -6,
169     kComponentUnregisterSelect    = -7,
170     kComponentGetMPWorkFunctionSelect = -8,
171     kComponentExecuteWiredActionSelect = -9,
172     kComponentGetPublicResourceSelect = -10
173 };
174 
175 struct ComponentDescription
176 {
177     OSType              componentType;
178     OSType              componentSubType;
179     OSType              componentManufacturer;
180     UInt32              componentFlags;
181     UInt32              componentFlagsMask;
182 }
183 
184 extern(C) nothrow @nogc
185 {
186     alias da_SetComponentInstanceStorage = void function(ComponentInstance, Handle);
187     alias da_GetComponentInfo = OSErr function(Component, ComponentDescription*, Handle, Handle, Handle);
188     alias da_GetComponentInstanceStorage = Handle function(ComponentInstance aComponentInstance);
189 }
190 
191 __gshared
192 {
193     da_SetComponentInstanceStorage SetComponentInstanceStorage;
194     da_GetComponentInfo GetComponentInfo;
195     da_GetComponentInstanceStorage GetComponentInstanceStorage;
196 }
197 
198