/*
* LaGUI: A graphical application framework.
* Copyright (C) 2022-2023 Wu Yiming
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#define _GNU_SOURCE
#include
#include "GL/glew.h"
#include "GL/gl.h"
#include "ft2build.h"
#include "freetype/freetype.h"
#include "la_icon.h"
#include "pthread.h"
#include
#include
#include
#include
#define NEED_STRUCTURE(a)\
typedef struct _##a a;
#define STRUCTURE(a)\
typedef struct _##a a;\
struct _##a
#define lengthof(a)\
(sizeof(a)/sizeof(a[0]))
#define DBL_TRIANGLE_LIM 1e-11
#define DBL_EDGE_LIM 1e-9
#ifndef LAGUI_GIT_BRANCH
#define LAGUI_GIT_BRANCH "Release 1"
#endif
// No need to show hash when not compiled from git repo.
//#ifndef LAGUI_GIT_HASH
//#define LAGUI_GIT_HASH "?"
//#endif
#define LA_HYPER_CREATED_TIME(hi)\
hi->TimeCreated.Year,hi->TimeCreated.Month,hi->TimeCreated.Day,hi->TimeCreated.Hour,hi->TimeCreated.Minute,hi->TimeCreated.Second
typedef double real;
typedef unsigned long long u64bit;
typedef unsigned int u32bit;
typedef unsigned short u16bit;
typedef unsigned short ushort;
typedef unsigned char u8bit;
typedef struct _laListSingle laListSingle;
struct _laListSingle {
void* pNext;
};
typedef struct _laListHandle laListHandle;
struct _laListHandle {
void* pFirst;
void* pLast;
};
typedef struct _laListWithPivot laListWithPivot;
struct _laListWithPivot {
void* pFirst;
void* pLast;
void* Pivot;
};
typedef struct _laListItem laListItem;
struct _laListItem {
void* pPrev;
void* pNext;
};
typedef struct _laListItem2 laListItem2;
struct _laListItem2 {
void* O1;
void* O2;
void* pPrev;
void* pNext;
};
typedef struct _laListItem3 laListItem3;
struct _laListItem3 {
void* O1;
void* O2;
void* O3;
void* O4;
void* pPrev;
void* pNext;
};
NEED_STRUCTURE(laSafeString);
STRUCTURE(laAuthorInfo) {
laListItem Item;
laSafeString* Name;
laSafeString* CopyrightString;
};
STRUCTURE(laTimeInfo) {
u16bit Year;//Also Used As Timer [ms] counter
u8bit Month;
u8bit Day;
u8bit Hour;
u8bit Minute;
u8bit Second;
};
NEED_STRUCTURE(laPropContainer);
typedef struct _laUID laUID;
struct _laUID {
char String[32];//a simplified uuid, example: 0E3F9BA4802FDDC2-20160601123546 [\0]
};
typedef struct _laListItemPointer laListItemPointer;
struct _laListItemPointer {
void* pPrev;
void* pNext;
void* p;
};
typedef struct _laItemUserLinker laItemUserLinker;
typedef void(*laUserRemoveFunc)(void* This, laItemUserLinker* iul);
NEED_STRUCTURE(laProp);
struct _laItemUserLinker {
laListItemPointer Pointer;
laUserRemoveFunc Remove;
laProp* Which;
void* Additional;
unsigned int FrameDistinguish;
int ForceRecalc;
};
typedef struct _laItemUserLinkerLocal laItemUserLinkerLocal;
struct _laItemUserLinkerLocal {
laItemUserLinker Link;
void* Instance;
};
typedef struct _laElementListItem laElementListItem;
struct _laElementListItem {
laListItem Item;
void* Ext;
};
typedef struct _laListNonRecursiveRoot laListNonRecursiveRoot;
struct _laListNonRecursiveRoot {
laListHandle NSItems;
};
typedef int(*laCompareFunc)(void*, void*);
typedef void(*laListDoFunc)(void*);
typedef void(*laListNonRecursiveDoFunc)(laListNonRecursiveRoot*, void*, void*);//item,custom
typedef void(*laListNonRecursiveCopyFunc)(laListNonRecursiveRoot*, void*, void*, void*);//old,new,custom
typedef void(*laListDoFuncArgp)(void*, void*);
typedef void(*laCopyListFunc)(void*, void*);
typedef void(*laListCustomDataRemover)(void*);
//typedef void(*ListMatcherFunc)(void*,void*);//gotten value,enumed curent lst item.
typedef struct _laListNonRecursiveItem laListNonRecursiveItem;
struct _laListNonRecursiveItem {
laListItem Item;
laListHandle handle;
laListHandle *ToHandle;//This Is Pointer!
laListNonRecursiveDoFunc func;
laListNonRecursiveCopyFunc CopyFunc;
laListCustomDataRemover remover;
void* CustomData;
int bFreeList;
int SizeEachNode;
};
typedef struct _laHash256 laHash256;
struct _laHash256 {
laListHandle Entries[256];
};
typedef struct _laHash65536 laHash65536;
struct _laHash65536 {
laListHandle Entries[65536];
//laHash256 HashHandles[256];
};
typedef struct _laHash16M laHash16M;
struct _laHash16M {
laListHandle Entries[16777216];
};
typedef struct _laSafeString laSafeString;
struct _laSafeString {
laListItem Item;
char * Ptr;
};
typedef struct _laSafeStringCollection laSafeStringCollection;
struct _laSafeStringCollection {
laListHandle SafeStrings;
};
typedef struct _laStringSplitor laStringSplitor;
struct _laStringSplitor {
int NumberParts;
laListHandle parts;
};
typedef struct _laStringPart laStringPart;
struct _laStringPart {
laListItem Item;
char * Content;
int IntValue;
real FloatValue;
char Type;
};
STRUCTURE(laStringLine) {
laListItem Item;
wchar_t Buf[1024];//unicode
};
STRUCTURE(laStringEdit) {
laListHandle Lines;
int CursorLine, CursorBefore, CursorPreferBefore;
int BeginLine, BeginBefore;
int EndLine, EndBefore;
int _BeginLine, _BeginBefore; // selection order
int _EndLine, _EndBefore;
int TotalLines;
int ViewStartLine, ViewStartCol;
int ViewHeight, ViewWidth;
int MouseSelecting;
};
#define LA_SWAP(T,x,y)\
{ T SWAP = x; x = y; y = SWAP; }
#define LA_MEMORY_POOL_1MB 1048576
#define LA_MEMORY_POOL_128MB 134217728
#define LA_MEMORY_POOL_256MB 268435456
#define LA_MEMORY_POOL_512MB 536870912
STRUCTURE(laMemoryPool) {
laListItem Item;
int NodeSize;
int NextCount;
int UsableCount;
int Hyperlevel;
laListHandle Pools;
};
STRUCTURE(laMemoryPoolPart) {
laListItem Item;
laListHandle FreeMemoryNodes;
int UsedCount;
laMemoryPool* PoolRoot;
//<------Pool mem starts here
};
NEED_STRUCTURE(laDBInst);
STRUCTURE(laMemNode0){
laListItem Item;
laMemoryPoolPart* InPool;//<---- Keep at the last
//<------User mem starts here
};
STRUCTURE(laMemNode) {
laListItem Item;
laListHandle Users; //<---- Keep at the second
void* ReadInstance;
laMemoryPoolPart* InPool; //<---- Keep at the last
//<------User mem starts here
};
NEED_STRUCTURE(laManagedUDF);
STRUCTURE(laMemNodeHyper) {
laListItem Item;
laListHandle Users; //<---- Keep at the second
laUID NUID;
laTimeInfo TimeCreated;
laManagedUDF* FromFile;
int Modified;
int UNUSEDUndoDirty;
laMemoryPoolPart* InPool; //<---- Keep at the last
//<------User mem starts here
};
STRUCTURE(laStaticMemoryPoolNode) {
laListItem Item;
int UsedByte;
//<------User mem starts here
};
STRUCTURE(laStaticMemoryPool) {
int EachSize;
laListHandle Pools;
//pthread_spinlock_t csMem;
};
STRUCTURE(laAVLNodeReal64) {
laAVLNodeReal64* Parent;
u64bit Index;
real Value;
//real SmallestValue;
//real GreatestValue;
laAVLNodeReal64* Smaller;
laAVLNodeReal64* Greater;
char Height;
void* Pointer;
};
STRUCTURE(laAVLTreeReal64) {
laAVLNodeReal64* Root;
u64bit ItemCount;
laMemoryPool MemoryPool;
};
STRUCTURE(laTimeRecorder) {
struct timespec ts;
};
STRUCTURE(laTranslationNode) {
laListItem Item;
laSafeString* LanguageName;
laHash256 Matches;
};
STRUCTURE(laTranslation) {
int EnableTranslation;
laListHandle Languages;
laTranslationNode* CurrentLanguage;
laHash256 MisMatches;
};
STRUCTURE(laTranslationMatch) {
laListItem Item;
char * Target;
char * Replacement;
};
NEED_STRUCTURE(laBaseNode);
typedef void (*laBaseNodeInitF)(laBaseNode*, int NoCreate);
typedef void (*laBaseNodeDestroyF)(laBaseNode*);
typedef int (*laBaseNodeVisitF)(laBaseNode*, laListHandle*);
typedef int (*laBaseNodeEvalF)(laBaseNode*);
STRUCTURE(laBaseNodeType){
laBaseNodeInitF Init;
laBaseNodeDestroyF Destroy;
laBaseNodeVisitF Visit;
laBaseNodeEvalF Eval;
laPropContainer* pc;
char* TypeName;
char* Name;
int Icon;
int NodeSize;
};
NEED_STRUCTURE(laNodeRack);
STRUCTURE(laBaseNode){
laListItem Item;
laSafeString* Name;
laBaseNodeType* Type;
laNodeRack* InRack;
int Gap; int Eval; int InitDone;
};
#define CreateNew(Type)\
calloc(sizeof(Type),1)
#define CreateNew_Size(size)\
calloc(size,1)
#define CreateNewBuffer(Type,Num)\
calloc(sizeof(Type),Num);
#define FreeMem(ptr)\
nutFreeMem((&ptr))
#define elif\
else if
#define LA_UNAVAILABLE_NAME "- Unknown -"
uint32_t laToUnicode(const unsigned char* ch, int* advance);
int laToUTF8(const uint32_t ch, char* out, char** next);
int strToUnicode(uint32_t* target, unsigned char* const src);
int strToUTF8(unsigned char* target, uint32_t* const src);
int strlenU(uint32_t* const str);
int strcpyU(uint32_t* target, uint32_t* const source );
int strcatU(uint32_t* target, uint32_t* const source );
struct tm* laGetFullTime();
void laRecordTime(laTimeRecorder* tr);
real laTimeElapsedSecondsf(laTimeRecorder* End, laTimeRecorder* Begin);
int laTimeElapsedMilliseconds(laTimeRecorder* End, laTimeRecorder* Begin);
void laSetAuthorInfo(char * Name, char * CopyrightString);
void memCreateNUID(char* buf,laMemNodeHyper* hyper);
NEED_STRUCTURE(laPropPack);
int nutHyperUserCount(void* instance, laProp* p_optional, int *p_count);
void memHyperInfo(laPropPack* pp, char* buf);
void memMakeHyperData(laMemNodeHyper* hi);
void nutFreeMem(void** ptr);
int nutFloatCompare(real l, real r);
int nutSameAddress(void* l, void* r);
void* arrElement(void* head, int i, int size);
int arrEnsureLength(void** head, int next, int* max, size_t ElementSize);
int arrInitLength(void** head, int max, int* pmax, size_t ElementSize);
void arrFree(void** head, int* max);
void lstPushSingle(void** Head, laListSingle* Item);
void* lstPopSingle(void** Head, laListSingle* Item);
void lstClearPrevNext(laListItem* li);
int lstCountElements(laListHandle* Handle);
void lstAppendItem(laListHandle* Handle, void* Item);
void lstPushItem(laListHandle* Handle, void* Item);
void* lstPopItem(laListHandle* Handle) ;
void lstAppendItem2(laListHandle* Handle, void* Item);
void* lstPopItem2(laListHandle* Handle);
void lstPushItem2(laListHandle* Handle, void* Item);
void lstAppendItem3(laListHandle* Handle, void* Item);
void* lstPopItem3(laListHandle* Handle);
void lstPushItem3(laListHandle* Handle, void* Item);
int lstRemoveItem(laListHandle* Handle, laListItem* li) ;
int lstRemoveItem2(laListHandle* Handle, laListItem2* li);
int lstRemoveSegment(laListHandle* Handle, laListItem* Begin, laListItem* End);
void lstInsertItemBefore(laListHandle* Handle, laListItem* toIns, laListItem* pivot);
void lstInsertItemAfter(laListHandle* Handle, laListItem* toIns, laListItem* pivot);
void lstInsertSegmentBefore(laListHandle* Handle, laListItem* Begin, laListItem* End, laListItem* pivot);
void lstInsertSegmentAfter(laListHandle* Handle, laListItem* Begin, laListItem* End, laListItem* pivot);
int lstHaveItemInList(laListHandle* Handle);
/**/ void* lstGetTop(laListHandle* Handle);
void lstPushSimpleItem(void** first, laItemUserLinker* iul);
void* lstPushItemUser(void** first, void* p);
void* lstPushItemUsing(void** first, void* p);
void* lstAppendPointerOnly(laListHandle* h, void* p);
void* lstAppendPointerSizedOnly(laListHandle* h, void* p, int size);
void* lstPushPointerOnly(laListHandle* h, void* p);
void* lstPushPointerSizedOnly(laListHandle* h, void* p, int size);
void lstReverse(laListHandle* h);
int lstHasPointer(laListHandle* h, void *p);
void* lstAppendPointer(laListHandle* h, void* p);
void* lstAppendPointerSized(laListHandle* h, void* p, int size);
void* lstPushPointer(laListHandle* h, void* p);
void* lstPushPointerSized(laListHandle* h, void* p, int size);
void* lstAppendPointerStatic(laListHandle* h, laStaticMemoryPool* smp, void* p);
void* lstAppendPointerStaticSized(laListHandle* h, laStaticMemoryPool* smp, void* p, int size);
void* lstPushPointerStatic(laListHandle* h, laStaticMemoryPool* smp, void* p);
void* lstPushPointerStaticSized(laListHandle* h, laStaticMemoryPool* smp, void* p, int size);
void* lstPopPointerOnly(laListHandle* h);
void lstRemovePointerItemOnly(laListHandle* h, laListItemPointer* lip);
void lstRemovePointerOnly(laListHandle* h, void* p);
void lstClearPointerOnly(laListHandle* h);
void lstGeneratePointerListOnly(laListHandle* from1, laListHandle* from2, laListHandle* to);
void* lstPopPointer(laListHandle* h);
void lstRemovePointerItem(laListHandle* h, laListItemPointer* lip);
void lstRemovePointer(laListHandle* h, void* p);
void lstRemovePointerLeave(laListHandle *h, void *p);
void lstClearPointer(laListHandle* h);
void lstGeneratePointerList(laListHandle* from1, laListHandle* from2, laListHandle* to);
void lstCopyHandle(laListHandle* target, laListHandle* src);
void* lstAppendPointerStaticPool(laStaticMemoryPool* mph, laListHandle* h, void* p);
void* lstPopPointerLeave(laListHandle* h);
void lstRemovePointerItemNoFree(laListHandle* h, laListItemPointer* lip);
void lstMoveUp(laListHandle* h, laListItem* li);
void lstMoveDown(laListHandle* h, laListItem* li);
void lstForAllItemsDo(laListDoFunc func, laListHandle* hList);
void lstForAllItemsDoLNRR(laListNonRecursiveDoFunc func, laListHandle* hList);
void lstForAllItemsDo_DirectFree(laListDoFunc func, laListHandle* hList);
void lstForAllItemsDo_arg_ptr(laListDoFuncArgp func, laListHandle* hList, void* arg);
void lstForAllItemsDo_NonRecursive_Root(laListHandle* FirstHandle, laListNonRecursiveDoFunc func, int bFreeItem, void* custom_data, laListCustomDataRemover remover);
void lstCopy_NonRecursive_Root(laListHandle* FromHandle, laListHandle* ToHandle, int SizeEachNode, laListNonRecursiveCopyFunc func, void* custom_data, laListCustomDataRemover remover);
void lstAddNonRecursiveListHandle(laListNonRecursiveRoot* root, laListHandle* newHandle, laListNonRecursiveDoFunc nrFunc, int bFreeList, void* custom_data, laListCustomDataRemover remover);
void lstAddNonRecursiveListCopier(laListNonRecursiveRoot* root, laListHandle* oldHandle, laListHandle* newHandle, int sizeEach, laListNonRecursiveCopyFunc nrCpyFunc, void* custom_data, laListCustomDataRemover remover);
void* lstFindItem(void* CmpData, laCompareFunc func, laListHandle* hList);
void lstCombineLists(laListHandle* dest, laListHandle* src);
void lstDestroyList(laListHandle* hlst);
void* lstReMatch(laListHandle* SearchHandle, laListHandle* CurrentHandle, void* ItemToFind);
typedef int(*MatcherFunc)(void*, void*);
void* lstReMatchEx(laListHandle* SearchHandle, laListHandle* CurrentHandle, void* ItemToFind, MatcherFunc func);
void lstAddElement(laListHandle* hlst, void* ext);
void lstDestroyElementList(laListHandle* hlst);
void hsh256InsertItemCSTR(laHash256* hash, laListItem* li, char * buckle);
void hsh256InsertItem(laHash256* hash, laListItem* li, char buckle);
void hsh65536InsertItem(laHash65536* hash, laListItem* li, long buckle);
void hsh65536Init(laHash65536** h);
void hshFree(laHash65536** h);
laListHandle* hsh65536DoHashLongPtr(laHash65536* hash, unsigned long long buckle);
laListHandle* hsh65536DoHashNUID(laHash65536* hash, char * NUID);
laListHandle* hsh16MDoHashLongPtr(laHash16M* hash, long long buckle);
laListHandle* hsh16MDoHashNUID(laHash16M* hash, char * NUID);
laListItem* hsh256FindItemSTR(laHash256* hash, laCompareFunc func, char * buckle);
unsigned char hsh256DoHashSTR(char * buckle);
void memResetByteCount();
int memGetByteCount();
void* memGetHead(void* UserMem, int* HyperLevel);
laListHandle* memGetUserList(void* UserMem);
laMemoryPool *memInitPool(int NodeSize, int HyperLevel);
void memInitPoolSmall(laMemoryPool* mph, int NodeSize);
laMemoryPoolPart* memNewPoolPart(laMemoryPool* mph);
void* memAcquireH(laMemoryPool* Handle);
void* memAcquireSimple(int Size);
void* memAcquireNoAppend(int Size);
void* memAcquireHyperNoAppend(int Size);
void* memAcquire(int Size);
void* memAcquireHyper(int Size);
void memFree(void* Data);
void memDestroyPool(laMemoryPool* Handle);
void memNoLonger();
void memMarkClean(void* HyperUserMem);
void memLeave(void *Data);
void memTake(void* Data);
void memFreeRemainingLeftNodes();
laStaticMemoryPoolNode* memNewStaticPool(laStaticMemoryPool* smp);
void* memStaticAcquire(laStaticMemoryPool*smp, int size);
void* memStaticAcquireThread(laStaticMemoryPool*smp, int size);
void* memStaticDestroy(laStaticMemoryPool*smp);
NEED_STRUCTURE(laSubProp);
void memAssignRef(void* This, void** ptr, void* instance);
void memAssignRefSafe(laSubProp* sp, void* This, void** ptr, void* instance);
char * strSub(char *input, char *substring, char *replace);
int strGetStringTerminateBy(char * content, char terminator, char * Out);
int strHeadOfStringMatch(char * Str, char * SubStr);
int strSkipSegmet(char ** pivot, char * content);
char * strGetLastSegment(char * Content, char Seperator);
void strDiscardLastSegmentSeperateBy(char * Content, char Seperator);
void strDiscardSameBeginningSeperatedBy(char * s1, char * s2, char ** Result1, char ** Result2, char Seperator);
int strCountSegmentSeperateBy(char * Content, char Seperator);
void strMakeDifferentName(char * Target);
void strReplaceCharacter(char * Str, char Find, char Replace);
void strToUpper(char * Str);
void strToLower(char * Str);
laStringSplitor *strSplitPath(char *path,char terminator);
int strMakeInstructions(laStringSplitor** result,char * content);
laStringPart* strGetArgument(laStringSplitor* ss, char * content);
char * strGetArgumentString(laStringSplitor* ss, char * content);
int strArgumentMatch(laStringSplitor* ss, char * id, char * value);
int strDestroyStringSplitor(laStringSplitor** ss);
int strGetIntSimple(char * content);
real strGetFloatSimple(char * content);
void strConvInt_CString(int src, char * dest, int lenth);
void strConvFloat_CString(real src, char * dest, int lenth);
void strCopyFull(char * dest, char * src);
void strCopySized(char * dest, int LenthLim, char * src);
#define strAppend strcat
void strPrintFloatAfter(char * dest, int LenthLim, int bits, real data);
void strPrintIntAfter(char * dest, int LenthLim, int data);
int strSame(char * src, char *dest);
void strEscapePath(char* OutCanBeSame, char* path);
void strSafeDestroy(laSafeString** ss);
void strSafeSet(laSafeString** ss, char * Content);
void strSafeAppend(laSafeString **ss, char *Content);
void strSafePrint(laSafeString **ss, char *Format, ...);
void strSafePrintV(laSafeString **ss, char *Format, va_list arg);
void strSafeDump();
void strBeginEdit(laStringEdit** se, char * FullStr);
char* strGetEditString(laStringEdit *se, int SelectionOnly);
char* strEndEdit(laStringEdit** se, int FreeString);
void strSetEditViewRange(laStringEdit* se, int Lines, int Cols);
void strEnsureCursorVisible(laStringEdit* se);
void strRemoveLine(laStringEdit* se, laStringLine* sl);
void strRemoveLineI(laStringEdit* se, int LineIndex);
void strSetCursor(laStringEdit* se, int LineIndex, int BeforeIndex);
void strMoveCursor(laStringEdit* se, int Left, int Select);
void strMoveCursorLine(laStringEdit *se, int Up, int Select);
int strHasSelection(laStringEdit* se);
void strCancelSelect(laStringEdit *se);
void strLazySelect(laStringEdit *se);
void strEndSelect(laStringEdit *se);
void strSelectLineAll(laStringEdit* se);
void strDeselectAll(laStringEdit* se);
void strPanFoward(uint32_t * str, int Before, int Offset);
void strSquishBackward(uint32_t * str, int Before, int EndBefore);
void strClearSelection(laStringEdit* se);
laStringLine *strGetCursorLine(laStringEdit *se, int* IndexIfLast);
laStringLine* strGetBeginLine(laStringEdit* se);
void strInsertChar(laStringEdit* se, uint32_t a);
void strBackspace(laStringEdit* se);
void strMoveView(laStringEdit *se, int DownLines, int RightCharacters);
int laCopyFile(char *to, char *from);
void transNewLanguage(const char * LanguageID);
void transSetLanguage(const char * LanguageID);
void transDumpMissMatchRecord(const char * filename);
void transNewEntry(const char * Target, const char * replacement);
char * transLate(char * Target);
void transState(void* UNUSED, int val);
void transInitTranslation_zh_cn();
void laOpenInternetLink(char* url);
#define SEND_PANIC_ERROR(msg)\
{printf(msg); exit(0);}