*/}}

#3 WIP: macOS support via GLFW3

Open
jyrki wants to merge 2 commits from jyrki/glfw3-macos into chengdulittlea/master
16 changed files with 117 additions and 15 deletions
  1. 3 1
      .gitignore
  2. 4 0
      CMakeLists.txt
  3. 6 0
      la_5.h
  4. 1 1
      la_animation.c
  5. 1 1
      la_audio.c
  6. 4 1
      la_data.c
  7. 14 0
      la_interface.h
  8. 13 2
      la_kernel.c
  9. 2 0
      la_resource.c
  10. 2 2
      la_tns.h
  11. 8 1
      la_tns_kernel.c
  12. 2 2
      la_util.c
  13. 13 3
      la_util.h
  14. 33 0
      lagui-config.cmake
  15. 4 1
      resources/la_modelling.c
  16. 7 0
      resources/la_properties.c

+ 3 - 1
.gitignore

@@ -1,4 +1,6 @@
 build/*
 build/*
 .vscode/
 .vscode/
 screenshots/
 screenshots/
-*.udf
+*.udf
+# Qt creator-generated files
+*.user

+ 4 - 0
CMakeLists.txt

@@ -23,6 +23,10 @@ find_package(Freetype REQUIRED)
 find_package(GLEW REQUIRED)
 find_package(GLEW REQUIRED)
 find_package(LuaJIT)
 find_package(LuaJIT)
 find_package(PNG)
 find_package(PNG)
+if (APPLE)
+    find_package(GLFW3 REQUIRED)
+endif()
+set(CMAKE_CXX_STANDARD 17)
 
 
 SET(LAGUI_USE_LUAJIT true CACHE BOOL "Whether to use LuaJIT in LaGUI")
 SET(LAGUI_USE_LUAJIT true CACHE BOOL "Whether to use LuaJIT in LaGUI")
 if(${LuaJIT_FOUND} AND ${LAGUI_USE_LUAJIT})
 if(${LuaJIT_FOUND} AND ${LAGUI_USE_LUAJIT})

+ 6 - 0
la_5.h

@@ -23,6 +23,12 @@
 
 
 #define BYTE uint8_t
 #define BYTE uint8_t
 
 
+#ifdef __APPLE__
+// on macOS require GL libraries as early as possible without C linkage, libc++ requires templates to have C++ linkage
+#include <GL/glew.h>
+#include <GL/gl.h>
+#endif
+
 #ifdef __cplusplus
 #ifdef __cplusplus
     extern "C" {
     extern "C" {
 #endif
 #endif

+ 1 - 1
la_animation.c

@@ -137,7 +137,7 @@ laActionKey* laAnimationInsertKeyFrame(laAction* aa, void* hyper1, laProp* p, in
             if(error) *error=2; return 0;
             if(error) *error=2; return 0;
         }
         }
     }
     }
-    laActionChannel* ac=laAnimationEnsureChannel(aa,hyper1,p); if(!ac || !ac->AP || !ac->AP->For) return;
+    laActionChannel* ac=laAnimationEnsureChannel(aa,hyper1,p); if(!ac || !ac->AP || !ac->AP->For) return 0;
     int frame=LA_ACTION_FRAME(aa);
     int frame=LA_ACTION_FRAME(aa);
     laActionKey* ak=laAnimationEnsureFrame(ac,frame);
     laActionKey* ak=laAnimationEnsureFrame(ac,frame);
     laAnimationStoreKeyValue(ac,ak);
     laAnimationStoreKeyValue(ac,ak);

+ 1 - 1
la_audio.c

@@ -650,5 +650,5 @@ void laInitAudio(){
 }
 }
 
 
 void laAudioDummy(){
 void laAudioDummy(){
-    return 0;
+    return;
 }
 }

+ 4 - 1
la_data.c

@@ -26,6 +26,9 @@ const char* LA_UDF_EXTENSION_STRINGS[]={
     "",
     "",
 };
 };
 
 
+int la_WriteHyperRecords(laUDF *udf);
+int laIterateDB(laDBInst* parent, laPropPack* pp, laDiff* diff, laDBProp* dp);
+
 int la_IsThisProp(laProp *p, char *id){
 int la_IsThisProp(laProp *p, char *id){
     return (!strcmp(p->Identifier, id));
     return (!strcmp(p->Identifier, id));
 }
 }
@@ -1337,7 +1340,7 @@ int laSetIntArraySingle(laPropPack *pp, int index, int n){
     if (p->Base.DetachedPP.LastPs){
     if (p->Base.DetachedPP.LastPs){
         p->Detached[index] = n;
         p->Detached[index] = n;
         laNotifyUsersPP(pp);
         laNotifyUsersPP(pp);
-        return;
+        return 0;
     }
     }
     if (!pp->LastPs->UseInstance) return 0;
     if (!pp->LastPs->UseInstance) return 0;
     if (pp->LastPs->p->PropertyType & LA_PROP_INT){
     if (pp->LastPs->p->PropertyType & LA_PROP_INT){

+ 14 - 0
la_interface.h

@@ -116,6 +116,20 @@
 #define XK_F11 11
 #define XK_F11 11
 #define XK_F12 12
 #define XK_F12 12
 #endif
 #endif
+#ifdef __APPLE__ // TODO
+#define XK_F1  1
+#define XK_F2  2
+#define XK_F3  3
+#define XK_F4  4
+#define XK_F5  5
+#define XK_F6  6
+#define XK_F7  7
+#define XK_F8  8
+#define XK_F9  9
+#define XK_F10 10
+#define XK_F11 11
+#define XK_F12 12
+#endif
 #define LA_KEY_F1        XK_F1
 #define LA_KEY_F1        XK_F1
 #define LA_KEY_F2        XK_F2
 #define LA_KEY_F2        XK_F2
 #define LA_KEY_F3        XK_F3
 #define LA_KEY_F3        XK_F3

+ 13 - 2
la_kernel.c

@@ -45,6 +45,9 @@
 #include <X11/cursorfont.h>
 #include <X11/cursorfont.h>
 #include <GL/glx.h>
 #include <GL/glx.h>
 #endif
 #endif
+#ifdef __APPLE__
+#include <execinfo.h>
+#endif
 #ifdef _WIN32
 #ifdef _WIN32
 #include <GL/wglew.h>
 #include <GL/wglew.h>
 #include <GL/wgl.h>
 #include <GL/wgl.h>
@@ -436,7 +439,7 @@ void la_DestroySystemWindowWin32(laWindow* w) {
 };
 };
 #endif
 #endif
 
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
 void la_HandlerSIGSEGV(int sig) {
 void la_HandlerSIGSEGV(int sig) {
     void *array[30];
     void *array[30];
     size_t sz;
     size_t sz;
@@ -527,6 +530,9 @@ int la_CreateSystemWindow(laWindow *window, int SyncToVBlank){
 #endif
 #endif
 #ifdef _WIN32
 #ifdef _WIN32
     SYSWINDOW hwnd = la_CreateWindowWin32(window->X, window->Y, window->W, window->H, window->Title->Ptr, SyncToVBlank, &glc);
     SYSWINDOW hwnd = la_CreateWindowWin32(window->X, window->Y, window->W, window->H, window->Title->Ptr, SyncToVBlank, &glc);
+#endif
+#ifdef __APPLE__
+    SYSWINDOW hwnd = glfwCreateWindow(window->W, window->H, window->Title->Ptr, NULL, NULL);
 #endif
 #endif
     window->win = hwnd;
     window->win = hwnd;
     window->glc = glc;
     window->glc = glc;
@@ -884,7 +890,7 @@ void laProcessInitArguments(int argc, char* argv[],laInitArguments* ia) {
     }
     }
 }
 }
 int laGetReadyWith(laInitArguments* ia){
 int laGetReadyWith(laInitArguments* ia){
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
     signal(SIGSEGV,la_HandlerSIGSEGV);
     signal(SIGSEGV,la_HandlerSIGSEGV);
 #endif
 #endif
 
 
@@ -1134,6 +1140,9 @@ int laGetReadyWith(laInitArguments* ia){
 #endif
 #endif
 #ifdef __linux__
 #ifdef __linux__
     int dpi = la_GetDPI(DefaultRootWindow(MAIN.dpy));
     int dpi = la_GetDPI(DefaultRootWindow(MAIN.dpy));
+#endif
+#ifdef __APPLE__
+    int dpi = 72;
 #endif
 #endif
     if((!dpi) || dpi<144){ dpi=144; } if(dpi>300){ dpi=300; }
     if((!dpi) || dpi<144){ dpi=144; } if(dpi>300){ dpi=300; }
     int UiSize=(int)(tnsLinearItp(16.0f,24.0f,tnsGetRatiod(96,144,dpi))+0.5);
     int UiSize=(int)(tnsLinearItp(16.0f,24.0f,tnsGetRatiod(96,144,dpi))+0.5);
@@ -1519,7 +1528,9 @@ int la_OnWindowDestroy(SYSWINDOW wnd){
 void la_MakeSpecialKeyBit(SYSWINDOW hwnd,laWindow*wnd,laEvent *e,int use_last_pos){
 void la_MakeSpecialKeyBit(SYSWINDOW hwnd,laWindow*wnd,laEvent *e,int use_last_pos){
     laListHandle *el = &wnd->EventList;
     laListHandle *el = &wnd->EventList;
     laEvent* last_e=el->pLast;
     laEvent* last_e=el->pLast;
+#ifndef __APPLE__ // TODO
     SYSWINDOW root_ret, win_ret; int rrx=0,rry=0,rx=e->x,ry=e->y,rmask=0;
     SYSWINDOW root_ret, win_ret; int rrx=0,rry=0,rx=e->x,ry=e->y,rmask=0;
+#endif
 #ifdef __linux__
 #ifdef __linux__
     XQueryPointer(MAIN.dpy, wnd->win, &root_ret,&win_ret,&rrx,&rry,&rx,&ry,&rmask);
     XQueryPointer(MAIN.dpy, wnd->win, &root_ret,&win_ret,&rrx,&rry,&rx,&ry,&rmask);
     e->SpecialKeyBit = ((rmask&ShiftMask)?LA_KEY_SHIFT:0)|((rmask&ControlMask)?LA_KEY_CTRL:0)|((rmask&Mod1Mask)?LA_KEY_ALT:0);
     e->SpecialKeyBit = ((rmask&ShiftMask)?LA_KEY_SHIFT:0)|((rmask&ControlMask)?LA_KEY_CTRL:0)|((rmask&Mod1Mask)?LA_KEY_ALT:0);

+ 2 - 0
la_resource.c

@@ -89,6 +89,8 @@ laPropContainer *_LA_PROP_FILE_BROWSER;
 
 
 laProp _P_LA_USE_INSTANCE_ONLY;
 laProp _P_LA_USE_INSTANCE_ONLY;
 
 
+void la_RegisterViewerOperators();
+
 void la_RegisterMainOperators(){
 void la_RegisterMainOperators(){
     la_RegisterUiOperatorsBasic();
     la_RegisterUiOperatorsBasic();
     la_RegisterViewerOperators();
     la_RegisterViewerOperators();

+ 2 - 2
la_tns.h

@@ -337,7 +337,7 @@ struct _tnsOffscreen
 #ifdef _WIN32
 #ifdef _WIN32
     SYSTEMDC FboDC;
     SYSTEMDC FboDC;
 #endif
 #endif
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
     SYSWINDOW FboWindow;
     SYSWINDOW FboWindow;
 #endif
 #endif
 
 
@@ -1157,7 +1157,7 @@ tnsShapeObject *tnsCreateShapeSquare(tnsObject *under, char *Name, real AtX, rea
 int tnsMergeMeshObjects(tnsMeshObject* into, tnsMeshObject* mo);
 int tnsMergeMeshObjects(tnsMeshObject* into, tnsMeshObject* mo);
 tnsInstancer* tnsDuplicateInstancer(tnsInstancer* from);
 tnsInstancer* tnsDuplicateInstancer(tnsInstancer* from);
 tnsMeshObject* tnsDuplicateMeshObject(tnsMeshObject* from);
 tnsMeshObject* tnsDuplicateMeshObject(tnsMeshObject* from);
-tnsShapeObject* tnsDuplicateShappeObject(tnsShapeObject* from);
+tnsShapeObject* tnsDuplicateShapeObject(tnsShapeObject* from);
 
 
 void tnsInitMeshPlane(tnsMeshObject* mo, real size);
 void tnsInitMeshPlane(tnsMeshObject* mo, real size);
 void tnsAddMMeshPlane(tnsMeshObject* mo, real size);
 void tnsAddMMeshPlane(tnsMeshObject* mo, real size);

+ 8 - 1
la_tns_kernel.c

@@ -107,6 +107,8 @@ tnsMatrixStackItem *tKnlGetCurrentMatStackItem();
 void tnsAttach2DOffscreenBuffer(tnsOffscreen *target, GLuint attatchment, tnsTexture *use);
 void tnsAttach2DOffscreenBuffer(tnsOffscreen *target, GLuint attatchment, tnsTexture *use);
 void tnsDetach2DOffscreenBuffer(tnsOffscreen *target, GLuint which_attach_point);
 void tnsDetach2DOffscreenBuffer(tnsOffscreen *target, GLuint which_attach_point);
 
 
+void tns_InvalidateMeshWithMaterial(tnsMaterial* m);
+
 //=========================================================================================
 //=========================================================================================
 
 
 tnsMain *T;
 tnsMain *T;
@@ -135,6 +137,11 @@ void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSTEMDC hdc,void* unused){
     tnsUnbindTexture(); tnsUseNoTexture();
     tnsUnbindTexture(); tnsUseNoTexture();
 };
 };
 #endif
 #endif
+#ifdef __APPLE__
+void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSWINDOW win, void* unused){
+    glfwMakeContextCurrent(context);
+};
+#endif
 #ifdef LA_USE_GLES
 #ifdef LA_USE_GLES
 void tnsContextMakeFBOCurrent(tnsOffscreen* off){
 void tnsContextMakeFBOCurrent(tnsOffscreen* off){
     tnsContextMakeCurrent(off->FboContext,off->FboWindow,off->FboSurface);
     tnsContextMakeCurrent(off->FboContext,off->FboWindow,off->FboSurface);
@@ -1620,7 +1627,7 @@ void tnsDrawBatchInitArrayStates(tnsBatch* batch){
     tnsUniformUseTexture(cs, 0, 0);
     tnsUniformUseTexture(cs, 0, 0);
 }
 }
 int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) {
 int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) {
-	if (!batch) return;
+    if (!batch) return 0;
     int Drawn=0; tnsShader *LastShader=T->BindedShader,*SaveShader=T->BindedShader; int NeedInit=1;
     int Drawn=0; tnsShader *LastShader=T->BindedShader,*SaveShader=T->BindedShader; int NeedInit=1;
 
 
     int IsOverrideColor=0; int PointSizeChanged=0,LineWidthChanged=0;
     int IsOverrideColor=0; int PointSizeChanged=0,LineWidthChanged=0;

+ 2 - 2
la_util.c

@@ -62,7 +62,7 @@ struct tm *laGetFullTime(){
 }
 }
 
 
 void laRecordTime(laTimeRecorder *tr){
 void laRecordTime(laTimeRecorder *tr){
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
     clock_gettime(CLOCK_REALTIME, &tr->ts);
     clock_gettime(CLOCK_REALTIME, &tr->ts);
 #endif
 #endif
 #ifdef _WIN32
 #ifdef _WIN32
@@ -70,7 +70,7 @@ void laRecordTime(laTimeRecorder *tr){
 #endif
 #endif
 }
 }
 real laTimeElapsedSecondsf(laTimeRecorder *End, laTimeRecorder *Begin){
 real laTimeElapsedSecondsf(laTimeRecorder *End, laTimeRecorder *Begin){
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
     real sec=End->ts.tv_sec-Begin->ts.tv_sec; sec+=((End->ts.tv_nsec-Begin->ts.tv_nsec)/1e9);
     real sec=End->ts.tv_sec-Begin->ts.tv_sec; sec+=((End->ts.tv_nsec-Begin->ts.tv_nsec)/1e9);
 #endif
 #endif
 #ifdef _WIN32
 #ifdef _WIN32

+ 13 - 3
la_util.h

@@ -42,11 +42,13 @@
 #include <stddef.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdint.h>
 #include <ctype.h>
 #include <ctype.h>
-#ifdef __linux__
+#if defined(__linux__) || defined(__APPLE__)
 #include <fcntl.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <errno.h>
 #include <errno.h>
 #include <wchar.h>
 #include <wchar.h>
+#endif
+#ifdef __linux__
 #define SYSWINDOW Window
 #define SYSWINDOW Window
 #ifdef LA_USE_GLES
 #ifdef LA_USE_GLES
 	#define SYSGLCONTEXT EGLContext
 	#define SYSGLCONTEXT EGLContext
@@ -69,6 +71,14 @@
 #define PATH_MAX 4096
 #define PATH_MAX 4096
 #define SYSLOCK CRITICAL_SECTION
 #define SYSLOCK CRITICAL_SECTION
 #endif
 #endif
+#ifdef __APPLE__
+#include <os/lock.h>
+#include <GLFW/glfw3.h>
+#define SYSLOCK os_unfair_lock
+#define SYSGLCONTEXT GLFWwindow*
+#define SYSWINDOW GLFWwindow*
+#define SYSTEMDISPLAY uint32_t
+#endif
 
 
 #ifdef LA_WITH_LUAJIT
 #ifdef LA_WITH_LUAJIT
 
 
@@ -404,8 +414,8 @@ STRUCTURE(laAVLTreeReal64) {
 };
 };
 
 
 STRUCTURE(laTimeRecorder) {
 STRUCTURE(laTimeRecorder) {
-#ifdef __linux__
-	struct timespec ts;
+#if defined(__linux__) || defined(__APPLE__)
+    struct timespec ts;
 #endif
 #endif
 #ifdef _WIN32
 #ifdef _WIN32
 	LARGE_INTEGER tm;
 	LARGE_INTEGER tm;

+ 33 - 0
lagui-config.cmake

@@ -24,6 +24,9 @@ find_package(Freetype REQUIRED)
 find_package(GLEW REQUIRED)
 find_package(GLEW REQUIRED)
 find_package(PNG)
 find_package(PNG)
 find_package(LuaJIT)
 find_package(LuaJIT)
+if (APPLE)
+    find_package(GLFW3 REQUIRED)
+endif()
 
 
 set(CMAKE_THREAD_PREFER_PTHREAD ON)
 set(CMAKE_THREAD_PREFER_PTHREAD ON)
 set(THREADS_PREFER_PTHREAD_FLAG ON)
 set(THREADS_PREFER_PTHREAD_FLAG ON)
@@ -73,6 +76,36 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
         list(APPEND LAGUI_SHARED_LIBS ${PNG_LIBRARY})
         list(APPEND LAGUI_SHARED_LIBS ${PNG_LIBRARY})
         list(APPEND LAGUI_INCLUDE_DIRS_ALL ${PNG_INCLUDE_DIR})
         list(APPEND LAGUI_INCLUDE_DIRS_ALL ${PNG_INCLUDE_DIR})
     endif()
     endif()
+elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+    set(LAGUI_SHARED_LIBS
+        ${OPENGL_LIBRARY}
+        ${GLEW_LIBRARIES}
+        ${LAGUI_GL_LIB}
+        ${FREETYPE_LIBRARIES}
+        m
+        ${GLFW3_LIBRARIES}
+        ${CMAKE_DL_LIBS}
+        Threads::Threads
+        ${LUA_LIBRARY}
+        lagui
+        CACHE INTERNAL "LaGUI shared libs"
+    )
+    set(LAGUI_INCLUDE_DIRS_ALL
+        ${OPENGL_LIBRARY}
+        ${CMAKE_SOURCE_DIR}
+        ${GLEW_INCLUDE_PATH}
+        ${FREETYPE_INCLUDE_DIRS}
+        ${LAGUI_INCLUDE_DIRS}
+        CACHE INTERNAL "Include dirs of LaGUI and dependencies"
+    )
+    if(${LuaJIT_FOUND})
+        list(APPEND LAGUI_SHARED_LIBS ${LUA_LIBRARY})
+        list(APPEND LAGUI_INCLUDE_DIRS_ALL ${LUA_INCLUDE_DIR})
+    endif()
+    if(${PNG_FOUND})
+        list(APPEND LAGUI_SHARED_LIBS ${PNG_LIBRARY})
+        list(APPEND LAGUI_INCLUDE_DIRS_ALL ${PNG_INCLUDE_DIR})
+    endif()
 elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
 elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
     set(LAGUI_SHARED_LIBS
     set(LAGUI_SHARED_LIBS
         ${GLEW_LIBRARIES}
         ${GLEW_LIBRARIES}

+ 4 - 1
resources/la_modelling.c

@@ -22,6 +22,9 @@
 extern LA MAIN;
 extern LA MAIN;
 extern struct _tnsMain *T;
 extern struct _tnsMain *T;
 
 
+void tnsRemoveMaterial(tnsMaterial* mat);
+void tns_InvalidateMeshWithMaterial(tnsMaterial* m);
+
 void la_ReadGLocation(tnsOffscreen* off, int x, int y,float* xyz0){
 void la_ReadGLocation(tnsOffscreen* off, int x, int y,float* xyz0){
     if(!off->pColor[2]){ tnsVectorSet3(xyz0,0,0,0); return; }
     if(!off->pColor[2]){ tnsVectorSet3(xyz0,0,0,0); return; }
     glBindFramebuffer(GL_READ_FRAMEBUFFER, off->FboHandle);
     glBindFramebuffer(GL_READ_FRAMEBUFFER, off->FboHandle);
@@ -1929,7 +1932,7 @@ int OPINV_RemoveRootObject(laOperator *a, laEvent *e){
 
 
 int OPINV_NewMaterial(laOperator *a, laEvent *e){
 int OPINV_NewMaterial(laOperator *a, laEvent *e){
     tnsMaterial* mat=tnsCreateMaterial("Material"); laNotifyUsers("tns.world.materials");
     tnsMaterial* mat=tnsCreateMaterial("Material"); laNotifyUsers("tns.world.materials");
-    if(!a->This && a->This->EndInstance) return;
+    if(!a->This && a->This->EndInstance) return LA_CANCELED;
     laPropContainer* pc=la_EnsureSubTarget(a->This->LastPs->p,a->This->EndInstance);
     laPropContainer* pc=la_EnsureSubTarget(a->This->LastPs->p,a->This->EndInstance);
     if(pc==TNS_PC_OBJECT_MESH){
     if(pc==TNS_PC_OBJECT_MESH){
         tnsMeshObject* mo=a->This->EndInstance; if(mo->CurrentMaterial){
         tnsMeshObject* mo=a->This->EndInstance; if(mo->CurrentMaterial){

+ 7 - 0
resources/la_properties.c

@@ -21,6 +21,13 @@
 extern LA MAIN;
 extern LA MAIN;
 extern struct _tnsMain *T;
 extern struct _tnsMain *T;
 
 
+void logClear();
+void la_ConditionNodeFreeRecursive(laUiConditionNode *ucn);
+void la_AssignWindowPP(laWindow* w);
+void la_AssignPropExtras(laUiItem* ui);
+void la_AssignBlockPP(laBlock* b);
+int la_GetPropertySize(int Type);
+
 void laset_TerminalInput(void* unused, char* content){
 void laset_TerminalInput(void* unused, char* content){
     if((!content)||(!content[0])){ MAIN.TerminalInput[0]=0; return; }
     if((!content)||(!content[0])){ MAIN.TerminalInput[0]=0; return; }
     int len=strlen(content);
     int len=strlen(content);