Created
June 10, 2019 15:26
-
-
Save sbarisic/86a7702522983615640b4f84ebfbcede to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <jni.h> | |
#include <ui.h> | |
#pragma comment(lib, "libui.lib") | |
#define DEF_ARGS JNIEnv* Env, jobject This | |
#define CLASS_FUNC(Name) Java_com_sbarisic_LibUI ## _ ## Name | |
#define JNI_FUNC(RetType, Name) JNIEXPORT RetType JNICALL CLASS_FUNC(Name) | |
#define CREATE_POINTER(Ptr) Env->NewDirectByteBuffer((void*)Ptr, 0) | |
#define FETCH_POINTER(Buffer) Env->GetDirectBufferAddress(Buffer) | |
#define SET_FIELD(Name, Sig, Val) Env->SetObjectField(This, Env->GetFieldID(Env->GetObjectClass(This), Name, Sig), Val) | |
#define SET_POINTER(Name, Ptr) SET_FIELD(Name, "Ljava/nio/ByteBuffer;", CREATE_POINTER(Ptr)) | |
#define GET_FIELD(Name, Sig) Env->GetObjectField(This, Env->GetFieldID(Env->GetObjectClass(This), Name, Sig)) | |
#define GET_POINTER(Name) FETCH_POINTER(GET_FIELD(Name, "Ljava/nio/ByteBuffer;")) | |
typedef struct { | |
public: | |
uiInitOptions Opt; | |
} LibUIState; | |
typedef struct { | |
JNIEnv* Env; | |
jobject Func; | |
jmethodID MethodID; | |
} JavaDelegate; | |
int OnShouldQuit(void* Data) { | |
uiQuit(); | |
return 1; | |
} | |
int OnClosing(uiWindow* W, void* Data) { | |
return OnShouldQuit(Data); | |
} | |
JavaDelegate* CreateDelegate(JNIEnv* Env, jobject Obj, const char* Name, const char* Sig) { | |
Obj = Env->NewGlobalRef(Obj); | |
JavaDelegate* Delegate = (JavaDelegate*)malloc(sizeof(JavaDelegate)); | |
Delegate->Func = Obj; | |
Delegate->MethodID = Env->GetMethodID(Env->GetObjectClass(Obj), Name, Sig); | |
Delegate->Env = Env; | |
return Delegate; | |
} | |
void DestroyDelegate(JavaDelegate* Delegate) { | |
Delegate->Env->DeleteGlobalRef(Delegate->Func); | |
memset(Delegate, 0, sizeof(JavaDelegate)); | |
free(Delegate); | |
} | |
void InvokeVoidDelegate(JavaDelegate* Delegate) { | |
Delegate->Env->CallVoidMethod(Delegate->Func, Delegate->MethodID); | |
} | |
void InvokePointerDelegate(JavaDelegate* Delegate, void* Ptr) { | |
JNIEnv* Env = Delegate->Env; | |
Env->CallVoidMethod(Delegate->Func, Delegate->MethodID, CREATE_POINTER(Ptr)); | |
} | |
extern "C" { | |
JNI_FUNC(void, Init)(DEF_ARGS) { | |
LibUIState* State = (LibUIState*)malloc(sizeof(LibUIState)); | |
memset(State, 0, sizeof(LibUIState)); | |
if (uiInit(&State->Opt) != NULL) | |
abort(); | |
SET_POINTER("StatePtr", State); | |
} | |
JNI_FUNC(void, RunMain)(DEF_ARGS) { | |
uiMain(); | |
} | |
JNI_FUNC(jobject, NewWindow)(DEF_ARGS, jstring Title, jint Width, jint Height, jboolean HasMenuBar) { | |
uiMenu* wndMenu = uiNewMenu("File"); | |
//item = uiMenuAppendItem(menu, "Save"); | |
//uiMenuItemOnClicked(item, saveClicked, NULL); | |
uiMenuAppendQuitItem(wndMenu); | |
uiOnShouldQuit(OnShouldQuit, NULL); | |
const char* TitleStr = Env->GetStringUTFChars(Title, NULL); | |
uiWindow* W = uiNewWindow(TitleStr, Width, Height, HasMenuBar ? 1 : 0); | |
uiWindowOnClosing(W, OnClosing, NULL); | |
return CREATE_POINTER(W); | |
} | |
JNI_FUNC(jobject, NewMultilineEntry)(DEF_ARGS) { | |
return CREATE_POINTER(uiNewMultilineEntry()); | |
} | |
JNI_FUNC(jobject, NewButton)(DEF_ARGS, jstring Text) { | |
const char* TextStr = Env->GetStringUTFChars(Text, NULL); | |
return CREATE_POINTER(uiNewButton(TextStr)); | |
} | |
JNI_FUNC(jobject, NewVerticalBox)(DEF_ARGS) { | |
uiBox* Box = uiNewVerticalBox(); | |
return CREATE_POINTER(Box); | |
} | |
JNI_FUNC(jobject, NewHorizontalBox)(DEF_ARGS) { | |
uiBox* Box = uiNewHorizontalBox(); | |
return CREATE_POINTER(Box); | |
} | |
JNI_FUNC(jobject, NewEntry)(DEF_ARGS) { | |
return CREATE_POINTER(uiNewEntry()); | |
} | |
JNI_FUNC(jobject, NewTab)(DEF_ARGS) { | |
return CREATE_POINTER(uiNewTab()); | |
} | |
JNI_FUNC(void, MultilineEntrySetReadOnly)(DEF_ARGS, jobject Entry, jboolean ReadOnly) { | |
uiMultilineEntrySetReadOnly((uiMultilineEntry*)FETCH_POINTER(Entry), ReadOnly ? 1 : 0); | |
} | |
JNI_FUNC(void, BoxAppend)(DEF_ARGS, jobject Box, jobject Child, jboolean Stretchy) { | |
uiBox* BoxPtr = (uiBox*)FETCH_POINTER(Box); | |
uiControl* ChildPtr = uiControl(FETCH_POINTER(Child)); | |
uiBoxAppend(BoxPtr, ChildPtr, Stretchy ? 1 : 0); | |
} | |
JNI_FUNC(void, ControlShow)(DEF_ARGS, jobject Ctrl) { | |
uiControlShow(uiControl(FETCH_POINTER(Ctrl))); | |
} | |
JNI_FUNC(void, WindowSetChild)(DEF_ARGS, jobject Window, jobject Child) { | |
uiWindowSetChild((uiWindow*)FETCH_POINTER(Window), uiControl(FETCH_POINTER(Child))); | |
} | |
JNI_FUNC(void, WindowSetMargined)(DEF_ARGS, jobject Window, jboolean Margined) { | |
uiWindowSetMargined((uiWindow*)FETCH_POINTER(Window), Margined ? 1 : 0); | |
} | |
JNI_FUNC(void, TabAppend)(DEF_ARGS, jobject Tab, jstring Name, jobject Ctrl) { | |
const char* NamePtr = Env->GetStringUTFChars(Name, NULL); | |
uiTabAppend((uiTab*)FETCH_POINTER(Tab), NamePtr, (uiControl*)FETCH_POINTER(Ctrl)); | |
} | |
JNI_FUNC(void, BoxSetPadded)(DEF_ARGS, jobject Box, jboolean Padded) { | |
uiBoxSetPadded((uiBox*)FETCH_POINTER(Box), Padded ? 1 : 0); | |
} | |
void OnMultilineEntryChanged(uiMultilineEntry* Entry, void* Data) { | |
InvokePointerDelegate((JavaDelegate*)Data, (void*)Entry); | |
} | |
JNI_FUNC(void, MultilineEntryOnChanged)(DEF_ARGS, jobject Entry, jobject Func) { | |
uiMultilineEntryOnChanged((uiMultilineEntry*)FETCH_POINTER(Entry), OnMultilineEntryChanged, CreateDelegate(Env, Func, "Func", "(Ljava/nio/ByteBuffer;)V")); | |
} | |
JNI_FUNC(jstring, MultilineEntryText)(DEF_ARGS, jobject Entry) { | |
return Env->NewStringUTF(uiMultilineEntryText((uiMultilineEntry*)FETCH_POINTER(Entry))); | |
} | |
JNI_FUNC(void, MultilineEntrySetText)(DEF_ARGS, jobject Entry, jstring Text) { | |
const char* TextPtr = Env->GetStringUTFChars(Text, NULL); | |
uiMultilineEntrySetText((uiMultilineEntry*)FETCH_POINTER(Entry), TextPtr); | |
} | |
void OnButtonClicked(uiButton* Button, void* Data) { | |
InvokePointerDelegate((JavaDelegate*)Data, (void*)Data); | |
} | |
JNI_FUNC(void, ButtonOnClicked)(DEF_ARGS, jobject Button, jobject Func) { | |
uiButtonOnClicked((uiButton*)FETCH_POINTER(Button), OnButtonClicked, CreateDelegate(Env, Func, "Func", "(Ljava/nio/ByteBuffer;)V")); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment