1 /**
2 Dynamic bindings to the CoreFoundation framework.
3 
4 Copyright: Guillaume Piolat 2015.
5 License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
6 */
7 module derelict.carbon.corefoundation;
8 
9 import core.stdc.config;
10 
11 import dplug.core.sharedlib;
12 import dplug.core.nogc;
13 
14 version(OSX)
15     enum libNames = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation";
16 else
17     enum libNames = "";
18 
19 
20 class DerelictCoreFoundationLoader : SharedLibLoader
21 {
22     public
23     {
24         nothrow @nogc:
25         this()
26         {
27             super(libNames);
28         }
29 
30         override void loadSymbols()
31         {
32             bindFunc(cast(void**)&CFRetain, "CFRetain");
33             bindFunc(cast(void**)&CFRelease, "CFRelease");
34             bindFunc(cast(void**)&CFEqual, "CFEqual");
35             bindFunc(cast(void**)&CFHash, "CFHash");
36             bindFunc(cast(void**)&CFCopyDescription, "CFCopyDescription");
37 
38             bindFunc(cast(void**)&CFArrayCreate, "CFArrayCreate");
39             bindFunc(cast(void**)&CFArrayCreateMutable, "CFArrayCreateMutable");
40             bindFunc(cast(void**)&CFArrayAppendValue, "CFArrayAppendValue");
41 
42             bindFunc(cast(void**)&CFAllocatorAllocate, "CFAllocatorAllocate");
43             bindFunc(cast(void**)&CFAllocatorDeallocate, "CFAllocatorDeallocate");
44 
45             bindFunc(cast(void**)&CFBundleGetMainBundle, "CFBundleGetMainBundle");
46             bindFunc(cast(void**)&CFBundleGetBundleWithIdentifier, "CFBundleGetBundleWithIdentifier");
47             bindFunc(cast(void**)&CFBundleCopyBundleURL, "CFBundleCopyBundleURL");
48             bindFunc(cast(void**)&CFBundleCopyResourcesDirectoryURL, "CFBundleCopyResourcesDirectoryURL");
49 
50             bindFunc(cast(void**)&CFURLGetFileSystemRepresentation, "CFURLGetFileSystemRepresentation");
51 
52             bindFunc(cast(void**)&CFStringCreateWithCString, "CFStringCreateWithCString");
53             bindFunc(cast(void**)&CFStringGetLength, "CFStringGetLength");
54             bindFunc(cast(void**)&CFStringGetCString, "CFStringGetCString");
55             bindFunc(cast(void**)&CFStringCreateCopy, "CFStringCreateCopy");
56             bindFunc(cast(void**)&CFStringCompare, "CFStringCompare");
57             bindFunc(cast(void**)&CFStringCreateWithFormat, "CFStringCreateWithFormat");
58 
59             bindFunc(cast(void**)&CFDataCreate, "CFDataCreate");
60             bindFunc(cast(void**)&CFDataGetLength, "CFDataGetLength");
61             bindFunc(cast(void**)&CFDataGetBytePtr, "CFDataGetBytePtr");
62 
63             bindFunc(cast(void**)&CFDictionaryCreateMutable, "CFDictionaryCreateMutable");
64             bindFunc(cast(void**)&CFDictionaryGetValue, "CFDictionaryGetValue");
65             bindFunc(cast(void**)&CFDictionarySetValue, "CFDictionarySetValue");
66 
67             bindFunc(cast(void**)&CFNumberCreate, "CFNumberCreate");
68             bindFunc(cast(void**)&CFNumberGetValue, "CFNumberGetValue");
69 
70             with (kCFTypeArrayCallBacks)
71             {
72                 version_ = 0;
73                 retain = &myRetainCallBack;
74                 release = &myReleaseCallBack;
75                 copyDescription = CFCopyDescription;
76                 equal = CFEqual;
77             }
78 
79             with (kCFTypeDictionaryKeyCallBacks)
80             {
81                 version_ = 0;
82                 retain = &myRetainCallBack;
83                 release = &myReleaseCallBack;
84                 copyDescription = CFCopyDescription;
85                 equal = CFEqual;
86                 hash = CFHash;
87             }
88 
89             with (kCFTypeDictionaryValueCallBacks)
90             {
91                 version_ = 0;
92                 retain = &myRetainCallBack;
93                 release = &myReleaseCallBack;
94                 copyDescription = CFCopyDescription;
95                 equal = CFEqual;
96             }
97         }
98     }
99 }
100 
101 private __gshared DerelictCoreFoundationLoader DerelictCoreFoundation;
102 
103 private __gshared loaderCounterCF = 0;
104 
105 // Call this each time a novel owner uses these functions
106 // TODO: hold a mutex, because this isn't thread-safe
107 void acquireCoreFoundationFunctions() nothrow @nogc
108 {
109     if (DerelictCoreFoundation is null)  // You only live once
110     {
111         DerelictCoreFoundation = mallocNew!DerelictCoreFoundationLoader();
112         DerelictCoreFoundation.load();
113     }
114 }
115 
116 // Call this each time a novel owner releases a Cocoa functions
117 // TODO: hold a mutex, because this isn't thread-safe
118 void releaseCoreFoundationFunctions() nothrow @nogc
119 {
120     /*if (--loaderCounterCF == 0)
121     {
122         DerelictCoreFoundation.unload();
123         DerelictCoreFoundation.destroyFree();
124     }*/
125 }
126 
127 unittest
128 {
129     version(OSX)
130     {
131         acquireCoreFoundationFunctions();
132         releaseCoreFoundationFunctions();
133     }
134 }
135 
136 // To support character constants
137 package int CCONST(int a, int b, int c, int d) pure nothrow
138 {
139     return (a << 24) | (b << 16) | (c << 8) | (d << 0);
140 }
141 
142 
143 // <MacTypes.h>
144 
145 alias UInt8 = ubyte;
146 alias SInt8 = byte;
147 alias UInt16 = ushort;
148 alias SInt16 = short;
149 alias UInt32 = uint;
150 alias SInt32 = int;
151 alias UInt64 = ulong;
152 alias SInt64 = long;
153 
154 
155   // binary layout should be what is expected on this platform
156 version (LittleEndian)
157 {
158     struct wide
159     {
160         UInt32              lo;
161         SInt32              hi;
162     }
163 
164     struct UnsignedWide
165     {
166         UInt32              lo;
167         UInt32              hi;
168     }
169 }
170 else
171 {
172     struct wide
173     {
174         SInt32              hi;
175         UInt32              lo;
176     }
177 
178     struct UnsignedWide
179     {
180         UInt32              hi;
181         UInt32              lo;
182     }
183 }
184 
185 
186 alias Fixed = SInt32;
187 alias FixedPtr = Fixed*;
188 alias Fract = SInt32;
189 alias FractPtr = Fract*;
190 alias UnsignedFixed = UInt32;
191 alias UnsignedFixedPtr = UnsignedFixed*;
192 alias ShortFixed = short;
193 alias ShortFixedPtr = ShortFixed*;
194 
195 alias Float32 = float;
196 alias Float64 = double;
197 
198 struct Float32Point
199 {
200     Float32 x;
201     Float32 y;
202 }
203 
204 alias Ptr = char*;
205 alias Handle = Ptr*;
206 alias Size = long;
207 
208 
209 alias OSErr = SInt16;
210 alias OSStatus = SInt32;
211 alias LogicalAddress = void*;
212 alias ConstLogicalAddress = const(void)*;
213 alias PhysicalAddress = void*;
214 alias BytePtr = UInt8*;
215 alias ByteCount = c_ulong;
216 alias ByteOffset = c_ulong;
217 alias Duration = SInt32;
218 alias AbsoluteTime = UnsignedWide;
219 alias OptionBits = UInt32;
220 alias ItemCount = c_ulong;
221 alias PBVersion = UInt32;
222 alias ScriptCode = SInt16;
223 alias LangCode = SInt16;
224 alias RegionCode = SInt16;
225 alias FourCharCode = UInt32;
226 alias OSType = FourCharCode;
227 alias ResType = FourCharCode;
228 alias OSTypePtr = OSType*;
229 alias ResTypePtr = ResType*;
230 
231 enum
232 {
233     noErr                         = 0,
234     kNilOptions                   = 0,
235     kInvalidID                    = 0,
236     kVariableLengthArray          = 1,
237     kUnknownType                  = 0x3F3F3F3F
238 }
239 
240 alias UnicodeScalarValue = UInt32;
241 alias UTF32Char = UInt32;
242 alias UniChar = UInt16;
243 alias UTF16Char = UInt16;
244 alias UTF8Char = UInt8;
245 alias UniCharPtr = UniChar*;
246 alias UniCharCount = c_ulong;
247 alias UniCharCountPtr = UniCharCount*;
248 alias Str255 = char[256];
249 alias Str63 = char[64];
250 alias Str32 = char[33];
251 alias Str31 = char[32];
252 alias Str27 = char[28];
253 alias Str15 = char[16];
254 
255 
256 // <CoreFoundation/CFBase.h>
257 
258 
259 alias Boolean = ubyte;
260 
261 alias StringPtr = char*;
262 alias ConstStringPtr = const(char)*;
263 alias ConstStr255Param = const(char)*;
264 alias Byte = UInt8;
265 alias SignedByte = SInt8;
266 
267 
268 alias CFTypeID = c_ulong;
269 alias CFOptionFlags = c_ulong;
270 alias CFHashCode = c_ulong;
271 alias CFIndex = c_long;
272 
273 alias CFTypeRef = const(void)*;
274 
275 alias CFStringRef = void*;
276 alias CFMutableStringRef = void*;
277 alias CFAllocatorRef = void*;
278 
279 enum CFAllocatorRef kCFAllocatorDefault = null;
280 
281 alias CFPropertyListRef = CFTypeRef;
282 
283 
284 struct CFRange
285 {
286     CFIndex location;
287     CFIndex length;
288 }
289 
290 CFRange CFRangeMake(CFIndex loc, CFIndex len)
291 {
292     return CFRange(loc, len);
293 }
294 
295 alias CFComparisonResult = CFIndex;
296 enum : CFComparisonResult
297 {
298     kCFCompareLessThan = -1,
299     kCFCompareEqualTo = 0,
300     kCFCompareGreaterThan = 1
301 }
302 
303 alias CFNullRef = const(void)*;
304 
305 struct Point
306 {
307     short               v;
308     short               h;
309 }
310 alias PointPtr = Point*;
311 
312 struct Rect
313 {
314   short               top;
315   short               left;
316   short               bottom;
317   short               right;
318 }
319 alias RectPtr = Rect*;
320 
321 extern(C) nothrow @nogc
322 {
323     alias da_CFRetain = CFTypeRef function(CFTypeRef cf);
324     alias da_CFRelease = void function(CFTypeRef cf);
325     alias da_CFEqual = Boolean function(CFTypeRef cf1, CFTypeRef cf2);
326     alias da_CFHash = CFHashCode function(CFTypeRef cf);
327     alias da_CFCopyDescription = CFStringRef function(CFTypeRef cf);
328 }
329 
330 __gshared
331 {
332     da_CFRetain CFRetain;
333     da_CFRelease CFRelease;
334     da_CFEqual CFEqual;
335     da_CFHash CFHash;
336     da_CFCopyDescription CFCopyDescription;
337 }
338 
339 
340 extern(C) nothrow @nogc
341 {
342     alias da_CFAllocatorAllocate = void* function(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint);
343     alias da_CFAllocatorDeallocate = void function(CFAllocatorRef allocator, void *ptr);
344 }
345 
346 __gshared
347 {
348     da_CFAllocatorAllocate CFAllocatorAllocate;
349     da_CFAllocatorDeallocate CFAllocatorDeallocate;
350 }
351 
352 // <CoreFoundation/CFBundle.h>
353 
354 alias CFBundleRef = void*;
355 
356 extern(C) nothrow @nogc
357 {
358     alias da_CFBundleGetBundleWithIdentifier = CFBundleRef function(CFStringRef bundleID);
359     alias da_CFBundleCopyBundleURL = CFURLRef function(CFBundleRef bundle);
360     alias da_CFBundleGetMainBundle = CFBundleRef function();
361     alias da_CFBundleCopyResourcesDirectoryURL = CFURLRef function(CFBundleRef bundle);
362 
363     alias da_CFURLGetFileSystemRepresentation = Boolean function(CFURLRef url, Boolean resolveAgainstBase, UInt8* buffer, CFIndex maxBufLen);
364 }
365 
366 __gshared
367 {
368     da_CFBundleGetBundleWithIdentifier CFBundleGetBundleWithIdentifier;
369     da_CFBundleCopyBundleURL CFBundleCopyBundleURL;
370     da_CFBundleGetMainBundle CFBundleGetMainBundle;
371     da_CFBundleCopyResourcesDirectoryURL CFBundleCopyResourcesDirectoryURL;
372 
373     da_CFURLGetFileSystemRepresentation CFURLGetFileSystemRepresentation;
374 }
375 
376 
377 // <CoreFoundation/CFArray.h>
378 
379 alias CFArrayRef = void*;
380 alias CFMutableArrayRef = void*;
381 
382 extern(C) nothrow @nogc
383 {
384     alias CFArrayRetainCallBack = const(void)* function(CFAllocatorRef allocator, const(void)* value);
385     alias CFArrayReleaseCallBack = void function(CFAllocatorRef allocator, const(void)* value);
386     alias CFArrayEqualCallBack = Boolean function(const(void)* value1, const(void)* value2);
387 }
388 
389 // This one isn't forced to be @nogc (this is arbitrary, only nothrow is needed)
390 extern(C) nothrow
391 {
392     alias CFArrayCopyDescriptionCallBack = CFStringRef function(const(void)* value);
393 }
394 
395 struct CFArrayCallBacks
396 {
397     CFIndex             version_;
398     CFArrayRetainCallBack       retain;
399     CFArrayReleaseCallBack      release;
400     CFArrayCopyDescriptionCallBack  copyDescription;
401     CFArrayEqualCallBack        equal;
402 }
403 
404 __gshared CFArrayCallBacks kCFTypeArrayCallBacks;
405 
406 extern(C) nothrow @nogc
407 {
408     alias da_CFArrayCreate = CFArrayRef function(CFAllocatorRef allocator, const(void)** values, CFIndex numValues, const(CFArrayCallBacks)* callBacks);
409     alias da_CFArrayCreateMutable = CFMutableArrayRef function(CFAllocatorRef allocator, CFIndex capacity, const(CFArrayCallBacks)* callBacks);
410     alias da_CFArrayAppendValue = void function(CFMutableArrayRef theArray, const(void)* value);
411 }
412 
413 __gshared
414 {
415     da_CFArrayCreate CFArrayCreate;
416     da_CFArrayCreateMutable CFArrayCreateMutable;
417     da_CFArrayAppendValue CFArrayAppendValue;
418 }
419 
420 
421 // <CoreFoundation/CFData.h>
422 
423 alias CFDataRef = void*;
424 alias CFMutableDataRef = void*;
425 
426 extern(C) nothrow @nogc
427 {
428     alias da_CFDataCreate = CFDataRef function(CFAllocatorRef allocator, const(UInt8)* bytes, CFIndex length);
429 
430     alias da_CFDataGetLength = CFIndex function(CFDataRef theData);
431     alias da_CFDataGetBytePtr = const(UInt8)* function(CFDataRef theData);
432 }
433 
434 __gshared
435 {
436     da_CFDataCreate CFDataCreate;
437     da_CFDataGetLength CFDataGetLength;
438     da_CFDataGetBytePtr CFDataGetBytePtr;
439 }
440 
441 // <CoreFoundation/CFDictionary.h>
442 
443 extern(C) nothrow @nogc
444 {
445     alias CFDictionaryRetainCallBack = const(void)* function(CFAllocatorRef allocator, const(void)* value);
446     alias CFDictionaryReleaseCallBack = void function(CFAllocatorRef allocator, const(void)* value);
447     alias CFDictionaryCopyDescriptionCallBack = CFStringRef function(const(void)* value);
448     alias CFDictionaryEqualCallBack = Boolean function(const(void)* value1, const(void)* value2);
449     alias CFDictionaryHashCallBack = CFHashCode function(const(void)* value);
450 }
451 
452 
453 // Dictionnaries callback
454 private extern(C) nothrow @nogc
455 {
456     const(void)* myRetainCallBack(CFAllocatorRef allocator, const(void)* value)
457     {
458         // MAYDO: not sure what to do with the allocator
459         return CFRetain(value);
460     }
461 
462     void myReleaseCallBack(CFAllocatorRef allocator, const(void)* value)
463     {
464         // MAYDO: not sure what to do with the allocator
465         return CFRelease(value);
466     }
467 }
468 
469 struct CFDictionaryKeyCallBacks
470 {
471     CFIndex             version_;
472     CFDictionaryRetainCallBack      retain;
473     CFDictionaryReleaseCallBack     release;
474     CFDictionaryCopyDescriptionCallBack copyDescription;
475     CFDictionaryEqualCallBack       equal;
476     CFDictionaryHashCallBack        hash;
477 }
478 
479 __gshared CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
480 
481 struct CFDictionaryValueCallBacks
482 {
483     CFIndex             version_;
484     CFDictionaryRetainCallBack      retain;
485     CFDictionaryReleaseCallBack     release;
486     CFDictionaryCopyDescriptionCallBack copyDescription;
487     CFDictionaryEqualCallBack       equal;
488 }
489 
490 __gshared CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
491 
492 alias CFDictionaryRef = void*;
493 alias CFMutableDictionaryRef = void*;
494 
495 extern(C) nothrow @nogc
496 {
497     alias da_CFDictionaryCreateMutable = CFMutableDictionaryRef function(CFAllocatorRef, CFIndex, const(CFDictionaryKeyCallBacks)*, const(CFDictionaryValueCallBacks)*);
498     alias da_CFDictionaryGetValue = const(void)* function(CFDictionaryRef theDict, const(void) *key);
499     alias da_CFDictionarySetValue = void function(CFMutableDictionaryRef theDict, const(void)* key, const(void)* value);
500 }
501 
502 __gshared
503 {
504     da_CFDictionaryCreateMutable CFDictionaryCreateMutable;
505     da_CFDictionaryGetValue CFDictionaryGetValue;
506     da_CFDictionarySetValue CFDictionarySetValue;
507 }
508 
509 // <CoreFoundation/CFNumber.h>
510 
511 alias CFNumberRef = void*;
512 
513 alias CFNumberType = CFIndex;
514 enum : CFNumberType
515 {
516     kCFNumberSInt8Type = 1,
517     kCFNumberSInt16Type = 2,
518     kCFNumberSInt32Type = 3,
519     kCFNumberSInt64Type = 4,
520     kCFNumberFloat32Type = 5,
521     kCFNumberFloat64Type = 6,
522     kCFNumberCharType = 7,
523     kCFNumberShortType = 8,
524     kCFNumberIntType = 9,
525     kCFNumberLongType = 10,
526     kCFNumberLongLongType = 11,
527     kCFNumberFloatType = 12,
528     kCFNumberDoubleType = 13,
529     kCFNumberCFIndexType = 14,
530     kCFNumberNSIntegerType = 15,
531     kCFNumberCGFloatType = 16,
532     kCFNumberMaxType = 16
533 }
534 
535 extern(C) nothrow @nogc
536 {
537     alias da_CFNumberCreate = CFNumberRef function(CFAllocatorRef allocator, CFNumberType theType, const(void) *valuePtr);
538     alias da_CFNumberGetValue = Boolean function(CFNumberRef number, CFNumberType theType, void *valuePtr);
539 }
540 
541 __gshared
542 {
543     da_CFNumberCreate CFNumberCreate;
544     da_CFNumberGetValue CFNumberGetValue;
545 }
546 
547 // <CoreFoundation/CFString.h>
548 
549 alias CFStringEncoding = UInt32;
550 alias CFStringBuiltInEncodings = CFStringEncoding;
551 enum : CFStringBuiltInEncodings
552 {
553     kCFStringEncodingMacRoman = 0,
554     kCFStringEncodingWindowsLatin1 = 0x0500,
555     kCFStringEncodingISOLatin1 = 0x0201,
556     kCFStringEncodingNextStepLatin = 0x0B01,
557     kCFStringEncodingASCII = 0x0600,
558     kCFStringEncodingUnicode = 0x0100,
559     kCFStringEncodingUTF8 = 0x08000100,
560     kCFStringEncodingNonLossyASCII = 0x0BFF,
561 
562     kCFStringEncodingUTF16 = 0x0100,
563     kCFStringEncodingUTF16BE = 0x10000100,
564     kCFStringEncodingUTF16LE = 0x14000100,
565 
566     kCFStringEncodingUTF32 = 0x0c000100,
567     kCFStringEncodingUTF32BE = 0x18000100,
568     kCFStringEncodingUTF32LE = 0x1c000100
569 }
570 
571 alias CFStringCompareFlags = CFOptionFlags;
572 enum : CFStringCompareFlags
573 {
574     kCFCompareCaseInsensitive = 1,
575     kCFCompareBackwards = 4,
576     kCFCompareAnchored = 8,
577     kCFCompareNonliteral = 16,
578     kCFCompareLocalized = 32,
579     kCFCompareNumerically = 64,
580     kCFCompareDiacriticInsensitive = 128,
581     kCFCompareWidthInsensitive = 256,
582     kCFCompareForcedOrdering = 512
583 }
584 
585 extern(C) nothrow @nogc
586 {
587     alias da_CFStringCreateWithCString = CFStringRef function(CFAllocatorRef, const(char)*, CFStringEncoding);
588     alias da_CFStringGetLength = CFIndex function(CFStringRef);
589     alias da_CFStringGetCString = Boolean function(CFStringRef, char*, CFIndex, CFStringEncoding);
590     alias da_CFStringCreateCopy = CFStringRef function(CFAllocatorRef alloc, CFStringRef theString);
591     alias da_CFStringCompare = CFComparisonResult function(CFStringRef theString1, CFStringRef theString2, CFStringCompareFlags compareOptions);
592     alias da_CFStringCreateWithFormat = CFStringRef function(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
593 }
594 
595 __gshared
596 {
597     da_CFStringCreateWithCString CFStringCreateWithCString;
598     da_CFStringGetLength CFStringGetLength;
599     da_CFStringGetCString CFStringGetCString;
600     da_CFStringCreateCopy CFStringCreateCopy;
601     da_CFStringCompare CFStringCompare;
602     da_CFStringCreateWithFormat CFStringCreateWithFormat;
603 }
604 
605 // <CoreFoundation/CFURL.h>
606 
607 alias CFURLRef = void*;