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