0
# Mac Platform APIs
1
2
macOS-specific frameworks including Core Foundation, IOKit for hardware access, Carbon for system events, and other macOS system services. These bindings provide native access to macOS frameworks through JNA interfaces.
3
4
## Capabilities
5
6
### Core Foundation Framework
7
8
Fundamental macOS framework providing basic services like string handling, collections, memory management, and run loops.
9
10
```java { .api }
11
/**
12
* Core Foundation framework functions
13
*/
14
public interface CoreFoundation extends Library {
15
CoreFoundation INSTANCE = Native.load("CoreFoundation", CoreFoundation.class);
16
17
// String encoding constants
18
int kCFStringEncodingUTF8 = 0x08000100;
19
int kCFStringEncodingASCII = 0x0600;
20
21
/**
22
* Create CFString from C string
23
* @param alloc Allocator to use (can be null for default)
24
* @param cStr C string to convert
25
* @param encoding String encoding (kCFStringEncodingUTF8, etc.)
26
* @return CFString reference, or null if failed
27
*/
28
CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, String cStr, int encoding);
29
30
/**
31
* Create CFString from characters
32
* @param alloc Allocator to use (can be null for default)
33
* @param chars Character array
34
* @param numChars Number of characters
35
* @return CFString reference, or null if failed
36
*/
37
CFStringRef CFStringCreateWithCharacters(CFAllocatorRef alloc, char[] chars, CFIndex numChars);
38
39
/**
40
* Get length of CFString
41
* @param theString CFString to measure
42
* @return String length in characters
43
*/
44
CFIndex CFStringGetLength(CFStringRef theString);
45
46
/**
47
* Get C string from CFString
48
* @param theString CFString to convert
49
* @param buffer Buffer to store C string
50
* @param bufferSize Buffer size
51
* @param encoding String encoding
52
* @return true if successful
53
*/
54
boolean CFStringGetCString(CFStringRef theString, byte[] buffer, CFIndex bufferSize, int encoding);
55
56
/**
57
* Release Core Foundation object
58
* @param cf Object to release
59
*/
60
void CFRelease(CFTypeRef cf);
61
62
/**
63
* Retain Core Foundation object
64
* @param cf Object to retain
65
* @return Same object with incremented reference count
66
*/
67
CFTypeRef CFRetain(CFTypeRef cf);
68
69
/**
70
* Get reference count of object
71
* @param cf Core Foundation object
72
* @return Current reference count
73
*/
74
CFIndex CFGetRetainCount(CFTypeRef cf);
75
76
/**
77
* Get type identifier for object
78
* @param cf Core Foundation object
79
* @return Type identifier
80
*/
81
CFTypeID CFGetTypeID(CFTypeRef cf);
82
83
/**
84
* Get type identifier for CFString
85
* @return CFString type identifier
86
*/
87
CFTypeID CFStringGetTypeID();
88
}
89
90
/**
91
* Core Foundation type definitions
92
*/
93
public static class CFTypeRef extends PointerType {
94
public CFTypeRef() { }
95
public CFTypeRef(Pointer p) { super(p); }
96
}
97
98
public static class CFStringRef extends CFTypeRef {
99
public CFStringRef() { }
100
public CFStringRef(Pointer p) { super(p); }
101
}
102
103
public static class CFAllocatorRef extends CFTypeRef {
104
public CFAllocatorRef() { }
105
public CFAllocatorRef(Pointer p) { super(p); }
106
}
107
108
public static class CFIndex extends NativeLong {
109
public CFIndex() { }
110
public CFIndex(long value) { super(value); }
111
}
112
113
public static class CFTypeID extends NativeLong {
114
public CFTypeID() { }
115
public CFTypeID(long value) { super(value); }
116
}
117
```
118
119
**Usage Examples:**
120
121
```java
122
import com.sun.jna.platform.mac.CoreFoundation;
123
import com.sun.jna.platform.mac.CoreFoundation.*;
124
125
// Create a CFString
126
CFStringRef cfString = CoreFoundation.INSTANCE.CFStringCreateWithCString(
127
null, "Hello, macOS!", CoreFoundation.kCFStringEncodingUTF8);
128
129
if (cfString != null) {
130
// Get string length
131
CFIndex length = CoreFoundation.INSTANCE.CFStringGetLength(cfString);
132
System.out.println("String length: " + length.longValue());
133
134
// Convert back to Java string
135
byte[] buffer = new byte[256];
136
boolean success = CoreFoundation.INSTANCE.CFStringGetCString(
137
cfString, buffer, new CFIndex(256), CoreFoundation.kCFStringEncodingUTF8);
138
139
if (success) {
140
String javaString = new String(buffer, "UTF-8").trim();
141
System.out.println("Retrieved string: " + javaString);
142
}
143
144
// Release the CFString
145
CoreFoundation.INSTANCE.CFRelease(cfString);
146
}
147
```
148
149
### I/O Kit Framework
150
151
Hardware communication framework for device access, system information, and hardware management.
152
153
```java { .api }
154
/**
155
* I/O Kit framework functions
156
*/
157
public interface IOKit extends Library {
158
IOKit INSTANCE = Native.load("IOKit", IOKit.class);
159
160
// I/O Kit return codes
161
int kIOReturnSuccess = 0;
162
int kIOReturnError = 0xe00002bc;
163
int kIOReturnBadArgument = 0xe00002c2;
164
165
/**
166
* Create matching dictionary for I/O Kit services
167
* @param name Service name to match
168
* @return Matching dictionary, or null if failed
169
*/
170
CFMutableDictionaryRef IOServiceMatching(String name);
171
172
/**
173
* Get services matching criteria
174
* @param masterPort Master port (usually 0)
175
* @param matching Matching dictionary
176
* @param existing Iterator for matching services
177
* @return I/O Kit return code
178
*/
179
int IOServiceGetMatchingServices(int masterPort, CFDictionaryRef matching,
180
Pointer /* io_iterator_t */ existing);
181
182
/**
183
* Get next service from iterator
184
* @param iterator Service iterator
185
* @return Service object, or 0 if no more services
186
*/
187
int /* io_object_t */ IOIteratorNext(int /* io_iterator_t */ iterator);
188
189
/**
190
* Get service property
191
* @param service Service object
192
* @param key Property key as CFString
193
* @return Property value as CFType, or null if not found
194
*/
195
CFTypeRef IORegistryEntryCreateCFProperty(int /* io_registry_entry_t */ service,
196
CFStringRef key, CFAllocatorRef allocator, int options);
197
198
/**
199
* Get service name
200
* @param service Service object
201
* @param name Buffer for service name
202
* @return I/O Kit return code
203
*/
204
int IORegistryEntryGetName(int /* io_registry_entry_t */ service, byte[] name);
205
206
/**
207
* Get parent service
208
* @param service Child service
209
* @param plane I/O Registry plane name
210
* @param parent Parent service output
211
* @return I/O Kit return code
212
*/
213
int IORegistryEntryGetParentEntry(int /* io_registry_entry_t */ service, String plane,
214
IntByReference /* io_registry_entry_t */ parent);
215
216
/**
217
* Release I/O Kit object
218
* @param object Object to release
219
* @return I/O Kit return code
220
*/
221
int IOObjectRelease(int /* io_object_t */ object);
222
}
223
224
/**
225
* Core Foundation dictionary reference
226
*/
227
public static class CFDictionaryRef extends CFTypeRef {
228
public CFDictionaryRef() { }
229
public CFDictionaryRef(Pointer p) { super(p); }
230
}
231
232
public static class CFMutableDictionaryRef extends CFDictionaryRef {
233
public CFMutableDictionaryRef() { }
234
public CFMutableDictionaryRef(Pointer p) { super(p); }
235
}
236
```
237
238
**Usage Examples:**
239
240
```java
241
import com.sun.jna.platform.mac.IOKit;
242
import com.sun.jna.platform.mac.CoreFoundation;
243
import com.sun.jna.ptr.IntByReference;
244
245
// Enumerate USB devices
246
CFMutableDictionaryRef matchingDict = IOKit.INSTANCE.IOServiceMatching("IOUSBDevice");
247
if (matchingDict != null) {
248
IntByReference iterator = new IntByReference();
249
int result = IOKit.INSTANCE.IOServiceGetMatchingServices(0, matchingDict, iterator.getPointer());
250
251
if (result == IOKit.kIOReturnSuccess) {
252
int service;
253
while ((service = IOKit.INSTANCE.IOIteratorNext(iterator.getValue())) != 0) {
254
// Get device name
255
byte[] nameBuffer = new byte[256];
256
if (IOKit.INSTANCE.IORegistryEntryGetName(service, nameBuffer) == IOKit.kIOReturnSuccess) {
257
String deviceName = new String(nameBuffer).trim();
258
System.out.println("USB Device: " + deviceName);
259
}
260
261
// Get device properties
262
CFStringRef vendorKey = CoreFoundation.INSTANCE.CFStringCreateWithCString(
263
null, "idVendor", CoreFoundation.kCFStringEncodingUTF8);
264
265
CFTypeRef vendorID = IOKit.INSTANCE.IORegistryEntryCreateCFProperty(
266
service, vendorKey, null, 0);
267
268
if (vendorID != null) {
269
// Process vendor ID...
270
CoreFoundation.INSTANCE.CFRelease(vendorID);
271
}
272
273
CoreFoundation.INSTANCE.CFRelease(vendorKey);
274
IOKit.INSTANCE.IOObjectRelease(service);
275
}
276
}
277
}
278
```
279
280
### Carbon Framework
281
282
Legacy Carbon framework for system events, hot key registration, and low-level system interaction.
283
284
```java { .api }
285
/**
286
* Carbon framework functions (legacy)
287
*/
288
public interface Carbon extends Library {
289
Carbon INSTANCE = Native.load("Carbon", Carbon.class);
290
291
// Event class constants
292
int kEventClassKeyboard = 1801812322; // 'keyb'
293
int kEventClassApplication = 1634758764; // 'appl'
294
295
// Event kind constants
296
int kEventHotKeyPressed = 5;
297
int kEventHotKeyReleased = 6;
298
299
/**
300
* Register global hot key
301
* @param inHotKeyID Hot key identifier
302
* @param inHotKey Hot key specification
303
* @param inTarget Event target (can be null)
304
* @param inOptions Options (usually 0)
305
* @param outRef Hot key reference output
306
* @return OSStatus result code
307
*/
308
int RegisterEventHotKey(int inHotKeyID, int inHotKey, Pointer inTarget,
309
int inOptions, Pointer outRef);
310
311
/**
312
* Unregister global hot key
313
* @param inHotKey Hot key reference to unregister
314
* @return OSStatus result code
315
*/
316
int UnregisterEventHotKey(Pointer inHotKey);
317
318
/**
319
* Install event handler
320
* @param inTarget Event target
321
* @param inHandler Handler function
322
* @param inNumTypes Number of event types
323
* @param inList Event type specifications
324
* @param inUserData User data for handler
325
* @param outRef Handler reference output
326
* @return OSStatus result code
327
*/
328
int InstallEventHandler(Pointer inTarget, Pointer inHandler, int inNumTypes,
329
Pointer inList, Pointer inUserData, Pointer outRef);
330
331
/**
332
* Get application event target
333
* @return Event target for current application
334
*/
335
Pointer GetApplicationEventTarget();
336
337
/**
338
* Run application event loop
339
*/
340
void RunApplicationEventLoop();
341
342
/**
343
* Quit application event loop
344
*/
345
void QuitApplicationEventLoop();
346
}
347
```
348
349
### System B (BSD Layer)
350
351
BSD system calls and low-level system services available on macOS.
352
353
```java { .api }
354
/**
355
* BSD system calls on macOS
356
*/
357
public interface SystemB extends Library {
358
SystemB INSTANCE = Native.load("System", SystemB.class);
359
360
/**
361
* Get system information
362
* @param name System parameter name
363
* @param oldp Buffer for current value
364
* @param oldlenp Size of buffer / returned size
365
* @param newp New value to set (can be null)
366
* @param newlen Size of new value
367
* @return 0 if successful, -1 if failed
368
*/
369
int sysctlbyname(String name, Pointer oldp, IntByReference oldlenp,
370
Pointer newp, size_t newlen);
371
372
/**
373
* Get process information
374
* @param pid Process ID (0 for current process)
375
* @param info Process info structure
376
* @param size Size of info structure
377
* @return 0 if successful, -1 if failed
378
*/
379
int proc_pidinfo(int pid, int flavor, long arg, Pointer info, int size);
380
381
/**
382
* Get host information
383
* @param host Host port
384
* @param flavor Information type
385
* @param host_info Buffer for host information
386
* @param host_info_cnt Size of buffer
387
* @return KERN_SUCCESS if successful
388
*/
389
int host_info(int host, int flavor, Pointer host_info, IntByReference host_info_cnt);
390
}
391
```
392
393
### Disk Arbitration Framework
394
395
Framework for disk mounting, unmounting, and volume management.
396
397
```java { .api }
398
/**
399
* Disk Arbitration framework functions
400
*/
401
public interface DiskArbitration extends Library {
402
DiskArbitration INSTANCE = Native.load("DiskArbitration", DiskArbitration.class);
403
404
/**
405
* Create disk arbitration session
406
* @param allocator Allocator to use (can be null)
407
* @return Session reference, or null if failed
408
*/
409
DASessionRef DASessionCreate(CFAllocatorRef allocator);
410
411
/**
412
* Create disk object from BSD name
413
* @param allocator Allocator to use (can be null)
414
* @param session Disk arbitration session
415
* @param name BSD device name (e.g., "disk1")
416
* @return Disk reference, or null if failed
417
*/
418
DADiskRef DADiskCreateFromBSDName(CFAllocatorRef allocator, DASessionRef session, String name);
419
420
/**
421
* Get disk description
422
* @param disk Disk reference
423
* @return Description dictionary
424
*/
425
CFDictionaryRef DADiskCopyDescription(DADiskRef disk);
426
427
/**
428
* Mount disk
429
* @param disk Disk to mount
430
* @param path Mount path (can be null for default)
431
* @param options Mount options
432
* @param callback Completion callback
433
* @param context Callback context
434
*/
435
void DADiskMount(DADiskRef disk, CFURLRef path, int options,
436
DADiskMountCallback callback, Pointer context);
437
438
/**
439
* Unmount disk
440
* @param disk Disk to unmount
441
* @param options Unmount options
442
* @param callback Completion callback
443
* @param context Callback context
444
*/
445
void DADiskUnmount(DADiskRef disk, int options,
446
DADiskUnmountCallback callback, Pointer context);
447
}
448
449
public static class DASessionRef extends CFTypeRef {
450
public DASessionRef() { }
451
public DASessionRef(Pointer p) { super(p); }
452
}
453
454
public static class DADiskRef extends CFTypeRef {
455
public DADiskRef() { }
456
public DADiskRef(Pointer p) { super(p); }
457
}
458
```
459
460
### Extended Attributes (Mac)
461
462
macOS implementation of extended file attributes with HFS+ and APFS support.
463
464
```java { .api }
465
/**
466
* macOS extended attributes
467
*/
468
public interface XAttr extends Library {
469
XAttr INSTANCE = Native.load("c", XAttr.class);
470
471
// Extended attribute options
472
int XATTR_NOFOLLOW = 1; // Don't follow symbolic links
473
int XATTR_CREATE = 2; // Create only (fail if exists)
474
int XATTR_REPLACE = 4; // Replace only (fail if doesn't exist)
475
476
/**
477
* Set extended attribute
478
* @param path File path
479
* @param name Attribute name
480
* @param value Attribute value
481
* @param size Value size
482
* @param position Starting position (usually 0)
483
* @param options Operation options
484
* @return 0 if successful, -1 if failed
485
*/
486
int setxattr(String path, String name, Pointer value, size_t size, int position, int options);
487
488
/**
489
* Get extended attribute
490
* @param path File path
491
* @param name Attribute name
492
* @param value Buffer for value
493
* @param size Buffer size
494
* @param position Starting position (usually 0)
495
* @param options Operation options
496
* @return Size of attribute, or -1 if failed
497
*/
498
size_t getxattr(String path, String name, Pointer value, size_t size, int position, int options);
499
500
/**
501
* Remove extended attribute
502
* @param path File path
503
* @param name Attribute name
504
* @param options Operation options
505
* @return 0 if successful, -1 if failed
506
*/
507
int removexattr(String path, String name, int options);
508
509
/**
510
* List extended attributes
511
* @param path File path
512
* @param namebuf Buffer for attribute names
513
* @param size Buffer size
514
* @param options Operation options
515
* @return Size of name list, or -1 if failed
516
*/
517
size_t listxattr(String path, Pointer namebuf, size_t size, int options);
518
}
519
520
/**
521
* macOS extended attribute utilities
522
*/
523
public class XAttrUtil {
524
/**
525
* Set string extended attribute
526
* @param path File path
527
* @param name Attribute name
528
* @param value String value
529
* @throws IOException if operation fails
530
*/
531
public static void setXAttr(String path, String name, String value) throws IOException;
532
533
/**
534
* Get string extended attribute
535
* @param path File path
536
* @param name Attribute name
537
* @return Attribute value, or null if not found
538
* @throws IOException if operation fails
539
*/
540
public static String getXAttr(String path, String name) throws IOException;
541
542
/**
543
* List all extended attributes
544
* @param path File path
545
* @return Array of attribute names
546
* @throws IOException if operation fails
547
*/
548
public static String[] listXAttrs(String path) throws IOException;
549
}
550
```
551
552
### Mac Utility Classes
553
554
High-level utility classes providing easier access to macOS functionality.
555
556
```java { .api }
557
/**
558
* High-level I/O Kit utilities
559
*/
560
public class IOKitUtil {
561
/**
562
* Get system serial number
563
* @return System serial number string
564
* @throws IOReturnException if operation fails
565
*/
566
public static String getSystemSerialNumber() throws IOReturnException;
567
568
/**
569
* Get system model identifier
570
* @return Model identifier string (e.g., "MacBookPro15,1")
571
* @throws IOReturnException if operation fails
572
*/
573
public static String getSystemModel() throws IOReturnException;
574
575
/**
576
* Get list of USB devices
577
* @return List of USB device information
578
* @throws IOReturnException if enumeration fails
579
*/
580
public static List<USBDeviceInfo> getUSBDevices() throws IOReturnException;
581
582
/**
583
* Get thermal state information
584
* @return Thermal state data
585
* @throws IOReturnException if operation fails
586
*/
587
public static ThermalState getThermalState() throws IOReturnException;
588
}
589
590
/**
591
* I/O Kit specific exception
592
*/
593
public class IOReturnException extends Exception {
594
private final int returnCode;
595
596
public IOReturnException(int returnCode) {
597
super("I/O Kit operation failed with code: 0x" + Integer.toHexString(returnCode));
598
this.returnCode = returnCode;
599
}
600
601
public int getReturnCode() {
602
return returnCode;
603
}
604
}
605
606
/**
607
* macOS file utilities
608
*/
609
public class MacFileUtils extends FileUtils {
610
@Override
611
public boolean moveToTrash(File... files) throws IOException {
612
// Implementation uses Finder to move files to Trash
613
// Returns true if all files moved successfully
614
}
615
616
@Override
617
public boolean hasTrash() {
618
return true; // macOS always has Trash
619
}
620
621
/**
622
* Get file type and creator codes (legacy HFS)
623
* @param file File to examine
624
* @return Type and creator information
625
* @throws IOException if operation fails
626
*/
627
public static FileTypeInfo getFileTypeInfo(File file) throws IOException;
628
629
/**
630
* Set file type and creator codes (legacy HFS)
631
* @param file File to modify
632
* @param type File type code
633
* @param creator Creator code
634
* @throws IOException if operation fails
635
*/
636
public static void setFileTypeInfo(File file, String type, String creator) throws IOException;
637
}
638
```
639
640
**Complete macOS Integration Example:**
641
642
```java
643
import com.sun.jna.platform.mac.*;
644
645
public class MacOSExample {
646
public static void main(String[] args) {
647
try {
648
// Get system information using I/O Kit
649
String serialNumber = IOKitUtil.getSystemSerialNumber();
650
String model = IOKitUtil.getSystemModel();
651
System.out.println("System: " + model + " (" + serialNumber + ")");
652
653
// Work with Core Foundation strings
654
CFStringRef cfStr = CoreFoundation.INSTANCE.CFStringCreateWithCString(
655
null, "Hello macOS", CoreFoundation.kCFStringEncodingUTF8);
656
657
// Use Disk Arbitration to get volume info
658
DASessionRef session = DiskArbitration.INSTANCE.DASessionCreate(null);
659
if (session != null) {
660
DADiskRef disk = DiskArbitration.INSTANCE.DADiskCreateFromBSDName(
661
null, session, "disk1");
662
if (disk != null) {
663
CFDictionaryRef description = DiskArbitration.INSTANCE.DADiskCopyDescription(disk);
664
// Process disk description...
665
CoreFoundation.INSTANCE.CFRelease(description);
666
CoreFoundation.INSTANCE.CFRelease(disk);
667
}
668
CoreFoundation.INSTANCE.CFRelease(session);
669
}
670
671
// Set extended attributes
672
XAttrUtil.setXAttr("/tmp/testfile", "com.myapp.comment", "My test file");
673
String comment = XAttrUtil.getXAttr("/tmp/testfile", "com.myapp.comment");
674
System.out.println("File comment: " + comment);
675
676
// Clean up
677
CoreFoundation.INSTANCE.CFRelease(cfStr);
678
679
} catch (Exception e) {
680
e.printStackTrace();
681
}
682
}
683
}
684
```