#include "osapp_win.inl"
#include "../osapp.h"
#include "../osapp.inl"
#include <osgui/osgui.h>
#include <core/event.h>
#include <sewer/cassert.h>
#include <sewer/unicode.h>
#if !defined(__WINDOWS__)
#error This file is only for Windows system
#endif
#include <sewer/nowarn.hxx>
#include <Windows.h>
#include <ShlObj.h>
#include <sewer/warn.hxx>
struct _osapp_t
{
HINSTANCE instance;
int nArgs;
LPWSTR *szArgList;
UINT_PTR timer;
void *listener;
bool_t abnormal_termination;
bool_t with_run_loop;
FPtr_app_call func_OnFinishLaunching;
FPtr_app_call func_OnTimerSignal;
FPtr_destroy func_destroy;
FPtr_app_void func_OnExecutionEnd;
};
OSApp i_APP = {0};
OSApp *_osapp_init_imp(
uint32_t argc,
char_t **argv,
void *instance,
void *listener,
const bool_t with_run_loop,
FPtr_app_call func_OnFinishLaunching,
FPtr_app_call func_OnTimerSignal)
{
unref(argc);
unref(argv);
cassert_no_null(instance);
cassert_no_null(listener);
cassert_no_nullf(func_OnFinishLaunching);
cassert(i_APP.instance == NULL);
cassert(i_APP.listener == NULL);
cassert(i_APP.func_OnFinishLaunching == NULL);
cassert(i_APP.func_OnTimerSignal == NULL);
i_APP.instance = (HINSTANCE)instance;
i_APP.szArgList = CommandLineToArgvW(GetCommandLineW(), &i_APP.nArgs);
cassert(i_APP.szArgList != NULL);
i_APP.listener = listener;
i_APP.abnormal_termination = FALSE;
i_APP.with_run_loop = with_run_loop;
i_APP.func_OnFinishLaunching = func_OnFinishLaunching;
i_APP.func_OnTimerSignal = func_OnTimerSignal;
return &i_APP;
}
void *_osapp_init_pool(void)
{
return NULL;
}
void _osapp_release_pool(void *pool)
{
cassert_unref(pool == NULL, pool);
}
void *_osapp_listener_imp(void)
{
return i_APP.listener;
}
static void i_terminate(OSApp *app)
{
cassert_no_null(app);
cassert(app == &i_APP);
if (app->func_OnTimerSignal != NULL)
{
BOOL ok = KillTimer(NULL, app->timer);
cassert_unref(ok != 0, ok);
}
{
HLOCAL ret = LocalFree(app->szArgList);
cassert_unref(ret == NULL, ret);
}
cassert_no_nullf(app->func_destroy);
cassert_no_nullf(app->func_OnExecutionEnd);
if (app->abnormal_termination == FALSE)
{
app->func_destroy(&app->listener);
app->func_OnExecutionEnd();
}
}
void _osapp_terminate_imp(OSApp **app, const bool_t abnormal_termination, FPtr_destroy func_destroy, FPtr_app_void func_OnExecutionEnd)
{
cassert_no_null(app);
cassert_no_null(*app);
cassert(*app == &i_APP);
cassert((*app)->func_destroy == NULL);
cassert((*app)->func_OnExecutionEnd == NULL);
cassert_no_nullf(func_destroy);
cassert_no_nullf(func_OnExecutionEnd);
(*app)->func_destroy = func_destroy;
(*app)->func_OnExecutionEnd = func_OnExecutionEnd;
if (abnormal_termination == TRUE)
ExitProcess(0);
(*app)->abnormal_termination = FALSE;
if ((*app)->with_run_loop == TRUE)
PostQuitMessage(0);
else
i_terminate(*app);
}
uint32_t _osapp_argc_imp(OSApp *app)
{
cassert_no_null(app);
cassert(app == &i_APP);
return (uint32_t)app->nArgs;
}
uint32_t _osapp_argv_imp(OSApp *app, const uint32_t index, char_t *argv, const uint32_t max_size)
{
cassert_no_null(app);
cassert(app == &i_APP);
cassert(index < (uint32_t)app->nArgs);
return unicode_convers(cast_const(app->szArgList[index], char_t), argv, ekUTF16, ekUTF8, max_size);
}
static VOID CALLBACK i_OnTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
cassert(hwnd == NULL);
unref(hwnd);
cassert(uMsg == WM_TIMER);
unref(uMsg);
cassert(idEvent == i_APP.timer);
unref(idEvent);
unref(dwTime);
cassert_no_nullf(i_APP.func_OnTimerSignal);
i_APP.func_OnTimerSignal(i_APP.listener);
}
void _osapp_run(OSApp *app)
{
cassert_no_null(app);
cassert_no_null(app->listener);
cassert_no_nullf(app->func_OnFinishLaunching);
cassert(app->timer == 0);
if (app->func_OnTimerSignal != NULL)
{
app->timer = SetTimer(NULL, 0, 20, i_OnTimer);
cassert(app->timer > 0);
}
app->func_OnFinishLaunching(app->listener);
if (app->with_run_loop == TRUE)
{
osgui_message_loop();
i_terminate(app);
}
}
void _osapp_request_user_attention(OSApp *app)
{
unref(app);
}
void _osapp_cancel_user_attention(OSApp *app)
{
unref(app);
}
void *_osapp_begin_thread(OSApp *app)
{
unref(app);
return NULL;
}
void _osapp_end_thread(OSApp *app, void *data)
{
unref(app);
unref(data);
}
void osapp_open_url(const char_t *url)
{
WCHAR wurl[512];
uint32_t num_bytes = 0;
num_bytes = unicode_convers(url, cast(wurl, char_t), ekUTF8, ekUTF16, sizeof(wurl));
cassert_unref(num_bytes < sizeof(wurl), num_bytes);
ShellExecute(NULL, L"open", wurl, NULL, NULL, SW_RESTORE);
}
void _osapp_set_lang(OSApp *app, const char_t *lang)
{
unref(app);
unref(lang);
}
void _osapp_OnThemeChanged(OSApp *app, Listener *listener)
{
unref(app);
listener_destroy(&listener);
}
void _osapp_menubar(OSApp *app, void *menu, void *window)
{
unref(app);
unref(menu);
unref(window);
}