Split up mac window implementations too

This commit is contained in:
UnknownShadow200 2021-07-16 08:29:30 +10:00
parent df6cc32cdf
commit d8bee2e32c
5 changed files with 175 additions and 115 deletions

View File

@ -319,6 +319,7 @@
<ClCompile Include="Logger.c" />
<ClCompile Include="Window.c" />
<ClCompile Include="Window_Android.c" />
<ClCompile Include="Window_Carbon.c" />
<ClCompile Include="Window_SDL.c" />
<ClCompile Include="Window_Web.c" />
<ClCompile Include="Window_Win.c" />

View File

@ -581,5 +581,8 @@
<ClCompile Include="Window_Win.c">
<Filter>Source Files\Platform</Filter>
</ClCompile>
<ClCompile Include="Window_Carbon.c">
<Filter>Source Files\Platform</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -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 <ApplicationServices/ApplicationServices.h>
CC_OBJC_VISIBLE int windowX, windowY;
#include <Carbon/Carbon.h>
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 <Carbon/Carbon.h>
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 <AGL/agl.h>
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

View File

@ -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;

View File

@ -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 <Cocoa/Cocoa.h>
#include <ApplicationServices/ApplicationServices.h>
/*########################################################################################################################*
*-------------------------------------------------------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