diff options
Diffstat (limited to 'core/sys/darwin')
32 files changed, 3488 insertions, 0 deletions
diff --git a/core/sys/darwin/Foundation/NSApplication.odin b/core/sys/darwin/Foundation/NSApplication.odin new file mode 100644 index 000000000..d332345f9 --- /dev/null +++ b/core/sys/darwin/Foundation/NSApplication.odin @@ -0,0 +1,609 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +import "base:intrinsics" +import "base:runtime" +import "core:strings" + +RunLoopMode :: ^String + +@(link_prefix="NS") +foreign Foundation { + RunLoopCommonModes: RunLoopMode + DefaultRunLoopMode: RunLoopMode + EventTrackingRunLoopMode: RunLoopMode + ModalPanelRunLoopMode: RunLoopMode +} + +ActivationPolicy :: enum UInteger { + Regular = 0, + Accessory = 1, + Prohibited = 2, +} + +ApplicationTerminateReply :: enum UInteger { + TerminateCancel = 0, + TerminateNow = 1, + TerminateLater = 2, +} + +ApplicationPrintReply :: enum UInteger { + PrintingCancelled = 0, + PrintingSuccess = 1, + PrintingReplyLater = 2, + PrintingFailure = 3, +} + +ApplicationPresentationOptionFlag :: enum UInteger { + AutoHideDock = 0, + HideDock = 1, + AutoHideMenuBar = 2, + HideMenuBar = 3, + DisableAppleMenu = 4, + DisableProcessSwitching = 5, + DisableForceQuit = 6, + DisableSessionTermination = 7, + DisableHideApplication = 8, + DisableMenuBarTransparency = 9, + FullScreen = 10, + AutoHideToolbar = 11, + DisableCursorLocationAssistance = 12, +} +ApplicationPresentationOptions :: distinct bit_set[ApplicationPresentationOptionFlag; UInteger] +ApplicationPresentationOptionsDefault :: ApplicationPresentationOptions {} +ApplicationPresentationOptionsAutoHideDock :: ApplicationPresentationOptions {.AutoHideDock} +ApplicationPresentationOptionsHideDock :: ApplicationPresentationOptions {.HideDock} +ApplicationPresentationOptionsAutoHideMenuBar :: ApplicationPresentationOptions {.AutoHideMenuBar} +ApplicationPresentationOptionsHideMenuBar :: ApplicationPresentationOptions {.HideMenuBar} +ApplicationPresentationOptionsDisableAppleMenu :: ApplicationPresentationOptions {.DisableAppleMenu} +ApplicationPresentationOptionsDisableProcessSwitching :: ApplicationPresentationOptions {.DisableProcessSwitching} +ApplicationPresentationOptionsDisableForceQuit :: ApplicationPresentationOptions {.DisableForceQuit} +ApplicationPresentationOptionsDisableSessionTermination :: ApplicationPresentationOptions {.DisableSessionTermination} +ApplicationPresentationOptionsDisableHideApplication :: ApplicationPresentationOptions {.DisableHideApplication} +ApplicationPresentationOptionsDisableMenuBarTransparency :: ApplicationPresentationOptions {.DisableMenuBarTransparency} +ApplicationPresentationOptionsFullScreen :: ApplicationPresentationOptions {.FullScreen} +ApplicationPresentationOptionsAutoHideToolbar :: ApplicationPresentationOptions {.AutoHideToolbar} +ApplicationPresentationOptionsDisableCursorLocationAssistance :: ApplicationPresentationOptions {.DisableCursorLocationAssistance} + +@(objc_class="NSApplication") +Application :: struct {using _: Object} + +@(objc_type=Application, objc_name="sharedApplication", objc_is_class_method=true) +Application_sharedApplication :: proc "c" () -> ^Application { + return msgSend(^Application, Application, "sharedApplication") +} + +@(objc_type=Application, objc_name="setActivationPolicy") +Application_setActivationPolicy :: proc "c" (self: ^Application, activationPolicy: ActivationPolicy) -> BOOL { + return msgSend(BOOL, self, "setActivationPolicy:", activationPolicy) +} + +@(deprecated="Use NSApplication method activate instead.") +@(objc_type=Application, objc_name="activateIgnoringOtherApps") +Application_activateIgnoringOtherApps :: proc "c" (self: ^Application, ignoreOtherApps: BOOL) { + msgSend(nil, self, "activateIgnoringOtherApps:", ignoreOtherApps) +} + +@(objc_type=Application, objc_name="activate") +Application_activate :: proc "c" (self: ^Application) { + msgSend(nil, self, "activate") +} + +@(objc_type=Application, objc_name="setTitle") +Application_setTitle :: proc "c" (self: ^Application, title: ^String) { + msgSend(nil, self, "setTitle", title) +} + +@(objc_type=Application, objc_name="setMainMenu") +Application_setMainMenu :: proc "c" (self: ^Application, menu: ^Menu) { + msgSend(nil, self, "setMainMenu:", menu) +} + +@(objc_type=Application, objc_name="windows") +Application_windows :: proc "c" (self: ^Application) -> ^Array { + return msgSend(^Array, self, "windows") +} + +@(objc_type=Application, objc_name="run") +Application_run :: proc "c" (self: ^Application) { + msgSend(nil, self, "run") +} + +@(objc_type=Application, objc_name="terminate") +Application_terminate :: proc "c" (self: ^Application, sender: ^Object) { + msgSend(nil, self, "terminate:", sender) +} + +@(objc_type=Application, objc_name="isRunning") +Application_isRunning :: proc "c" (self: ^Application) -> BOOL { + return msgSend(BOOL, self, "isRunning") +} + +@(objc_type=Application, objc_name="currentEvent") +Application_currentEvent :: proc "c" (self: ^Application) -> ^Event { + return msgSend(^Event, self, "currentEvent") +} + +@(objc_type=Application, objc_name="nextEventMatchingMask") +Application_nextEventMatchingMask :: proc "c" (self: ^Application, mask: EventMask, expiration: ^Date, in_mode: RunLoopMode, dequeue: BOOL) -> ^Event { + return msgSend(^Event, self, "nextEventMatchingMask:untilDate:inMode:dequeue:", mask, expiration, in_mode, dequeue) +} + +@(objc_type=Application, objc_name="sendEvent") +Application_sendEvent :: proc "c" (self: ^Application, event: ^Event) { + msgSend(Event, self, "sendEvent:", event) +} +@(objc_type=Application, objc_name="updateWindows") +Application_updateWindows :: proc "c" (self: ^Application) { + msgSend(nil, self, "updateWindows") +} + + +@(objc_class="NSRunningApplication") +RunningApplication :: struct {using _: Object} + +@(objc_type=RunningApplication, objc_name="currentApplication", objc_is_class_method=true) +RunningApplication_currentApplication :: proc "c" () -> ^RunningApplication { + return msgSend(^RunningApplication, RunningApplication, "currentApplication") +} + +@(objc_type=RunningApplication, objc_name="localizedName") +RunningApplication_localizedName :: proc "c" (self: ^RunningApplication) -> ^String { + return msgSend(^String, self, "localizedName") +} + +ApplicationDelegateTemplate :: struct { + // Launching Applications + applicationWillFinishLaunching: proc(notification: ^Notification), + applicationDidFinishLaunching: proc(notification: ^Notification), + // Managing Active Status + applicationWillBecomeActive: proc(notification: ^Notification), + applicationDidBecomeActive: proc(notification: ^Notification), + applicationWillResignActive: proc(notification: ^Notification), + applicationDidResignActive: proc(notification: ^Notification), + // Terminating Applications + applicationShouldTerminate: proc(sender: ^Application) -> ApplicationTerminateReply, + applicationShouldTerminateAfterLastWindowClosed: proc(sender: ^Application) -> BOOL, + applicationWillTerminate: proc(notification: ^Notification), + // Hiding Applications + applicationWillHide: proc(notification: ^Notification), + applicationDidHide: proc(notification: ^Notification), + applicationWillUnhide: proc(notification: ^Notification), + applicationDidUnhide: proc(notification: ^Notification), + // Managing Windows + applicationWillUpdate: proc(notification: ^Notification), + applicationDidUpdate: proc(notification: ^Notification), + applicationShouldHandleReopenHasVisibleWindows: proc(sender: ^Application, flag: BOOL) -> BOOL, + // Managing the Dock Menu + applicationDockMenu: proc(sender: ^Application) -> ^Menu, + // Localizing Keyboard Shortcuts + applicationShouldAutomaticallyLocalizeKeyEquivalents: proc(application: ^Application) -> BOOL, + // Displaying Errors + applicationWillPresentError: proc(application: ^Application, error: ^Error) -> ^Error, + // Managing the Screen + applicationDidChangeScreenParameters: proc(notification: ^Notification), + // Continuing User Activities + applicationWillContinueUserActivityWithType: proc(application: ^Application, userActivityType: ^String) -> BOOL, + applicationContinueUserActivityRestorationHandler: proc(application: ^Application, userActivity: ^UserActivity, restorationHandler: ^Block) -> BOOL, + applicationDidFailToContinueUserActivityWithTypeError: proc(application: ^Application, userActivityType: ^String, error: ^Error), + applicationDidUpdateUserActivity: proc(application: ^Application, userActivity: ^UserActivity), + // Handling Push Notifications + applicationDidRegisterForRemoteNotificationsWithDeviceToken: proc(application: ^Application, deviceToken: ^Data), + applicationDidFailToRegisterForRemoteNotificationsWithError: proc(application: ^Application, error: ^Error), + applicationDidReceiveRemoteNotification: proc(application: ^Application, userInfo: ^Dictionary), + // Handling CloudKit Invitations + // TODO: if/when we have cloud kit bindings implement + // applicationUserDidAcceptCloudKitShareWithMetadata: proc(application: ^Application, metadata: ^CKShareMetadata), + // Handling SiriKit Intents + // TODO: if/when we have siri kit bindings implement + // applicationHandlerForIntent: proc(application: ^Application, intent: ^INIntent) -> id, + // Opening Files + applicationOpenURLs: proc(application: ^Application, urls: ^Array), + applicationOpenFile: proc(sender: ^Application, filename: ^String) -> BOOL, + applicationOpenFileWithoutUI: proc(sender: id, filename: ^String) -> BOOL, + applicationOpenTempFile: proc(sender: ^Application, filename: ^String) -> BOOL, + applicationOpenFiles: proc(sender: ^Application, filenames: ^Array), + applicationShouldOpenUntitledFile: proc(sender: ^Application) -> BOOL, + applicationOpenUntitledFile: proc(sender: ^Application) -> BOOL, + // Printing + applicationPrintFile: proc(sender: ^Application, filename: ^String) -> BOOL, + applicationPrintFilesWithSettingsShowPrintPanels: proc(application: ^Application, fileNames: ^Array, printSettings: ^Dictionary, showPrintPanels: BOOL) -> ApplicationPrintReply, + // Restoring Application State + applicationSupportsSecureRestorableState: proc(app: ^Application) -> BOOL, + applicationProtectedDataDidBecomeAvailable: proc(notification: ^Notification), + applicationProtectedDataWillBecomeUnavailable: proc(notification: ^Notification), + applicationWillEncodeRestorableState: proc(app: ^Application, coder: ^Coder), + applicationDidDecodeRestorableState: proc(app: ^Application, coder: ^Coder), + // Handling Changes to the Occlusion State + applicationDidChangeOcclusionState: proc(notification: ^Notification), + // Scripting Your App + applicationDelegateHandlesKey: proc(sender: ^Application, key: ^String) -> BOOL, +} + +ApplicationDelegate :: struct { using _: Object } +_ApplicationDelegateInternal :: struct { + using _: ApplicationDelegateTemplate, + _context: runtime.Context, +} + +application_delegate_register_and_alloc :: proc(template: ApplicationDelegateTemplate, class_name: string, delegate_context: Maybe(runtime.Context)) -> ^ApplicationDelegate { + class := objc_allocateClassPair(intrinsics.objc_find_class("NSObject"), strings.clone_to_cstring(class_name, context.temp_allocator), 0); if class == nil { + // Class already registered + return nil + } + if template.applicationWillFinishLaunching != nil { + applicationWillFinishLaunching :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillFinishLaunching(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationWillFinishLaunching:"), auto_cast applicationWillFinishLaunching, "v@:@") + } + if template.applicationDidFinishLaunching != nil { + applicationDidFinishLaunching :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidFinishLaunching(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidFinishLaunching:"), auto_cast applicationDidFinishLaunching, "v@:@") + } + if template.applicationWillBecomeActive != nil { + applicationWillBecomeActive :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillBecomeActive(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationWillBecomeActive:"), auto_cast applicationWillBecomeActive, "v@:@") + } + if template.applicationDidBecomeActive != nil { + applicationDidBecomeActive :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidBecomeActive(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidBecomeActive:"), auto_cast applicationDidBecomeActive, "v@:@") + } + if template.applicationWillResignActive != nil { + applicationWillResignActive :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillResignActive(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationWillResignActive:"), auto_cast applicationWillResignActive, "v@:@") + } + if template.applicationDidResignActive != nil { + applicationDidResignActive :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidResignActive(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidResignActive:"), auto_cast applicationDidResignActive, "v@:@") + } + if template.applicationShouldTerminate != nil { + applicationShouldTerminate :: proc "c" (self: id, sender: ^Application) -> ApplicationTerminateReply { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationShouldTerminate(sender) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationShouldTerminate:"), auto_cast applicationShouldTerminate, _UINTEGER_ENCODING+"@:@") + } + if template.applicationShouldTerminateAfterLastWindowClosed != nil { + applicationShouldTerminateAfterLastWindowClosed :: proc "c" (self: id, sender: ^Application) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationShouldTerminateAfterLastWindowClosed(sender) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationShouldTerminateAfterLastWindowClosed:"), auto_cast applicationShouldTerminateAfterLastWindowClosed, "B@:@") + } + if template.applicationWillTerminate != nil { + applicationWillTerminate :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillTerminate(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationWillTerminate:"), auto_cast applicationWillTerminate, "v@:@") + } + if template.applicationWillHide != nil { + applicationWillHide :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillHide(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationWillHide:"), auto_cast applicationWillHide, "v@:@") + } + if template.applicationDidHide != nil { + applicationDidHide :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidHide(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidHide:"), auto_cast applicationDidHide, "v@:@") + } + if template.applicationWillUnhide != nil { + applicationWillUnhide :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillUnhide(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationWillUnhide:"), auto_cast applicationWillUnhide, "v@:@") + } + if template.applicationDidUnhide != nil { + applicationDidUnhide :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidUnhide(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidUnhide:"), auto_cast applicationDidUnhide, "v@:@") + } + if template.applicationWillUpdate != nil { + applicationWillUpdate :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillUpdate(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationWillUpdate:"), auto_cast applicationWillUpdate, "v@:@") + } + if template.applicationDidUpdate != nil { + applicationDidUpdate :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidUpdate(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidUpdate:"), auto_cast applicationDidUpdate, "v@:@") + } + if template.applicationShouldHandleReopenHasVisibleWindows != nil { + applicationShouldHandleReopenHasVisibleWindows :: proc "c" (self: id, sender: ^Application, flag: BOOL) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationShouldHandleReopenHasVisibleWindows(sender, flag) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationShouldHandleReopen:hasVisibleWindows:"), auto_cast applicationShouldHandleReopenHasVisibleWindows, "B@:@B") + } + if template.applicationDockMenu != nil { + applicationDockMenu :: proc "c" (self: id, sender: ^Application) -> ^Menu { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationDockMenu(sender) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDockMenu:"), auto_cast applicationDockMenu, "@@:@") + } + if template.applicationShouldAutomaticallyLocalizeKeyEquivalents != nil { + applicationShouldAutomaticallyLocalizeKeyEquivalents :: proc "c" (self: id, application: ^Application) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationShouldAutomaticallyLocalizeKeyEquivalents(application) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationShouldAutomaticallyLocalizeKeyEquivalents:"), auto_cast applicationShouldAutomaticallyLocalizeKeyEquivalents, "B@:@") + } + if template.applicationWillPresentError != nil { + applicationWillPresentError :: proc "c" (self: id, application: ^Application, error: ^Error) -> ^Error { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationWillPresentError(application, error) + } + class_addMethod(class, intrinsics.objc_find_selector("application:willPresentError:"), auto_cast applicationWillPresentError, "@@:@@") + } + if template.applicationDidChangeScreenParameters != nil { + applicationDidChangeScreenParameters :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidChangeScreenParameters(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidChangeScreenParameters:"), auto_cast applicationDidChangeScreenParameters, "v@:@") + } + if template.applicationWillContinueUserActivityWithType != nil { + applicationWillContinueUserActivityWithType :: proc "c" (self: id, application: ^Application, userActivityType: ^String) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationWillContinueUserActivityWithType(application, userActivityType) + } + class_addMethod(class, intrinsics.objc_find_selector("application:willContinueUserActivityWithType:"), auto_cast applicationWillContinueUserActivityWithType, "B@:@@") + } + if template.applicationContinueUserActivityRestorationHandler != nil { + applicationContinueUserActivityRestorationHandler :: proc "c" (self: id, application: ^Application, userActivity: ^UserActivity, restorationHandler: ^Block) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationContinueUserActivityRestorationHandler(application, userActivity, restorationHandler) + } + class_addMethod(class, intrinsics.objc_find_selector("application:continueUserActivity:restorationHandler:"), auto_cast applicationContinueUserActivityRestorationHandler, "B@:@@?") + } + if template.applicationDidFailToContinueUserActivityWithTypeError != nil { + applicationDidFailToContinueUserActivityWithTypeError :: proc "c" (self: id, application: ^Application, userActivityType: ^String, error: ^Error) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidFailToContinueUserActivityWithTypeError(application, userActivityType, error) + } + class_addMethod(class, intrinsics.objc_find_selector("application:didFailToContinueUserActivityWithType:error:"), auto_cast applicationDidFailToContinueUserActivityWithTypeError, "v@:@@@") + } + if template.applicationDidUpdateUserActivity != nil { + applicationDidUpdateUserActivity :: proc "c" (self: id, application: ^Application, userActivity: ^UserActivity) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidUpdateUserActivity(application, userActivity) + } + class_addMethod(class, intrinsics.objc_find_selector("application:didUpdateUserActivity:"), auto_cast applicationDidUpdateUserActivity, "v@:@@") + } + if template.applicationDidRegisterForRemoteNotificationsWithDeviceToken != nil { + applicationDidRegisterForRemoteNotificationsWithDeviceToken :: proc "c" (self: id, application: ^Application, deviceToken: ^Data) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidRegisterForRemoteNotificationsWithDeviceToken(application, deviceToken) + } + class_addMethod(class, intrinsics.objc_find_selector("application:didRegisterForRemoteNotificationsWithDeviceToken:"), auto_cast applicationDidRegisterForRemoteNotificationsWithDeviceToken, "v@:@@") + } + if template.applicationDidFailToRegisterForRemoteNotificationsWithError != nil { + applicationDidFailToRegisterForRemoteNotificationsWithError :: proc "c" (self: id, application: ^Application, error: ^Error) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidFailToRegisterForRemoteNotificationsWithError(application, error) + } + class_addMethod(class, intrinsics.objc_find_selector("application:didFailToRegisterForRemoteNotificationsWithError:"), auto_cast applicationDidFailToRegisterForRemoteNotificationsWithError, "v@:@@") + } + if template.applicationDidReceiveRemoteNotification != nil { + applicationDidReceiveRemoteNotification :: proc "c" (self: id, application: ^Application, userInfo: ^Dictionary) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidReceiveRemoteNotification(application, userInfo) + } + class_addMethod(class, intrinsics.objc_find_selector("application:didReceiveRemoteNotification:"), auto_cast applicationDidReceiveRemoteNotification, "v@:@@") + } + // if template.applicationUserDidAcceptCloudKitShareWithMetadata != nil { + // applicationUserDidAcceptCloudKitShareWithMetadata :: proc "c" (self: id, application: ^Application, metadata: ^CKShareMetadata) { + // del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + // context = del._context + // del.applicationUserDidAcceptCloudKitShareWithMetadata(application, metadata) + // } + // class_addMethod(class, intrinsics.objc_find_selector("application:userDidAcceptCloudKitShareWithMetadata:"), auto_cast applicationUserDidAcceptCloudKitShareWithMetadata, "v@:@@") + // } + // if template.applicationHandlerForIntent != nil { + // applicationHandlerForIntent :: proc "c" (self: id, application: ^Application, intent: ^INIntent) -> id { + // del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + // context = del._context + // return del.applicationHandlerForIntent(application, intent) + // } + // class_addMethod(class, intrinsics.objc_find_selector("application:handlerForIntent:"), auto_cast applicationHandlerForIntent, "@@:@@") + // } + if template.applicationOpenURLs != nil { + applicationOpenURLs :: proc "c" (self: id, application: ^Application, urls: ^Array) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationOpenURLs(application, urls) + } + class_addMethod(class, intrinsics.objc_find_selector("application:openURLs:"), auto_cast applicationOpenURLs, "v@:@@") + } + if template.applicationOpenFile != nil { + applicationOpenFile :: proc "c" (self: id, sender: ^Application, filename: ^String) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationOpenFile(sender, filename) + } + class_addMethod(class, intrinsics.objc_find_selector("application:openFile:"), auto_cast applicationOpenFile, "B@:@@") + } + if template.applicationOpenFileWithoutUI != nil { + applicationOpenFileWithoutUI :: proc "c" (self: id, sender: id, filename: ^String) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationOpenFileWithoutUI(sender, filename) + } + class_addMethod(class, intrinsics.objc_find_selector("application:openFileWithoutUI:"), auto_cast applicationOpenFileWithoutUI, "B@:@@") + } + if template.applicationOpenTempFile != nil { + applicationOpenTempFile :: proc "c" (self: id, sender: ^Application, filename: ^String) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationOpenTempFile(sender, filename) + } + class_addMethod(class, intrinsics.objc_find_selector("application:openTempFile:"), auto_cast applicationOpenTempFile, "B@:@@") + } + if template.applicationOpenFiles != nil { + applicationOpenFiles :: proc "c" (self: id, sender: ^Application, filenames: ^Array) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationOpenFiles(sender, filenames) + } + class_addMethod(class, intrinsics.objc_find_selector("application:openFiles:"), auto_cast applicationOpenFiles, "v@:@@") + } + if template.applicationShouldOpenUntitledFile != nil { + applicationShouldOpenUntitledFile :: proc "c" (self: id, sender: ^Application) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationShouldOpenUntitledFile(sender) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationShouldOpenUntitledFile:"), auto_cast applicationShouldOpenUntitledFile, "B@:@") + } + if template.applicationOpenUntitledFile != nil { + applicationOpenUntitledFile :: proc "c" (self: id, sender: ^Application) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationOpenUntitledFile(sender) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationOpenUntitledFile:"), auto_cast applicationOpenUntitledFile, "B@:@") + } + if template.applicationPrintFile != nil { + applicationPrintFile :: proc "c" (self: id, sender: ^Application, filename: ^String) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationPrintFile(sender, filename) + } + class_addMethod(class, intrinsics.objc_find_selector("application:printFile:"), auto_cast applicationPrintFile, "B@:@@") + } + if template.applicationPrintFilesWithSettingsShowPrintPanels != nil { + applicationPrintFilesWithSettingsShowPrintPanels :: proc "c" (self: id, application: ^Application, fileNames: ^Array, printSettings: ^Dictionary, showPrintPanels: BOOL) -> ApplicationPrintReply { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationPrintFilesWithSettingsShowPrintPanels(application, fileNames, printSettings, showPrintPanels) + } + class_addMethod(class, intrinsics.objc_find_selector("application:printFiles:withSettings:showPrintPanels:"), auto_cast applicationPrintFilesWithSettingsShowPrintPanels, _UINTEGER_ENCODING+"@:@@@B") + } + if template.applicationSupportsSecureRestorableState != nil { + applicationSupportsSecureRestorableState :: proc "c" (self: id, app: ^Application) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationSupportsSecureRestorableState(app) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationSupportsSecureRestorableState:"), auto_cast applicationSupportsSecureRestorableState, "B@:@") + } + if template.applicationProtectedDataDidBecomeAvailable != nil { + applicationProtectedDataDidBecomeAvailable :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationProtectedDataDidBecomeAvailable(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationProtectedDataDidBecomeAvailable:"), auto_cast applicationProtectedDataDidBecomeAvailable, "v@:@") + } + if template.applicationProtectedDataWillBecomeUnavailable != nil { + applicationProtectedDataWillBecomeUnavailable :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationProtectedDataWillBecomeUnavailable(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationProtectedDataWillBecomeUnavailable:"), auto_cast applicationProtectedDataWillBecomeUnavailable, "v@:@") + } + if template.applicationWillEncodeRestorableState != nil { + applicationWillEncodeRestorableState :: proc "c" (self: id, app: ^Application, coder: ^Coder) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationWillEncodeRestorableState(app, coder) + } + class_addMethod(class, intrinsics.objc_find_selector("application:willEncodeRestorableState:"), auto_cast applicationWillEncodeRestorableState, "v@:@@") + } + if template.applicationDidDecodeRestorableState != nil { + applicationDidDecodeRestorableState :: proc "c" (self: id, app: ^Application, coder: ^Coder) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidDecodeRestorableState(app, coder) + } + class_addMethod(class, intrinsics.objc_find_selector("application:didDecodeRestorableState:"), auto_cast applicationDidDecodeRestorableState, "v@:@@") + } + if template.applicationDidChangeOcclusionState != nil { + applicationDidChangeOcclusionState :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.applicationDidChangeOcclusionState(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("applicationDidChangeOcclusionState:"), auto_cast applicationDidChangeOcclusionState, "v@:@") + } + if template.applicationDelegateHandlesKey != nil { + applicationDelegateHandlesKey :: proc "c" (self: id, sender: ^Application, key: ^String) -> BOOL { + del := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.applicationDelegateHandlesKey(sender, key) + } + class_addMethod(class, intrinsics.objc_find_selector("application:delegateHandlesKey:"), auto_cast applicationDelegateHandlesKey, "B@:@@") + } + + objc_registerClassPair(class) + del := class_createInstance(class, size_of(_ApplicationDelegateInternal)) + del_internal := cast(^_ApplicationDelegateInternal)object_getIndexedIvars(del) + del_internal^ = { + template, + delegate_context.(runtime.Context) or_else runtime.default_context(), + } + return cast(^ApplicationDelegate)del +} + +@(objc_type=Application, objc_name="setDelegate") +Application_setDelegate :: proc "c" (self: ^Application, delegate: ^ApplicationDelegate) { + msgSend(nil, self, "setDelegate:", delegate) +} diff --git a/core/sys/darwin/Foundation/NSArray.odin b/core/sys/darwin/Foundation/NSArray.odin new file mode 100644 index 000000000..b238f63f8 --- /dev/null +++ b/core/sys/darwin/Foundation/NSArray.odin @@ -0,0 +1,42 @@ +package objc_Foundation + +import "base:intrinsics" + +@(objc_class="NSArray") +Array :: struct { + using _: Copying(Array), +} + +@(objc_type=Array, objc_name="alloc", objc_is_class_method=true) +Array_alloc :: proc "c" () -> ^Array { + return msgSend(^Array, Array, "alloc") +} + +@(objc_type=Array, objc_name="init") +Array_init :: proc "c" (self: ^Array) -> ^Array { + return msgSend(^Array, self, "init") +} + +@(objc_type=Array, objc_name="initWithObjects") +Array_initWithObjects :: proc "c" (self: ^Array, objects: [^]^Object, count: UInteger) -> ^Array { + return msgSend(^Array, self, "initWithObjects:count:", objects, count) +} + +@(objc_type=Array, objc_name="initWithCoder") +Array_initWithCoder :: proc "c" (self: ^Array, coder: ^Coder) -> ^Array { + return msgSend(^Array, self, "initWithCoder:", coder) +} + +@(objc_type=Array, objc_name="object") +Array_object :: proc "c" (self: ^Array, index: UInteger) -> ^Object { + return msgSend(^Object, self, "objectAtIndex:", index) +} +@(objc_type=Array, objc_name="objectAs") +Array_objectAs :: proc "c" (self: ^Array, index: UInteger, $T: typeid) -> T where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { + return (T)(Array_object(self, index)) +} + +@(objc_type=Array, objc_name="count") +Array_count :: proc "c" (self: ^Array) -> UInteger { + return msgSend(UInteger, self, "count") +} diff --git a/core/sys/darwin/Foundation/NSAutoreleasePool.odin b/core/sys/darwin/Foundation/NSAutoreleasePool.odin new file mode 100644 index 000000000..8eb3657b6 --- /dev/null +++ b/core/sys/darwin/Foundation/NSAutoreleasePool.odin @@ -0,0 +1,33 @@ +package objc_Foundation + +@(objc_class="NSAutoreleasePool") +AutoreleasePool :: struct {using _: Object} + +@(objc_type=AutoreleasePool, objc_name="alloc", objc_is_class_method=true) +AutoreleasePool_alloc :: proc "c" () -> ^AutoreleasePool { + return msgSend(^AutoreleasePool, AutoreleasePool, "alloc") +} + +@(objc_type=AutoreleasePool, objc_name="init") +AutoreleasePool_init :: proc "c" (self: ^AutoreleasePool) -> ^AutoreleasePool { + return msgSend(^AutoreleasePool, self, "init") +} + +@(objc_type=AutoreleasePool, objc_name="drain") +AutoreleasePool_drain :: proc "c" (self: ^AutoreleasePool) { + msgSend(nil, self, "drain") +} +@(objc_type=AutoreleasePool, objc_name="addObject") +AutoreleasePool_addObject :: proc "c" (self: ^AutoreleasePool, obj: ^Object) { + msgSend(nil, self, "addObject:", obj) +} +@(objc_type=AutoreleasePool, objc_name="showPools") +AutoreleasePool_showPools :: proc "c" (self: ^AutoreleasePool, obj: ^Object) { + msgSend(nil, self, "showPools") +} + + +@(deferred_out=AutoreleasePool_drain) +scoped_autoreleasepool :: proc "c" () -> ^AutoreleasePool { + return AutoreleasePool.alloc()->init() +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSBlock.odin b/core/sys/darwin/Foundation/NSBlock.odin new file mode 100644 index 000000000..b9d94bfee --- /dev/null +++ b/core/sys/darwin/Foundation/NSBlock.odin @@ -0,0 +1,120 @@ +package objc_Foundation + +import "base:intrinsics" +import "base:builtin" +import "core:mem" + +@(objc_class="NSBlock") +Block :: struct {using _: Object} + +@(objc_type=Block, objc_name="createGlobal", objc_is_class_method=true) +Block_createGlobal :: proc (user_data: rawptr, user_proc: proc "c" (user_data: rawptr), allocator := context.allocator) -> (^Block, mem.Allocator_Error) #optional_allocator_error { + return Block_createInternal(true, user_data, user_proc, allocator) +} +@(objc_type=Block, objc_name="createLocal", objc_is_class_method=true) +Block_createLocal :: proc (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + b, _ := Block_createInternal(false, user_data, user_proc, {}) + return b +} +@(objc_type=Block, objc_name="createGlobalWithParam", objc_is_class_method=true) +Block_createGlobalWithParam :: proc (user_data: rawptr, user_proc: proc "c" (user_data: rawptr, t: $T), allocator := context.allocator) -> (^Block, mem.Allocator_Error) #optional_allocator_error { + return Block_createInternalWithParam(true, user_data, user_proc, allocator) +} +@(objc_type=Block, objc_name="createLocalWithParam", objc_is_class_method=true) +Block_createLocalWithParam :: proc (user_data: rawptr, user_proc: proc "c" (user_data: rawptr, t: $T)) -> ^Block { + b, _ := Block_createInternalWithParam(false, user_data, user_proc, {}) + return b +} + +@(private) +Internal_Block_Literal_Base :: struct { + isa: ^intrinsics.objc_class, + flags: u32, + reserved: u32, + invoke: rawptr, // contains a pointer to a proc "c" (^Internal_Block_Literal, ...) + descriptor: ^Block_Descriptor, +} + +@(private) +Internal_Block_Literal :: struct { + using base: Internal_Block_Literal_Base, + // Imported Variables + user_proc: rawptr, // contains a pointer to a proc "c" (user_data: rawptr, ...) + user_data: rawptr, +} + +@(private) +Block_Descriptor :: struct { + reserved: uint, + size: uint, + copy_helper: proc "c" (dst, src: rawptr), + dispose_helper: proc "c" (src: rawptr), + signature: cstring, +} + +@(private) +global_block_descriptor := Block_Descriptor{ + reserved = 0, + size = size_of(Internal_Block_Literal), +} + +foreign import libSystem "system:System.framework" +foreign libSystem { + _NSConcreteGlobalBlock: intrinsics.objc_class + _NSConcreteStackBlock: intrinsics.objc_class +} + +@(private="file") +internal_block_literal_make :: proc (is_global: bool, user_data: rawptr, user_proc: rawptr, invoke: rawptr, allocator: mem.Allocator) -> (b: ^Block, err: mem.Allocator_Error) { + _init :: proc(bl: ^Internal_Block_Literal, is_global: bool, user_data: rawptr, user_proc: rawptr, invoke: rawptr) { + // Set to true on blocks that have captures (and thus are not true + // global blocks) but are known not to escape for various other + // reasons. For backward compatibility with old runtimes, whenever + // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a + // non-escaping block returns the original block and releasing such a + // block is a no-op, which is exactly how global blocks are handled. + BLOCK_IS_NOESCAPE :: (1 << 23)|BLOCK_IS_GLOBAL + + BLOCK_HAS_COPY_DISPOSE :: 1 << 25 + BLOCK_HAS_CTOR :: 1 << 26 // helpers have C++ code + BLOCK_IS_GLOBAL :: 1 << 28 + BLOCK_HAS_STRET :: 1 << 29 // IFF BLOCK_HAS_SIGNATURE + BLOCK_HAS_SIGNATURE :: 1 << 30 + + bl.isa = is_global ? &_NSConcreteGlobalBlock : &_NSConcreteStackBlock + bl.flags = BLOCK_IS_GLOBAL if is_global else 0 + bl.invoke = invoke + bl.descriptor = &global_block_descriptor + bl.user_proc = auto_cast user_proc + bl.user_data = user_data + } + if is_global { + bl := builtin.new (Internal_Block_Literal, allocator) or_return + _init(bl, true, user_data, user_proc, invoke) + return auto_cast bl, .None + } else { + // malloc blocks are created by calling 'copy' on a stack block + bl: Internal_Block_Literal + _init(&bl, false, user_data, user_proc, invoke) + return auto_cast copy(cast(^Copying(Block))(&bl)), .None + } +} + +@(private="file") +Block_createInternal :: proc (is_global: bool, user_data: rawptr, user_proc: proc "c" (user_data: rawptr), allocator: mem.Allocator) -> (b: ^Block, err: mem.Allocator_Error) { + invoke :: proc "c" (bl: ^Internal_Block_Literal) { + user_proc := (proc "c" (rawptr))(bl.user_proc) + user_proc(bl.user_data) + } + return internal_block_literal_make(is_global, user_data, auto_cast user_proc, auto_cast invoke, allocator) +} + +@(private="file") +Block_createInternalWithParam :: proc (is_global: bool, user_data: rawptr, user_proc: proc "c" (user_data: rawptr, t: $T), allocator: mem.Allocator) -> (b: ^Block, err: mem.Allocator_Error) { + invoke :: proc "c" (bl: ^Internal_Block_Literal, t: T) { + user_proc := (proc "c" (rawptr, T))(bl.user_proc) + user_proc(bl.user_data, t) + } + return internal_block_literal_make(is_global, user_data, auto_cast user_proc, auto_cast invoke, allocator) +} + diff --git a/core/sys/darwin/Foundation/NSBundle.odin b/core/sys/darwin/Foundation/NSBundle.odin new file mode 100644 index 000000000..25fc8df32 --- /dev/null +++ b/core/sys/darwin/Foundation/NSBundle.odin @@ -0,0 +1,191 @@ +package objc_Foundation + +@(objc_class="NSBundle") +Bundle :: struct { using _: Object } + +@(objc_type=Bundle, objc_name="mainBundle", objc_is_class_method=true) +Bundle_mainBundle :: proc "c" () -> ^Bundle { + return msgSend(^Bundle, Bundle, "mainBundle") +} + +@(objc_type=Bundle, objc_name="bundleWithPath", objc_is_class_method=true) +Bundle_bundleWithPath :: proc "c" (path: ^String) -> ^Bundle { + return msgSend(^Bundle, Bundle, "bundleWithPath:", path) +} + +@(objc_type=Bundle, objc_name="bundleWithURL", objc_is_class_method=true) +Bundle_bundleWithURL :: proc "c" (url: ^URL) -> ^Bundle { + return msgSend(^Bundle, Bundle, "bundleWithUrl:", url) +} + + +@(objc_type=Bundle, objc_name="alloc", objc_is_class_method=true) +Bundle_alloc :: proc "c" () -> ^Bundle { + return msgSend(^Bundle, Bundle, "alloc") +} + +@(objc_type=Bundle, objc_name="init") +Bundle_init :: proc "c" (self: ^Bundle) -> ^Bundle { + return msgSend(^Bundle, self, "init") +} + +@(objc_type=Bundle, objc_name="initWithPath") +Bundle_initWithPath :: proc "c" (self: ^Bundle, path: ^String) -> ^Bundle { + return msgSend(^Bundle, self, "initWithPath:", path) +} + +@(objc_type=Bundle, objc_name="initWithURL") +Bundle_initWithURL :: proc "c" (self: ^Bundle, url: ^URL) -> ^Bundle { + return msgSend(^Bundle, self, "initWithUrl:", url) +} + +@(objc_type=Bundle, objc_name="allBundles") +Bundle_allBundles :: proc "c" () -> (all: ^Array) { + return msgSend(type_of(all), Bundle, "allBundles") +} + +@(objc_type=Bundle, objc_name="allFrameworks") +Bundle_allFrameworks :: proc "c" () -> (all: ^Array) { + return msgSend(type_of(all), Bundle, "allFrameworks") +} + +@(objc_type=Bundle, objc_name="load") +Bundle_load :: proc "c" (self: ^Bundle) -> BOOL { + return msgSend(BOOL, self, "load") +} +@(objc_type=Bundle, objc_name="unload") +Bundle_unload :: proc "c" (self: ^Bundle) -> BOOL { + return msgSend(BOOL, self, "unload") +} + +@(objc_type=Bundle, objc_name="isLoaded") +Bundle_isLoaded :: proc "c" (self: ^Bundle) -> BOOL { + return msgSend(BOOL, self, "isLoaded") +} + +@(objc_type=Bundle, objc_name="preflightAndReturnError") +Bundle_preflightAndReturnError :: proc "contextless" (self: ^Bundle) -> (ok: BOOL, error: ^Error) { + ok = msgSend(BOOL, self, "preflightAndReturnError:", &error) + return +} + +@(objc_type=Bundle, objc_name="loadAndReturnError") +Bundle_loadAndReturnError :: proc "contextless" (self: ^Bundle) -> (ok: BOOL, error: ^Error) { + ok = msgSend(BOOL, self, "loadAndReturnError:", &error) + return +} + +@(objc_type=Bundle, objc_name="bundleURL") +Bundle_bundleURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "bundleURL") +} + +@(objc_type=Bundle, objc_name="resourceURL") +Bundle_resourceURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "resourceURL") +} + +@(objc_type=Bundle, objc_name="executableURL") +Bundle_executableURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "executableURL") +} + +@(objc_type=Bundle, objc_name="URLForAuxiliaryExecutable") +Bundle_URLForAuxiliaryExecutable :: proc "c" (self: ^Bundle, executableName: ^String) -> ^URL { + return msgSend(^URL, self, "URLForAuxiliaryExecutable:", executableName) +} + +@(objc_type=Bundle, objc_name="privateFrameworksURL") +Bundle_privateFrameworksURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "privateFrameworksURL") +} + +@(objc_type=Bundle, objc_name="sharedFrameworksURL") +Bundle_sharedFrameworksURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "sharedFrameworksURL") +} + +@(objc_type=Bundle, objc_name="sharedSupportURL") +Bundle_sharedSupportURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "sharedSupportURL") +} + +@(objc_type=Bundle, objc_name="builtInPlugInsURL") +Bundle_builtInPlugInsURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "builtInPlugInsURL") +} + +@(objc_type=Bundle, objc_name="appStoreReceiptURL") +Bundle_appStoreReceiptURL :: proc "c" (self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "appStoreReceiptURL") +} + +@(objc_type=Bundle, objc_name="bundlePath") +Bundle_bundlePath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "bundlePath") +} + +@(objc_type=Bundle, objc_name="resourcePath") +Bundle_resourcePath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "resourcePath") +} + +@(objc_type=Bundle, objc_name="executablePath") +Bundle_executablePath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "executablePath") +} + +@(objc_type=Bundle, objc_name="PathForAuxiliaryExecutable") +Bundle_PathForAuxiliaryExecutable :: proc "c" (self: ^Bundle, executableName: ^String) -> ^String { + return msgSend(^String, self, "PathForAuxiliaryExecutable:", executableName) +} + +@(objc_type=Bundle, objc_name="privateFrameworksPath") +Bundle_privateFrameworksPath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "privateFrameworksPath") +} + +@(objc_type=Bundle, objc_name="sharedFrameworksPath") +Bundle_sharedFrameworksPath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "sharedFrameworksPath") +} + +@(objc_type=Bundle, objc_name="sharedSupportPath") +Bundle_sharedSupportPath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "sharedSupportPath") +} + +@(objc_type=Bundle, objc_name="builtInPlugInsPath") +Bundle_builtInPlugInsPath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "builtInPlugInsPath") +} + +@(objc_type=Bundle, objc_name="appStoreReceiptPath") +Bundle_appStoreReceiptPath :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "appStoreReceiptPath") +} + +@(objc_type=Bundle, objc_name="bundleIdentifier") +Bundle_bundleIdentifier :: proc "c" (self: ^Bundle) -> ^String { + return msgSend(^String, self, "bundleIdentifier") +} + +@(objc_type=Bundle, objc_name="infoDictionary") +Bundle_infoDictionary :: proc "c" (self: ^Bundle) -> ^Dictionary { + return msgSend(^Dictionary, self, "infoDictionary") +} + +@(objc_type=Bundle, objc_name="localizedInfoDictionary") +Bundle_localizedInfoDictionary :: proc "c" (self: ^Bundle) -> ^Dictionary { + return msgSend(^Dictionary, self, "localizedInfoDictionary") +} + +@(objc_type=Bundle, objc_name="objectForInfoDictionaryKey") +Bundle_objectForInfoDictionaryKey :: proc "c" (self: ^Bundle, key: ^String) -> ^Object { + return msgSend(^Object, self, "objectForInfoDictionaryKey:", key) +} + +@(objc_type=Bundle, objc_name="localizedStringForKey") +Bundle_localizedStringForKey :: proc "c" (self: ^Bundle, key: ^String, value: ^String = nil, tableName: ^String = nil) -> ^String { + return msgSend(^String, self, "localizedStringForKey:value:table:", key, value, tableName) +} diff --git a/core/sys/darwin/Foundation/NSColor.odin b/core/sys/darwin/Foundation/NSColor.odin new file mode 100644 index 000000000..453b33144 --- /dev/null +++ b/core/sys/darwin/Foundation/NSColor.odin @@ -0,0 +1,149 @@ +package objc_Foundation + +@(objc_class="NSColorSpace") +ColorSpace :: struct {using _: Object} + +@(objc_class="NSColor") +Color :: struct {using _: Object} + +@(objc_type=Color, objc_name="colorWithSRGBRed", objc_is_class_method=true) +Color_colorWithSRGBRed :: proc "c" (red, green, blue, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithSRGBRed:green:blue:alpha:", red, green, blue, alpha) +} + +@(objc_type=Color, objc_name="colorWithCalibratedHue", objc_is_class_method=true) +Color_colorWithCalibratedHue :: proc "c" (hue, saturation, brightness, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithCalibratedHue:hue:saturation:brightness:alpha:", hue, saturation, brightness, alpha) +} +@(objc_type=Color, objc_name="colorWithCalibratedRed", objc_is_class_method=true) +Color_colorWithCalibratedRed :: proc "c" (red, green, blue, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithCalibratedRed:green:blue:alpha:", red, green, blue, alpha) +} +@(objc_type=Color, objc_name="colorWithCalibratedWhite", objc_is_class_method=true) +Color_colorWithCalibratedWhite :: proc "c" (white, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithCalibratedWhite:alpha:", white, alpha) +} + +@(objc_type=Color, objc_name="colorWithDeviceCyan", objc_is_class_method=true) +Color_colorWithDeviceCyan :: proc "c" (cyan, magenta, yellow, black, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithDeviceCyan:magenta:yellow:black:", cyan, magenta, yellow, black) +} +@(objc_type=Color, objc_name="colorWithDeviceHue", objc_is_class_method=true) +Color_colorWithDeviceHue :: proc "c" (hue, saturation, brightness, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithDeviceHue:hue:saturation:brightness:alpha:", hue, saturation, brightness, alpha) +} +@(objc_type=Color, objc_name="colorWithDeviceRed", objc_is_class_method=true) +Color_colorWithDeviceRed :: proc "c" (red, green, blue, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithDeviceRed:green:blue:alpha:", red, green, blue, alpha) +} +@(objc_type=Color, objc_name="colorWithDeviceWhite", objc_is_class_method=true) +Color_colorWithDeviceWhite :: proc "c" (white, alpha: Float) -> ^Color { + return msgSend(^Color, Color, "colorWithDeviceWhite:alpha:", white, alpha) +} + + +@(objc_type=Color, objc_name="blackColor", objc_is_class_method=true) +Color_blackColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "blackColor") +} + +@(objc_type=Color, objc_name="whiteColor", objc_is_class_method=true) +Color_whiteColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "whiteColor") +} + +@(objc_type=Color, objc_name="redColor", objc_is_class_method=true) +Color_redColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "redColor") +} + +@(objc_type=Color, objc_name="greenColor", objc_is_class_method=true) +Color_greenColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "greenColor") +} + +@(objc_type=Color, objc_name="orangeColor", objc_is_class_method=true) +Color_orangeColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "orangeColor") +} + +@(objc_type=Color, objc_name="purpleColor", objc_is_class_method=true) +Color_purpleColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "purpleColor") +} + +@(objc_type=Color, objc_name="cyanColor", objc_is_class_method=true) +Color_cyanColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "cyanColor") +} + +@(objc_type=Color, objc_name="blueColor", objc_is_class_method=true) +Color_blueColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "blueColor") +} + +@(objc_type=Color, objc_name="magentaColor", objc_is_class_method=true) +Color_magentaColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "magentaColor") +} + +@(objc_type=Color, objc_name="yellowColor", objc_is_class_method=true) +Color_yellowColor :: proc "c" () -> ^Color { + return msgSend(^Color, Color, "yellowColor") +} + + +@(objc_type=Color, objc_name="getCMYKA") +Color_getCMYKA :: proc "c" (self: ^Color) -> (cyan, magenta, yellow, black, alpha: Float) { + msgSend(nil, Color, "getCyan:magenta:yellow:black:alpha:", &cyan, &magenta, &yellow, &black, &alpha) + return +} +@(objc_type=Color, objc_name="getHSBA") +Color_getHSBA :: proc "c" (self: ^Color) -> (hue, saturation, brightness, alpha: Float) { + msgSend(nil, Color, "getHue:saturation:brightness:alpha:", &hue, &saturation, &brightness, &alpha) + return +} +@(objc_type=Color, objc_name="getRGBA") +Color_getRGBA :: proc "c" (self: ^Color) -> (red, green, blue, alpha: Float) { + msgSend(nil, Color, "getRed:green:blue:alpha:", &red, &green, &blue, &alpha) + return +} +@(objc_type=Color, objc_name="getWhiteAlpha") +Color_getWhiteAlpha :: proc "c" (self: ^Color) -> (white, alpha: Float) { + msgSend(nil, Color, "getWhite:alpha:", &white, &alpha) + return +} + + +@(objc_type=Color, objc_name="colorWithColorSpace", objc_is_class_method=true) +Color_colorWithColorSpace :: proc "c" (space: ^ColorSpace, components: []Float) -> ^Color { + return msgSend(^Color, Color, "colorWithColorSpace:components:count", space, raw_data(components), Integer(len(components))) +} + + +@(objc_type=Color, objc_name="colorSpaceName") +Color_colorSpaceName :: proc "c" (self: ^Color) -> ^String { + return msgSend(^String, self, "colorSpaceName") +} + +@(objc_type=Color, objc_name="colorSpace") +Color_colorSpace :: proc "c" (self: ^Color) -> ^ColorSpace { + return msgSend(^ColorSpace, self, "colorSpace") +} + +@(objc_type=Color, objc_name="colorUsingColorSpaceName") +Color_colorUsingColorSpaceName :: proc "c" (self: ^Color, colorSpace: ^String, device: ^Dictionary = nil) -> ^Color { + if device != nil { + return msgSend(^Color, self, "colorUsingColorSpaceName:device:", colorSpace, device) + } + return msgSend(^Color, self, "colorUsingColorSpaceName:", colorSpace) +} + +@(objc_type=Color, objc_name="numberOfComponents") +Color_numberOfComponents :: proc "c" (self: ^Color) -> Integer { + return msgSend(Integer, self, "numberOfComponents") +} +@(objc_type=Color, objc_name="getComponents") +Color_getComponents :: proc "c" (self: ^Color, components: [^]Float) { + msgSend(nil, self, "getComponents:", components) +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSData.odin b/core/sys/darwin/Foundation/NSData.odin new file mode 100644 index 000000000..04c1ce25d --- /dev/null +++ b/core/sys/darwin/Foundation/NSData.odin @@ -0,0 +1,24 @@ +package objc_Foundation + +@(objc_class="NSData") +Data :: struct {using _: Copying(Data)} + +@(objc_type=Data, objc_name="alloc", objc_is_class_method=true) +Data_alloc :: proc "c" () -> ^Data { + return msgSend(^Data, Data, "alloc") +} + +@(objc_type=Data, objc_name="init") +Data_init :: proc "c" (self: ^Data) -> ^Data { + return msgSend(^Data, self, "init") +} + +@(objc_type=Data, objc_name="mutableBytes") +Data_mutableBytes :: proc "c" (self: ^Data) -> rawptr { + return msgSend(rawptr, self, "mutableBytes") +} + +@(objc_type=Data, objc_name="length") +Data_length :: proc "c" (self: ^Data) -> UInteger { + return msgSend(UInteger, self, "length") +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSDate.odin b/core/sys/darwin/Foundation/NSDate.odin new file mode 100644 index 000000000..f8096c698 --- /dev/null +++ b/core/sys/darwin/Foundation/NSDate.odin @@ -0,0 +1,19 @@ +package objc_Foundation + +@(objc_class="NSDate") +Date :: struct {using _: Copying(Date)} + +@(objc_type=Date, objc_name="alloc", objc_is_class_method=true) +Date_alloc :: proc "c" () -> ^Date { + return msgSend(^Date, Date, "alloc") +} + +@(objc_type=Date, objc_name="init") +Date_init :: proc "c" (self: ^Date) -> ^Date { + return msgSend(^Date, self, "init") +} + +@(objc_type=Date, objc_name="dateWithTimeIntervalSinceNow") +Date_dateWithTimeIntervalSinceNow :: proc "c" (secs: TimeInterval) -> ^Date { + return msgSend(^Date, Date, "dateWithTimeIntervalSinceNow:", secs) +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSDictionary.odin b/core/sys/darwin/Foundation/NSDictionary.odin new file mode 100644 index 000000000..8af58cf62 --- /dev/null +++ b/core/sys/darwin/Foundation/NSDictionary.odin @@ -0,0 +1,50 @@ +package objc_Foundation + +@(objc_class="NSDictionary") +Dictionary :: struct {using _: Copying(Dictionary)} + +@(objc_type=Dictionary, objc_name="dictionary", objc_is_class_method=true) +Dictionary_dictionary :: proc "c" () -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "dictionary") +} + +@(objc_type=Dictionary, objc_name="dictionaryWithObject", objc_is_class_method=true) +Dictionary_dictionaryWithObject :: proc "c" (object: ^Object, forKey: ^Object) -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "dictionaryWithObject:forKey:", object, forKey) +} + +@(objc_type=Dictionary, objc_name="dictionaryWithObjects", objc_is_class_method=true) +Dictionary_dictionaryWithObjects :: proc "c" (objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "dictionaryWithObjects:forKeys:count", objects, forKeys, count) +} + + +@(objc_type=Dictionary, objc_name="alloc", objc_is_class_method=true) +Dictionary_alloc :: proc "c" () -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "alloc") +} + +@(objc_type=Dictionary, objc_name="init") +Dictionary_init :: proc "c" (self: ^Dictionary) -> ^Dictionary { + return msgSend(^Dictionary, self, "init") +} + +@(objc_type=Dictionary, objc_name="initWithObjects") +Dictionary_initWithObjects :: proc "c" (self: ^Dictionary, objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary { + return msgSend(^Dictionary, self, "initWithObjects:forKeys:count", objects, forKeys, count) +} + +@(objc_type=Dictionary, objc_name="objectForKey") +Dictionary_objectForKey :: proc "c" (self: ^Dictionary, key: ^Object) -> ^Object { + return msgSend(^Dictionary, self, "objectForKey:", key) +} + +@(objc_type=Dictionary, objc_name="count") +Dictionary_count :: proc "c" (self: ^Dictionary) -> UInteger { + return msgSend(UInteger, self, "count") +} + +@(objc_type=Dictionary, objc_name="keyEnumerator") +Dictionary_keyEnumerator :: proc "c" (self: ^Dictionary, $KeyType: typeid) -> (enumerator: ^Enumerator(KeyType)) { + return msgSend(type_of(enumerator), self, "keyEnumerator") +} diff --git a/core/sys/darwin/Foundation/NSEnumerator.odin b/core/sys/darwin/Foundation/NSEnumerator.odin new file mode 100644 index 000000000..52f3f49d7 --- /dev/null +++ b/core/sys/darwin/Foundation/NSEnumerator.odin @@ -0,0 +1,50 @@ +package objc_Foundation + +import "core:c" +import "base:intrinsics" + +FastEnumerationState :: struct #packed { + state: c.ulong, + itemsPtr: [^]^Object, + mutationsPtr: [^]c.ulong, + extra: [5]c.ulong, +} + +@(objc_class="NSFastEnumeration") +FastEnumeration :: struct {using _: Object} + +@(objc_class="NSEnumerator") +Enumerator :: struct($T: typeid) where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { + using _: FastEnumeration, +} + + +@(objc_type=FastEnumeration, objc_name="alloc", objc_is_class_method=true) +FastEnumeration_alloc :: proc "c" () -> ^FastEnumeration { + return msgSend(^FastEnumeration, FastEnumeration, "alloc") +} + +@(objc_type=FastEnumeration, objc_name="init") +FastEnumeration_init :: proc "c" (self: ^FastEnumeration) -> ^FastEnumeration { + return msgSend(^FastEnumeration, self, "init") +} + + +@(objc_type=FastEnumeration, objc_name="countByEnumerating") +FastEnumeration_countByEnumerating :: proc "c" (self: ^FastEnumeration, state: ^FastEnumerationState, buffer: [^]^Object, len: UInteger) -> UInteger { + return msgSend(UInteger, self, "countByEnumeratingWithState:objects:count:", state, buffer, len) +} + +Enumerator_nextObject :: proc "c" (self: ^$E/Enumerator($T)) -> T { + return msgSend(T, self, "nextObject") +} + +Enumerator_allObjects :: proc "c" (self: ^$E/Enumerator($T)) -> (all: ^Array) { + return msgSend(type_of(all), self, "allObjects") +} + +Enumerator_iterator :: proc "contextless" (self: ^$E/Enumerator($T)) -> (obj: T, ok: bool) { + obj = msgSend(T, self, "nextObject") + ok = obj != nil + return +} diff --git a/core/sys/darwin/Foundation/NSError.odin b/core/sys/darwin/Foundation/NSError.odin new file mode 100644 index 000000000..1657befe2 --- /dev/null +++ b/core/sys/darwin/Foundation/NSError.odin @@ -0,0 +1,88 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +ErrorDomain :: ^String + +foreign Foundation { + @(linkage="weak") CocoaErrorDomain: ErrorDomain + @(linkage="weak") POSIXErrorDomain: ErrorDomain + @(linkage="weak") OSStatusErrorDomain: ErrorDomain + @(linkage="weak") MachErrorDomain: ErrorDomain +} + +ErrorUserInfoKey :: ^String + +foreign Foundation { + @(linkage="weak") UnderlyingErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedDescriptionKey: ErrorUserInfoKey + @(linkage="weak") LocalizedFailureReasonErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedRecoverySuggestionErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedRecoveryOptionsErrorKey: ErrorUserInfoKey + @(linkage="weak") RecoveryAttempterErrorKey: ErrorUserInfoKey + @(linkage="weak") HelpAnchorErrorKey: ErrorUserInfoKey + @(linkage="weak") DebugDescriptionErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedFailureErrorKey: ErrorUserInfoKey + @(linkage="weak") StringEncodingErrorKey: ErrorUserInfoKey + @(linkage="weak") URLErrorKey: ErrorUserInfoKey + @(linkage="weak") FilePathErrorKey: ErrorUserInfoKey +} + +@(objc_class="NSError") +Error :: struct { using _: Copying(Error) } + + +@(objc_type=Error, objc_name="alloc", objc_is_class_method=true) +Error_alloc :: proc "c" () -> ^Error { + return msgSend(^Error, Error, "alloc") +} + +@(objc_type=Error, objc_name="init") +Error_init :: proc "c" (self: ^Error) -> ^Error { + return msgSend(^Error, self, "init") +} + +@(objc_type=Error, objc_name="errorWithDomain", objc_is_class_method=true) +Error_errorWithDomain :: proc "c" (domain: ErrorDomain, code: Integer, userInfo: ^Dictionary) -> ^Error { + return msgSend(^Error, Error, "errorWithDomain:code:userInfo:", domain, code, userInfo) +} + +@(objc_type=Error, objc_name="initWithDomain") +Error_initWithDomain :: proc "c" (self: ^Error, domain: ErrorDomain, code: Integer, userInfo: ^Dictionary) -> ^Error { + return msgSend(^Error, self, "initWithDomain:code:userInfo:", domain, code, userInfo) +} + +@(objc_type=Error, objc_name="code") +Error_code :: proc "c" (self: ^Error) -> Integer { + return msgSend(Integer, self, "code") +} + +@(objc_type=Error, objc_name="domain") +Error_domain :: proc "c" (self: ^Error) -> ErrorDomain { + return msgSend(ErrorDomain, self, "domain") +} + +@(objc_type=Error, objc_name="userInfo") +Error_userInfo :: proc "c" (self: ^Error) -> ^Dictionary { + return msgSend(^Dictionary, self, "userInfo") +} + +@(objc_type=Error, objc_name="localizedDescription") +Error_localizedDescription :: proc "c" (self: ^Error) -> ^String { + return msgSend(^String, self, "localizedDescription") +} + +@(objc_type=Error, objc_name="localizedRecoveryOptions") +Error_localizedRecoveryOptions :: proc "c" (self: ^Error) -> (options: ^Array) { + return msgSend(type_of(options), self, "localizedRecoveryOptions") +} + +@(objc_type=Error, objc_name="localizedRecoverySuggestion") +Error_localizedRecoverySuggestion :: proc "c" (self: ^Error) -> ^String { + return msgSend(^String, self, "localizedRecoverySuggestion") +} + +@(objc_type=Error, objc_name="localizedFailureReason") +Error_localizedFailureReason :: proc "c" (self: ^Error) -> ^String { + return msgSend(^String, self, "localizedFailureReason") +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSEvent.odin b/core/sys/darwin/Foundation/NSEvent.odin new file mode 100644 index 000000000..b9f247230 --- /dev/null +++ b/core/sys/darwin/Foundation/NSEvent.odin @@ -0,0 +1,466 @@ +package objc_Foundation + +@(objc_class="NSEvent") +Event :: struct {using _: Object} + + + +EventMask :: distinct bit_set[EventType; UInteger] +EventMaskAny :: ~EventMask{} + +when size_of(UInteger) == 4 { + // We don't support a 32-bit darwin system but this is mostly to shut up the type checker for the time being + EventType :: enum UInteger { + LeftMouseDown = 1, + LeftMouseUp = 2, + RightMouseDown = 3, + RightMouseUp = 4, + MouseMoved = 5, + LeftMouseDragged = 6, + RightMouseDragged = 7, + MouseEntered = 8, + MouseExited = 9, + KeyDown = 10, + KeyUp = 11, + FlagsChanged = 12, + AppKitDefined = 13, + SystemDefined = 14, + ApplicationDefined = 15, + Periodic = 16, + CursorUpdate = 17, + Rotate = 18, + BeginGesture = 19, + EndGesture = 20, + ScrollWheel = 22, + TabletPoint = 23, + TabletProximity = 24, + OtherMouseDown = 25, + OtherMouseUp = 26, + OtherMouseDragged = 27, + Gesture = 29, + Magnify = 30, + Swipe = 31, + } +} else { + EventType :: enum UInteger { + LeftMouseDown = 1, + LeftMouseUp = 2, + RightMouseDown = 3, + RightMouseUp = 4, + MouseMoved = 5, + LeftMouseDragged = 6, + RightMouseDragged = 7, + MouseEntered = 8, + MouseExited = 9, + KeyDown = 10, + KeyUp = 11, + FlagsChanged = 12, + AppKitDefined = 13, + SystemDefined = 14, + ApplicationDefined = 15, + Periodic = 16, + CursorUpdate = 17, + Rotate = 18, + BeginGesture = 19, + EndGesture = 20, + ScrollWheel = 22, + TabletPoint = 23, + TabletProximity = 24, + OtherMouseDown = 25, + OtherMouseUp = 26, + OtherMouseDragged = 27, + Gesture = 29, + Magnify = 30, + Swipe = 31, + SmartMagnify = 32, + QuickLook = 33, + Pressure = 34, + DirectTouch = 37, + ChangeMode = 38, + } +} + +EventPhase :: distinct bit_set[EventPhaseFlag; UInteger] +EventPhaseFlag :: enum UInteger { + Began = 0, + Stationary = 1, + Changed = 2, + Ended = 3, + Cancelled = 4, + MayBegin = 5, +} +EventPhaseNone :: EventPhase{} +EventPhaseBegan :: EventPhase{.Began} +EventPhaseStationary :: EventPhase{.Stationary} +EventPhaseChanged :: EventPhase{.Changed} +EventPhaseEnded :: EventPhase{.Ended} +EventPhaseCancelled :: EventPhase{.Cancelled} +EventPhaseMayBegin :: EventPhase{.MayBegin} + +/* pointer types for NSTabletProximity events or mouse events with subtype NSTabletProximityEventSubtype*/ +PointingDeviceType :: enum UInteger { + Unknown = 0, + Pen = 1, + Cursor = 2, + Eraser = 3, +} + +// Defined in Carbon.framework Events.h +kVK :: enum { + ANSI_A = 0x00, + ANSI_S = 0x01, + ANSI_D = 0x02, + ANSI_F = 0x03, + ANSI_H = 0x04, + ANSI_G = 0x05, + ANSI_Z = 0x06, + ANSI_X = 0x07, + ANSI_C = 0x08, + ANSI_V = 0x09, + ANSI_B = 0x0B, + ANSI_Q = 0x0C, + ANSI_W = 0x0D, + ANSI_E = 0x0E, + ANSI_R = 0x0F, + ANSI_Y = 0x10, + ANSI_T = 0x11, + ANSI_1 = 0x12, + ANSI_2 = 0x13, + ANSI_3 = 0x14, + ANSI_4 = 0x15, + ANSI_6 = 0x16, + ANSI_5 = 0x17, + ANSI_Equal = 0x18, + ANSI_9 = 0x19, + ANSI_7 = 0x1A, + ANSI_Minus = 0x1B, + ANSI_8 = 0x1C, + ANSI_0 = 0x1D, + ANSI_RightBracket = 0x1E, + ANSI_O = 0x1F, + ANSI_U = 0x20, + ANSI_LeftBracket = 0x21, + ANSI_I = 0x22, + ANSI_P = 0x23, + ANSI_L = 0x25, + ANSI_J = 0x26, + ANSI_Quote = 0x27, + ANSI_K = 0x28, + ANSI_Semicolon = 0x29, + ANSI_Backslash = 0x2A, + ANSI_Comma = 0x2B, + ANSI_Slash = 0x2C, + ANSI_N = 0x2D, + ANSI_M = 0x2E, + ANSI_Period = 0x2F, + ANSI_Grave = 0x32, + ANSI_KeypadDecimal = 0x41, + ANSI_KeypadMultiply = 0x43, + ANSI_KeypadPlus = 0x45, + ANSI_KeypadClear = 0x47, + ANSI_KeypadDivide = 0x4B, + ANSI_KeypadEnter = 0x4C, + ANSI_KeypadMinus = 0x4E, + ANSI_KeypadEquals = 0x51, + ANSI_Keypad0 = 0x52, + ANSI_Keypad1 = 0x53, + ANSI_Keypad2 = 0x54, + ANSI_Keypad3 = 0x55, + ANSI_Keypad4 = 0x56, + ANSI_Keypad5 = 0x57, + ANSI_Keypad6 = 0x58, + ANSI_Keypad7 = 0x59, + ANSI_Keypad8 = 0x5B, + ANSI_Keypad9 = 0x5C, + Return = 0x24, + Tab = 0x30, + Space = 0x31, + Delete = 0x33, + Escape = 0x35, + Command = 0x37, + Shift = 0x38, + CapsLock = 0x39, + Option = 0x3A, + Control = 0x3B, + RightCommand = 0x36, + RightShift = 0x3C, + RightOption = 0x3D, + RightControl = 0x3E, + Function = 0x3F, + F17 = 0x40, + VolumeUp = 0x48, + VolumeDown = 0x49, + Mute = 0x4A, + F18 = 0x4F, + F19 = 0x50, + F20 = 0x5A, + F5 = 0x60, + F6 = 0x61, + F7 = 0x62, + F3 = 0x63, + F8 = 0x64, + F9 = 0x65, + F11 = 0x67, + F13 = 0x69, + F16 = 0x6A, + F14 = 0x6B, + F10 = 0x6D, + F12 = 0x6F, + F15 = 0x71, + Help = 0x72, + Home = 0x73, + PageUp = 0x74, + ForwardDelete = 0x75, + F4 = 0x76, + End = 0x77, + F2 = 0x78, + PageDown = 0x79, + F1 = 0x7A, + LeftArrow = 0x7B, + RightArrow = 0x7C, + DownArrow = 0x7D, + UpArrow = 0x7E, + JIS_Yen = 0x5D, + JIS_Underscore = 0x5E, + JIS_KeypadComma = 0x5F, + JIS_Eisu = 0x66, + JIS_Kana = 0x68, + ISO_Section = 0x0A, +} + + +/* these messages are valid for all events */ + +@(objc_type=Event, objc_name="type") +Event_type :: proc "c" (self: ^Event) -> EventType { + return msgSend(EventType, self, "type") +} +@(objc_type=Event, objc_name="modifierFlags") +Event_modifierFlags :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "modifierFlags") +} +@(objc_type=Event, objc_name="timestamp") +Event_timestamp :: proc "c" (self: ^Event) -> TimeInterval { + return msgSend(TimeInterval, self, "timestamp") +} +@(objc_type=Event, objc_name="window") +Event_window :: proc "c" (self: ^Event) -> ^Window { + return msgSend(^Window, self, "window") +} +@(objc_type=Event, objc_name="windowNumber") +Event_windowNumber :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "windowNumber") +} + +/* these messages are valid for all mouse down/up/drag events */ + +@(objc_type=Event, objc_name="clickCount") +Event_clickCount :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "clickCount") +} + +// for NSOtherMouse events, but will return valid constants for NSLeftMouse and NSRightMouse +@(objc_type=Event, objc_name="buttonNumber") +Event_buttonNumber :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "buttonNumber") +} + +/* these messages are valid for all mouse down/up/drag and enter/exit events */ +@(objc_type=Event, objc_name="eventNumber") +Event_eventNumber :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "eventNumber") +} + +/* -pressure is valid for all mouse down/up/drag events, and is also valid for NSTabletPoint events on 10.4 or later */ +@(objc_type=Event, objc_name="pressure") +Event_pressure :: proc "c" (self: ^Event) -> f32 { + return msgSend(f32, self, "pressure") +} + +/* -locationInWindow is valid for all mouse-related events */ +@(objc_type=Event, objc_name="locationInWindow") +Event_locationInWindow :: proc "c" (self: ^Event) -> Point { + return msgSend(Point, self, "locationInWindow") +} + + +@(objc_type=Event, objc_name="deltaX") +Event_deltaX :: proc "c" (self: ^Event) -> Float { + return msgSend(Float, self, "deltaX") +} +@(objc_type=Event, objc_name="deltaY") +Event_deltaY :: proc "c" (self: ^Event) -> Float { + return msgSend(Float, self, "deltaY") +} +@(objc_type=Event, objc_name="deltaZ") +Event_deltaZ :: proc "c" (self: ^Event) -> Float { + return msgSend(Float, self, "deltaZ") +} +@(objc_type=Event, objc_name="delta") +Event_delta :: proc "c" (self: ^Event) -> (x, y, z: Float) { + x = self->deltaX() + y = self->deltaY() + z = self->deltaZ() + return +} + +@(objc_type=Event, objc_name="hasPreciseScrollingDeltas") +Event_hasPreciseScrollingDeltas :: proc "c" (self: ^Event) -> BOOL { + return msgSend(BOOL, self, "hasPreciseScrollingDeltas") +} + + +@(objc_type=Event, objc_name="scrollingDeltaX") +Event_scrollingDeltaX :: proc "c" (self: ^Event) -> Float { + return msgSend(Float, self, "scrollingDeltaX") +} +@(objc_type=Event, objc_name="scrollingDeltaY") +Event_scrollingDeltaY :: proc "c" (self: ^Event) -> Float { + return msgSend(Float, self, "scrollingDeltaY") +} +@(objc_type=Event, objc_name="scrollingDelta") +Event_scrollingDelta :: proc "c" (self: ^Event) -> (x, y: Float) { + x = self->scrollingDeltaX() + y = self->scrollingDeltaY() + return +} + + + +@(objc_type=Event, objc_name="momentumPhase") +Event_momentumPhase :: proc "c" (self: ^Event) -> EventPhase { + return msgSend(EventPhase, self, "momentumPhase") +} +@(objc_type=Event, objc_name="phase") +Event_phase :: proc "c" (self: ^Event) -> EventPhase { + return msgSend(EventPhase, self, "phase") +} + + +@(objc_type=Event, objc_name="isDirectionInvertedFromDevice") +Event_isDirectionInvertedFromDevice :: proc "c" (self: ^Event) -> BOOL { + return msgSend(BOOL, self, "isDirectionInvertedFromDevice") +} + +@(objc_type=Event, objc_name="characters") +Event_characters :: proc "c" (self: ^Event) -> ^String { + return msgSend(^String, self, "characters") +} +@(objc_type=Event, objc_name="charactersIgnoringModifiers") +Event_charactersIgnoringModifiers :: proc "c" (self: ^Event) -> ^String { + return msgSend(^String, self, "charactersIgnoringModifiers") +} +@(objc_type=Event, objc_name="isARepeat") +Event_isARepeat :: proc "c" (self: ^Event) -> BOOL { + return msgSend(BOOL, self, "isARepeat") +} + +@(objc_type=Event, objc_name="keyCode") +Event_keyCode :: proc "c" (self: ^Event) -> u16 { + return msgSend(u16, self, "keyCode") +} + +@(objc_type=Event, objc_name="subtype") +Event_subtype :: proc "c" (self: ^Event) -> i16 { + return msgSend(i16, self, "subtype") +} + +@(objc_type=Event, objc_name="data1") +Event_data1 :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "data1") +} +@(objc_type=Event, objc_name="data2") +Event_data2 :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "data2") +} + + +@(objc_type=Event, objc_name="absoluteX") +Event_absoluteX :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "absoluteX") +} +@(objc_type=Event, objc_name="absoluteY") +Event_absoluteY :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "absoluteY") +} +@(objc_type=Event, objc_name="absoluteZ") +Event_absoluteZ :: proc "c" (self: ^Event) -> Integer { + return msgSend(Integer, self, "absoluteZ") +} + +@(objc_type=Event, objc_name="absolute") +Event_absolute :: proc "c" (self: ^Event) -> (x, y, z: Integer) { + x = self->absoluteX() + y = self->absoluteY() + z = self->absoluteZ() + return +} + + +@(objc_type=Event, objc_name="buttonMask") +Event_buttonMask :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "buttonMask") +} + +@(objc_type=Event, objc_name="tilt") +tilt :: proc "c" (self: ^Event) -> Point { + return msgSend(Point, self, "tilt") +} + +@(objc_type=Event, objc_name="tangentialPressure") +Event_tangentialPressure :: proc "c" (self: ^Event) -> f32 { + return msgSend(f32, self, "tangentialPressure") +} + +@(objc_type=Event, objc_name="vendorDefined") +Event_vendorDefined :: proc "c" (self: ^Event) -> id { + return msgSend(id, self, "vendorDefined") +} + + +@(objc_type=Event, objc_name="vendorID") +Event_vendorID :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "vendorID") +} +@(objc_type=Event, objc_name="tabletID") +Event_tabletID :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "tabletID") +} +@(objc_type=Event, objc_name="pointingDeviceID") +Event_pointingDeviceID :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "pointingDeviceID") +} +@(objc_type=Event, objc_name="systemTabletID") +Event_systemTabletID :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "systemTabletID") +} +@(objc_type=Event, objc_name="vendorPointingDeviceType") +Event_vendorPointingDeviceType :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "vendorPointingDeviceType") +} +@(objc_type=Event, objc_name="pointingDeviceSerialNumber") +Event_pointingDeviceSerialNumber :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "pointingDeviceSerialNumber") +} +@(objc_type=Event, objc_name="uniqueID") +Event_uniqueID :: proc "c" (self: ^Event) -> u64 { + return msgSend(u64, self, "uniqueID") +} +@(objc_type=Event, objc_name="capabilityMask") +Event_capabilityMask :: proc "c" (self: ^Event) -> UInteger { + return msgSend(UInteger, self, "capabilityMask") +} +@(objc_type=Event, objc_name="pointingDeviceType") +Event_pointingDeviceType :: proc "c" (self: ^Event) -> PointingDeviceType { + return msgSend(PointingDeviceType, self, "pointingDeviceType") +} +@(objc_type=Event, objc_name="isEnteringProximity") +Event_isEnteringProximity :: proc "c" (self: ^Event) -> BOOL { + return msgSend(BOOL, self, "isEnteringProximity") +} + + +@(objc_type=Event, objc_name="isSwipeTrackingFromScrollEventsEnabled") +Event_isSwipeTrackingFromScrollEventsEnabled :: proc "c" (self: ^Event) -> BOOL { + return msgSend(BOOL, self, "isSwipeTrackingFromScrollEventsEnabled") +} diff --git a/core/sys/darwin/Foundation/NSLock.odin b/core/sys/darwin/Foundation/NSLock.odin new file mode 100644 index 000000000..168380669 --- /dev/null +++ b/core/sys/darwin/Foundation/NSLock.odin @@ -0,0 +1,53 @@ +package objc_Foundation + +Locking :: struct($T: typeid) {using _: Object} + +Locking_lock :: proc "c" (self: ^Locking($T)) { + msgSend(nil, self, "lock") +} +Locking_unlock :: proc "c" (self: ^Locking($T)) { + msgSend(nil, self, "unlock") +} + +@(objc_class="NSCondition") +Condition :: struct {using _: Locking(Condition) } + + +@(objc_type=Condition, objc_name="alloc", objc_is_class_method=true) +Condition_alloc :: proc "c" () -> ^Condition { + return msgSend(^Condition, Condition, "alloc") +} + +@(objc_type=Condition, objc_name="init") +Condition_init :: proc "c" (self: ^Condition) -> ^Condition { + return msgSend(^Condition, self, "init") +} + +@(objc_type=Condition, objc_name="wait") +Condition_wait :: proc "c" (self: ^Condition) { + msgSend(nil, self, "wait") +} + +@(objc_type=Condition, objc_name="waitUntilDate") +Condition_waitUntilDate :: proc "c" (self: ^Condition, limit: ^Date) -> BOOL { + return msgSend(BOOL, self, "waitUntilDate:", limit) +} + +@(objc_type=Condition, objc_name="signal") +Condition_signal :: proc "c" (self: ^Condition) { + msgSend(nil, self, "signal") +} + +@(objc_type=Condition, objc_name="broadcast") +Condition_broadcast :: proc "c" (self: ^Condition) { + msgSend(nil, self, "broadcast") +} + +@(objc_type=Condition, objc_name="lock") +Condition_lock :: proc "c" (self: ^Condition) { + msgSend(nil, self, "lock") +} +@(objc_type=Condition, objc_name="unlock") +Condition_unlock :: proc "c" (self: ^Condition) { + msgSend(nil, self, "unlock") +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSMenu.odin b/core/sys/darwin/Foundation/NSMenu.odin new file mode 100644 index 000000000..79da36601 --- /dev/null +++ b/core/sys/darwin/Foundation/NSMenu.odin @@ -0,0 +1,103 @@ +package objc_Foundation + +import "base:builtin" +import "base:intrinsics" + +KeyEquivalentModifierFlag :: enum UInteger { + CapsLock = 16, // Set if Caps Lock key is pressed. + Shift = 17, // Set if Shift key is pressed. + Control = 18, // Set if Control key is pressed. + Option = 19, // Set if Option or Alternate key is pressed. + Command = 20, // Set if Command key is pressed. + NumericPad = 21, // Set if any key in the numeric keypad is pressed. + Help = 22, // Set if the Help key is pressed. + Function = 23, // Set if any function key is pressed. +} +KeyEquivalentModifierMask :: distinct bit_set[KeyEquivalentModifierFlag; UInteger] + +// Used to retrieve only the device-independent modifier flags, allowing applications to mask off the device-dependent modifier flags, including event coalescing information. +KeyEventModifierFlagDeviceIndependentFlagsMask := transmute(KeyEquivalentModifierMask)_KeyEventModifierFlagDeviceIndependentFlagsMask +@(private) _KeyEventModifierFlagDeviceIndependentFlagsMask := UInteger(0xffff0000) + + +MenuItemCallback :: proc "c" (unused: rawptr, name: SEL, sender: ^Object) + + +@(objc_class="NSMenuItem") +MenuItem :: struct {using _: Object} + +@(objc_type=MenuItem, objc_name="alloc", objc_is_class_method=true) +MenuItem_alloc :: proc "c" () -> ^MenuItem { + return msgSend(^MenuItem, MenuItem, "alloc") +} +@(objc_type=MenuItem, objc_name="registerActionCallback", objc_is_class_method=true) +MenuItem_registerActionCallback :: proc "c" (name: cstring, callback: MenuItemCallback) -> SEL { + s := string(name) + n := len(s) + sel: SEL + if n > 0 && s[n-1] != ':' { + col_name := intrinsics.alloca(n+2, 1) + builtin.copy(col_name[:n], s) + col_name[n] = ':' + col_name[n+1] = 0 + sel = sel_registerName(cstring(col_name)) + } else { + sel = sel_registerName(name) + } + if callback != nil { + class_addMethod(intrinsics.objc_find_class("NSObject"), sel, auto_cast callback, "v@:@") + } + return sel +} + +@(objc_type=MenuItem, objc_name="init") +MenuItem_init :: proc "c" (self: ^MenuItem) -> ^MenuItem { + return msgSend(^MenuItem, self, "init") +} + +@(objc_type=MenuItem, objc_name="setKeyEquivalentModifierMask") +MenuItem_setKeyEquivalentModifierMask :: proc "c" (self: ^MenuItem, modifierMask: KeyEquivalentModifierMask) { + msgSend(nil, self, "setKeyEquivalentModifierMask:", modifierMask) +} + +@(objc_type=MenuItem, objc_name="keyEquivalentModifierMask") +MenuItem_keyEquivalentModifierMask :: proc "c" (self: ^MenuItem) -> KeyEquivalentModifierMask { + return msgSend(KeyEquivalentModifierMask, self, "keyEquivalentModifierMask") +} + +@(objc_type=MenuItem, objc_name="setSubmenu") +MenuItem_setSubmenu :: proc "c" (self: ^MenuItem, submenu: ^Menu) { + msgSend(nil, self, "setSubmenu:", submenu) +} + + + + +@(objc_class="NSMenu") +Menu :: struct {using _: Object} + +@(objc_type=Menu, objc_name="alloc", objc_is_class_method=true) +Menu_alloc :: proc "c" () -> ^Menu { + return msgSend(^Menu, Menu, "alloc") +} + +@(objc_type=Menu, objc_name="init") +Menu_init :: proc "c" (self: ^Menu) -> ^Menu { + return msgSend(^Menu, self, "init") +} + +@(objc_type=Menu, objc_name="initWithTitle") +Menu_initWithTitle :: proc "c" (self: ^Menu, title: ^String) -> ^Menu { + return msgSend(^Menu, self, "initWithTitle:", title) +} + + +@(objc_type=Menu, objc_name="addItem") +Menu_addItem :: proc "c" (self: ^Menu, item: ^MenuItem) { + msgSend(nil, self, "addItem:", item) +} + +@(objc_type=Menu, objc_name="addItemWithTitle") +Menu_addItemWithTitle :: proc "c" (self: ^Menu, title: ^String, selector: SEL, keyEquivalent: ^String) -> ^MenuItem { + return msgSend(^MenuItem, self, "addItemWithTitle:action:keyEquivalent:", title, selector, keyEquivalent) +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSNotification.odin b/core/sys/darwin/Foundation/NSNotification.odin new file mode 100644 index 000000000..f766d0cab --- /dev/null +++ b/core/sys/darwin/Foundation/NSNotification.odin @@ -0,0 +1,60 @@ +package objc_Foundation + +@(objc_class="NSNotification") +Notification :: struct{using _: Object} + + +@(objc_type=Notification, objc_name="alloc", objc_is_class_method=true) +Notification_alloc :: proc "c" () -> ^Notification { + return msgSend(^Notification, Notification, "alloc") +} + +@(objc_type=Notification, objc_name="init") +Notification_init :: proc "c" (self: ^Notification) -> ^Notification { + return msgSend(^Notification, self, "init") +} + +@(objc_type=Notification, objc_name="name") +Notification_name :: proc "c" (self: ^Notification) -> ^String { + return msgSend(^String, self, "name") +} + +@(objc_type=Notification, objc_name="object") +Notification_object :: proc "c" (self: ^Notification) -> ^Object { + return msgSend(^Object, self, "object") +} + +@(objc_type=Notification, objc_name="userInfo") +Notification_userInfo :: proc "c" (self: ^Notification) -> ^Dictionary { + return msgSend(^Dictionary, self, "userInfo") +} + +NotificationName :: ^String + +@(objc_class="NSNotificationCenter") +NotificationCenter :: struct{using _: Object} + + +@(objc_type=NotificationCenter, objc_name="alloc", objc_is_class_method=true) +NotificationCenter_alloc :: proc "c" () -> ^NotificationCenter { + return msgSend(^NotificationCenter, NotificationCenter, "alloc") +} + +@(objc_type=NotificationCenter, objc_name="init") +NotificationCenter_init :: proc "c" (self: ^NotificationCenter) -> ^NotificationCenter { + return msgSend(^NotificationCenter, self, "init") +} + +@(objc_type=NotificationCenter, objc_name="defaultCenter", objc_is_class_method=true) +NotificationCenter_defaultCenter :: proc "c" () -> ^NotificationCenter { + return msgSend(^NotificationCenter, NotificationCenter, "defaultCenter") +} + +@(objc_type=NotificationCenter, objc_name="addObserver") +NotificationCenter_addObserverName :: proc "c" (self: ^NotificationCenter, name: NotificationName, pObj: ^Object, pQueue: rawptr, block: ^Block) -> ^Object { + return msgSend(^Object, self, "addObserverName:object:queue:block:", name, pObj, pQueue, block) +} +@(objc_type=NotificationCenter, objc_name="removeObserver") +NotificationCenter_removeObserver :: proc "c" (self: ^NotificationCenter, pObserver: ^Object) { + msgSend(nil, self, "removeObserver:", pObserver) +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSNumber.odin b/core/sys/darwin/Foundation/NSNumber.odin new file mode 100644 index 000000000..b3124885f --- /dev/null +++ b/core/sys/darwin/Foundation/NSNumber.odin @@ -0,0 +1,154 @@ +package objc_Foundation + +import "core:c" +_ :: c +when ODIN_OS == .Darwin { + #assert(size_of(c.long) == size_of(int)) + #assert(size_of(c.ulong) == size_of(uint)) +} + +@(objc_class="NSValue") +Value :: struct{using _: Copying(Value)} + +@(objc_type=Value, objc_name="alloc", objc_is_class_method=true) +Value_alloc :: proc "c" () -> ^Value { + return msgSend(^Value, Value, "alloc") +} + +@(objc_type=Value, objc_name="init") +Value_init :: proc "c" (self: ^Value) -> ^Value { + return msgSend(^Value, self, "init") +} + +@(objc_type=Value, objc_name="valueWithBytes", objc_is_class_method=true) +Value_valueWithBytes :: proc "c" (value: rawptr, type: cstring) -> ^Value { + return msgSend(^Value, Value, "valueWithBytes:objCType:", value, type) +} + +@(objc_type=Value, objc_name="valueWithPointer", objc_is_class_method=true) +Value_valueWithPointer :: proc "c" (pointer: rawptr) -> ^Value { + return msgSend(^Value, Value, "valueWithPointer:", pointer) +} + +@(objc_type=Value, objc_name="initWithBytes") +Value_initWithBytes :: proc "c" (self: ^Value, value: rawptr, type: cstring) -> ^Value { + return msgSend(^Value, self, "initWithBytes:objCType:", value, type) +} + +@(objc_type=Value, objc_name="initWithCoder") +Value_initWithCoder :: proc "c" (self: ^Value, coder: ^Coder) -> ^Value { + return msgSend(^Value, self, "initWithCoder:", coder) +} + +@(objc_type=Value, objc_name="getValue") +Value_getValue :: proc "c" (self: ^Value, value: rawptr, size: UInteger) { + msgSend(nil, self, "getValue:size:", value, size) +} + + +@(objc_type=Value, objc_name="objCType") +Value_objCType :: proc "c" (self: ^Value) -> cstring { + return msgSend(cstring, self, "objCType") +} + +@(objc_type=Value, objc_name="isEqualToValue") +Value_isEqualToValue :: proc "c" (self, other: ^Value) -> BOOL { + return msgSend(BOOL, self, "isEqualToValue:", other) +} + +@(objc_type=Value, objc_name="pointerValue") +Value_pointerValue :: proc "c" (self: ^Value) -> rawptr { + return msgSend(rawptr, self, "pointerValue") +} + + +@(objc_class="NSNumber") +Number :: struct{using _: Copying(Number), using _: Value} + +@(objc_type=Number, objc_name="alloc", objc_is_class_method=true) +Number_alloc :: proc "c" () -> ^Number { + return msgSend(^Number, Number, "alloc") +} + +@(objc_type=Number, objc_name="init") +Number_init :: proc "c" (self: ^Number) -> ^Number { + return msgSend(^Number, self, "init") +} + +@(objc_type=Number, objc_name="numberWithI8", objc_is_class_method=true) Number_numberWithI8 :: proc "c" (value: i8) -> ^Number { return msgSend(^Number, Number, "numberWithChar:", value) } +@(objc_type=Number, objc_name="numberWithU8", objc_is_class_method=true) Number_numberWithU8 :: proc "c" (value: u8) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedChar:", value) } +@(objc_type=Number, objc_name="numberWithI16", objc_is_class_method=true) Number_numberWithI16 :: proc "c" (value: i16) -> ^Number { return msgSend(^Number, Number, "numberWithShort:", value) } +@(objc_type=Number, objc_name="numberWithU16", objc_is_class_method=true) Number_numberWithU16 :: proc "c" (value: u16) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedShort:", value) } +@(objc_type=Number, objc_name="numberWithI32", objc_is_class_method=true) Number_numberWithI32 :: proc "c" (value: i32) -> ^Number { return msgSend(^Number, Number, "numberWithInt:", value) } +@(objc_type=Number, objc_name="numberWithU32", objc_is_class_method=true) Number_numberWithU32 :: proc "c" (value: u32) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedInt:", value) } +@(objc_type=Number, objc_name="numberWithInt", objc_is_class_method=true) Number_numberWithInt :: proc "c" (value: int) -> ^Number { return msgSend(^Number, Number, "numberWithLong:", value) } +@(objc_type=Number, objc_name="numberWithUint", objc_is_class_method=true) Number_numberWithUint :: proc "c" (value: uint) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLong:", value) } +@(objc_type=Number, objc_name="numberWithU64", objc_is_class_method=true) Number_numberWithU64 :: proc "c" (value: u64) -> ^Number { return msgSend(^Number, Number, "numberWithLongLong:", value) } +@(objc_type=Number, objc_name="numberWithI64", objc_is_class_method=true) Number_numberWithI64 :: proc "c" (value: i64) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLongLong:", value) } +@(objc_type=Number, objc_name="numberWithF32", objc_is_class_method=true) Number_numberWithF32 :: proc "c" (value: f32) -> ^Number { return msgSend(^Number, Number, "numberWithFloat:", value) } +@(objc_type=Number, objc_name="numberWithF64", objc_is_class_method=true) Number_numberWithF64 :: proc "c" (value: f64) -> ^Number { return msgSend(^Number, Number, "numberWithDouble:", value) } +@(objc_type=Number, objc_name="numberWithBool", objc_is_class_method=true) Number_numberWithBool :: proc "c" (value: BOOL) -> ^Number { return msgSend(^Number, Number, "numberWithBool:", value) } + +@(objc_type=Number, objc_name="number", objc_is_class_method=true) +Number_number :: proc{ + Number_numberWithI8, + Number_numberWithU8, + Number_numberWithI16, + Number_numberWithU16, + Number_numberWithI32, + Number_numberWithU32, + Number_numberWithInt, + Number_numberWithUint, + Number_numberWithU64, + Number_numberWithI64, + Number_numberWithF32, + Number_numberWithF64, + Number_numberWithBool, +} + +@(objc_type=Number, objc_name="initWithI8") Number_initWithI8 :: proc "c" (self: ^Number, value: i8) -> ^Number { return msgSend(^Number, self, "initWithChar:", value) } +@(objc_type=Number, objc_name="initWithU8") Number_initWithU8 :: proc "c" (self: ^Number, value: u8) -> ^Number { return msgSend(^Number, self, "initWithUnsignedChar:", value) } +@(objc_type=Number, objc_name="initWithI16") Number_initWithI16 :: proc "c" (self: ^Number, value: i16) -> ^Number { return msgSend(^Number, self, "initWithShort:", value) } +@(objc_type=Number, objc_name="initWithU16") Number_initWithU16 :: proc "c" (self: ^Number, value: u16) -> ^Number { return msgSend(^Number, self, "initWithUnsignedShort:", value) } +@(objc_type=Number, objc_name="initWithI32") Number_initWithI32 :: proc "c" (self: ^Number, value: i32) -> ^Number { return msgSend(^Number, self, "initWithInt:", value) } +@(objc_type=Number, objc_name="initWithU32") Number_initWithU32 :: proc "c" (self: ^Number, value: u32) -> ^Number { return msgSend(^Number, self, "initWithUnsignedInt:", value) } +@(objc_type=Number, objc_name="initWithInt") Number_initWithInt :: proc "c" (self: ^Number, value: int) -> ^Number { return msgSend(^Number, self, "initWithLong:", value) } +@(objc_type=Number, objc_name="initWithUint") Number_initWithUint :: proc "c" (self: ^Number, value: uint) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLong:", value) } +@(objc_type=Number, objc_name="initWithU64") Number_initWithU64 :: proc "c" (self: ^Number, value: u64) -> ^Number { return msgSend(^Number, self, "initWithLongLong:", value) } +@(objc_type=Number, objc_name="initWithI64") Number_initWithI64 :: proc "c" (self: ^Number, value: i64) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLongLong:", value) } +@(objc_type=Number, objc_name="initWithF32") Number_initWithF32 :: proc "c" (self: ^Number, value: f32) -> ^Number { return msgSend(^Number, self, "initWithFloat:", value) } +@(objc_type=Number, objc_name="initWithF64") Number_initWithF64 :: proc "c" (self: ^Number, value: f64) -> ^Number { return msgSend(^Number, self, "initWithDouble:", value) } +@(objc_type=Number, objc_name="initWithBool") Number_initWithBool :: proc "c" (self: ^Number, value: BOOL) -> ^Number { return msgSend(^Number, self, "initWithBool:", value) } + + +@(objc_type=Number, objc_name="i8Value") Number_i8Value :: proc "c" (self: ^Number) -> i8 { return msgSend(i8, self, "charValue") } +@(objc_type=Number, objc_name="u8Value") Number_u8Value :: proc "c" (self: ^Number) -> u8 { return msgSend(u8, self, "unsignedCharValue") } +@(objc_type=Number, objc_name="i16Value") Number_i16Value :: proc "c" (self: ^Number) -> i16 { return msgSend(i16, self, "shortValue") } +@(objc_type=Number, objc_name="u16Value") Number_u16Value :: proc "c" (self: ^Number) -> u16 { return msgSend(u16, self, "unsignedShortValue") } +@(objc_type=Number, objc_name="i32Value") Number_i32Value :: proc "c" (self: ^Number) -> i32 { return msgSend(i32, self, "intValue") } +@(objc_type=Number, objc_name="u32Value") Number_u32Value :: proc "c" (self: ^Number) -> u32 { return msgSend(u32, self, "unsignedIntValue") } +@(objc_type=Number, objc_name="intValue") Number_intValue :: proc "c" (self: ^Number) -> int { return msgSend(int, self, "longValue") } +@(objc_type=Number, objc_name="uintValue") Number_uintValue :: proc "c" (self: ^Number) -> uint { return msgSend(uint, self, "unsignedLongValue") } +@(objc_type=Number, objc_name="u64Value") Number_u64Value :: proc "c" (self: ^Number) -> u64 { return msgSend(u64, self, "longLongValue") } +@(objc_type=Number, objc_name="i64Value") Number_i64Value :: proc "c" (self: ^Number) -> i64 { return msgSend(i64, self, "unsignedLongLongValue") } +@(objc_type=Number, objc_name="f32Value") Number_f32Value :: proc "c" (self: ^Number) -> f32 { return msgSend(f32, self, "floatValue") } +@(objc_type=Number, objc_name="f64Value") Number_f64Value :: proc "c" (self: ^Number) -> f64 { return msgSend(f64, self, "doubleValue") } +@(objc_type=Number, objc_name="boolValue") Number_boolValue :: proc "c" (self: ^Number) -> BOOL { return msgSend(BOOL, self, "boolValue") } +@(objc_type=Number, objc_name="integerValue") Number_integerValue :: proc "c" (self: ^Number) -> Integer { return msgSend(Integer, self, "integerValue") } +@(objc_type=Number, objc_name="uintegerValue") Number_uintegerValue :: proc "c" (self: ^Number) -> UInteger { return msgSend(UInteger, self, "unsignedIntegerValue") } +@(objc_type=Number, objc_name="stringValue") Number_stringValue :: proc "c" (self: ^Number) -> ^String { return msgSend(^String, self, "stringValue") } + +@(objc_type=Number, objc_name="compare") +Number_compare :: proc "c" (self, other: ^Number) -> ComparisonResult { + return msgSend(ComparisonResult, self, "compare:", other) +} + +@(objc_type=Number, objc_name="isEqualToNumber") +Number_isEqualToNumber :: proc "c" (self, other: ^Number) -> BOOL { + return msgSend(BOOL, self, "isEqualToNumber:", other) +} + +@(objc_type=Number, objc_name="descriptionWithLocale") +Number_descriptionWithLocale :: proc "c" (self: ^Number, locale: ^Object) -> ^String { + return msgSend(^String, self, "descriptionWithLocale:", locale) +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSObject.odin b/core/sys/darwin/Foundation/NSObject.odin new file mode 100644 index 000000000..31ece47a1 --- /dev/null +++ b/core/sys/darwin/Foundation/NSObject.odin @@ -0,0 +1,91 @@ +package objc_Foundation + +import "base:intrinsics" + +methodSignatureForSelector :: proc "c" (obj: ^Object, selector: SEL) -> rawptr { + return msgSend(rawptr, obj, "methodSignatureForSelector:", selector) +} + +respondsToSelector :: proc "c" (obj: ^Object, selector: SEL) -> BOOL { + return msgSend(BOOL, obj, "respondsToSelector:", selector) +} + +msgSendSafeCheck :: proc "c" (obj: ^Object, selector: SEL) -> BOOL { + return respondsToSelector(obj, selector) || methodSignatureForSelector(obj, selector) != nil +} + + +@(objc_class="NSObject") +Object :: struct {using _: intrinsics.objc_object} + +@(objc_class="NSObject") +Copying :: struct($T: typeid) {using _: Object} + +alloc :: proc "c" ($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return msgSend(^T, T, "alloc") +} +@(objc_type=Object, objc_name="init") +init :: proc "c" (self: ^$T) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return msgSend(^T, self, "init") +} +@(objc_type=Object, objc_name="copy") +copy :: proc "c" (self: ^Copying($T)) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return msgSend(^T, self, "copy") +} + +new :: proc "c" ($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return init(alloc(T)) +} + +@(objc_type=Object, objc_name="retain") +retain :: proc "c" (self: ^Object) { + _ = msgSend(^Object, self, "retain") +} +@(objc_type=Object, objc_name="release") +release :: proc "c" (self: ^Object) { + msgSend(nil, self, "release") +} +@(objc_type=Object, objc_name="autorelease") +autorelease :: proc "c" (self: ^Object) { + msgSend(nil, self, "autorelease") +} +@(objc_type=Object, objc_name="retainCount") +retainCount :: proc "c" (self: ^Object) -> UInteger { + return msgSend(UInteger, self, "retainCount") +} +@(objc_type=Object, objc_name="class") +class :: proc "c" (self: ^Object) -> Class { + return msgSend(Class, self, "class") +} + +@(objc_type=Object, objc_name="hash") +hash :: proc "c" (self: ^Object) -> UInteger { + return msgSend(UInteger, self, "hash") +} + +@(objc_type=Object, objc_name="isEqual") +isEqual :: proc "c" (self, pObject: ^Object) -> BOOL { + return msgSend(BOOL, self, "isEqual:", pObject) +} + +@(objc_type=Object, objc_name="description") +description :: proc "c" (self: ^Object) -> ^String { + return msgSend(^String, self, "description") +} + +@(objc_type=Object, objc_name="debugDescription") +debugDescription :: proc "c" (self: ^Object) -> ^String { + if msgSendSafeCheck(self, intrinsics.objc_find_selector("debugDescription")) { + return msgSend(^String, self, "debugDescription") + } + return nil +} + +bridgingCast :: proc "c" ($T: typeid, obj: ^Object) where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { + return (T)(obj) +} + + +@(objc_class="NSCoder") +Coder :: struct {using _: Object} +// TODO(bill): Implement all the methods for this massive type
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSOpenPanel.odin b/core/sys/darwin/Foundation/NSOpenPanel.odin new file mode 100644 index 000000000..ac5f9674e --- /dev/null +++ b/core/sys/darwin/Foundation/NSOpenPanel.odin @@ -0,0 +1,31 @@ +package objc_Foundation + +@(objc_class="NSOpenPanel") +OpenPanel :: struct{ using _: SavePanel } + +@(objc_type=OpenPanel, objc_name="openPanel", objc_is_class_method=true) +OpenPanel_openPanel :: proc "c" () -> ^OpenPanel { + return msgSend(^OpenPanel, OpenPanel, "openPanel") +} + +@(objc_type=OpenPanel, objc_name="URLs") +OpenPanel_URLs :: proc "c" (self: ^OpenPanel) -> ^Array { + return msgSend(^Array, self, "URLs") +} + +@(objc_type=OpenPanel, objc_name="setCanChooseFiles") +OpenPanel_setCanChooseFiles :: proc "c" (self: ^OpenPanel, setting: BOOL) { + msgSend(nil, self, "setCanChooseFiles:", setting) +} +@(objc_type=OpenPanel, objc_name="setCanChooseDirectories") +OpenPanel_setCanChooseDirectories :: proc "c" (self: ^OpenPanel, setting: BOOL) { + msgSend(nil, self, "setCanChooseDirectories:", setting) +} +@(objc_type=OpenPanel, objc_name="setResolvesAliases") +OpenPanel_setResolvesAliases :: proc "c" (self: ^OpenPanel, setting: BOOL) { + msgSend(nil, self, "setResolvesAliases:", setting) +} +@(objc_type=OpenPanel, objc_name="setAllowsMultipleSelection") +OpenPanel_setAllowsMultipleSelection :: proc "c" (self: ^OpenPanel, setting: BOOL) { + msgSend(nil, self, "setAllowsMultipleSelection:", setting) +} diff --git a/core/sys/darwin/Foundation/NSPanel.odin b/core/sys/darwin/Foundation/NSPanel.odin new file mode 100644 index 000000000..4bdf08cdb --- /dev/null +++ b/core/sys/darwin/Foundation/NSPanel.odin @@ -0,0 +1,9 @@ +package objc_Foundation + +ModalResponse :: enum UInteger { + Cancel = 0, + OK = 1, +} + +@(objc_class="NSPanel") +Panel :: struct{ using _: Window } diff --git a/core/sys/darwin/Foundation/NSPasteboard.odin b/core/sys/darwin/Foundation/NSPasteboard.odin new file mode 100644 index 000000000..74cf7d172 --- /dev/null +++ b/core/sys/darwin/Foundation/NSPasteboard.odin @@ -0,0 +1,5 @@ +package objc_Foundation + +@(objc_class="NSPasteboard") +Pasteboard :: struct {using _: Object} +// TODO: implement NSPasteboard diff --git a/core/sys/darwin/Foundation/NSRange.odin b/core/sys/darwin/Foundation/NSRange.odin new file mode 100644 index 000000000..dcb100e91 --- /dev/null +++ b/core/sys/darwin/Foundation/NSRange.odin @@ -0,0 +1,22 @@ +package objc_Foundation + +Range :: struct { + location: UInteger, + length: UInteger, +} + +Range_Make :: proc "c" (loc, len: UInteger) -> Range { + return Range{loc, len} +} + +Range_Equal :: proc "c" (a, b: Range) -> BOOL { + return a == b +} + +Range_LocationInRange :: proc "c" (self: Range, loc: UInteger) -> BOOL { + return !((loc < self.location) && ((loc - self.location) < self.length)) +} + +Range_Max :: proc "c" (self: Range) -> UInteger { + return self.location + self.length +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSSavePanel.odin b/core/sys/darwin/Foundation/NSSavePanel.odin new file mode 100644 index 000000000..8e4d7a07b --- /dev/null +++ b/core/sys/darwin/Foundation/NSSavePanel.odin @@ -0,0 +1,9 @@ +package objc_Foundation + +@(objc_class="NSSavePanel") +SavePanel :: struct{ using _: Panel } + +@(objc_type=SavePanel, objc_name="runModal") +SavePanel_runModal :: proc "c" (self: ^SavePanel) -> ModalResponse { + return msgSend(ModalResponse, self, "runModal") +} diff --git a/core/sys/darwin/Foundation/NSScreen.odin b/core/sys/darwin/Foundation/NSScreen.odin new file mode 100644 index 000000000..a8fe44aa5 --- /dev/null +++ b/core/sys/darwin/Foundation/NSScreen.odin @@ -0,0 +1,33 @@ +package objc_Foundation + +@(objc_class="NSScreen") +Screen :: struct {using _: Object} + +@(objc_type=Screen, objc_name="mainScreen") +Screen_mainScreen :: proc "c" () -> ^Screen { + return msgSend(^Screen, Screen, "mainScreen") +} +@(objc_type=Screen, objc_name="deepestScreen") +Screen_deepestScreen :: proc "c" () -> ^Screen { + return msgSend(^Screen, Screen, "deepestScreen") +} +@(objc_type=Screen, objc_name="screens") +Screen_screens :: proc "c" () -> ^Array { + return msgSend(^Array, Screen, "screens") +} +@(objc_type=Screen, objc_name="frame") +Screen_frame :: proc "c" (self: ^Screen) -> Rect { + return msgSend(Rect, self, "frame") +} +@(objc_type=Screen, objc_name="depth") +Screen_depth :: proc "c" (self: ^Screen) -> Depth { + return msgSend(Depth, self, "depth") +} +@(objc_type=Screen, objc_name="visibleFrame") +Screen_visibleFrame :: proc "c" (self: ^Screen) -> Rect { + return msgSend(Rect, self, "visibleFrame") +} +@(objc_type=Screen, objc_name="colorSpace") +Screen_colorSpace :: proc "c" (self: ^Screen) -> ^ColorSpace { + return msgSend(^ColorSpace, self, "colorSpace") +} diff --git a/core/sys/darwin/Foundation/NSSet.odin b/core/sys/darwin/Foundation/NSSet.odin new file mode 100644 index 000000000..7fb8db6c2 --- /dev/null +++ b/core/sys/darwin/Foundation/NSSet.odin @@ -0,0 +1,27 @@ +package objc_Foundation + +@(objc_class="NSSet") +Set :: struct {using _: Copying(Set)} + + +@(objc_type=Set, objc_name="alloc", objc_is_class_method=true) +Set_alloc :: proc "c" () -> ^Set { + return msgSend(^Set, Set, "alloc") +} + +@(objc_type=Set, objc_name="init") +Set_init :: proc "c" (self: ^Set) -> ^Set { + return msgSend(^Set, self, "init") +} + + +@(objc_type=Set, objc_name="initWithObjects") +Set_initWithObjects :: proc "c" (self: ^Set, objects: [^]^Object, count: UInteger) -> ^Set { + return msgSend(^Set, self, "initWithObjects:count:", objects, count) +} + + +@(objc_type=Set, objc_name="initWithCoder") +Set_initWithCoder :: proc "c" (self: ^Set, coder: ^Coder) -> ^Set { + return msgSend(^Set, self, "initWithCoder:", coder) +} diff --git a/core/sys/darwin/Foundation/NSString.odin b/core/sys/darwin/Foundation/NSString.odin new file mode 100644 index 000000000..d3c6c454d --- /dev/null +++ b/core/sys/darwin/Foundation/NSString.odin @@ -0,0 +1,140 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +@(objc_class="NSString") +String :: struct {using _: Copying(String)} + +StringEncoding :: enum UInteger { + ASCII = 1, + NEXTSTEP = 2, + JapaneseEUC = 3, + UTF8 = 4, + ISOLatin1 = 5, + Symbol = 6, + NonLossyASCII = 7, + ShiftJIS = 8, + ISOLatin2 = 9, + Unicode = 10, + WindowsCP1251 = 11, + WindowsCP1252 = 12, + WindowsCP1253 = 13, + WindowsCP1254 = 14, + WindowsCP1250 = 15, + ISO2022JP = 21, + MacOSRoman = 30, + + UTF16 = Unicode, + + UTF16BigEndian = 0x90000100, + UTF16LittleEndian = 0x94000100, + + UTF32 = 0x8c000100, + UTF32BigEndian = 0x98000100, + UTF32LittleEndian = 0x9c000100, +} + +StringCompareOptions :: distinct bit_set[StringCompareOption; UInteger] +StringCompareOption :: enum UInteger { + CaseInsensitive = 0, + LiteralSearch = 1, + BackwardsSearch = 2, + AnchoredSearch = 3, + NumericSearch = 6, + DiacriticInsensitive = 7, + WidthInsensitive = 8, + ForcedOrdering = 9, + RegularExpression = 10, +} + +unichar :: distinct u16 + +@(link_prefix="NS", default_calling_convention="c") +foreign Foundation { + StringFromClass :: proc(cls: Class) -> ^String --- +} + +AT :: MakeConstantString +MakeConstantString :: proc "c" (#const c: cstring) -> ^String { + foreign Foundation { + __CFStringMakeConstantString :: proc "c" (c: cstring) -> ^String --- + } + return __CFStringMakeConstantString(c) +} + + +@(objc_type=String, objc_name="alloc", objc_is_class_method=true) +String_alloc :: proc "c" () -> ^String { + return msgSend(^String, String, "alloc") +} + +@(objc_type=String, objc_name="init") +String_init :: proc "c" (self: ^String) -> ^String { + return msgSend(^String, self, "init") +} + + +@(objc_type=String, objc_name="initWithString") +String_initWithString :: proc "c" (self: ^String, other: ^String) -> ^String { + return msgSend(^String, self, "initWithString:", other) +} + +@(objc_type=String, objc_name="initWithCString") +String_initWithCString :: proc "c" (self: ^String, pString: cstring, encoding: StringEncoding) -> ^String { + return msgSend(^String, self, "initWithCstring:encoding:", pString, encoding) +} + +@(objc_type=String, objc_name="initWithBytesNoCopy") +String_initWithBytesNoCopy :: proc "c" (self: ^String, pBytes: rawptr, length: UInteger, encoding: StringEncoding, freeWhenDone: bool) -> ^String { + return msgSend(^String, self, "initWithBytesNoCopy:length:encoding:freeWhenDone:", pBytes, length, encoding, freeWhenDone) +} + +@(objc_type=String, objc_name="initWithOdinString") +String_initWithOdinString :: proc "c" (self: ^String, str: string) -> ^String { + return String_initWithBytesNoCopy(self, raw_data(str), UInteger(len(str)), .UTF8, false) +} + +@(objc_type=String, objc_name="characterAtIndex") +String_characterAtIndex :: proc "c" (self: ^String, index: UInteger) -> unichar { + return msgSend(unichar, self, "characterAtIndex:", index) +} + +@(objc_type=String, objc_name="length") +String_length :: proc "c" (self: ^String) -> UInteger { + return msgSend(UInteger, self, "length") +} + +@(objc_type=String, objc_name="cstringUsingEncoding") +String_cstringUsingEncoding :: proc "c" (self: ^String, encoding: StringEncoding) -> cstring { + return msgSend(cstring, self, "cStringUsingEncoding:", encoding) +} + +@(objc_type=String, objc_name="UTF8String") +String_UTF8String :: proc "c" (self: ^String) -> cstring { + return msgSend(cstring, self, "UTF8String") +} + +@(objc_type=String, objc_name="odinString") +String_odinString :: proc "c" (self: ^String) -> string { + return string(String_UTF8String(self)) +} + +@(objc_type=String, objc_name="maximumLengthOfBytesUsingEncoding") +String_maximumLengthOfBytesUsingEncoding :: proc "c" (self: ^String, encoding: StringEncoding) -> UInteger { + return msgSend(UInteger, self, "maximumLengthOfBytesUsingEncoding:", encoding) +} + +@(objc_type=String, objc_name="lengthOfBytesUsingEncoding") +String_lengthOfBytesUsingEncoding :: proc "c" (self: ^String, encoding: StringEncoding) -> UInteger { + return msgSend(UInteger, self, "lengthOfBytesUsingEncoding:", encoding) +} + +@(objc_type=String, objc_name="isEqualToString") +String_isEqualToString :: proc "c" (self, other: ^String) -> BOOL { + return msgSend(BOOL, self, "isEqualToString:", other) +} + +@(objc_type=String, objc_name="rangeOfString") +String_rangeOfString :: proc "c" (self, other: ^String, options: StringCompareOptions) -> Range { + return msgSend(Range, self, "rangeOfString:options:", other, options) +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSTypes.odin b/core/sys/darwin/Foundation/NSTypes.odin new file mode 100644 index 000000000..fbd883a8f --- /dev/null +++ b/core/sys/darwin/Foundation/NSTypes.odin @@ -0,0 +1,61 @@ +package objc_Foundation + +import "base:intrinsics" + +@(private) msgSend :: intrinsics.objc_send + +id :: ^intrinsics.objc_object +SEL :: ^intrinsics.objc_selector +Class :: ^intrinsics.objc_class + +TimeInterval :: distinct f64 +Integer :: distinct int +UInteger :: distinct uint + +IntegerMax :: max(Integer) +Integermin :: min(Integer) +UIntegerMax :: max(UInteger) + +BOOL :: bool // TODO(bill): should this be `distinct`? +YES :: true +NO :: false + +OperatingSystemVersion :: struct #packed { + majorVersion: Integer, + minorVersion: Integer, + patchVersion: Integer, +} + +ComparisonResult :: enum Integer { + OrderedAscending = -1, + OrderedSame = 0, + OrderedDescending = 1, +} + +NotFound :: IntegerMax + +Float :: distinct (f32 when size_of(uint) == 4 else f64) + +Point :: struct { + x: Float, + y: Float, +} + +Size :: struct { + width: Float, + height: Float, +} + +when size_of(UInteger) == 8 { + _UINTEGER_ENCODING :: "Q" +} else { + _UINTEGER_ENCODING :: "I" +} + +when size_of(Float) == 8 { + _POINT_ENCODING :: "{CGPoint=dd}" + _SIZE_ENCODING :: "{CGSize=dd}" +} else { + _POINT_ENCODING :: "{NSPoint=ff}" + _SIZE_ENCODING :: "{NSSize=ff}" +}
\ No newline at end of file diff --git a/core/sys/darwin/Foundation/NSURL.odin b/core/sys/darwin/Foundation/NSURL.odin new file mode 100644 index 000000000..9e9081219 --- /dev/null +++ b/core/sys/darwin/Foundation/NSURL.odin @@ -0,0 +1,30 @@ +package objc_Foundation + +@(objc_class="NSURL") +URL :: struct{using _: Copying(URL)} + + +@(objc_type=URL, objc_name="alloc", objc_is_class_method=true) +URL_alloc :: proc "c" () -> ^URL { + return msgSend(^URL, URL, "alloc") +} + +@(objc_type=URL, objc_name="init") +URL_init :: proc "c" (self: ^URL) -> ^URL { + return msgSend(^URL, self, "init") +} + +@(objc_type=URL, objc_name="initWithString") +URL_initWithString :: proc "c" (self: ^URL, value: ^String) -> ^URL { + return msgSend(^URL, self, "initWithString:", value) +} + +@(objc_type=URL, objc_name="initFileURLWithPath") +URL_initFileURLWithPath :: proc "c" (self: ^URL, path: ^String) -> ^URL { + return msgSend(^URL, self, "initFileURLWithPath:", path) +} + +@(objc_type=URL, objc_name="fileSystemRepresentation") +URL_fileSystemRepresentation :: proc "c" (self: ^URL) -> cstring { + return msgSend(cstring, self, "fileSystemRepresentation") +} diff --git a/core/sys/darwin/Foundation/NSUndoManager.odin b/core/sys/darwin/Foundation/NSUndoManager.odin new file mode 100644 index 000000000..16411dcb4 --- /dev/null +++ b/core/sys/darwin/Foundation/NSUndoManager.odin @@ -0,0 +1,5 @@ +package objc_Foundation + +@(objc_class="NSUndoManager") +UndoManager :: struct {using _: Object} +// TODO: implement NSUndoManager diff --git a/core/sys/darwin/Foundation/NSUserActivity.odin b/core/sys/darwin/Foundation/NSUserActivity.odin new file mode 100644 index 000000000..3b2f956ee --- /dev/null +++ b/core/sys/darwin/Foundation/NSUserActivity.odin @@ -0,0 +1,5 @@ +package objc_Foundation + +@(objc_class="NSUserActivity") +UserActivity :: struct {using _: Object} +// TODO: implement NSUserActivity diff --git a/core/sys/darwin/Foundation/NSUserDefaults.odin b/core/sys/darwin/Foundation/NSUserDefaults.odin new file mode 100644 index 000000000..a8a6d7545 --- /dev/null +++ b/core/sys/darwin/Foundation/NSUserDefaults.odin @@ -0,0 +1,14 @@ +package objc_Foundation + +@(objc_class="NSUserDefaults") +UserDefaults :: struct { using _: Object } + +@(objc_type=UserDefaults, objc_name="standardUserDefaults", objc_is_class_method=true) +UserDefaults_standardUserDefaults :: proc "c" () -> ^UserDefaults { + return msgSend(^UserDefaults, UserDefaults, "standardUserDefaults") +} + +@(objc_type=UserDefaults, objc_name="setBoolForKey") +UserDefaults_setBoolForKey :: proc "c" (self: ^UserDefaults, value: BOOL, name: ^String) { + msgSend(nil, self, "setBool:forKey:", value, name) +} diff --git a/core/sys/darwin/Foundation/NSWindow.odin b/core/sys/darwin/Foundation/NSWindow.odin new file mode 100644 index 000000000..7159a7c3a --- /dev/null +++ b/core/sys/darwin/Foundation/NSWindow.odin @@ -0,0 +1,714 @@ +package objc_Foundation + +import "core:strings" +import "base:runtime" +import "base:intrinsics" + +Rect :: struct { + using origin: Point, + using size: Size, +} + +Depth :: enum UInteger { + onehundredtwentyeightBitRGB = 544, + sixtyfourBitRGB = 528, + twentyfourBitRGB = 520, +} + +when size_of(Float) == 8 { + _RECT_ENCODING :: "{CGRect="+_POINT_ENCODING+_SIZE_ENCODING+"}" +} else { + _RECT_ENCODING :: "{NSRect="+_POINT_ENCODING+_SIZE_ENCODING+"}" +} + +WindowStyleFlag :: enum UInteger { + Titled = 0, + Closable = 1, + Miniaturizable = 2, + Resizable = 3, + TexturedBackground = 8, + UnifiedTitleAndToolbar = 12, + FullScreen = 14, + FullSizeContentView = 15, + UtilityWindow = 4, + DocModalWindow = 6, + NonactivatingPanel = 7, + HUDWindow = 13, +} +WindowStyleMask :: distinct bit_set[WindowStyleFlag; UInteger] +WindowStyleMaskBorderless :: WindowStyleMask{} +WindowStyleMaskTitled :: WindowStyleMask{.Titled} +WindowStyleMaskClosable :: WindowStyleMask{.Closable} +WindowStyleMaskMiniaturizable :: WindowStyleMask{.Miniaturizable} +WindowStyleMaskResizable :: WindowStyleMask{.Resizable} +WindowStyleMaskTexturedBackground :: WindowStyleMask{.TexturedBackground} +WindowStyleMaskUnifiedTitleAndToolbar :: WindowStyleMask{.UnifiedTitleAndToolbar} +WindowStyleMaskFullScreen :: WindowStyleMask{.FullScreen} +WindowStyleMaskFullSizeContentView :: WindowStyleMask{.FullSizeContentView} +WindowStyleMaskUtilityWindow :: WindowStyleMask{.UtilityWindow} +WindowStyleMaskDocModalWindow :: WindowStyleMask{.DocModalWindow} +WindowStyleMaskNonactivatingPanel :: WindowStyleMask{.NonactivatingPanel} +WindowStyleMaskHUDWindow :: WindowStyleMask{.HUDWindow} + +BackingStoreType :: enum UInteger { + Retained = 0, + Nonretained = 1, + Buffered = 2, +} + +WindowDelegateTemplate :: struct { + // Managing Sheets + windowWillPositionSheetUsingRect: proc(window: ^Window, sheet: ^Window, rect: Rect) -> Rect, + windowWillBeginSheet: proc(notification: ^Notification), + windowDidEndSheet: proc(notification: ^Notification), + // Sizing Windows + windowWillResizeToSize: proc(sender: ^Window, frameSize: Size) -> Size, + windowDidResize: proc(notification: ^Notification), + windowWillStartLiveResize: proc(noitifcation: ^Notification), + windowDidEndLiveResize: proc(notification: ^Notification), + // Minimizing Windows + windowWillMiniaturize: proc(notification: ^Notification), + windowDidMiniaturize: proc(notification: ^Notification), + windowDidDeminiaturize: proc(notification: ^Notification), + // Zooming window + windowWillUseStandardFrameDefaultFrame: proc(window: ^Window, newFrame: Rect) -> Rect, + windowShouldZoomToFrame: proc(window: ^Window, newFrame: Rect) -> BOOL, + // Managing Full-Screen Presentation + windowWillUseFullScreenContentSize: proc(window: ^Window, proposedSize: Size) -> Size, + windowWillUseFullScreenPresentationOptions: proc(window: ^Window, proposedOptions: ApplicationPresentationOptions) -> ApplicationPresentationOptions, + windowWillEnterFullScreen: proc(notification: ^Notification), + windowDidEnterFullScreen: proc(notification: ^Notification), + windowWillExitFullScreen: proc(notification: ^Notification), + windowDidExitFullScreen: proc(notification: ^Notification), + // Custom Full-Screen Presentation Animations + customWindowsToEnterFullScreenForWindow: proc(window: ^Window) -> ^Array, + customWindowsToEnterFullScreenForWindowOnScreen: proc(window: ^Window, screen: ^Screen) -> ^Array, + windowStartCustomAnimationToEnterFullScreenWithDuration: proc(window: ^Window, duration: TimeInterval), + windowStartCustomAnimationToEnterFullScreenOnScreenWithDuration: proc(window: ^Window, screen: ^Screen, duration: TimeInterval), + windowDidFailToEnterFullScreen: proc(window: ^Window), + customWindowsToExitFullScreenForWindow: proc(window: ^Window) -> ^Array, + windowStartCustomAnimationToExitFullScreenWithDuration: proc(window: ^Window, duration: TimeInterval), + windowDidFailToExitFullScreen: proc(window: ^Window), + // Moving Windows + windowWillMove: proc(notification: ^Notification), + windowDidMove: proc(notification: ^Notification), + windowDidChangeScreen: proc(notification: ^Notification), + windowDidChangeScreenProfile: proc(notification: ^Notification), + windowDidChangeBackingProperties: proc(notification: ^Notification), + // Closing Windows + windowShouldClose: proc(sender: ^Window) -> BOOL, + windowWillClose: proc(notification: ^Notification), + // Managing Key Status + windowDidBecomeKey: proc(notification: ^Notification), + windowDidResignKey: proc(notification: ^Notification), + // Managing Main Status + windowDidBecomeMain: proc(notification: ^Notification), + windowDidResignMain: proc(notification: ^Notification), + // Managing Field Editors + windowWillReturnFieldEditorToObject: proc(sender: ^Window, client: id) -> id, + // Updating Windows + windowDidUpdate: proc (notification: ^Notification), + // Exposing Windows + windowDidExpose: proc (notification: ^Notification), + // Managing Occlusion State + windowDidChangeOcclusionState: proc(notification: ^Notification), + // Dragging Windows + windowShouldDragDocumentWithEventFromWithPasteboard: proc(window: ^Window, event: ^Event, dragImageLocation: Point, pasteboard: ^Pasteboard) -> BOOL, + // Getting the Undo Manager + windowWillReturnUndoManager: proc(window: ^Window) -> ^UndoManager, + // Managing Titles + windowShouldPopUpDocumentPathMenu: proc(window: ^Window, menu: ^Menu) -> BOOL, + // Managing Restorable State + windowWillEncodeRestorableState: proc(window: ^Window, state: ^Coder), + windowDidEncodeRestorableState: proc(window: ^Window, state: ^Coder), + // Managing Presentation in Version Browsers + windowWillResizeForVersionBrowserWithMaxPreferredSizeMaxAllowedSize: proc(window: ^Window, maxPreferredFrameSize: Size, maxAllowedFrameSize: Size) -> Size, + windowWillEnterVersionBrowser: proc(notification: ^Notification), + windowDidEnterVersionBrowser: proc(notification: ^Notification), + windowWillExitVersionBrowser: proc(notification: ^Notification), + windowDidExitVersionBrowser: proc(notification: ^Notification), +} + + +WindowDelegate :: struct { using _: Object } // This is not the same as NSWindowDelegate +_WindowDelegateInternal :: struct { + using _: WindowDelegateTemplate, + _context: runtime.Context, +} + +window_delegate_register_and_alloc :: proc(template: WindowDelegateTemplate, class_name: string, delegate_context: Maybe(runtime.Context)) -> ^WindowDelegate { + class := objc_allocateClassPair(intrinsics.objc_find_class("NSObject"), strings.clone_to_cstring(class_name, context.temp_allocator), 0); if class == nil { + // Class already registered + return nil + } + if template.windowWillPositionSheetUsingRect != nil { + windowWillPositionSheetUsingRect :: proc "c" (self: id, window: ^Window, sheet: ^Window, rect: Rect) -> Rect { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillPositionSheetUsingRect(window, sheet, rect) + } + class_addMethod(class, intrinsics.objc_find_selector("window:willPositionSheet:usingRect:"), auto_cast windowWillPositionSheetUsingRect, _RECT_ENCODING+"@:@@"+_RECT_ENCODING) + } + if template.windowWillBeginSheet != nil { + windowWillBeginSheet :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillBeginSheet(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillBeginSheet:"), auto_cast windowWillBeginSheet, "v@:@") + } + if template.windowDidEndSheet != nil { + windowDidEndSheet :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidEndSheet(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidEndSheet:"), auto_cast windowDidEndSheet, "v@:@") + } + if template.windowWillResizeToSize != nil { + windowWillResizeToSize :: proc "c" (self: id, sender: ^Window, frameSize: Size) -> Size { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillResizeToSize(sender, frameSize) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillResize:toSize:"), auto_cast windowWillResizeToSize, _SIZE_ENCODING+"@:@"+_SIZE_ENCODING) + } + if template.windowDidResize != nil { + windowDidResize :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidResize(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidResize:"), auto_cast windowDidResize, "v@:@") + } + if template.windowWillStartLiveResize != nil { + windowWillStartLiveResize :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillStartLiveResize(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillStartLiveResize:"), auto_cast windowWillStartLiveResize, "v@:@") + } + if template.windowDidEndLiveResize != nil { + windowDidEndLiveResize :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidEndLiveResize(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidEndLiveResize:"), auto_cast windowDidEndLiveResize, "v@:@") + } + if template.windowWillMiniaturize != nil { + windowWillMiniaturize :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillMiniaturize(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillMiniaturize:"), auto_cast windowWillMiniaturize, "v@:@") + } + if template.windowDidMiniaturize != nil { + windowDidMiniaturize :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidMiniaturize(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidMiniaturize:"), auto_cast windowDidMiniaturize, "v@:@") + } + if template.windowDidDeminiaturize != nil { + windowDidDeminiaturize :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidDeminiaturize(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidDeminiaturize:"), auto_cast windowDidDeminiaturize, "v@:@") + } + if template.windowWillUseStandardFrameDefaultFrame != nil { + windowWillUseStandardFrameDefaultFrame :: proc(self: id, window: ^Window, newFrame: Rect) -> Rect { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillUseStandardFrameDefaultFrame(window, newFrame) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillUseStandardFrame:defaultFrame:"), auto_cast windowWillUseStandardFrameDefaultFrame, _RECT_ENCODING+"@:@"+_RECT_ENCODING) + } + if template.windowShouldZoomToFrame != nil { + windowShouldZoomToFrame :: proc "c" (self: id, window: ^Window, newFrame: Rect) -> BOOL { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowShouldZoomToFrame(window, newFrame) + } + class_addMethod(class, intrinsics.objc_find_selector("windowShouldZoom:toFrame:"), auto_cast windowShouldZoomToFrame, "B@:@"+_RECT_ENCODING) + } + if template.windowWillUseFullScreenContentSize != nil { + windowWillUseFullScreenContentSize :: proc "c" (self: id, window: ^Window, proposedSize: Size) -> Size { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillUseFullScreenContentSize(window, proposedSize) + } + class_addMethod(class, intrinsics.objc_find_selector("window:willUseFullScreenContentSize:"), auto_cast windowWillUseFullScreenContentSize, _SIZE_ENCODING+"@:@"+_SIZE_ENCODING) + } + if template.windowWillUseFullScreenPresentationOptions != nil { + windowWillUseFullScreenPresentationOptions :: proc(self: id, window: ^Window, proposedOptions: ApplicationPresentationOptions) -> ApplicationPresentationOptions { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillUseFullScreenPresentationOptions(window, proposedOptions) + } + class_addMethod(class, intrinsics.objc_find_selector("window:willUseFullScreenPresentationOptions:"), auto_cast windowWillUseFullScreenPresentationOptions, _UINTEGER_ENCODING+"@:@"+_UINTEGER_ENCODING) + } + if template.windowWillEnterFullScreen != nil { + windowWillEnterFullScreen :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillEnterFullScreen(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillEnterFullScreen:"), auto_cast windowWillEnterFullScreen, "v@:@") + } + if template.windowDidEnterFullScreen != nil { + windowDidEnterFullScreen :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidEnterFullScreen(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidEnterFullScreen:"), auto_cast windowDidEnterFullScreen, "v@:@") + } + if template.windowWillExitFullScreen != nil { + windowWillExitFullScreen :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillExitFullScreen(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillExitFullScreen:"), auto_cast windowWillExitFullScreen, "v@:@") + } + if template.windowDidExitFullScreen != nil { + windowDidExitFullScreen :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidExitFullScreen(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidExitFullScreen:"), auto_cast windowDidExitFullScreen, "v@:@") + } + if template.customWindowsToEnterFullScreenForWindow != nil { + customWindowsToEnterFullScreenForWindow :: proc "c" (self: id, window: ^Window) -> ^Array { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.customWindowsToEnterFullScreenForWindow(window) + } + class_addMethod(class, intrinsics.objc_find_selector("customWindowsToEnterFullScreenForWindow:"), auto_cast customWindowsToEnterFullScreenForWindow, "@@:@") + } + if template.customWindowsToEnterFullScreenForWindowOnScreen != nil { + customWindowsToEnterFullScreenForWindowOnScreen :: proc(self: id, window: ^Window, screen: ^Screen) -> ^Array { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.customWindowsToEnterFullScreenForWindowOnScreen(window, screen) + } + class_addMethod(class, intrinsics.objc_find_selector("customWindowsToEnterFullScreenForWindow:onScreen:"), auto_cast customWindowsToEnterFullScreenForWindowOnScreen, "@@:@@") + } + if template.windowStartCustomAnimationToEnterFullScreenWithDuration != nil { + windowStartCustomAnimationToEnterFullScreenWithDuration :: proc "c" (self: id, window: ^Window, duration: TimeInterval) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowStartCustomAnimationToEnterFullScreenWithDuration(window, duration) + } + class_addMethod(class, intrinsics.objc_find_selector("window:startCustomAnimationToEnterFullScreenWithDuration:"), auto_cast windowStartCustomAnimationToEnterFullScreenWithDuration, "v@:@@") + } + if template.windowStartCustomAnimationToEnterFullScreenOnScreenWithDuration != nil { + windowStartCustomAnimationToEnterFullScreenOnScreenWithDuration :: proc(self: id, window: ^Window, screen: ^Screen, duration: TimeInterval) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowStartCustomAnimationToEnterFullScreenOnScreenWithDuration(window, screen, duration) + } + class_addMethod(class, intrinsics.objc_find_selector("window:startCustomAnimationToEnterFullScreenOnScreen:withDuration:"), auto_cast windowStartCustomAnimationToEnterFullScreenOnScreenWithDuration, "v@:@@d") + } + if template.windowDidFailToEnterFullScreen != nil { + windowDidFailToEnterFullScreen :: proc "c" (self: id, window: ^Window) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidFailToEnterFullScreen(window) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidFailToEnterFullScreen:"), auto_cast windowDidFailToEnterFullScreen, "v@:@") + } + if template.customWindowsToExitFullScreenForWindow != nil { + customWindowsToExitFullScreenForWindow :: proc "c" (self: id, window: ^Window) -> ^Array { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.customWindowsToExitFullScreenForWindow(window) + } + class_addMethod(class, intrinsics.objc_find_selector("customWindowsToExitFullScreenForWindow:"), auto_cast customWindowsToExitFullScreenForWindow, "@@:@") + } + if template.windowStartCustomAnimationToExitFullScreenWithDuration != nil { + windowStartCustomAnimationToExitFullScreenWithDuration :: proc "c" (self: id, window: ^Window, duration: TimeInterval) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowStartCustomAnimationToExitFullScreenWithDuration(window, duration) + } + class_addMethod(class, intrinsics.objc_find_selector("window:startCustomAnimationToExitFullScreenWithDuration:"), auto_cast windowStartCustomAnimationToExitFullScreenWithDuration, "v@:@d") + } + if template.windowDidFailToExitFullScreen != nil { + windowDidFailToExitFullScreen :: proc "c" (self: id, window: ^Window) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidFailToExitFullScreen(window) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidFailToExitFullScreen:"), auto_cast windowDidFailToExitFullScreen, "v@:@") + } + if template.windowWillMove != nil { + windowWillMove :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillMove(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillMove:"), auto_cast windowWillMove, "v@:@") + } + if template.windowDidMove != nil { + windowDidMove :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidMove(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidMove:"), auto_cast windowDidMove, "v@:@") + } + if template.windowDidChangeScreen != nil { + windowDidChangeScreen :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidChangeScreen(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidChangeScreen:"), auto_cast windowDidChangeScreen, "v@:@") + } + if template.windowDidChangeScreenProfile != nil { + windowDidChangeScreenProfile :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidChangeScreenProfile(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidChangeScreenProfile:"), auto_cast windowDidChangeScreenProfile, "v@:@") + } + if template.windowDidChangeBackingProperties != nil { + windowDidChangeBackingProperties :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidChangeBackingProperties(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidChangeBackingProperties:"), auto_cast windowDidChangeBackingProperties, "v@:@") + } + if template.windowShouldClose != nil { + windowShouldClose :: proc "c" (self:id, sender: ^Window) -> BOOL { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowShouldClose(sender) + } + class_addMethod(class, intrinsics.objc_find_selector("windowShouldClose:"), auto_cast windowShouldClose, "B@:@") + } + if template.windowWillClose != nil { + windowWillClose :: proc "c" (self:id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillClose(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillClose:"), auto_cast windowWillClose, "v@:@") + } + if template.windowDidBecomeKey != nil { + windowDidBecomeKey :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidBecomeKey(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidBecomeKey:"), auto_cast windowDidBecomeKey, "v@:@") + } + if template.windowDidResignKey != nil { + windowDidResignKey :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidResignKey(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidResignKey:"), auto_cast windowDidResignKey, "v@:@") + } + if template.windowDidBecomeMain != nil { + windowDidBecomeMain :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidBecomeMain(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidBecomeMain:"), auto_cast windowDidBecomeMain, "v@:@") + } + if template.windowDidResignMain != nil { + windowDidResignMain :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidResignMain(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidResignMain:"), auto_cast windowDidResignMain, "v@:@") + } + if template.windowWillReturnFieldEditorToObject != nil { + windowWillReturnFieldEditorToObject :: proc "c" (self:id, sender: ^Window, client: id) -> id { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillReturnFieldEditorToObject(sender, client) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillReturnFieldEditor:toObject:"), auto_cast windowWillReturnFieldEditorToObject, "@@:@@") + } + if template.windowDidUpdate != nil { + windowDidUpdate :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidUpdate(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidUpdate:"), auto_cast windowDidUpdate, "v@:@") + } + if template.windowDidExpose != nil { + windowDidExpose :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidExpose(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidExpose:"), auto_cast windowDidExpose, "v@:@") + } + if template.windowDidChangeOcclusionState != nil { + windowDidChangeOcclusionState :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidChangeOcclusionState(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidChangeOcclusionState:"), auto_cast windowDidChangeOcclusionState, "v@:@") + } + if template.windowShouldDragDocumentWithEventFromWithPasteboard != nil { + windowShouldDragDocumentWithEventFromWithPasteboard :: proc "c" (self: id, window: ^Window, event: ^Event, dragImageLocation: Point, pasteboard: ^Pasteboard) -> BOOL { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowShouldDragDocumentWithEventFromWithPasteboard(window, event, dragImageLocation, pasteboard) + } + class_addMethod(class, intrinsics.objc_find_selector("window:shouldDragDocumentWithEvent:from:withPasteboard:"), auto_cast windowShouldDragDocumentWithEventFromWithPasteboard, "B@:@@"+_POINT_ENCODING+"@") + } + if template.windowWillReturnUndoManager != nil { + windowWillReturnUndoManager :: proc "c" (self: id, window: ^Window) -> ^UndoManager { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillReturnUndoManager(window) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillReturnUndoManager:"), auto_cast windowWillReturnUndoManager, "@@:@") + } + if template.windowShouldPopUpDocumentPathMenu != nil { + windowShouldPopUpDocumentPathMenu :: proc "c" (self: id, window: ^Window, menu: ^Menu) -> BOOL { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowShouldPopUpDocumentPathMenu(window, menu) + } + class_addMethod(class, intrinsics.objc_find_selector("window:shouldPopUpDocumentPathMenu:"), auto_cast windowShouldPopUpDocumentPathMenu, "B@:@@") + } + if template.windowWillEncodeRestorableState != nil { + windowWillEncodeRestorableState :: proc "c" (self: id, window: ^Window, state: ^Coder) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillEncodeRestorableState(window, state) + } + class_addMethod(class, intrinsics.objc_find_selector("window:willEncodeRestorableState:"), auto_cast windowWillEncodeRestorableState, "v@:@@") + } + if template.windowDidEncodeRestorableState != nil { + windowDidEncodeRestorableState :: proc "c" (self: id, window: ^Window, state: ^Coder) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidEncodeRestorableState(window, state) + } + class_addMethod(class, intrinsics.objc_find_selector("window:didDecodeRestorableState:"), auto_cast windowDidEncodeRestorableState, "v@:@@") + } + if template.windowWillResizeForVersionBrowserWithMaxPreferredSizeMaxAllowedSize != nil { + windowWillResizeForVersionBrowserWithMaxPreferredSizeMaxAllowedSize :: proc "c" (self: id, window: ^Window, maxPreferredFrameSize: Size, maxAllowedFrameSize: Size) -> Size { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + return del.windowWillResizeForVersionBrowserWithMaxPreferredSizeMaxAllowedSize(window, maxPreferredFrameSize, maxPreferredFrameSize) + } + class_addMethod(class, intrinsics.objc_find_selector("window:willResizeForVersionBrowserWithMaxPreferredSize:maxAllowedSize:"), auto_cast windowWillResizeForVersionBrowserWithMaxPreferredSizeMaxAllowedSize, _SIZE_ENCODING+"@:@"+_SIZE_ENCODING+_SIZE_ENCODING) + } + if template.windowWillEnterVersionBrowser != nil { + windowWillEnterVersionBrowser :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillEnterVersionBrowser(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillEnterVersionBrowser:"), auto_cast windowWillEnterVersionBrowser, "v@:@") + } + if template.windowDidEnterVersionBrowser != nil { + windowDidEnterVersionBrowser :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidEnterVersionBrowser(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidEnterVersionBrowser:"), auto_cast windowDidEnterVersionBrowser, "v@:@") + } + if template.windowWillExitVersionBrowser != nil { + windowWillExitVersionBrowser :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowWillExitVersionBrowser(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowWillExitVersionBrowser:"), auto_cast windowWillExitVersionBrowser, "v@:@") + } + if template.windowDidExitVersionBrowser != nil { + windowDidExitVersionBrowser :: proc "c" (self: id, notification: ^Notification) { + del := cast(^_WindowDelegateInternal)object_getIndexedIvars(self) + context = del._context + del.windowDidExitVersionBrowser(notification) + } + class_addMethod(class, intrinsics.objc_find_selector("windowDidExitVersionBrowser:"), auto_cast windowDidExitVersionBrowser, "v@:@") + } + + objc_registerClassPair(class) + del := class_createInstance(class, size_of(_WindowDelegateInternal)) + del_internal := cast(^_WindowDelegateInternal)object_getIndexedIvars(del) + del_internal^ = { + template, + delegate_context.(runtime.Context) or_else runtime.default_context(), + } + + return cast(^WindowDelegate)del +} + +@(objc_class="CALayer") +Layer :: struct { using _: Object } + +@(objc_type=Layer, objc_name="contentsScale") +Layer_contentsScale :: proc "c" (self: ^Layer) -> Float { + return msgSend(Float, self, "contentsScale") +} +@(objc_type=Layer, objc_name="setContentsScale") +Layer_setContentsScale :: proc "c" (self: ^Layer, scale: Float) { + msgSend(nil, self, "setContentsScale:", scale) +} +@(objc_type=Layer, objc_name="frame") +Layer_frame :: proc "c" (self: ^Layer) -> Rect { + return msgSend(Rect, self, "frame") +} +@(objc_type=Layer, objc_name="addSublayer") +Layer_addSublayer :: proc "c" (self: ^Layer, layer: ^Layer) { + msgSend(nil, self, "addSublayer:", layer) +} + +@(objc_class="NSResponder") +Responder :: struct {using _: Object} + +@(objc_class="NSView") +View :: struct {using _: Responder} + + +@(objc_type=View, objc_name="initWithFrame") +View_initWithFrame :: proc "c" (self: ^View, frame: Rect) -> ^View { + return msgSend(^View, self, "initWithFrame:", frame) +} +@(objc_type=View, objc_name="bounds") +View_bounds :: proc "c" (self: ^View) -> Rect { + return msgSend(Rect, self, "bounds") +} +@(objc_type=View, objc_name="layer") +View_layer :: proc "c" (self: ^View) -> ^Layer { + return msgSend(^Layer, self, "layer") +} +@(objc_type=View, objc_name="setLayer") +View_setLayer :: proc "c" (self: ^View, layer: ^Layer) { + msgSend(nil, self, "setLayer:", layer) +} +@(objc_type=View, objc_name="wantsLayer") +View_wantsLayer :: proc "c" (self: ^View) -> BOOL { + return msgSend(BOOL, self, "wantsLayer") +} +@(objc_type=View, objc_name="setWantsLayer") +View_setWantsLayer :: proc "c" (self: ^View, wantsLayer: BOOL) { + msgSend(nil, self, "setWantsLayer:", wantsLayer) +} +@(objc_type=View, objc_name="convertPointFromView") +View_convertPointFromView :: proc "c" (self: ^View, point: Point, view: ^View) -> Point { + return msgSend(Point, self, "convertPoint:fromView:", point, view) +} + +@(objc_class="NSWindow") +Window :: struct {using _: Responder} + +@(objc_type=Window, objc_name="alloc", objc_is_class_method=true) +Window_alloc :: proc "c" () -> ^Window { + return msgSend(^Window, Window, "alloc") +} + +@(objc_type=Window, objc_name="initWithContentRect") +Window_initWithContentRect :: proc (self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: BOOL) -> ^Window { + self := self + // HACK: due to a compiler bug, the generated calling code does not + // currently work for this message. Has to do with passing a struct along + // with other parameters, so we don't send the rect here. + // Omiting the rect argument here actually works, because of how the C + // calling conventions are defined. + self = msgSend(^Window, self, "initWithContentRect:styleMask:backing:defer:", styleMask, backing, doDefer) + + // apply the contentRect now, since we did not pass it to the init call + msgSend(nil, self, "setContentSize:", contentRect.size) + msgSend(nil, self, "setFrameOrigin:", contentRect.origin) + return self +} +@(objc_type=Window, objc_name="contentView") +Window_contentView :: proc "c" (self: ^Window) -> ^View { + return msgSend(^View, self, "contentView") +} +@(objc_type=Window, objc_name="setContentView") +Window_setContentView :: proc "c" (self: ^Window, content_view: ^View) { + msgSend(nil, self, "setContentView:", content_view) +} +@(objc_type=Window, objc_name="contentLayoutRect") +Window_contentLayoutRect :: proc "c" (self: ^Window) -> Rect { + return msgSend(Rect, self, "contentLayoutRect") +} +@(objc_type=Window, objc_name="frame") +Window_frame :: proc "c" (self: ^Window) -> Rect { + return msgSend(Rect, self, "frame") +} +@(objc_type=Window, objc_name="setFrame") +Window_setFrame :: proc "c" (self: ^Window, frame: Rect) { + msgSend(nil, self, "setFrame:", frame) +} +@(objc_type=Window, objc_name="opaque") +Window_opaque :: proc "c" (self: ^Window) -> BOOL { + return msgSend(BOOL, self, "opaque") +} +@(objc_type=Window, objc_name="setOpaque") +Window_setOpaque :: proc "c" (self: ^Window, ok: BOOL) { + msgSend(nil, self, "setOpaque:", ok) +} +@(objc_type=Window, objc_name="backgroundColor") +Window_backgroundColor :: proc "c" (self: ^Window) -> ^Color { + return msgSend(^Color, self, "backgroundColor") +} +@(objc_type=Window, objc_name="setBackgroundColor") +Window_setBackgroundColor :: proc "c" (self: ^Window, color: ^Color) { + msgSend(nil, self, "setBackgroundColor:", color) +} +@(objc_type=Window, objc_name="makeKeyAndOrderFront") +Window_makeKeyAndOrderFront :: proc "c" (self: ^Window, key: ^Object) { + msgSend(nil, self, "makeKeyAndOrderFront:", key) +} +@(objc_type=Window, objc_name="setTitle") +Window_setTitle :: proc "c" (self: ^Window, title: ^String) { + msgSend(nil, self, "setTitle:", title) +} +@(objc_type=Window, objc_name="setTitlebarAppearsTransparent") +Window_setTitlebarAppearsTransparent :: proc "c" (self: ^Window, ok: BOOL) { + msgSend(nil, self, "setTitlebarAppearsTransparent:", ok) +} +@(objc_type=Window, objc_name="setMovable") +Window_setMovable :: proc "c" (self: ^Window, ok: BOOL) { + msgSend(nil, self, "setMovable:", ok) +} +@(objc_type=Window, objc_name="setMovableByWindowBackground") +Window_setMovableByWindowBackground :: proc "c" (self: ^Window, ok: BOOL) { + msgSend(nil, self, "setMovableByWindowBackground:", ok) +} +@(objc_type=Window, objc_name="setStyleMask") +Window_setStyleMask :: proc "c" (self: ^Window, style_mask: WindowStyleMask) { + msgSend(nil, self, "setStyleMask:", style_mask) +} +@(objc_type=Window, objc_name="close") +Window_close :: proc "c" (self: ^Window) { + msgSend(nil, self, "close") +} +@(objc_type=Window, objc_name="setDelegate") +Window_setDelegate :: proc "c" (self: ^Window, delegate: ^WindowDelegate) { + msgSend(nil, self, "setDelegate:", delegate) +} +@(objc_type=Window, objc_name="backingScaleFactor") +Window_backingScaleFactor :: proc "c" (self: ^Window) -> Float { + return msgSend(Float, self, "backingScaleFactor") +} diff --git a/core/sys/darwin/Foundation/objc.odin b/core/sys/darwin/Foundation/objc.odin new file mode 100644 index 000000000..673996cbe --- /dev/null +++ b/core/sys/darwin/Foundation/objc.odin @@ -0,0 +1,81 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" +// NOTE: Most of our bindings are reliant on Cocoa (everything under appkit) so just unconditionally import it +@(require) foreign import "system:Cocoa.framework" + +import "base:intrinsics" +import "core:c" + +IMP :: proc "c" (object: id, sel: SEL, #c_vararg args: ..any) -> id + +foreign Foundation { + objc_lookUpClass :: proc "c" (name: cstring) -> Class --- + sel_registerName :: proc "c" (name: cstring) -> SEL --- + objc_allocateClassPair :: proc "c" (superclass : Class, name : cstring, extraBytes : c.size_t) -> Class --- + objc_registerClassPair :: proc "c" (cls : Class) --- + + class_addMethod :: proc "c" (cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL --- + class_getInstanceMethod :: proc "c" (cls: Class, name: SEL) -> Method --- + class_createInstance :: proc "c" (cls: Class, extraBytes: c.size_t) -> id --- + + method_setImplementation :: proc "c" (method: Method, imp: IMP) --- + object_getIndexedIvars :: proc(obj: id) -> rawptr --- +} + + +@(objc_class="NSZone") +Zone :: struct {using _: Object} + +@(link_prefix="NS") +foreign Foundation { + AllocateObject :: proc "c" (aClass: Class, extraBytes: UInteger, zone: ^Zone) -> id --- + DeallocateObject :: proc "c" (object: id) --- +} + +Method :: ^objc_method +objc_method :: struct { + method_name: SEL, + method_types: cstring, + method_imp: IMP, +} +objc_method_list :: struct {} + +objc_ivar :: struct {} +objc_ivar_list :: struct {} + +objc_cache :: struct { + mask: u32, + occupied: u32, + buckets: [1]Method, +} + +objc_protocol_list :: struct { + next: ^objc_protocol_list, + count: c.int, + list: [1]^Protocol, +} + +@(objc_class="Protocol") +Protocol :: struct{using _: intrinsics.objc_object} + +objc_object_internals :: struct { + isa: ^objc_class_internals, +} + + +objc_class_internals :: struct { + isa: Class, + super_class: Class, + name: cstring, + version: c.long, + info: c.long, + instance_size: c.long, + ivars: ^objc_ivar_list, + + methodLists: ^^objc_method_list, + + cache: rawptr, + protocols: rawptr, + +} |