Implemented uiInit() on macOS. The tests work so far!
This commit is contained in:
parent
74b1e2780d
commit
484989e925
|
@ -5,28 +5,54 @@
|
||||||
|
|
||||||
static int initialized = 0;
|
static int initialized = 0;
|
||||||
|
|
||||||
int uiprivInitCheckParams(void *options, uiInitError *err)
|
#define errAlreadyInitialized "libui already initialized"
|
||||||
|
#define errOptionsMustBeNULL "options parameter to uiInit() must be NULL"
|
||||||
|
|
||||||
|
static const char *commonInitErrors[] = {
|
||||||
|
errAlreadyInitialized,
|
||||||
|
errOptionsMustBeNULL,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int checkInitErrorLengths(uiInitError *err, const char *initErrors[])
|
||||||
|
{
|
||||||
|
const char **p;
|
||||||
|
|
||||||
|
for (p = initErrors; *p != NULL; p++)
|
||||||
|
if (strlen(*p) > 255) {
|
||||||
|
strcpy(err->Message, "[INTERNAL] uiInit() error too long: ");
|
||||||
|
strncat(err->Message, *p, 32);
|
||||||
|
strcat(err->Message, "...");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uiprivInitCheckParams(void *options, uiInitError *err, const char *initErrors[])
|
||||||
{
|
{
|
||||||
if (err == NULL)
|
if (err == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
if (err->Size != sizeof (uiInitError))
|
if (err->Size != sizeof (uiInitError))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!checkInitErrorLengths(err, commonInitErrors))
|
||||||
|
return 0;
|
||||||
|
if (!checkInitErrorLengths(err, initErrors))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (initialized)
|
if (initialized)
|
||||||
return uiprivInitReturnError(err, "xxxxxxxxx");
|
return uiprivInitReturnError(err, errAlreadyInitialized);
|
||||||
|
|
||||||
if (options != NULL)
|
if (options != NULL)
|
||||||
return uiprivInitReturnError(err, "xxxxxxxx");
|
return uiprivInitReturnError(err, errOptionsMustBeNULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uiprivInitReturnError(uiInitError *err, const char *msg)
|
int uiprivInitReturnError(uiInitError *err, const char *msg)
|
||||||
{
|
{
|
||||||
|
// checkInitErrorLengths() above ensures that err->Message[255] will always be '\0'
|
||||||
strncpy(err->Message, msg, 256);
|
strncpy(err->Message, msg, 256);
|
||||||
if (err->Message[255] != '\0')
|
|
||||||
// TODO there should be some check to make sure this doesn't happen
|
|
||||||
err->Message[255] = '\0';
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// 19 april 2019
|
// 19 april 2019
|
||||||
|
|
||||||
// init.c
|
// init.c
|
||||||
extern int uiprivInitCheckParams(void *options, uiInitError *err);
|
extern int uiprivInitCheckParams(void *options, uiInitError *err, const char *initErrors[]);
|
||||||
extern int uiprivInitReturnError(uiInitError *err, const char *msg);
|
extern int uiprivInitReturnError(uiInitError *err, const char *msg);
|
||||||
extern void uiprivMarkInitialized(void);
|
extern void uiprivMarkInitialized(void);
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
// 20 april 2019
|
||||||
|
#import "uipriv_darwin.h"
|
||||||
|
|
||||||
|
@interface uiprivApplication : NSApplication
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation uiprivApplication
|
||||||
|
@end
|
||||||
|
|
||||||
|
static NSApplication *uiprivApp;
|
||||||
|
|
||||||
|
#define errNSAppAlreadyInitialized "NSApp is not of type uiprivApplication; was likely already initialized beforehand"
|
||||||
|
|
||||||
|
static const char *initErrors[] = {
|
||||||
|
errNSAppAlreadyInitialized,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
int uiInit(void *options, uiInitError *err)
|
||||||
|
{
|
||||||
|
if (!uiprivInitCheckParams(options, err, initErrors))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uiprivApp = [uiprivApplication sharedApplication];
|
||||||
|
if (![NSApp isKindOfClass:[uiprivApplication class]])
|
||||||
|
return uiprivInitReturnError(err, errNSAppAlreadyInitialized);
|
||||||
|
|
||||||
|
uiprivMarkInitialized();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiUninit(void)
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
# 23 march 2019
|
||||||
|
|
||||||
|
libui_sources += [
|
||||||
|
'darwin/main.m',
|
||||||
|
]
|
||||||
|
|
||||||
|
libui_deps += [
|
||||||
|
meson.get_compiler('objc').find_library('objc',
|
||||||
|
required: true),
|
||||||
|
dependency('appleframeworks',
|
||||||
|
modules: ['Foundation', 'AppKit'],
|
||||||
|
required: true),
|
||||||
|
]
|
||||||
|
libui_soversion = 'A'
|
||||||
|
# the / is required by some older versions of OS X
|
||||||
|
libui_rpath = '@executable_path/'
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 6 january 2015
|
||||||
|
// note: as of OS X Sierra, the -mmacosx-version-min compiler options governs deprecation warnings; keep these around anyway just in case
|
||||||
|
#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_8
|
||||||
|
#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_8
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <dlfcn.h> // see future.m
|
||||||
|
#import "../ui.h"
|
||||||
|
#import "../ui_darwin.h"
|
||||||
|
#import "../common/uipriv.h"
|
||||||
|
|
||||||
|
#if __has_feature(objc_arc)
|
||||||
|
#error Sorry, libui cannot be compiled with ARC.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO find a better place for this
|
||||||
|
#ifndef NSAppKitVersionNumber10_9
|
||||||
|
#define NSAppKitVersionNumber10_9 1265
|
||||||
|
#endif
|
|
@ -145,7 +145,7 @@ if libui_OS == 'windows'
|
||||||
# subdir('windows')
|
# subdir('windows')
|
||||||
install_headers('ui_windows.h')
|
install_headers('ui_windows.h')
|
||||||
elif libui_OS == 'darwin'
|
elif libui_OS == 'darwin'
|
||||||
# subdir('darwin')
|
subdir('darwin')
|
||||||
install_headers('ui_darwin.h')
|
install_headers('ui_darwin.h')
|
||||||
else
|
else
|
||||||
# subdir('unix')
|
# subdir('unix')
|
||||||
|
|
|
@ -3,11 +3,14 @@
|
||||||
#include "../ui.h"
|
#include "../ui.h"
|
||||||
#include "testing.h"
|
#include "testing.h"
|
||||||
|
|
||||||
#define invalidOptionsError "TODOTODOTODO"
|
// TODO fix up the formatting of testing.c so we can use newlines on the got/want stuff
|
||||||
#define alreadyInitializedError "TODOTODOTODO"
|
|
||||||
|
#define errInvalidOptions "options parameter to uiInit() must be NULL"
|
||||||
|
#define errAlreadyInitialized "libui already initialized"
|
||||||
|
|
||||||
testingTestBefore(Init)
|
testingTestBefore(Init)
|
||||||
{
|
{
|
||||||
|
uiInitError err;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = uiInit(NULL, NULL);
|
ret = uiInit(NULL, NULL);
|
||||||
|
@ -26,8 +29,8 @@ testingTestBefore(Init)
|
||||||
ret = uiInit(&err, &err);
|
ret = uiInit(&err, &err);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
testingTErrorf(t, "uiInit() with non-NULL options succeeded with return value %d; expected failure", err);
|
testingTErrorf(t, "uiInit() with non-NULL options succeeded with return value %d; expected failure", err);
|
||||||
if (strcmp(err.Message, invalidOptionsError) != 0)
|
if (strcmp(err.Message, errInvalidOptions) != 0)
|
||||||
testingTErrorf(t, "uiInit() with non-NULL options returned bad error message: got %s, want %s", err.Message, invalidOptionsError);
|
testingTErrorf(t, "uiInit() with non-NULL options returned bad error message: got %s, want %s", err.Message, errInvalidOptions);
|
||||||
|
|
||||||
memset(&err, 0, sizeof (uiInitError));
|
memset(&err, 0, sizeof (uiInitError));
|
||||||
err.Size = sizeof (uiInitError);
|
err.Size = sizeof (uiInitError);
|
||||||
|
@ -40,8 +43,8 @@ testingTestBefore(Init)
|
||||||
ret = uiInit(NULL, &err);
|
ret = uiInit(NULL, &err);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
testingTErrorf(t, "uiInit() after a previous successful call succeeded with return value %d; expected failure", ret);
|
testingTErrorf(t, "uiInit() after a previous successful call succeeded with return value %d; expected failure", ret);
|
||||||
if (strcmp(err.Message, alreadyInitializedError) != 0)
|
if (strcmp(err.Message, errAlreadyInitialized) != 0)
|
||||||
testingTErrorf(t, "uiInit() after a previous successful call returned bad error message: got %s, want %s", err.Message, alreadyInitializedError);
|
testingTErrorf(t, "uiInit() after a previous successful call returned bad error message: got %s, want %s", err.Message, errAlreadyInitialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
testingTestAfter(Uninit)
|
testingTestAfter(Uninit)
|
||||||
|
|
2
ui.h
2
ui.h
|
@ -13,7 +13,7 @@ extern "C" {
|
||||||
#ifdef uiprivBuildingLibui
|
#ifdef uiprivBuildingLibui
|
||||||
#if defined(_WIN32) && !defined(uiStatic)
|
#if defined(_WIN32) && !defined(uiStatic)
|
||||||
#define uiprivExtern __declspec(dllexport) extern
|
#define uiprivExtern __declspec(dllexport) extern
|
||||||
#elif deffined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
#define uiprivExtern extern
|
#define uiprivExtern extern
|
||||||
#else
|
#else
|
||||||
#define uiprivExtern __attribute__((visibility("default"))) extern
|
#define uiprivExtern __attribute__((visibility("default"))) extern
|
||||||
|
|
Loading…
Reference in New Issue