From d8bee2e32cec2134ae1a9c07091d0f7c88347246 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 16 Jul 2021 08:29:30 +1000 Subject: [PATCH] Split up mac window implementations too --- src/ClassiCube.vcxproj | 1 + src/ClassiCube.vcxproj.filters | 3 + src/{Window.c => Window_Carbon.c} | 101 +++++++----------- src/_WindowBase.h | 21 +--- src/interop_cocoa.m | 164 +++++++++++++++++++++++------- 5 files changed, 175 insertions(+), 115 deletions(-) rename src/{Window.c => Window_Carbon.c} (91%) diff --git a/src/ClassiCube.vcxproj b/src/ClassiCube.vcxproj index c50137e25..239fed2fc 100644 --- a/src/ClassiCube.vcxproj +++ b/src/ClassiCube.vcxproj @@ -319,6 +319,7 @@ + diff --git a/src/ClassiCube.vcxproj.filters b/src/ClassiCube.vcxproj.filters index 50399b1a5..aeb0c93be 100644 --- a/src/ClassiCube.vcxproj.filters +++ b/src/ClassiCube.vcxproj.filters @@ -581,5 +581,8 @@ Source Files\Platform + + Source Files\Platform + \ No newline at end of file diff --git a/src/Window.c b/src/Window_Carbon.c similarity index 91% rename from src/Window.c rename to src/Window_Carbon.c index 995451751..478a07211 100644 --- a/src/Window.c +++ b/src/Window_Carbon.c @@ -1,17 +1,22 @@ #include "Core.h" -/*########################################################################################################################* -*---------------------------------------------------Carbon/Cocoa window---------------------------------------------------* -*#########################################################################################################################*/ -#if defined CC_BUILD_CARBON || defined CC_BUILD_COCOA +#if defined CC_BUILD_CARBON && !defined CC_BUILD_SDL #include "_WindowBase.h" #include "String.h" #include "Funcs.h" #include "Bitmap.h" #include "Errors.h" #include -CC_OBJC_VISIBLE int windowX, windowY; +#include -CC_OBJC_VISIBLE void Window_CommonInit(void) { +static int windowX, windowY; +static WindowRef win_handle; +static cc_bool win_fullscreen, showingDialog; + +/*########################################################################################################################* +*------------------------------------------------=---Shared with Cocoa----------------------------------------------------* +*#########################################################################################################################*/ +/* NOTE: If code here is changed, don't forget to update corresponding code in interop_cocoa.m */ +static void Window_CommonInit(void) { CGDirectDisplayID display = CGMainDisplayID(); CGRect bounds = CGDisplayBounds(display); @@ -29,8 +34,7 @@ static pascal OSErr HandleQuitMessage(const AppleEvent* ev, AppleEvent* reply, l return 0; } -CC_OBJC_VISIBLE void Window_CommonCreate(void) { - WindowInfo.Exists = true; +static void Window_CommonCreate(void) { /* for quit buttons in dock and menubar */ AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(HandleQuitMessage), 0, false); @@ -47,7 +51,7 @@ static const cc_uint8 key_map[8 * 16] = { KEY_F5, KEY_F6, KEY_F7, KEY_F3, KEY_F8, KEY_F9, 0, KEY_F11, 0, KEY_F13, 0, KEY_F14, 0, KEY_F10, 0, KEY_F12, 'U', KEY_F15, KEY_INSERT, KEY_HOME, KEY_PAGEUP, KEY_DELETE, KEY_F4, KEY_END, KEY_F2, KEY_PAGEDOWN, KEY_F1, KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0, }; -CC_OBJC_VISIBLE int MapNativeKey(UInt32 key) { return key < Array_Elems(key_map) ? key_map[key] : 0; } +static int MapNativeKey(UInt32 key) { return key < Array_Elems(key_map) ? key_map[key] : 0; } /* TODO: Check these.. */ /* case 0x37: return KEY_LWIN; */ /* case 0x38: return KEY_LSHIFT; */ @@ -74,10 +78,6 @@ static void Cursor_DoSetVisible(cc_bool visible) { } } -void Window_OpenKeyboard(const struct OpenKeyboardArgs* args) { } -void Window_SetKeyboardText(const cc_string* text) { } -void Window_CloseKeyboard(void) { } - void Window_EnableRawMouse(void) { DefaultEnableRawMouse(); CGAssociateMouseAndMouseCursorPosition(0); @@ -91,28 +91,8 @@ void Window_DisableRawMouse(void) { /*########################################################################################################################* -*------------------------------------------------------Carbon window------------------------------------------------------* +*---------------------------------------------------------General---------------------------------------------------------* *#########################################################################################################################*/ -#if defined CC_BUILD_CARBON -#include - -static WindowRef win_handle; -static cc_bool win_fullscreen, showingDialog; - -/* fullscreen is tied to OpenGL context unfortunately */ -static cc_result GLContext_UnsetFullscreen(void); -static cc_result GLContext_SetFullscreen(void); - -static void RefreshWindowBounds(void) { - Rect r; - if (win_fullscreen) return; - - /* TODO: kWindowContentRgn ??? */ - GetWindowBounds(win_handle, kWindowGlobalPortRgn, &r); - windowX = r.left; WindowInfo.Width = r.right - r.left; - windowY = r.top; WindowInfo.Height = r.bottom - r.top; -} - /* NOTE: All Pasteboard functions are OSX 10.3 or later */ static PasteboardRef Window_GetPasteboard(void) { PasteboardRef pbRef; @@ -174,6 +154,24 @@ void Clipboard_SetText(const cc_string* value) { PasteboardPutItemFlavor(pbRef, 1, FMT_UTF8, cfData, 0); } + +/*########################################################################################################################* +*----------------------------------------------------------Wwindow--------------------------------------------------------* +*#########################################################################################################################*/ +/* fullscreen is tied to OpenGL context unfortunately */ +static cc_result GLContext_UnsetFullscreen(void); +static cc_result GLContext_SetFullscreen(void); + +static void RefreshWindowBounds(void) { + Rect r; + if (win_fullscreen) return; + + /* TODO: kWindowContentRgn ??? */ + GetWindowBounds(win_handle, kWindowGlobalPortRgn, &r); + windowX = r.left; WindowInfo.Width = r.right - r.left; + windowY = r.top; WindowInfo.Height = r.bottom - r.top; +} + static OSStatus Window_ProcessKeyboardEvent(EventRef inEvent) { UInt32 kind, code; int key; @@ -502,6 +500,7 @@ void Window_Create(int width, int height) { /* TODO: Use BringWindowToFront instead.. (look in the file which has RepositionWindow in it) !!!! */ HookEvents(); Window_CommonCreate(); + WindowInfo.Exists = true; WindowInfo.Handle = win_handle; conn = _CGSDefaultConnection(); @@ -652,21 +651,15 @@ void Window_FreeFramebuffer(struct Bitmap* bmp) { CGColorSpaceRelease(colorSpace); } - -/*########################################################################################################################* -*-------------------------------------------------------Cocoa window------------------------------------------------------* -*#########################################################################################################################*/ -#elif defined CC_BUILD_COCOA -/* NOTE: Mostly implemented in interop_cocoa.m */ -#endif -#endif +void Window_OpenKeyboard(const struct OpenKeyboardArgs* args) { } +void Window_SetKeyboardText(const cc_string* text) { } +void Window_CloseKeyboard(void) { } -#ifdef CC_BUILD_GL /*########################################################################################################################* *-------------------------------------------------------AGL OpenGL--------------------------------------------------------* *#########################################################################################################################*/ -#if defined CC_BUILD_CARBON +#if defined CC_BUILD_GL && !defined CC_BUILD_EGL #include static AGLContext ctx_handle; @@ -835,25 +828,5 @@ void GLContext_SetFpsLimit(cc_bool vsync, float minFrameMs) { aglSetInteger(ctx_handle, AGL_SWAP_INTERVAL, &value); } void GLContext_GetApiInfo(cc_string* info) { } - - -/*########################################################################################################################* -*--------------------------------------------------------NSOpenGL---------------------------------------------------------* -*#########################################################################################################################*/ -#elif defined CC_BUILD_COCOA -/* NOTE: Mostly implemented in interop_cocoa.m */ -cc_bool GLContext_TryRestore(void) { return true; } - -void* GLContext_GetAddress(const char* function) { - static const cc_string glPath = String_FromConst("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"); - static void* lib; - void* addr; - - if (!lib) lib = DynamicLib_Load2(&glPath); - addr = DynamicLib_Get2(lib, function); - return GLContext_IsInvalidAddress(addr) ? NULL : addr; -} - -void GLContext_GetApiInfo(cc_string* info) { } #endif #endif diff --git a/src/_WindowBase.h b/src/_WindowBase.h index 3b0c85c4f..907334b8a 100644 --- a/src/_WindowBase.h +++ b/src/_WindowBase.h @@ -8,26 +8,13 @@ struct _DisplayData DisplayInfo; struct _WinData WindowInfo; int Display_ScaleX(int x) { return (int)(x * DisplayInfo.ScaleX); } -int Display_ScaleY(int y) { return (int)(y * DisplayInfo.ScaleY); } - -#if defined CC_BUILD_COCOA -/* Cocoa implements some functions in external interop_cocoa.m file */ -#define CC_MAYBE_OBJC1 extern -#define CC_MAYBE_OBJC2 static -#define CC_OBJC_VISIBLE -#else -/* All other platforms implement in the file including this .h file */ -#define CC_MAYBE_OBJC1 static -#define CC_MAYBE_OBJC2 static -#define CC_OBJC_VISIBLE static -#endif - +int Display_ScaleY(int y) { return (int)(y * DisplayInfo.ScaleY); } static int cursorPrevX, cursorPrevY; static cc_bool cursorVisible = true; /* Gets the position of the cursor in screen or window coordinates. */ -CC_MAYBE_OBJC1 void Cursor_GetRawPos(int* x, int* y); -CC_MAYBE_OBJC2 void Cursor_DoSetVisible(cc_bool visible); +static void Cursor_GetRawPos(int* x, int* y); +static void Cursor_DoSetVisible(cc_bool visible); void Cursor_SetVisible(cc_bool visible) { if (cursorVisible == visible) return; @@ -66,7 +53,7 @@ static void DefaultDisableRawMouse(void) { } /* The actual windowing system specific method to display a message box */ -CC_MAYBE_OBJC1 void ShowDialogCore(const char* title, const char* msg); +static void ShowDialogCore(const char* title, const char* msg); void Window_ShowDialog(const char* title, const char* msg) { /* Ensure cursor is visible while showing message box */ cc_bool visible = cursorVisible; diff --git a/src/interop_cocoa.m b/src/interop_cocoa.m index 520976583..6a3d4d778 100644 --- a/src/interop_cocoa.m +++ b/src/interop_cocoa.m @@ -1,49 +1,96 @@ -#include "Logger.h" +#include "_WindowBase.h" #include "ExtMath.h" -#include "Platform.h" -#include "Window.h" -#include "Input.h" -#include "Event.h" #include "Bitmap.h" #include "String.h" #include +#include -/*########################################################################################################################* -*-------------------------------------------------------Cocoa window------------------------------------------------------* -*#########################################################################################################################*/ +static int windowX, windowY; static NSApplication* appHandle; static NSWindow* winHandle; static NSView* viewHandle; -extern int windowX, windowY; -extern void Window_CommonCreate(void); -extern void Window_CommonInit(void); -extern int MapNativeKey(UInt32 key); -#ifndef kCGBitmapByteOrder32Host -/* Undefined in < 10.4 SDK. No issue since < 10.4 is only Big Endian PowerPC anyways */ -#define kCGBitmapByteOrder32Host 0 -#endif +/*########################################################################################################################* +*---------------------------------------------------Shared with Carbon----------------------------------------------------* +*#########################################################################################################################*/ +/* NOTE: If code here is changed, don't forget to update corresponding code in Window_Carbon.c */ +static void Window_CommonInit(void) { + CGDirectDisplayID display = CGMainDisplayID(); + CGRect bounds = CGDisplayBounds(display); -static void RefreshWindowBounds(void) { - NSRect win, view; - int viewY; - - win = [winHandle frame]; - view = [viewHandle frame]; - - /* For cocoa, the 0,0 origin is the bottom left corner of windows/views/screen. */ - /* To get window's real Y screen position, first need to find Y of top. (win.y + win.height) */ - /* Then just subtract from screen height to make relative to top instead of bottom of the screen. */ - /* Of course this is only half the story, since we're really after Y position of the content. */ - /* To work out top Y of view relative to window, it's just win.height - (view.y + view.height) */ - viewY = (int)win.size.height - ((int)view.origin.y + (int)view.size.height); - windowX = (int)win.origin.x + (int)view.origin.x; - windowY = DisplayInfo.Height - ((int)win.origin.y + (int)win.size.height) + viewY; - - WindowInfo.Width = (int)view.size.width; - WindowInfo.Height = (int)view.size.height; + DisplayInfo.X = (int)bounds.origin.x; + DisplayInfo.Y = (int)bounds.origin.y; + DisplayInfo.Width = (int)bounds.size.width; + DisplayInfo.Height = (int)bounds.size.height; + DisplayInfo.Depth = CGDisplayBitsPerPixel(display); + DisplayInfo.ScaleX = 1; + DisplayInfo.ScaleY = 1; } +static pascal OSErr HandleQuitMessage(const AppleEvent* ev, AppleEvent* reply, long handlerRefcon) { + Window_Close(); + return 0; +} + +static void Window_CommonCreate(void) { + /* for quit buttons in dock and menubar */ + AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, + NewAEEventHandlerUPP(HandleQuitMessage), 0, false); +} + +/* Sourced from https://www.meandmark.com/keycodes.html */ +static const cc_uint8 key_map[8 * 16] = { + 'A', 'S', 'D', 'F', 'H', 'G', 'Z', 'X', 'C', 'V', 0, 'B', 'Q', 'W', 'E', 'R', + 'Y', 'T', '1', '2', '3', '4', '6', '5', KEY_EQUALS, '9', '7', KEY_MINUS, '8', '0', KEY_RBRACKET, 'O', + 'U', KEY_LBRACKET, 'I', 'P', KEY_ENTER, 'L', 'J', KEY_QUOTE, 'K', KEY_SEMICOLON, KEY_BACKSLASH, KEY_COMMA, KEY_SLASH, 'N', 'M', KEY_PERIOD, + KEY_TAB, KEY_SPACE, KEY_TILDE, KEY_BACKSPACE, 0, KEY_ESCAPE, 0, 0, 0, KEY_CAPSLOCK, 0, 0, 0, 0, 0, 0, + 0, KEY_KP_DECIMAL, 0, KEY_KP_MULTIPLY, 0, KEY_KP_PLUS, 0, KEY_NUMLOCK, 0, 0, 0, KEY_KP_DIVIDE, KEY_KP_ENTER, 0, KEY_KP_MINUS, 0, + 0, KEY_KP_ENTER, KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, 0, KEY_KP8, KEY_KP9, 'N', 'M', KEY_PERIOD, + KEY_F5, KEY_F6, KEY_F7, KEY_F3, KEY_F8, KEY_F9, 0, KEY_F11, 0, KEY_F13, 0, KEY_F14, 0, KEY_F10, 0, KEY_F12, + 'U', KEY_F15, KEY_INSERT, KEY_HOME, KEY_PAGEUP, KEY_DELETE, KEY_F4, KEY_END, KEY_F2, KEY_PAGEDOWN, KEY_F1, KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0, +}; +static int MapNativeKey(UInt32 key) { return key < Array_Elems(key_map) ? key_map[key] : 0; } +/* TODO: Check these.. */ +/* case 0x37: return KEY_LWIN; */ +/* case 0x38: return KEY_LSHIFT; */ +/* case 0x3A: return KEY_LALT; */ +/* case 0x3B: return Key_ControlLeft; */ + +/* TODO: Verify these differences from OpenTK */ +/*Backspace = 51, (0x33, KEY_DELETE according to that link)*/ +/*Return = 52, (0x34, ??? according to that link)*/ +/*Menu = 110, (0x6E, ??? according to that link)*/ + +void Cursor_SetPosition(int x, int y) { + CGPoint point; + point.x = x + windowX; + point.y = y + windowY; + CGDisplayMoveCursorToPoint(CGMainDisplayID(), point); +} + +static void Cursor_DoSetVisible(cc_bool visible) { + if (visible) { + CGDisplayShowCursor(CGMainDisplayID()); + } else { + CGDisplayHideCursor(CGMainDisplayID()); + } +} + +void Window_EnableRawMouse(void) { + DefaultEnableRawMouse(); + CGAssociateMouseAndMouseCursorPosition(0); +} + +void Window_UpdateRawMouse(void) { CentreMousePosition(); } +void Window_DisableRawMouse(void) { + CGAssociateMouseAndMouseCursorPosition(1); + DefaultDisableRawMouse(); +} + + +/*########################################################################################################################* +*---------------------------------------------------------General---------------------------------------------------------* +*#########################################################################################################################*/ void Clipboard_GetText(cc_string* value) { NSPasteboard* pasteboard; const char* src; @@ -73,6 +120,34 @@ void Clipboard_SetText(const cc_string* value) { } +/*########################################################################################################################* +*----------------------------------------------------------Wwindow--------------------------------------------------------* +*#########################################################################################################################*/ +#ifndef kCGBitmapByteOrder32Host +/* Undefined in < 10.4 SDK. No issue since < 10.4 is only Big Endian PowerPC anyways */ +#define kCGBitmapByteOrder32Host 0 +#endif + +static void RefreshWindowBounds(void) { + NSRect win, view; + int viewY; + + win = [winHandle frame]; + view = [viewHandle frame]; + + /* For cocoa, the 0,0 origin is the bottom left corner of windows/views/screen. */ + /* To get window's real Y screen position, first need to find Y of top. (win.y + win.height) */ + /* Then just subtract from screen height to make relative to top instead of bottom of the screen. */ + /* Of course this is only half the story, since we're really after Y position of the content. */ + /* To work out top Y of view relative to window, it's just win.height - (view.y + view.height) */ + viewY = (int)win.size.height - ((int)view.origin.y + (int)view.size.height); + windowX = (int)win.origin.x + (int)view.origin.x; + windowY = DisplayInfo.Height - ((int)win.origin.y + (int)win.size.height) + viewY; + + WindowInfo.Width = (int)view.size.width; + WindowInfo.Height = (int)view.size.height; +} + @interface CCWindow : NSWindow { } @end @implementation CCWindow @@ -203,6 +278,8 @@ void Window_Create(int width, int height) { [winHandle setAcceptsMouseMovedEvents:YES]; Window_CommonCreate(); + WindowInfo.Exists = true; + del = [CCWindowDelegate alloc]; [winHandle setDelegate:del]; RefreshWindowBounds(); @@ -466,10 +543,15 @@ void Window_FreeFramebuffer(struct Bitmap* bmp) { Mem_Free(bmp->scan0); } +void Window_OpenKeyboard(const struct OpenKeyboardArgs* args) { } +void Window_SetKeyboardText(const cc_string* text) { } +void Window_CloseKeyboard(void) { } + /*########################################################################################################################* *--------------------------------------------------------NSOpenGL---------------------------------------------------------* *#########################################################################################################################*/ +#if defined CC_BUILD_GL && !defined CC_BUILD_EGL static NSOpenGLContext* ctxHandle; static NSOpenGLPixelFormat* MakePixelFormat(cc_bool fullscreen) { @@ -508,6 +590,7 @@ void GLContext_Update(void) { // TODO: Why does this crash on resizing [ctxHandle update]; } +cc_bool GLContext_TryRestore(void) { return true; } void GLContext_Free(void) { [NSOpenGLContext clearCurrentContext]; @@ -515,6 +598,16 @@ void GLContext_Free(void) { [ctxHandle release]; } +void* GLContext_GetAddress(const char* function) { + static const cc_string glPath = String_FromConst("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"); + static void* lib; + void* addr; + + if (!lib) lib = DynamicLib_Load2(&glPath); + addr = DynamicLib_Get2(lib, function); + return GLContext_IsInvalidAddress(addr) ? NULL : addr; +} + cc_bool GLContext_SwapBuffers(void) { [ctxHandle flushBuffer]; return true; @@ -524,3 +617,6 @@ void GLContext_SetFpsLimit(cc_bool vsync, float minFrameMs) { int value = vsync ? 1 : 0; [ctxHandle setValues:&value forParameter: NSOpenGLCPSwapInterval]; } + +void GLContext_GetApiInfo(cc_string* info) { } +#endif