First WebUI v2.2.0 Commit

# WebUI v2.2.0

* Now, creating a wrapper is easier as core functions have been removed from `webui.h`
* Removing many functions (webui_open, webui_new_server...)

* C - Complete
* Go - Complete
* Deno - Complete
* All other things still need to be completed...
This commit is contained in:
Hassan DRAGA 2023-04-17 15:43:46 -04:00
parent abe94a1387
commit 18d68ab586
94 changed files with 4948 additions and 5317 deletions

5
.gitignore vendored
View File

@ -1,9 +1,5 @@
# Build
*.exe
*.dll
*.so
*.dylib
*.a
*.ilk
*.pdb
*.lib
@ -13,7 +9,6 @@
*.o
*.def
*.obj
*.dyn
# IDE
.idea/

View File

@ -8,13 +8,13 @@ all: release
debug:
# Static with Debug info
@echo "Build WebUI Library (Debug Static)..."
@echo "Build WebUI Library (Clang Debug Static)..."
@clang -g -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -g -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@llvm-ar rc libwebui-2-static-x64.a webui.o mongoose.o
@llvm-ranlib libwebui-2-static-x64.a
# Dynamic with Debug info
@echo "Build WebUI Library (Debug Dynamic)..."
@echo "Build WebUI Library (Clang Debug Dynamic)..."
@clang -g -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -g -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@clang -g -shared -o webui-2-x64.so webui.o mongoose.o
@ -24,13 +24,13 @@ debug:
release:
# Static Release
@echo "Build WebUI Library (Release Static)..."
@echo "Build WebUI Library (Clang Release Static)..."
@clang -Os -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -Os -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@llvm-ar rc libwebui-2-static-x64.a webui.o mongoose.o
@llvm-ranlib libwebui-2-static-x64.a
# Dynamic Release
@echo "Build WebUI Library (Release Dynamic)..."
@echo "Build WebUI Library (Clang Release Dynamic)..."
@clang -O3 -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -O3 -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@clang -shared -o webui-2-x64.so webui.o mongoose.o

View File

@ -8,13 +8,13 @@ all: release
debug:
# Static with Debug info
@echo "Build WebUI Library (Debug Static)..."
@echo "Build WebUI Library (GCC Debug Static)..."
@gcc -g -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -g -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@ar rc libwebui-2-static-x64.a webui.o mongoose.o
@ranlib libwebui-2-static-x64.a
# Dynamic with Debug info
@echo "Build WebUI Library (Debug Dynamic)..."
@echo "Build WebUI Library (GCC Debug Dynamic)..."
@gcc -g -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -g -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@gcc -g -shared -o webui-2-x64.so webui.o mongoose.o
@ -24,13 +24,13 @@ debug:
release:
# Static Release
@echo "Build WebUI Library (Release Static)..."
@echo "Build WebUI Library (GCC Release Static)..."
@gcc -Os -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -Os -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@ar rc libwebui-2-static-x64.a webui.o mongoose.o
@ranlib libwebui-2-static-x64.a
# Dynamic Release
@echo "Build WebUI Library (Release Dynamic)..."
@echo "Build WebUI Library (GCC Release Dynamic)..."
@gcc -O3 -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -O3 -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@gcc -shared -o webui-2-x64.so webui.o mongoose.o

View File

@ -9,13 +9,13 @@ all: release
debug:
# Static with Debug info
@echo Build WebUI Library (Debug Static)...
@echo Build WebUI Library (GCC Debug Static)...
@gcc -g -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -g -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c" -DWEBUI_LOG
@ar rc libwebui-2-static-x64.a webui.o mongoose.o
@ranlib libwebui-2-static-x64.a
# Dynamic with Debug info
@echo Build WebUI Library (Debug Dynamic)...
@echo Build WebUI Library (GCC Debug Dynamic)...
@gcc -g -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -g -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c" -DWEBUI_LOG
@gcc -g -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32
@ -25,13 +25,13 @@ debug:
release:
# Static Release
@echo Build WebUI Library (Release Static)...
@echo Build WebUI Library (GCC Release Static)...
@gcc -Os -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -Os -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@ar rc libwebui-2-static-x64.a webui.o mongoose.o
@ranlib libwebui-2-static-x64.a
# Dynamic Release
@echo Build WebUI Library (Release Dynamic)...
@echo Build WebUI Library (GCC Release Dynamic)...
@gcc -O3 -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c" -Wno-stringop-overread
@gcc -O3 -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@gcc -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32

Binary file not shown.

View File

@ -5,30 +5,30 @@ all: release
debug:
# Static with Debug info
@echo Build WebUI Library (Debug Static)...
@cl /Zi /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" >nul 2>&1
@cl /Zi /Fowebui.obj /c /EHsc /DWEBUI_LOG "../../../src/webui.c" /I "../../../include" >nul 2>&1
@lib /OUT:webui-2-static-x64.lib webui.obj mongoose.obj >nul 2>&1
@echo Build WebUI Library (MSVC Debug Static)...
@cl /Zi /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" 1>NUL 2>&1
@cl /Zi /Fowebui.obj /c /EHsc /DWEBUI_LOG "../../../src/webui.c" /I "../../../include" 1>NUL 2>&1
@lib /OUT:webui-2-static-x64.lib webui.obj mongoose.obj 1>NUL 2>&1
# Dynamic with Debug info
@echo Build WebUI Library (Debug Dynamic)...
@cl /Zi /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" >nul 2>&1
@cl /Zi /Fowebui.obj /c /EHsc /DWEBUI_LOG "../../../src/webui.c" /I "../../../include" >nul 2>&1
@link /DLL /OUT:webui-2-x64.dll webui.obj mongoose.obj user32.lib Advapi32.lib >nul 2>&1
@echo Build WebUI Library (MSVC Debug Dynamic)...
@cl /Zi /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" 1>NUL 2>&1
@cl /Zi /Fowebui.obj /c /EHsc /DWEBUI_LOG "../../../src/webui.c" /I "../../../include" 1>NUL 2>&1
@link /DLL /OUT:webui-2-x64.dll webui.obj mongoose.obj user32.lib Advapi32.lib 1>NUL 2>&1
# Clean
@- del *.obj >nul 2>&1
@echo Done.
release:
# Static Release
@echo Build WebUI Library (Release Static)...
@cl /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" >nul 2>&1
@cl /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include" >nul 2>&1
@lib /OUT:webui-2-static-x64.lib webui.obj mongoose.obj >nul 2>&1
@echo Build WebUI Library (MSVC Release Static)...
@cl /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" 1>NUL 2>&1
@cl /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include" 1>NUL 2>&1
@lib /OUT:webui-2-static-x64.lib webui.obj mongoose.obj 1>NUL 2>&1
# Dynamic Release
@echo Build WebUI Library (Release Dynamic)...
@cl /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" >nul 2>&1
@cl /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include" >nul 2>&1
@link /DLL /OUT:webui-2-x64.dll webui.obj mongoose.obj user32.lib Advapi32.lib >nul 2>&1
@echo Build WebUI Library (MSVC Release Dynamic)...
@cl /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include" 1>NUL 2>&1
@cl /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include" 1>NUL 2>&1
@link /DLL /OUT:webui-2-x64.dll webui.obj mongoose.obj user32.lib Advapi32.lib 1>NUL 2>&1
# Clean
@- del *.obj >nul 2>&1
@- del *.ilk >nul 2>&1

Binary file not shown.

View File

@ -9,12 +9,12 @@ all: release
debug:
# Static with Debug info
@echo Build WebUI Library (Debug Static)...
@echo Build WebUI Library (TCC Debug Static)...
@tcc -g -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@tcc -g -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c" -DWEBUI_LOG
@tcc -m64 -ar rcs libwebui-2-static-x64.a webui.o mongoose.o
# Dynamic with Debug info
@echo Build WebUI Library (Debug Dynamic)...
@echo Build WebUI Library (TCC Debug Dynamic)...
@tcc -g -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@tcc -g -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c" -DWEBUI_LOG
@tcc -g -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32 -lAdvapi32
@ -24,12 +24,12 @@ debug:
release:
# Static Release
@echo Build WebUI Library (Release Static)...
@echo Build WebUI Library (TCC Release Static)...
@tcc -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@tcc -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@tcc -m64 -ar rcs libwebui-2-static-x64.a webui.o mongoose.o
# Dynamic Release
@echo Build WebUI Library (Release Dynamic)...
@echo Build WebUI Library (TCC Release Dynamic)...
@tcc -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@tcc -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@tcc -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32 -lAdvapi32

View File

@ -8,13 +8,13 @@ all: release
debug:
# Static with Debug info
@echo "Build WebUI Library (Debug Static)..."
@echo "Build WebUI Library (Clang Debug Static)..."
@clang -g -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -DWEBUI_LOG -g -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@ar rc libwebui-2-static-x64.a webui.o mongoose.o
@ranlib libwebui-2-static-x64.a
# Dynamic with Debug info
@echo "Build WebUI Library (Debug Dynamic)..."
@echo "Build WebUI Library (Clang Debug Dynamic)..."
@clang -g -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -DWEBUI_LOG -g -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@clang -g -shared -o webui-2-x64.dyn webui.o mongoose.o
@ -24,13 +24,13 @@ debug:
release:
# Static Release
@echo "Build WebUI Library (Release Static)..."
@echo "Build WebUI Library (Clang Release Static)..."
@clang -Os -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -Os -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@ar rc libwebui-2-static-x64.a webui.o mongoose.o
@ranlib libwebui-2-static-x64.a
# Dynamic Release
@echo "Build WebUI Library (Release Dynamic)..."
@echo "Build WebUI Library (Clang Release Dynamic)..."
@clang -O3 -fPIC -m64 -o mongoose.o -I "$(INCLUDE)" -c "$(SOURCE)/mongoose.c"
@clang -O3 -fPIC -m64 -o webui.o -I "$(INCLUDE)" -c "$(SOURCE)/webui.c"
@clang -shared -o webui-2-x64.dyn webui.o mongoose.o

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C++ Example
# Linux - Clang

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C++ Example
# Linux - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C++ Example
# Windows - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C++ Example
# Windows - Microsoft Visual C

View File

@ -1,91 +1,20 @@
// The C++ wrapper is coming soon.
// Please see the C example for now.
extern "C" {
#include <webui.h>
extern "C"{
#include "webui.h"
}
// Window struct
webui_window_t* my_window;
// UI HTML
const char* my_html = "<!DOCTYPE html>"
"<html><head><title>WebUI 2 - C++ Visual Studio Example</title>"
"<style>body{color: white; background: #0F2027;"
"background: -webkit-linear-gradient(to right, #8d4887, #521b4e, #3e073a);"
"background: linear-gradient(to right, #8d4887, #521b4e, #3e073a);"
"text-align:center; font-size: 18px; font-family: sans-serif;}</style></head><body>"
"<h1>WebUI 2 - C++ Visual Studio Example</h1><br>"
"<input type=\"password\" id=\"MyInput\"><br><br>"
"<button id=\"MyButton1\">Check Password</button> - <button id=\"MyButton2\">Exit</button>"
"</body></html>";
// Check the password function
void check_the_password(webui_event_t* e) {
// This function get called every time the user click on "MyButton1"
webui_script_t js;
js.script = " return document.getElementById(\"MyInput\").value; ";
js.timeout = 3;
// Run the JavaScript on the UI (Web Browser)
webui_script(my_window, &js);
// Check if there is any JavaScript error
if (js.result.error) {
printf("JavaScript Error: %s\n", js.result.data);
return;
}
// Get the password
const char* password = js.result.data;
printf("Password: %s\n", password);
// Check the password
if (strcmp(password, "123456") == 0) {
// Correct password
js.script = "alert('Good. Password is correct.')";
webui_script(my_window, &js);
}
else {
// Wrong password
js.script = "alert('Sorry. Wrong password.')";
webui_script(my_window, &js);
}
// Free data resources
webui_script_cleanup(&js);
}
void close_the_application(webui_event_t* e) {
// Close all opened windows
webui_exit();
}
#include <iostream>
int main() {
// Create a window
my_window = webui_new_window();
// Bind HTML elements with functions
webui_bind(my_window, "MyButton1", check_the_password);
webui_bind(my_window, "MyButton2", close_the_application);
// Show the window
if (!webui_show(my_window, my_html, webui.browser.chrome)) // Run the window on Chrome
webui_show(my_window, my_html, webui.browser.any); // If not, run on any other installed web browser
// Wait until all windows get closed
webui_wait();
return 0;
std::cout << "The C++ wrapper is coming soon. Please see the C examples for now.";
return 0;
}
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
main();
}
#if defined(_MSC_VER)
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
main();
}
#endif

View File

@ -1,91 +1,20 @@
// The C++ wrapper is coming soon.
// Please see the C example for now.
extern "C" {
#include <webui.h>
extern "C"{
#include "webui.h"
}
// Window struct
webui_window_t* my_window;
// UI HTML
const char* my_html = "<!DOCTYPE html>"
"<html><head><title>WebUI 2 - C++ Visual Studio Example</title>"
"<style>body{color: white; background: #0F2027;"
"background: -webkit-linear-gradient(to right, #8d4887, #521b4e, #3e073a);"
"background: linear-gradient(to right, #8d4887, #521b4e, #3e073a);"
"text-align:center; font-size: 18px; font-family: sans-serif;}</style></head><body>"
"<h1>WebUI 2 - C++ Visual Studio Example</h1><br>"
"<input type=\"password\" id=\"MyInput\"><br><br>"
"<button id=\"MyButton1\">Check Password</button> - <button id=\"MyButton2\">Exit</button>"
"</body></html>";
// Check the password function
void check_the_password(webui_event_t* e) {
// This function get called every time the user click on "MyButton1"
webui_script_t js;
js.script = " return document.getElementById(\"MyInput\").value; ";
js.timeout = 3;
// Run the JavaScript on the UI (Web Browser)
webui_script(my_window, &js);
// Check if there is any JavaScript error
if (js.result.error) {
printf("JavaScript Error: %s\n", js.result.data);
return;
}
// Get the password
const char* password = js.result.data;
printf("Password: %s\n", password);
// Check the password
if (strcmp(password, "123456") == 0) {
// Correct password
js.script = "alert('Good. Password is correct.')";
webui_script(my_window, &js);
}
else {
// Wrong password
js.script = "alert('Sorry. Wrong password.')";
webui_script(my_window, &js);
}
// Free data resources
webui_script_cleanup(&js);
}
void close_the_application(webui_event_t* e) {
// Close all opened windows
webui_exit();
}
#include <iostream>
int main() {
// Create a window
my_window = webui_new_window();
// Bind HTML elements with functions
webui_bind(my_window, "MyButton1", check_the_password);
webui_bind(my_window, "MyButton2", close_the_application);
// Show the window
if (!webui_show(my_window, my_html, webui.browser.chrome)) // Run the window on Chrome
webui_show(my_window, my_html, webui.browser.any); // If not, run on any other installed web browser
// Wait until all windows get closed
webui_wait();
return 0;
std::cout << "The C++ wrapper is coming soon. Please see the C examples for now.";
return 0;
}
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
main();
}
#if defined(_MSC_VER)
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
main();
}
#endif

View File

@ -9,7 +9,7 @@ extern "C"{
int main() {
std::cout << "The C++ wrapper is coming soon. Please see the C example for now.";
std::cout << "The C++ wrapper is coming soon. Please see the C examples for now.";
return 0;
}

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - Clang

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Microsoft Visual C

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Tiny C Compiler

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# macOS - Clang

View File

@ -103,7 +103,7 @@ int main() {
"</html>";
// Create a window
webui_window_t* my_window = webui_new_window();
void* my_window = webui_new_window();
// Bind HTML elements with C functions
webui_bind(my_window, "MyID_One", my_function_string);

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - Clang

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Microsoft Visual C

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Tiny C Compiler

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# macOS - Clang

View File

@ -12,38 +12,28 @@ void my_function_count(webui_event_t* e) {
// This function gets called every time the user clicks on "MyButton1"
// Create a WebUI JavaScript struct
webui_script_t MyJavaScript = {
.script = "return GetCount();",
.timeout = 3
};
// Create a buffer to hold the response
char response[64];
// Run JavaScript
webui_script(e->window, &MyJavaScript);
if(!webui_script(e->window, "return GetCount();", 0, response, 64)) {
// Check if there is any JavaScript error
if(MyJavaScript.result.error) {
printf("JavaScript Error: %s\n", MyJavaScript.result.data);
printf("JavaScript Error: %s\n", response);
return;
}
// Get the count
int count = atoi(MyJavaScript.result.data);
int count = atoi(response);
// Increment
count++;
// Generate a JavaScript
char buf[64];
sprintf(buf, "SetCount(%d);", count);
char js[64];
sprintf(js, "SetCount(%d);", count);
// Run JavaScript
MyJavaScript.script = buf;
webui_script(e->window, &MyJavaScript);
// Free data resources
webui_script_cleanup(&MyJavaScript);
// Run JavaScript (Quick Way)
webui_run(e->window, js);
}
int main() {
@ -88,7 +78,7 @@ int main() {
"</html>";
// Create a window
webui_window_t* my_window = webui_new_window();
void* my_window = webui_new_window();
// Bind HTML elements with C functions
webui_bind(my_window, "MyButton1", my_function_count);

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - Clang

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Microsoft Visual C

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Tiny C Compiler

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# macOS - Clang

View File

@ -4,7 +4,7 @@
int main() {
webui_window_t* my_window = webui_new_window();
void* my_window = webui_new_window();
webui_show(my_window, "<html>Hello</html>");
webui_wait();
return 0;

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - Clang

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Linux - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - GCC

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Microsoft Visual C

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# Windows - Tiny C Compiler

View File

@ -1,4 +1,4 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
# C99 Example
# macOS - Clang

View File

@ -2,8 +2,8 @@
#include "webui.h"
webui_window_t* my_window;
webui_window_t* my_second_window;
void* my_window;
void* my_second_window;
void exit_app(webui_event_t* e) {

View File

@ -3,5 +3,6 @@
```sh
git clone https://github.com/alifcommunity/webui.git
cd webui\examples\Go\hello_world
go clean
go build
```

View File

@ -1,3 +1,3 @@
module github.com/alifcommunity/webui
go 1.19
go 1.20

View File

@ -52,46 +52,50 @@ const dashboard_html string = `<!DOCTYPE html>
<body>
<h1>Welcome !</h1>
<br>
Call Secret() function and get the response
<br>
<br>
<button OnClick="alert('Response is ' + webui_fn('Sec'))">Secret</button>
<br>
<br>
<button id="Exit">Exit</button>
</body>
</html>`
func Exit(e webui.Event) {
func Exit(e webui.Event) string {
webui.Exit()
return ""
}
func Check(e webui.Event) {
func Secret(e webui.Event) string {
// Script to get the text value
MyScript := webui.JavaScript{
Timeout: 10,
Script: " return document.getElementById('MyInput').value; ",
}
return "I Love Go!"
}
func Check(e webui.Event) string {
// Create new JavaScript object
js := webui.NewJavaScript()
// Run the script
webui.RunJavaScript(e.Window, &MyScript)
// Check if any error
if !MyScript.Error {
fmt.Printf("Password: %s\n", MyScript.Data)
// Check the password
if MyScript.Data == "123456" {
webui.Show(e.Window, dashboard_html)
} else {
MyScript.Script = " document.getElementById('err').innerHTML = 'Sorry. Wrong password'; "
webui.RunJavaScript(e.Window, &MyScript)
}
} else {
if !webui.Script(e.Window, &js, "return document.getElementById('MyInput').value;") {
// There is an error in our script
fmt.Printf("JavaScript Error: %s\n", MyScript.Data)
fmt.Printf("JavaScript Error: %s\n", js.Response)
return ""
}
fmt.Printf("Password: [%s]\n", js.Response)
// Check the password
if js.Response == "123456" {
webui.Show(e.Window, dashboard_html)
} else {
webui.Script(e.Window, &js, "document.getElementById('err').innerHTML = 'Sorry. Wrong password';")
}
return ""
}
func main() {
@ -101,6 +105,7 @@ func main() {
// Bind
webui.Bind(my_window, "CheckPassword", Check)
webui.Bind(my_window, "Sec", Secret)
webui.Bind(my_window, "Exit", Exit)
// Show window

View File

@ -1,131 +1,200 @@
/*
WebUI Library 2.1.1
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
WebUI Library 2.2.0
http://_webui_core.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
*/
package webui
/*
// [?] Change the library path as you need
#cgo CFLAGS: -I ./ -I ../../../../include
#cgo windows LDFLAGS: -L ./ -L ../../../../build/Windows/GCC/ -L ../../../../build/Windows/MSVC/ -lwebui-2-static-x64 -lws2_32
#cgo darwin LDFLAGS: -L ./ -L ../../../../build/macOS/GCC/ -L ../../../../build/macOS/Clang/ -lwebui-2-static-x64 -lpthread -lm
#cgo linux LDFLAGS: -L ./ -L ../../../../build/Linux/GCC/ -L ../../../../build/Linux/Clang/ -lwebui-2-static-x64 -lpthread -lm
#cgo CFLAGS: -I ./
#cgo windows LDFLAGS: -L ./ -lwebui-2-static-x64 -lws2_32
#cgo darwin LDFLAGS: -L ./ -lwebui-2-static-x64 -lpthread -lm
#cgo linux LDFLAGS: -L ./ -lwebui-2-static-x64 -lpthread -lm
#include <webui.h>
extern void webui_go_handler(webui_window_t* _window, unsigned int _element_id, unsigned int _window_id, char* _element_name);
static void webui_bind_go_handler(webui_event_t* e) {
webui_go_handler(e->window, e->element_id, e->window_id, e->element_name);
extern void go_webui_event(void* _window, unsigned int _event_type, char* _element, char* _data, char* _response);
static void go_webui_events_handler(webui_event_t* e) {
go_webui_event(e->window, e->type, e->element, e->data, (char*)&e->response);
}
static unsigned int webui_bind_go(webui_window_t* win, const char* element) {
return webui_bind(win, element, webui_bind_go_handler);
static void go_webui_bind(void* win, const char* element) {
webui_bind(win, element, go_webui_events_handler);
}
*/
import "C"
import (
"C"
"bytes"
"strconv"
"unsafe"
)
const AnyBrowser uint = 0
const Chrome uint = 1
const Firefox uint = 2
const Edge uint = 3
const Safari uint = 4
const Chromium uint = 5
const Custom uint = 99
// Event Struct
type Event struct {
Window *C.webui_window_t
ElementID uint
WindowID uint
ElementName string
}
// JavaScript Struct
type JavaScript struct {
Timeout uint
Script string
Error bool
Length uint
Data string
}
// Heap
var isIni bool = false
// User Go Callback Functions list
var fun_list [64][256]func(Event)
var fun_list map[string]func(Event) string
//export webui_go_handler
func webui_go_handler(_window *C.webui_window_t, _element_id C.uint, _window_id C.uint, _element_name *C.char) {
// Web browsers enum
const AnyBrowser uint = 0 // 0. Default recommended web browser
const Chrome uint = 1 // 1. Google Chrome
const Firefox uint = 2 // 2. Mozilla Firefox
const Edge uint = 3 // 3. Microsoft Edge
const Safari uint = 4 // 4. Apple Safari
const Chromium uint = 5 // 5. The Chromium Project
const Opera uint = 6 // 6. Opera Browser
const Brave uint = 7 // 7. The Brave Browser
const Vivaldi uint = 8 // 8. The Vivaldi Browser
const Epic uint = 9 // 9. The Epic Browser
const Yandex uint = 10 // 10. The Yandex Browser
var window *C.webui_window_t = (*C.webui_window_t)(_window)
var element_id uint = uint(_element_id)
var window_id uint = uint(_window_id)
var element_name string = C.GoString(_element_name)
// Events enum
const WEBUI_EVENT_DISCONNECTED uint = 0 // 0. Window disconnection event
const WEBUI_EVENT_CONNECTED uint = 1 // 1. Window connection event
const WEBUI_EVENT_MULTI_CONNECTION uint = 2 // 2. New window connection event
const WEBUI_EVENT_UNWANTED_CONNECTION uint = 3 // 3. New unwanted window connection event
const WEBUI_EVENT_MOUSE_CLICK uint = 4 // 4. Mouse click event
const WEBUI_EVENT_NAVIGATION uint = 5 // 5. Window navigation event
const WEBUI_EVENT_CALLBACK uint = 6 // 6. Function call event
// Events struct
type Event struct {
Window unsafe.Pointer
EventType uint
Element string
Data string
}
// JavaScript struct
type JavaScript struct {
Timeout uint
BufferSize uint
Response string
}
// Initilializing
func Ini() {
if isIni {
return
}
isIni = true
fun_list = make(map[string]func(Event) string)
}
// JavaScript object constructor
func NewJavaScript() JavaScript {
Ini()
js := JavaScript{
Timeout: 0,
BufferSize: (1024 * 8),
Response: "",
}
return js
}
// This function receives all events
//
//export go_webui_event
func go_webui_event(window unsafe.Pointer, _event_type C.uint, _element *C.char, _data *C.char, _response *C.char) {
Ini()
// Create a new event struct
var event_type uint = uint(_event_type)
var element string = C.GoString(_element)
var data string = C.GoString(_data)
e := Event{
Window: window,
ElementID: element_id,
WindowID: window_id,
ElementName: element_name,
Window: window,
EventType: event_type,
Element: element,
Data: data,
}
fun_list[window_id][element_id](e)
}
// Call user callback function
var window_id uint = uint(C.webui_interface_get_window_id(unsafe.Pointer(window)))
var func_id string = strconv.Itoa(int(window_id)) + element
response := string(fun_list[func_id](e))
func RunJavaScript(window *C.webui_window_t, js *JavaScript) {
// Interface
c_js := C.webui_script_interface_t{
script: C.CString(js.Script),
timeout: 30, // uint(js.Timeout),
error: C.bool(false),
// length: uint(0),
// data: C.CString(nil),
// Set the response back
if len(response) > 0 {
c_response := C.CString(response)
C.webui_interface_set_response(_response, c_response)
}
C.webui_script_interface_struct(window, &c_js)
js.Error = bool(c_js.error)
js.Data = C.GoString(c_js.data)
}
func NewWindow() *C.webui_window_t {
// Run a JavaScript, and get the response back (Make sure your local buffer can hold the response).
func Script(window unsafe.Pointer, js *JavaScript, script string) bool {
return C.webui_new_window()
Ini()
// Convert the JavaScript from Go-String to C-String
c_script := C.CString(script)
// Create a local buffer to hold the response
ResponseBuffer := make([]byte, uint64(js.BufferSize))
// Create a pointer to the local buffer
ptr := (*C.char)(unsafe.Pointer(&ResponseBuffer[0]))
// Run the JavaScript and wait for response
status := C.webui_script(window, c_script, C.uint(js.Timeout), ptr, C.size_t(uint64(js.BufferSize)))
// Copy the response to the users struct
ResponseLen := bytes.IndexByte(ResponseBuffer[:], 0)
js.Response = string(ResponseBuffer[:ResponseLen])
// return the status of the JavaScript execution
// True: No JavaScript error.
// False: JavaScript error.
return bool(status)
}
// Create a new window object
func NewWindow() unsafe.Pointer {
Ini()
// Create a new window object
// this return a (void pointer) and we should
// never change it. It's only managed by WebUI
return unsafe.Pointer(C.webui_new_window())
}
// Close all opened windows
func Exit() {
Ini()
C.webui_exit()
}
func Show(window *C.webui_window_t, content string) {
// Show a window using a embedded HTML, or a file. If the window is already opened then it will be refreshed.
func Show(window unsafe.Pointer, content string) {
Ini()
c_content := C.CString(content)
C.webui_show(window, c_content)
}
func Open(window *C.webui_window_t, url string, browser uint) {
c_url := C.CString(url)
C.webui_open(window, c_url, C.uint(browser))
}
// Wait until all opened windows get closed.
func Wait() {
Ini()
C.webui_wait()
}
func Bind(window *C.webui_window_t, element string, callback func(Event)) {
// Bind a specific html element click event with a function. Empty element means all events.
func Bind(window unsafe.Pointer, element string, callback func(Event) string) {
Ini()
// Convert element from Go-String to C-String
c_element := C.CString(element)
var window_id uint = uint(C._webui_window_get_number(window))
var cb_index uint = uint(C.webui_bind_go(window, c_element))
C.go_webui_bind(window, c_element)
fun_list[window_id][cb_index] = callback
// Get the window ID
var window_id uint = uint(C.webui_interface_get_window_id(window))
// Generate a unique ID for this element
var func_id string = strconv.Itoa(int(window_id)) + element
// Add the user callback function to the list
fun_list[func_id] = callback
}

View File

@ -0,0 +1,189 @@
/*
WebUI Library 2.2.0
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
*/
#ifndef _WEBUI_H
#define _WEBUI_H
#define WEBUI_VERSION "2.2.0"
// Dynamic Library Exports
#if defined(_MSC_VER) || defined(__TINYC__)
#ifndef WEBUI_EXPORT
#define WEBUI_EXPORT __declspec(dllexport)
#endif
#else
#ifndef WEBUI_EXPORT
#define WEBUI_EXPORT extern
#endif
#endif
// -- C STD ---------------------------
#include <stdbool.h>
#include <inttypes.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <time.h>
#include <errno.h>
#include <math.h>
#if defined(__GNUC__) || defined(__TINYC__)
#include <dirent.h>
#endif
// -- Windows -------------------------
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <direct.h>
#include <io.h>
#include <tchar.h>
#define WEBUI_GET_CURRENT_DIR _getcwd
#define WEBUI_FILE_EXIST _access
#define WEBUI_POPEN _popen
#define WEBUI_PCLOSE _pclose
#define WEBUI_MAX_PATH MAX_PATH
#endif
// -- Linux ---------------------------
#ifdef __linux__
#include <pthread.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/time.h>
#define WEBUI_GET_CURRENT_DIR getcwd
#define WEBUI_FILE_EXIST access
#define WEBUI_POPEN popen
#define WEBUI_PCLOSE pclose
#define WEBUI_MAX_PATH PATH_MAX
#endif
// -- Apple ---------------------------
#ifdef __APPLE__
#include <pthread.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/syslimits.h> // PATH_MAX
#include <sys/time.h>
#define WEBUI_GET_CURRENT_DIR getcwd
#define WEBUI_FILE_EXIST access
#define WEBUI_POPEN popen
#define WEBUI_PCLOSE pclose
#define WEBUI_MAX_PATH PATH_MAX
#endif
// -- Enums ---------------------------
enum webui_browsers {
AnyBrowser = 0, // 0. Default recommended web browser
Chrome, // 1. Google Chrome
Firefox, // 2. Mozilla Firefox
Edge, // 3. Microsoft Edge
Safari, // 4. Apple Safari
Chromium, // 5. The Chromium Project
Opera, // 6. Opera Browser
Brave, // 7. The Brave Browser
Vivaldi, // 8. The Vivaldi Browser
Epic, // 9. The Epic Browser
Yandex, // 10. The Yandex Browser
};
enum webui_runtimes {
None = 0, // 0. Prevent WebUI from using any runtime for .js and .ts files
Deno, // 1. Use Deno runtime for .js and .ts files
NodeJS, // 2. Use Nodejs runtime for .js files
};
enum webui_events {
WEBUI_EVENT_DISCONNECTED = 0, // 0. Window disconnection event
WEBUI_EVENT_CONNECTED, // 1. Window connection event
WEBUI_EVENT_MULTI_CONNECTION, // 2. New window connection event
WEBUI_EVENT_UNWANTED_CONNECTION, // 3. New unwanted window connection event
WEBUI_EVENT_MOUSE_CLICK, // 4. Mouse click event
WEBUI_EVENT_NAVIGATION, // 5. Window navigation event
WEBUI_EVENT_CALLBACK, // 6. Function call event
};
// -- Structs -------------------------
typedef struct webui_event_t {
void* window; // Pointer to the window object
unsigned int type; // Event type
char* element; // HTML element ID
char* data; // JavaScript data
char* response; // Callback response
} webui_event_t;
// -- Definitions ---------------------
// Create a new webui window object.
WEBUI_EXPORT void* webui_new_window(void);
// Bind a specific html element click event with a function. Empty element means all events.
WEBUI_EXPORT unsigned int webui_bind(void* window, const char* element, void (*func)(webui_event_t* e));
// Show a window using a embedded HTML, or a file. If the window is already opened then it will be refreshed.
WEBUI_EXPORT bool webui_show(void* window, const char* content);
// Same as webui_show(). But with a specific web browser.
WEBUI_EXPORT bool webui_show_browser(void* window, const char* content, unsigned int browser);
// Wait until all opened windows get closed.
WEBUI_EXPORT void webui_wait(void);
// Close a specific window.
WEBUI_EXPORT void webui_close(void* window);
// Close all opened windows. webui_wait() will break.
WEBUI_EXPORT void webui_exit(void);
// -- Other ---------------------------
WEBUI_EXPORT bool webui_is_shown(void* window);
WEBUI_EXPORT void webui_set_timeout(unsigned int second);
WEBUI_EXPORT void webui_set_icon(void* window, const char* icon, const char* type);
WEBUI_EXPORT void webui_set_multi_access(void* window, bool status);
// -- JavaScript ----------------------
// Quickly run a JavaScript.
WEBUI_EXPORT bool webui_run(void* window, const char* script);
// Run a JavaScript, and get the response back (Make sure your local buffer can hold the response).
WEBUI_EXPORT bool webui_script(void* window, const char* script, unsigned int timeout, char* buffer, size_t buffer_length);
// Chose between Deno and Nodejs runtime for .js and .ts files.
WEBUI_EXPORT void webui_set_runtime(void* window, unsigned int runtime);
// Parse argument as integer.
WEBUI_EXPORT long long int webui_get_int(webui_event_t* e);
// Parse argument as string.
WEBUI_EXPORT const char* webui_get_string(webui_event_t* e);
// Parse argument as boolean.
WEBUI_EXPORT bool webui_get_bool(webui_event_t* e);
// Return the response to JavaScript as integer.
WEBUI_EXPORT void webui_return_int(webui_event_t* e, long long int n);
// Return the response to JavaScript as string.
WEBUI_EXPORT void webui_return_string(webui_event_t* e, char* s);
// Return the response to JavaScript as boolean.
WEBUI_EXPORT void webui_return_bool(webui_event_t* e, bool b);
// -- Interface -----------------------
// Bind a specific html element click event with a function. Empty element means all events. This replace webui_bind().
WEBUI_EXPORT unsigned int webui_interface_bind(void* window, const char* element, void (*func)(void*, unsigned int, char*, char*, char*));
// When using `webui_interface_bind()` you need this function to easily set your response.
WEBUI_EXPORT void webui_interface_set_response(char* ptr, const char* response);
// Check if the app still running or not. This replace webui_wait().
WEBUI_EXPORT bool webui_interface_is_app_running(void);
// Get window unique ID
WEBUI_EXPORT unsigned int webui_interface_get_window_id(void* window);
#endif /* _WEBUI_H */

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "webui2"
version = "2.1.1"
version = "2.2.0"
authors = [
{ name="Hassan Draga" },
]

Binary file not shown.

View File

@ -1,5 +1,5 @@
# WebUI Library 2.1.1
# WebUI Library 2.2.0
#
# http://webui.me
# https://github.com/alifcommunity/webui
@ -26,7 +26,6 @@ PTR_PTR_CHAR = ctypes.POINTER(PTR_CHAR)
# Event
class event:
element_id = 0
window_id = 0
element_name = ""
data = ""
@ -137,7 +136,7 @@ class window:
err_library_not_found('bind')
return
cb_index = int(
WebUI.webui_bind_interface(
WebUI.webui_interface_bind(
self.window,
element.encode('utf-8'),
self.c_events))

View File

@ -1,12 +1,12 @@
# This script is for debugging & development of the WebUI Python wrapper
# The source code is located at 'webui/packages/PyPI/src/webui/webui.py'
# The source code is located at 'webui/examples/Python/PyPI/Package/src/webui/webui.py'
# [!] Make sure to remove the WebUI package
# pip uninstall webui2
# Import the WebUI local module
import sys
sys.path.append('../../../packages/PyPI/src/webui')
sys.path.append('Package/src/webui')
import webui
# Use the local WebUI Dynamic lib

13
examples/Rust/README.md Normal file
View File

@ -0,0 +1,13 @@
# WebUI Examples - Rust
# NOTICE:
## The Rust wrapper still needs to be completed. You can finish it and submit the patch as PR. Or, if you prefer to maintain it in your repo, you can create a new issue and submit the link to your Rust wrapper repo. Thank you.
```sh
git clone https://github.com/alifcommunity/webui.git
cd webui\examples\Rust\hello_world
cargo clean
cargo build
cargo run
```

View File

@ -2,5 +2,7 @@
name = "my-webui-application"
version = "0.1.0"
build = "build.rs"
edition = "2021"
[dependencies]
lazy_static = "1.4.0"

View File

@ -1,13 +1,11 @@
/*
WebUI Library 2.1.1
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
WebUI Library 2.2.0
http://_webui_core.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
*/
// Flags
@ -22,484 +20,238 @@
use std::os::raw::c_char;
use std::ffi::CString;
use std::ffi::CStr;
use std::collections::HashMap;
use lazy_static::lazy_static;
use std::sync::Mutex;
// --[WebUI Library References]--------
pub type size_t = ::std::os::raw::c_ulonglong;
pub const WEBUI_MAX_ARRAY: u32 = 32;
pub const __bool_true_false_are_defined: u32 = 1;
// Consts
pub const true_: u32 = 1;
pub const false_: u32 = 0;
pub const __bool_true_false_are_defined: u32 = 1;
pub type size_t = ::std::os::raw::c_ulong;
pub type wchar_t = ::std::os::raw::c_int;
// Event struct
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_event_t {
pub window_id: ::std::os::raw::c_uint,
pub element_id: ::std::os::raw::c_uint,
pub element_name: *mut ::std::os::raw::c_char,
pub window: *mut webui_window_t,
pub window: *mut ::std::os::raw::c_void,
pub type_: ::std::os::raw::c_uint,
pub element: *mut ::std::os::raw::c_char,
pub data: *mut ::std::os::raw::c_char,
pub data_len: ::std::os::raw::c_uint,
pub response: *mut ::std::os::raw::c_char,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_window_core_t {
pub window_number: ::std::os::raw::c_uint,
pub server_running: bool,
pub connected: bool,
pub server_handled: bool,
pub multi_access: bool,
pub server_root: bool,
pub server_port: ::std::os::raw::c_uint,
pub url: *mut ::std::os::raw::c_char,
pub html: *const ::std::os::raw::c_char,
pub html_cpy: *const ::std::os::raw::c_char,
pub icon: *const ::std::os::raw::c_char,
pub icon_type: *const ::std::os::raw::c_char,
pub CurrentBrowser: ::std::os::raw::c_uint,
pub browser_path: *mut ::std::os::raw::c_char,
pub profile_path: *mut ::std::os::raw::c_char,
pub connections: ::std::os::raw::c_uint,
pub runtime: ::std::os::raw::c_uint,
pub detect_process_close: bool,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_window_t {
pub core: webui_window_core_t,
pub path: *mut ::std::os::raw::c_char,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_javascript_result_t {
pub error: bool,
pub length: ::std::os::raw::c_uint,
pub data: *const ::std::os::raw::c_char,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_script_t {
pub script: *const ::std::os::raw::c_char,
pub timeout: ::std::os::raw::c_uint,
pub result: webui_javascript_result_t,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_cb_t {
pub win: *mut webui_window_t,
pub webui_internal_id: *mut ::std::os::raw::c_char,
pub element_name: *mut ::std::os::raw::c_char,
pub data: *mut ::std::os::raw::c_char,
pub data_len: ::std::os::raw::c_uint,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_cmd_async_t {
pub win: *mut webui_window_t,
pub cmd: *mut ::std::os::raw::c_char,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_custom_browser_t {
pub app: *mut ::std::os::raw::c_char,
pub arg: *mut ::std::os::raw::c_char,
pub auto_link: bool,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_browser_t {
pub any: ::std::os::raw::c_uint,
pub chrome: ::std::os::raw::c_uint,
pub firefox: ::std::os::raw::c_uint,
pub edge: ::std::os::raw::c_uint,
pub safari: ::std::os::raw::c_uint,
pub chromium: ::std::os::raw::c_uint,
pub opera: ::std::os::raw::c_uint,
pub brave: ::std::os::raw::c_uint,
pub vivaldi: ::std::os::raw::c_uint,
pub epic: ::std::os::raw::c_uint,
pub yandex: ::std::os::raw::c_uint,
pub current: ::std::os::raw::c_uint,
pub custom: ::std::os::raw::c_uint,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_runtime_t {
pub none: ::std::os::raw::c_uint,
pub deno: ::std::os::raw::c_uint,
pub nodejs: ::std::os::raw::c_uint,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_t {
pub servers: ::std::os::raw::c_uint,
pub connections: ::std::os::raw::c_uint,
pub custom_browser: *mut webui_custom_browser_t,
pub wait_for_socket_window: bool,
pub html_elements: [*mut ::std::os::raw::c_char; 32usize],
pub used_ports: [::std::os::raw::c_uint; 32usize],
pub last_window: ::std::os::raw::c_uint,
pub startup_timeout: ::std::os::raw::c_uint,
pub use_timeout: bool,
pub timeout_extra: bool,
pub exit_now: bool,
pub run_responses: [*const ::std::os::raw::c_char; 32usize],
pub run_done: [bool; 32usize],
pub run_error: [bool; 32usize],
pub run_last_id: ::std::os::raw::c_uint,
pub browser: webui_browser_t,
pub runtime: webui_runtime_t,
pub initialized: bool,
pub cb: [::std::option::Option<unsafe extern "C" fn(e: *mut webui_event_t)>;
32usize],
pub cb_interface: [::std::option::Option<
unsafe extern "C" fn(
element_id: ::std::os::raw::c_uint,
window_id: ::std::os::raw::c_uint,
element_name: *mut ::std::os::raw::c_char,
window: *mut webui_window_t,
),
>; 32usize],
pub executable_path: *mut ::std::os::raw::c_char,
pub ptr_list: [*mut ::std::os::raw::c_void; 32usize],
pub ptr_position: ::std::os::raw::c_uint,
pub ptr_size: [usize; 32usize],
// References
extern "C" {
pub fn webui_new_window() -> *mut ::std::os::raw::c_void;
}
extern "C" {
pub static mut webui: webui_t;
pub fn webui_bind(
window: *mut ::std::os::raw::c_void,
element: *const ::std::os::raw::c_char,
func: ::std::option::Option<unsafe extern "C" fn(e: *mut webui_event_t)>
) -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn webui_show(
window: *mut ::std::os::raw::c_void,
content: *const ::std::os::raw::c_char
) -> bool;
}
extern "C" {
pub fn webui_show_browser(
window: *mut ::std::os::raw::c_void,
content: *const ::std::os::raw::c_char,
browser: ::std::os::raw::c_uint
) -> bool;
}
extern "C" {
pub fn webui_wait();
}
extern "C" {
pub fn webui_close(window: *mut ::std::os::raw::c_void);
}
extern "C" {
pub fn webui_exit();
}
extern "C" {
pub fn webui_is_any_window_running() -> bool;
pub fn webui_is_shown(window: *mut ::std::os::raw::c_void) -> bool;
}
extern "C" {
pub fn webui_set_timeout(second: ::std::os::raw::c_uint);
}
extern "C" {
pub fn webui_new_window() -> *mut webui_window_t;
}
extern "C" {
pub fn webui_show(
win: *mut webui_window_t,
content: *const ::std::os::raw::c_char
) -> bool;
}
extern "C" {
pub fn webui_set_icon(
win: *mut webui_window_t,
icon_s: *const ::std::os::raw::c_char,
type_s: *const ::std::os::raw::c_char,
window: *mut ::std::os::raw::c_void,
icon: *const ::std::os::raw::c_char,
type_: *const ::std::os::raw::c_char
);
}
extern "C" {
pub fn webui_multi_access(win: *mut webui_window_t, status: bool);
pub fn webui_set_multi_access(window: *mut ::std::os::raw::c_void, status: bool);
}
extern "C" {
pub fn _webui_set_root_folder(
win: *mut webui_window_t,
path: *const ::std::os::raw::c_char,
pub fn webui_run(
window: *mut ::std::os::raw::c_void,
script: *const ::std::os::raw::c_char
) -> bool;
}
extern "C" {
pub fn webui_new_server(
win: *mut webui_window_t,
path: *const ::std::os::raw::c_char,
) -> *const ::std::os::raw::c_char;
}
extern "C" {
pub fn webui_close(win: *mut webui_window_t);
}
extern "C" {
pub fn webui_is_shown(win: *mut webui_window_t) -> bool;
}
extern "C" {
pub fn webui_script(
win: *mut webui_window_t,
script: *mut webui_script_t,
);
}
extern "C" {
pub fn webui_bind(
win: *mut webui_window_t,
element: *const ::std::os::raw::c_char,
func: ::std::option::Option<
// unsafe extern "C" fn(e: *mut webui_event_t),
unsafe fn(e: *mut webui_event_t),
>,
) -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn webui_open(
win: *mut webui_window_t,
url: *const ::std::os::raw::c_char,
browser: ::std::os::raw::c_uint,
) -> bool;
}
extern "C" {
pub fn webui_script_cleanup(script: *mut webui_script_t);
}
extern "C" {
pub fn webui_script_runtime(
win: *mut webui_window_t,
runtime: ::std::os::raw::c_uint,
);
}
extern "C" {
pub fn _webui_wait_process(win: *mut webui_window_t, status: bool);
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct webui_script_interface_t {
pub script: *mut ::std::os::raw::c_char,
pub timeout: ::std::os::raw::c_uint,
pub error: bool,
pub length: ::std::os::raw::c_uint,
pub data: *const ::std::os::raw::c_char,
}
extern "C" {
pub fn webui_bind_interface(
win: *mut webui_window_t,
element: *const ::std::os::raw::c_char,
func: ::std::option::Option<
// unsafe extern "C" fn(
// element_id: ::std::os::raw::c_uint,
// window_id: ::std::os::raw::c_uint,
// element_name: *mut ::std::os::raw::c_char,
// window: *mut webui_window_t,
// ),
unsafe fn(
element_id: ::std::os::raw::c_uint,
window_id: ::std::os::raw::c_uint,
element_name: *mut ::std::os::raw::c_char,
window: *mut webui_window_t,
// TODO: Add char*, char**
),
>,
) -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn webui_script_interface(
win: *mut webui_window_t,
window: *mut ::std::os::raw::c_void,
script: *const ::std::os::raw::c_char,
timeout: ::std::os::raw::c_uint,
error: *mut bool,
length: *mut ::std::os::raw::c_uint,
data: *mut ::std::os::raw::c_char, // TODO: Change this from char* to char**
);
buffer: *mut ::std::os::raw::c_char,
buffer_length: size_t
) -> bool;
}
extern "C" {
pub fn webui_script_interface_struct(
win: *mut webui_window_t,
//js_int: *mut webui_script_interface_t,
js_int: &webui_script_interface_t,
);
pub fn webui_set_runtime(window: *mut ::std::os::raw::c_void, runtime: ::std::os::raw::c_uint);
}
extern "C" {
pub fn _webui_init();
pub fn webui_get_int(e: *mut webui_event_t) -> ::std::os::raw::c_longlong;
}
extern "C" {
pub fn _webui_get_cb_index(
webui_internal_id: *mut ::std::os::raw::c_char,
pub fn webui_get_string(e: *mut webui_event_t) -> *const ::std::os::raw::c_char;
}
extern "C" {
pub fn webui_get_bool(e: *mut webui_event_t) -> bool;
}
extern "C" {
pub fn webui_return_int(e: *mut webui_event_t, n: ::std::os::raw::c_longlong);
}
extern "C" {
pub fn webui_return_string(e: *mut webui_event_t, s: *mut ::std::os::raw::c_char);
}
extern "C" {
pub fn webui_return_bool(e: *mut webui_event_t, b: bool);
}
extern "C" {
pub fn webui_interface_bind(
window: *mut ::std::os::raw::c_void,
element: *const ::std::os::raw::c_char,
func: ::std::option::Option<
unsafe fn(
arg1: *mut ::std::os::raw::c_void,
arg2: ::std::os::raw::c_uint,
arg3: *mut ::std::os::raw::c_char,
arg4: *mut ::std::os::raw::c_char,
arg5: *mut ::std::os::raw::c_char
)
>
) -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn _webui_set_cb_index(
webui_internal_id: *mut ::std::os::raw::c_char,
pub fn webui_interface_set_response(
ptr: *mut ::std::os::raw::c_char,
response: *const ::std::os::raw::c_char
);
}
extern "C" {
pub fn webui_interface_is_app_running() -> bool;
}
extern "C" {
pub fn webui_interface_get_window_id(
window: *mut ::std::os::raw::c_void
) -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn _webui_get_free_port() -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn _webui_get_new_window_number() -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn _webui_wait_for_startup();
}
extern "C" {
pub fn _webui_free_port(port: ::std::os::raw::c_uint);
}
extern "C" {
pub fn _webui_set_custom_browser(p: *mut webui_custom_browser_t);
}
extern "C" {
pub fn _webui_get_current_path() -> *mut ::std::os::raw::c_char;
}
extern "C" {
pub fn _webui_window_receive(
win: *mut webui_window_t,
packet: *const ::std::os::raw::c_char,
len: usize,
);
}
extern "C" {
pub fn _webui_window_send(
win: *mut webui_window_t,
packet: *mut ::std::os::raw::c_char,
packets_size: usize,
);
}
extern "C" {
pub fn _webui_window_event(
win: *mut webui_window_t,
element_id: *mut ::std::os::raw::c_char,
element: *mut ::std::os::raw::c_char,
data: *mut ::std::os::raw::c_char,
data_len: ::std::os::raw::c_uint,
);
}
extern "C" {
pub fn _webui_window_get_number(
win: *mut webui_window_t,
) -> ::std::os::raw::c_uint;
}
extern "C" {
pub fn _webui_window_open(
win: *mut webui_window_t,
link: *mut ::std::os::raw::c_char,
browser: ::std::os::raw::c_uint,
);
}
extern "C" {
pub fn _webui_cmd_sync(
cmd: *mut ::std::os::raw::c_char,
show: bool,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn _webui_cmd_async(
cmd: *mut ::std::os::raw::c_char,
show: bool,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn _webui_run_browser(
win: *mut webui_window_t,
cmd: *mut ::std::os::raw::c_char,
) -> ::std::os::raw::c_int;
}
extern "C" {
pub fn _webui_clean();
}
extern "C" {
pub fn _webui_browser_exist(
win: *mut webui_window_t,
browser: ::std::os::raw::c_uint,
) -> bool;
}
extern "C" {
pub fn _webui_browser_get_temp_path(
browser: ::std::os::raw::c_uint,
) -> *const ::std::os::raw::c_char;
}
extern "C" {
pub fn _webui_folder_exist(folder: *mut ::std::os::raw::c_char) -> bool;
}
extern "C" {
pub fn _webui_browser_create_profile_folder(
win: *mut webui_window_t,
browser: ::std::os::raw::c_uint,
) -> bool;
}
extern "C" {
pub fn _webui_browser_start_edge(
win: *mut webui_window_t,
address: *const ::std::os::raw::c_char,
) -> bool;
}
extern "C" {
pub fn _webui_browser_start_firefox(
win: *mut webui_window_t,
address: *const ::std::os::raw::c_char,
) -> bool;
}
extern "C" {
pub fn _webui_browser_start_custom(
win: *mut webui_window_t,
address: *const ::std::os::raw::c_char,
) -> bool;
}
extern "C" {
pub fn _webui_browser_start_chrome(
win: *mut webui_window_t,
address: *const ::std::os::raw::c_char,
) -> bool;
}
extern "C" {
pub fn _webui_browser_start(
win: *mut webui_window_t,
address: *const ::std::os::raw::c_char,
browser: ::std::os::raw::c_uint,
) -> bool;
}
extern "C" {
pub fn _webui_system_win32(
cmd: *mut ::std::os::raw::c_char,
show: bool,
) -> ::std::os::raw::c_int;
}
// --[Tools]---------------------------
// fn char_to_string(c : *mut ::std::os::raw::c_char) -> String {
// let cstr = unsafe {CStr::from_ptr(c)};
// let s : String = String::from_utf8_lossy(cstr.to_bytes()).to_string();
// return s;
// }
fn char_to_string(c : *const i8) -> String {
let cstr = unsafe {CStr::from_ptr(c)};
let s : String = String::from_utf8_lossy(cstr.to_bytes()).to_string();
return s;
}
fn cstr_to_string(c : CString) -> String {
let s : String = String::from_utf8_lossy(c.to_bytes()).to_string();
return s;
}
// --[Wrapper]-------------------------
// Browsers
pub const AnyBrowser: u32 = 0;
pub const Chrome: u32 = 1;
pub const Firefox: u32 = 2;
pub const Edge: u32 = 3;
pub const Safari: u32 = 4;
pub const Chromium: u32 = 5;
pub const opera: u32 = 6;
pub const brave: u32 = 7;
pub const vivaldi: u32 = 8;
pub const epic: u32 = 9;
pub const yandex: u32 = 10;
pub const current: u32 = 0;
pub const Custom: u32 = 99;
pub const Opera: u32 = 6;
pub const Brave: u32 = 7;
pub const Vivaldi: u32 = 8;
pub const Epic: u32 = 9;
pub const Yandex: u32 = 10;
// Runtimes
pub const None: u32 = 0;
pub const Deno: u32 = 1;
pub const NodeJS: u32 = 2;
// Events
pub const WEBUI_EVENT_DISCONNECTED: u32 = 0;
pub const WEBUI_EVENT_CONNECTED: u32 = 1;
pub const WEBUI_EVENT_MULTI_CONNECTION: u32 = 2;
pub const WEBUI_EVENT_UNWANTED_CONNECTION: u32 = 3;
pub const WEBUI_EVENT_MOUSE_CLICK: u32 = 4;
pub const WEBUI_EVENT_NAVIGATION: u32 = 5;
pub const WEBUI_EVENT_CALLBACK: u32 = 6;
pub struct JavaScript {
pub timeout: u32,
pub script: String,
pub error: bool,
pub data: String,
pub script: String,
pub error: bool,
pub data: String,
}
pub struct Event {
pub ElementId: u32,
pub WindowId: u32,
pub ElementName: String,
pub Window: *mut webui_window_t,
pub Window: *mut ::std::os::raw::c_void,
pub EventType: u32,
pub Element: String,
pub Data: String,
}
// List of Rust user functions (2-dimensional array)
static mut func_list: [[Option::<fn(e: Event) -> ()>; 64]; 64] = [[None; 64]; 64];
// static mut func_list: [[Option::<fn(e: Event) -> ()>; 64]; 64] = [[64; 64]; 64];
// static mut func_array: Vec<Vec<fn(Event)>> = vec![vec![]; 1024];
// static mut elements_map = HashMap::<String, usize>::new();
// static mut elements_map: HashMap::new();
pub fn RunJavaScript(win: *mut webui_window_t, js: &mut JavaScript) {
type FunctionType = fn(Event);
const ROWS: usize = 64;
const COLS: usize = 64;
static mut GLOBAL_ARRAY: Option<[[Option<FunctionType>; COLS]; ROWS]> = None;
lazy_static! {
static ref elements_map: HashMap<String, usize> = HashMap::new();
// static mut func_array: Vec<Vec<fn(Event)>> = vec![vec![]; 1024];
}
// Save a string in the map and return its index
fn save_string(map: &mut HashMap<String, usize>, s: &str) -> usize {
// Check if the string already exists in the map
if let Some(&index) = map.get(s) {
return index;
}
// If the string does not exist, add it to the map and return the new index
let index = map.len();
map.insert(s.to_owned(), index);
index
}
// Search for a string in the map and return its index if found, or -1 if not found
fn find_string(map: &HashMap<String, usize>, s: &str) -> isize {
if let Some(&index) = map.get(s) {
index as isize
} else {
-1
}
}
fn char_to_string(c: *const i8) -> String {
let cstr = unsafe { CStr::from_ptr(c) };
let s: String = String::from_utf8_lossy(cstr.to_bytes()).to_string();
return s;
}
fn cstr_to_string(c: CString) -> String {
let s: String = String::from_utf8_lossy(c.to_bytes()).to_string();
return s;
}
pub fn RunJavaScript(win: *mut ::std::os::raw::c_void, js: &mut JavaScript) {
unsafe {
// Script String to i8/u8
let script_cpy = String::from(js.script.clone());
let script_c_str = CString::new(script_cpy).unwrap();
@ -508,46 +260,41 @@ pub fn RunJavaScript(win: *mut webui_window_t, js: &mut JavaScript) {
let script: webui_script_interface_t = webui_script_interface_t {
timeout: js.timeout,
script: script_c_char as *mut i8,
data: script_c_char, // 'data' TODO: Should be null
data: script_c_char,
error: false,
length: 0,
};
// deprecated
webui_script_interface_struct(win, &script);
// TODO: `webui_script_interface_struct` is deprecated. use `webui_script` instead.
js.error = script.error;
js.data = char_to_string(script.data);
}
}
pub fn NewWindow() -> *mut webui_window_t {
pub fn NewWindow() -> *mut ::std::os::raw::c_void {
unsafe {
GLOBAL_ARRAY = Some([[None; COLS]; ROWS]);
return webui_new_window();
}
}
pub fn Wait() {
unsafe {
webui_wait();
}
}
pub fn Exit() {
unsafe {
webui_exit();
}
}
pub fn Show(win: *mut webui_window_t, content: &str) -> bool {
pub fn Show(win: *mut ::std::os::raw::c_void, content: &str) -> bool {
unsafe {
// Content String to i8/u8
let content_c_str = CString::new(content).unwrap();
let content_c_char: *const c_char = content_c_str.as_ptr() as *const c_char;
@ -556,47 +303,75 @@ pub fn Show(win: *mut webui_window_t, content: &str) -> bool {
}
}
fn events_handler (element_id: ::std::os::raw::c_uint, window_id: ::std::os::raw::c_uint, element_name: *mut ::std::os::raw::c_char, window: *mut webui_window_t) {
fn events_handler(
_window: *mut ::std::os::raw::c_void,
_event_type: ::std::os::raw::c_uint,
_element: *mut ::std::os::raw::c_char,
_data: *mut ::std::os::raw::c_char,
_response: *mut ::std::os::raw::c_char
) {
let Window: *mut ::std::os::raw::c_void = _window;
let EventType: u32 = _event_type;
let Element: String = char_to_string(_element);
let Data: String = char_to_string(_data);
let ElementId: u32 = element_id;
let WindowId: u32 = window_id;
let ElementName: String = char_to_string(element_name);
let Window: *mut webui_window_t = window;
let element_index = find_string(&elements_map, &Element);
if element_index < 0 {
return;
}
let E = Event {
ElementId: ElementId,
WindowId: WindowId,
ElementName: ElementName,
Window: Window,
EventType: EventType,
Element: Element,
Data: Data,
};
// Call the Rust user function
let WindowId_64 = WindowId as usize;
let ElementId_64 = ElementId as usize;
let window_id = webui_interface_get_window_id(_window);
let window_id_64 = window_id as usize;
let element_index_64 = element_index as usize;
unsafe {
(func_list[WindowId_64][ElementId_64]).expect("non-null function pointer")(E);
// func_list[window_id_64][element_index_64].expect("non-null function pointer")(E);
// func_array[window_id_64][element_index_64](E);
// if let Some(func) = GLOBAL_ARRAY[window_id_64][element_index_64] {
// func(E.clone());
// }
if let Some(func) = GLOBAL_ARRAY.as_ref().unwrap()[window_id_64][element_index_64] {
func(E);
}
}
}
pub fn Bind(win: *mut webui_window_t, element: &str, func: fn(e: Event)) {
pub fn Bind(win: *mut ::std::os::raw::c_void, element: &str, func: fn(Event)) {
// Element String to i8/u8
let element_c_str = CString::new(element).unwrap();
let element_c_char: *const c_char = element_c_str.as_ptr() as *const c_char;
// Bind
unsafe {
let f: Option<unsafe fn(element_id: ::std::os::raw::c_uint, window_id: ::std::os::raw::c_uint, element_name: *mut ::std::os::raw::c_char, window: *mut webui_window_t)> = Some(events_handler);
let window_id: ::std::os::raw::c_uint = _webui_window_get_number(win);
let cb_index: ::std::os::raw::c_uint = webui_bind_interface(win, element_c_char, f);
let f: Option<
unsafe fn(
_window: *mut ::std::os::raw::c_void,
_event_type: ::std::os::raw::c_uint,
_element: *mut ::std::os::raw::c_char,
_data: *mut ::std::os::raw::c_char,
_response: *mut ::std::os::raw::c_char
)
> = Some(events_handler);
let element_index = save_string(&mut elements_map, element);
let window_id = webui_interface_get_window_id(win);
let window_id_64 = window_id as usize;
let cb_index_64 = cb_index as usize;
let element_index_64 = element_index as usize;
webui_interface_bind(win, element_c_char, f);
// Add the Rust user function to the list
let user_cb: Option<fn(e: Event)> = Some(func);
func_list[window_id_64][cb_index_64] = user_cb;
// let user_cb: Option<fn(e: Event)> = Some(func);
// func_list[window_id_64][element_index_64] = user_cb;
// func_array[window_id_64][element_index_64] = func;
// GLOBAL_ARRAY[window_id_64][element_index_64] = Some(func as FunctionType);
GLOBAL_ARRAY.as_mut().unwrap()[window_id_64][element_index_64] = Some(func as FunctionType);
}
}

View File

@ -1,5 +1,3 @@
mod Webui;
fn close_the_application (_e: Webui::Event) {

View File

@ -1,7 +1,24 @@
# WebUI Examples - Deno
WebUI can create a web server and use [Deno](https://deno.land/) runtimes to parse `TypeScript` and `JavaScript` files. Another way is simply create a web server using Deno and run a simple system command to run a basic WebUI application to open a window.
This is an example of how to use the WebUI dynamic library in Deno to create an HTML5 based user interface.
Tested using Deno v1.32.3 (v8 11.2.214.9, typescript 5.0.3).
### Deno Hello World
This example shows how to use the WebUI Dynamic Library in Deno.
1. Download and [Install Deno](https://github.com/denoland/deno/releases) (*Or just copy deno binary file into this folder*)
2. Download WebUI pre-built Library (*[webui.me](https://webui.me/)*)
3. Run `deno run --allow-all --unstable hello_world.ts`
Folder structure example (*Windows*)
[My Folder]
* deno
* hello_world.ts
* module/webui.ts
* module/`webui-2-x64` library

View File

@ -1,16 +0,0 @@
### Deno Server
This example shows how to show a simple WebUI window using a Deno-Web-Server.
1. Download and [Install Deno](https://github.com/denoland/deno/releases) (*Or just copy deno binary file into this folder*)
2. Download WebUI pre-built Library (*[webui.me](https://webui.me/)*)
3. Run `deno run --allow-all --unstable deno_server.ts`
Folder structure example (*Windows*)
[My Folder]
* deno.exe (if not installed)
* deno_server.ts --> Import webui.ts -> Load `webui-2-x64` library
* file1.js
* file2.ts
* ...

View File

@ -1,40 +0,0 @@
// Run this script by:
// deno run --allow-all --unstable deno_server.ts
// Import WebUI module
import * as webui from "../module/webui.ts";
// Import Deno Server Module
import { serve } from "https://deno.land/std@0.158.0/http/server.ts";
// Optional - Set a custom library path:
// const lib_full_path = '../../../../build/Windows/MSVC/webui-2-x64.dll';
// console.log("Looking for the WebUI dynamic library at: " + lib_full_path);
// webui.set_lib_path(lib_full_path);
// Deno Server Listener
const port = 8080;
const url = "http://localhost:" + 8080;
const handler = (request: Request): Response => {
const body = `This is a Deno-Web-Server example. Your user-agent is:\n\n${
request.headers.get("user-agent") ?? "Unknown"
}`;
return new Response(body, { status: 200 });
};
serve(handler, { port });
// Create new window
const my_window = webui.new_window();
// Show the window
if(!webui.open(my_window, url, webui.browser.chrome))
webui.open(my_window, url, webui.browser.any);
// Wait until all windows get closed
await webui.wait();
// The window is closed.
console.log('Thank you.');
Deno.exit(0);

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<title>WebUI 2 - Deno Hello World Example</title>
<style>
body {
color: white;
background: #101314;
background: linear-gradient(to right, #101314, #0f1c20, #061f2a);
text-align: center;
font-size: 16px;
font-family: sans-serif;
}
</style>
</head>
<body>
<h1>WebUI 2 - Deno Hello World (File)</h1><br>
A: <input id="MyInputA" value="4"><br><br>
B: <input id="MyInputB" value="6"><br><br>
<div id="Result" style="color: #dbdd52">A + B = ?</div><br><br>
<button id="Calculate">Calculate</button> - <button id="Exit">Exit</button>
<script>
function get_A() {
return parseInt(document.getElementById('MyInputA').value);
}
function get_B() {
return parseInt(document.getElementById('MyInputB').value);
}
function set_result(res) {
document.getElementById("Result").innerHTML = 'A + B = ' + res;
}
</script>
</body>
<!-- Connect this window to the background app -->
<script src="/webui.js"></script>
</html>

View File

@ -2,7 +2,7 @@
// Run this script by:
// deno run --allow-all --unstable hello_world.ts
// Import WebUI module
// Import WebUI module (Local file)
import * as webui from "../module/webui.ts";
// Optional - Set a custom library path:
@ -34,15 +34,15 @@ const my_html = `
<button id="Calculate">Calculate</button> - <button id="Exit">Exit</button>
<script>
function get_A() {
return parseInt(document.getElementById('MyInputA').value);
return parseInt(document.getElementById('MyInputA').value);
}
function get_B() {
return parseInt(document.getElementById('MyInputB').value);
return parseInt(document.getElementById('MyInputB').value);
}
function set_result(res) {
document.getElementById("Result").innerHTML = 'A + B = ' + res;
document.getElementById("Result").innerHTML = 'A + B = ' + res;
}
</script>
</body>
@ -51,32 +51,38 @@ const my_html = `
function calculate(e : webui.event) {
// Create a JS struct
const MyJS: webui.js = {
Script: "",
Timeout: 0,
};
// Call JS function `get_A()`
MyJS.Script = "return get_A();";
webui.run(e.win, MyJS);
const A = MyJS.Data;
// Create a JavaScript object
const my_js = webui.js;
// Check for error
if(MyJS.Error) {
console.log("Error in the JavaScript: " + MyJS.Data);
}
// Settings if needed
// my_js.timeout = 30; // Set javascript execution timeout
// my_js.response_size = 64; // Set the response size in bytes
// Call JS function `get_B()`
MyJS.Script = "return get_B();";
webui.run(e.win, MyJS);
const B = MyJS.Data;
// Call a js function
if(!webui.script(e.win, my_js, "return get_A()")) {
// Error
console.log("Error in the JavaScript: " + my_js.response);
return;
}
const C : Number = parseInt(A) + parseInt(B);
// Get A
const A = my_js.response;
// Set the result
MyJS.Script = "set_result(" + C + ");";
webui.run(e.win, MyJS);
// Call a js function
if(!webui.script(e.win, my_js, "return get_B();")) {
// Error
console.log("Error in the JavaScript: " + my_js.response);
return;
}
// Get B
const B = my_js.response;
// Calculate
const C : number = parseInt(A) + parseInt(B);
// Run js (Quick Way)
webui.run(e.win, "set_result(" + C + ");");
}
// Create new window
@ -85,12 +91,12 @@ const my_window = webui.new_window();
// Bind
webui.bind(my_window, "Calculate", calculate);
webui.bind(my_window, "Exit", function(e : webui.event) {
// Close all windows and exit
webui.exit();
// Close all windows and exit
webui.exit();
});
// Show the window
webui.show(my_window, my_html);
webui.show(my_window, my_html); // Or webui.show(my_window, 'hello_world.html');
// Wait until all windows get closed
await webui.wait();

View File

@ -1,13 +0,0 @@
### Deno Server
This example shows how to use the WebUI Dynamic Library in Deno.
1. Download and [Install Deno](https://github.com/denoland/deno/releases) (*Or just copy deno binary file into this folder*)
2. Download WebUI pre-built Library (*[webui.me](https://webui.me/)*)
3. Run `deno run --allow-all --unstable hello_world.ts`
Folder structure example (*Windows*)
[My Folder]
* deno.exe (if not installed)
* hello_world.ts --> Import webui.ts -> Load `webui-2-x64` library

View File

@ -1,309 +0,0 @@
/*
WebUI Library 2.1.1
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
*/
import { existsSync } from "https://deno.land/std/fs/mod.ts";
// import { readCString } from "https://deno.land/std/c/strings/mod.ts";
export const version = '2.1.1';
const encoder = new TextEncoder();
const decoder = new TextDecoder();
let lib_loaded = false;
let webui_lib;
export const browser = {};
browser.any = 0;
browser.chrome = 1;
browser.firefox = 2;
browser.edge = 3;
browser.safari = 4;
browser.chromium = 5;
export interface event {
element_id: number;
window_id: number;
element_name_ptr: string;
win: Deno.Pointer;
data: string;
}
export interface js {
Timeout: number;
Script: string;
Error: boolean;
Length: number;
Data: string;
}
// Determine the library name based
// on the current operating system
let lib_name : string;
let os_sep : string;
if (Deno.build.os === 'windows') {
lib_name = 'webui-2-x64.dll';
os_sep = '\\';
}
else if (Deno.build.os === 'linux') {
lib_name = 'webui-2-x64.so';
os_sep = '/';
}
else {
lib_name = 'webui-2-x64.dyn';
os_sep = '/';
}
// Full path to the library name
let lib_path = './' + lib_name;
// Check if a file exist
function is_file_exist(path : string): boolean {
// TODO: existsSync() is deprecated
return existsSync(path);
}
// Convert String to C-String
function string_to_uint8array(value: string) : Uint8Array {
return encoder.encode(value + '\0');
}
// Get current folder path
function get_current_module_path() : string {
const __dirname = new URL('.', import.meta.url).pathname;
let directory = String(__dirname);
if (Deno.build.os === 'windows') {
// Remove '/'
let buf = directory.substring(1);
directory = buf;
// Replace '/' by '\'
buf = directory.replaceAll('/', os_sep);
directory = buf;
}
return directory;
}
// Convert C-String to String
function uint8array_to_string(value: ArrayBuffer) : string {
return decoder.decode(value);
}
// Load the library
function load_lib() {
if(lib_loaded)
return;
// Check if the library file exist
if(!is_file_exist(lib_path)) {
let lib_path_cwd = get_current_module_path() + lib_name;
if(!is_file_exist(lib_path_cwd)) {
console.log('WebUI Error: File not found (' + lib_path + ') or (' + lib_path_cwd + ')');
Deno.exit(1);
}
lib_path = lib_path_cwd;
}
// Load the library
// FFI
webui_lib = Deno.dlopen(
lib_path,
{
webui_wait: {
parameters: [],
result: 'void',
nonblocking: true,
},
webui_new_window: {
parameters: [],
result: 'pointer',
nonblocking: false,
},
webui_new_server: {
parameters: ['pointer', 'buffer'],
result: 'pointer',
nonblocking: false,
},
webui_show: {
parameters: ['pointer', 'buffer'],
result: 'i32',
nonblocking: false,
},
webui_open: {
parameters: ['pointer', 'buffer', 'u32'],
result: 'i32',
nonblocking: false,
},
webui_bind_interface: {
parameters: ['pointer', 'buffer', 'function'],
result: 'u32',
nonblocking: false,
},
webui_is_app_running: {
parameters: [],
result: 'i32',
nonblocking: false,
},
webui_exit: {
parameters: [],
result: 'void',
nonblocking: false,
},
webui_script_interface: {
parameters: ['pointer', 'buffer', 'u32', 'buffer', 'buffer', 'buffer'],
result: 'void',
nonblocking: false,
},
webui_clean_mem: {
parameters: ['pointer'],
result: 'void',
nonblocking: false,
},
} as const,
);
// Make sure we don't load twice
lib_loaded = true;
}
export function set_lib_path(path : string) {
lib_path = path;
}
export function new_window() : Deno.Pointer {
load_lib();
return webui_lib.symbols.webui_new_window();
}
export function new_server(win : Deno.Pointer = null, path : string) : string {
load_lib();
const ptr = webui_lib.symbols.webui_new_server(win, string_to_uint8array(path));
const dataView = new Deno.UnsafePointerView(ptr);
return String(dataView.getCString());
}
export function show(win : Deno.Pointer, content : string) : number {
load_lib();
return webui_lib.symbols.webui_show(win, string_to_uint8array(content));
}
export function open(win, url : string, browser : number) : number {
load_lib();
return webui_lib.symbols.webui_open(win, string_to_uint8array(url), browser);
}
export function exit() {
load_lib();
webui_lib.symbols.webui_exit();
}
// - - - - - - - - - - - - - - - -
// TODO: We should use the Non-blocking FFI to call
// `webui_lib.symbols.webui_wait()`. but it breaks
// the main thread. Lets do it in another way for now.
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
export async function wait() {
load_lib();
while(true) {
await sleep(50);
if(!webui_lib.symbols.webui_is_app_running())
break;
}
}
// - - - - - - - - - - - - - - - -
export function run(win : number, javascript : js) {
load_lib();
// Buffers
const bool_buffer = new Uint8Array(1); // 1 byte bool
const integer_buffer = new Uint8Array(4); // 4 bytes integer
const pointer_buffer = new Uint8Array(8); // 8 bytes pointer (x64)
// Execute the script
webui_lib.symbols.webui_script_interface(win, string_to_uint8array(javascript.Script), javascript.Timeout, bool_buffer, integer_buffer, pointer_buffer);
let error : Boolean = false;
let length : Number = 0;
let data : String = "";
// Resolve boolean
if(bool_buffer[0] === 0)
error = false;
else
error = true;
// Resolve number
length = Number(new Uint32Array(integer_buffer.buffer)[0]);
// Resolve string
const charPointer = Deno.UnsafePointer.create(BigInt(new BigUint64Array(pointer_buffer.buffer)[0]));
data = String(Deno.UnsafePointerView.getCString(charPointer, 0));
// Update
javascript.Error = Boolean(error);
javascript.Length = Number(length);
javascript.Data = String(data);
// Clean memory
webui_lib.symbols.webui_clean_mem(charPointer);
}
export function bind(win : number, element : string, func : Function) : number {
load_lib();
const callbackResource = new Deno.UnsafeCallback(
{
parameters: ['u32', 'u32', 'pointer', 'pointer', 'pointer', 'pointer'],
result: 'void',
} as const,
(
param_element_id: Deno.u32,
param_window_id: Deno.u32,
param_element_name_ptr: Deno.Pointer,
param_win: Deno.Pointer,
param_data: Deno.Pointer,
param_response: Deno.PointerValue,
) => {
// Create elements
const element_id = parseInt(param_element_id);
const window_id = parseInt(param_window_id);
const element_name = new Deno.UnsafePointerView(param_element_name_ptr).getCString();
const win = param_win;
const data = new Deno.UnsafePointerView(param_data).getCString();
// Create struct
const e: event = {
element_id: element_id,
window_id: window_id,
element_name: element_name,
win: win,
data: data,
};
// Call the user callback
const result = String(func(e));
// -- This code is by ChatGPT (AI) --------
const resultBytes = encoder.encode(result); // Convert the string to bytes
const buf = new Uint8Array(resultBytes.length + 1); // Allocate a buffer to hold the string
buf.set(resultBytes); // Copy the bytes of the string into the buffer
buf[resultBytes.length] = 0; // Set the null terminator
// ----------------------------------------
// 8 bytes ie. pointer size on a 64 bit machine, use BigUin64Array to get a writable and suitable view into it.
const response_writable = new BigUint64Array(Deno.UnsafePointerView.getArrayBuffer(param_response, 8));
// Write our string response buffer address into the `param_response` memory slot.
response_writable[0] = BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(buf)));
},
);
webui_lib.symbols.webui_bind_interface(win, string_to_uint8array(element), callbackResource.pointer);
return 0;
}

Binary file not shown.

View File

@ -0,0 +1,287 @@
/*
WebUI Library 2.2.0
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
*/
import { existsSync } from "https://deno.land/std/fs/mod.ts";
export const version = '2.2.0';
const encoder = new TextEncoder();
const decoder = new TextDecoder();
let lib_loaded = false;
let webui_lib;
export const browser = {
AnyBrowser: 0, // 0. Default recommended web browser
Chrome: 1, // 1. Google Chrome
Firefox: 2, // 2. Mozilla Firefox
Edge: 3, // 3. Microsoft Edge
Safari: 4, // 4. Apple Safari
Chromium: 5, // 5. The Chromium Project
Opera: 6, // 6. Opera Browser
Brave: 7, // 7. The Brave Browser
Vivaldi: 8, // 8. The Vivaldi Browser
Epic: 9, // 9. The Epic Browser
Yandex: 10, // 10. The Yandex Browser
};
export interface event {
win: Deno.Pointer,
type: number,
element: string,
data: string,
}
export const js = {
timeout: 0,
BufferSize: (1024 * 8),
response: "",
}
// Determine the library name based
// on the current operating system
let lib_name: string;
let os_sep: string;
if (Deno.build.os === 'windows') {
lib_name = 'webui-2-x64.dll';
os_sep = '\\';
}
else if (Deno.build.os === 'linux') {
lib_name = 'webui-2-x64.so';
os_sep = '/';
}
else {
lib_name = 'webui-2-x64.dyn';
os_sep = '/';
}
// Full path to the library name
let lib_path = './' + lib_name;
// Check if a file exist
function is_file_exist(path: string): boolean {
// TODO: existsSync() is deprecated
return existsSync(path);
}
// Convert String to C-String
function string_to_uint8array(value: string): Uint8Array {
return encoder.encode(value + '\0');
}
// Get current folder path
function get_current_module_path(): string {
const __dirname = new URL('.', import.meta.url).pathname;
let directory = String(__dirname);
if (Deno.build.os === 'windows') {
// Remove '/'
let buf = directory.substring(1);
directory = buf;
// Replace '/' by '\'
buf = directory.replaceAll('/', os_sep);
directory = buf;
}
return directory;
}
// Convert C-String to String
function uint8array_to_string(value: ArrayBuffer): string {
return decoder.decode(value);
}
// Load the library
function load_lib() {
if(lib_loaded)
return;
// Check if the library file exist
if(!is_file_exist(lib_path)) {
let lib_path_cwd = get_current_module_path() + lib_name;
if(!is_file_exist(lib_path_cwd)) {
console.log('WebUI Error: File not found (' + lib_path + ') or (' + lib_path_cwd + ')');
Deno.exit(1);
}
lib_path = lib_path_cwd;
}
// Load the library
// FFI
webui_lib = Deno.dlopen(
lib_path,
{
webui_wait: {
// void webui_wait(void)
parameters: [],
result: 'void',
nonblocking: true,
},
webui_interface_is_app_running: {
// bool webui_interface_is_app_running(void)
parameters: [],
result: 'i32',
nonblocking: false,
},
webui_new_window: {
// void* webui_new_window(void)
parameters: [],
result: 'pointer',
nonblocking: false,
},
webui_show: {
// bool webui_show(void* window, const char* content)
parameters: ['pointer', 'buffer'],
result: 'i32',
nonblocking: false,
},
webui_show_browser: {
// bool webui_show_browser(void* window, const char* content, unsigned int browser)
parameters: ['pointer', 'buffer', 'u32'],
result: 'i32',
nonblocking: false,
},
webui_interface_bind: {
// unsigned int webui_interface_bind(void* window, const char* element, void (*func)(void*, int, char*, char*, char*))
parameters: ['pointer', 'buffer', 'function'],
result: 'u32',
nonblocking: false,
},
webui_script: {
// bool webui_script(void* window, const char* script, unsigned int timeout, char* buffer, size_t buffer_length)
parameters: ['pointer', 'buffer', 'u32', 'buffer', 'i32'],
result: 'i32',
nonblocking: false,
},
webui_run: {
// bool webui_run(void* window, const char* script)
parameters: ['pointer', 'buffer'],
result: 'i32',
nonblocking: false,
},
webui_interface_set_response: {
// void webui_interface_set_response(char* ptr, const char* response)
parameters: ['pointer', 'buffer'],
result: 'void',
nonblocking: false,
},
webui_exit: {
// void webui_exit(void)
parameters: [],
result: 'void',
nonblocking: false,
}
} as const,
);
// Make sure we don't load twice
lib_loaded = true;
}
export function set_lib_path(path: string) {
lib_path = path;
}
export function new_window(): Deno.Pointer {
load_lib();
return webui_lib.symbols.webui_new_window();
}
export function show(win: Deno.Pointer, content: string): number {
load_lib();
return webui_lib.symbols.webui_show(win, string_to_uint8array(content));
}
export function show_browser(win: Deno.Pointer, content: string, browser: number): number {
load_lib();
return webui_lib.symbols.webui_show_browser(win, string_to_uint8array(content), browser);
}
export function exit() {
load_lib();
webui_lib.symbols.webui_exit();
}
export function script(win: Deno.Pointer, js, script: string): boolean {
load_lib();
// Response Buffer
const size: number = (js.BufferSize > 0 ? js.BufferSize: (1024 * 8));
const buffer = new Uint8Array(size);
// Execute the script
const status = webui_lib.symbols.webui_script(win, string_to_uint8array(script), js.timeout, buffer, size);
// Update
js.response = String(uint8array_to_string(buffer));
return Boolean(status);
}
export function run(win: Deno.Pointer, script: string): boolean {
load_lib();
// Execute the script
const status = webui_lib.symbols.webui_run(win, string_to_uint8array(script));
return Boolean(status);
}
export function bind(win: Deno.Pointer, element: string, func: Function) {
load_lib();
const callbackResource = new Deno.UnsafeCallback(
{
parameters: ['pointer', 'u32', 'pointer', 'pointer', 'pointer'],
result: 'void',
} as const,
(
param_window: Deno.Pointer,
param_type: Deno.u32,
param_element: Deno.Pointer,
param_data: Deno.Pointer,
param_response: Deno.Pointer
) => {
// Create elements
const win = param_window;
const type = parseInt(param_type);
const element = new Deno.UnsafePointerView(param_element).getCString();
const data = new Deno.UnsafePointerView(param_data).getCString();
// Create struct
const e: event = {
win: win,
type: type,
element: element,
data: data,
};
// Call the user callback
const result = String(func(e));
// Send back the response
webui_lib.symbols.webui_interface_set_response(param_response, string_to_uint8array(result));
},
);
webui_lib.symbols.webui_interface_bind(win, string_to_uint8array(element), callbackResource.pointer);
}
// TODO: We should use the Non-blocking FFI to call
// `webui_lib.symbols.webui_wait()`. but it breaks
// the main thread. Lets do it in another way for now.
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
export async function wait() {
load_lib();
while(true) {
await sleep(10);
if(!webui_lib.symbols.webui_interface_is_app_running())
break;
}
}

View File

@ -1,4 +1,7 @@
# WebUI Examples - Node.js
# WebUI Examples - Nodejs
WebUI can create a web server and use [Node.js](https://nodejs.org/) runtimes to parse `JavaScript` files. Another way is simply create a web server using Node.js and run a simple system command to run a basic WebUI application to open a window.
Unfortunately, Nodejs does not support FFI natively (only trough unofficial addon). We recommend using Deno instead.
The only way to use Nodejs with WebUI is to create a simple app in another language like C, C++, Nim, Go, Python, V, Zig, Rust... and use `webui_set_runtime()` to interpret the Nodejs files.

View File

@ -1,18 +0,0 @@
### Node.js Server
This example shows how to create a web server using Node.js and run a simple system command to run a basic WebUI application to open a window.
1. Download and [Install Node.js](https://nodejs.org/en/download/)
2. Build WebUI Library (*[instructions](https://github.com/alifcommunity/webui/tree/main/build)*)
3. Build `window.c` using any C compiler (*[instructions](https://github.com/alifcommunity/webui/tree/main/examples/C)*)
3. Run `node server.js`
Folder structure example (*Windows*)
[My Folder]
* node.exe (if not installed)
* window.exe
* server.js
* file1.js
* file2.js
* ...

View File

@ -1,30 +0,0 @@
// Modules
const http = require('http');
// Config
const port = 8080;
const url = "http://localhost:" + 8080;
// Server Listener
const requestListener = function (req, res) {
res.writeHead(200);
res.end('Hello, World!\nNode.js will automatically stop when you close this window.\nNo need for Ctrl + D!');
}
// Create a web server using Nodejs
const server = http.createServer(requestListener);
server.listen(port);
// Run the WebUI example application to open a new window
const { spawn } = require("child_process");
const ls = spawn("window", [url]);
ls.on('error', (error) => {
console.log('Failed to start the window');
process.exit();
});
ls.on("close", code => {
console.log('Thank you.');
process.exit();
});

View File

@ -1,27 +0,0 @@
#include "webui.h"
int main(int argc, char* argv[]) {
// argc should be exactly 2
if(argc != 2)
return 1;
// Get the Nodejs server url
const char *url = argv[1];
// Create a new window
webui_window_t* my_window;
my_window = webui_new_window();
// Show the window
if(!webui_open(my_window, url, webui.browser.chrome)) // Run the window on Chrome
webui_open(my_window, url, webui.browser.any); // If not, run on any other installed web browser
// Wait until all windows get closed
webui_wait();
return 0;
}

View File

@ -1,18 +0,0 @@
### WebUI Server
This example shows how to create a WebUI web server and use Node.js runtimes to parse JavaScript files.
1. Download and [Install Node.js](https://nodejs.org/en/download/)
2. Build WebUI Library (*[instructions](https://github.com/alifcommunity/webui/tree/main/build)*)
3. Build `example.c` using any C compiler (*[instructions](https://github.com/alifcommunity/webui/tree/main/examples/C)*)
Folder structure example (*Windows*)
[My Folder]
* node.exe (if not installed)
* example.exe
* index.js or index.html
* style.css
* file1.js
* file2.js
* ...

View File

@ -1,34 +0,0 @@
#include "webui.h"
int main() {
// Create a new window
webui_window_t* my_window;
my_window = webui_new_window();
// Chose your preferable runtime for .js files
// Deno: webui.runtime.deno
// Node.js: webui.runtime.nodejs
webui_script_runtime(my_window, webui.runtime.nodejs);
// Create a new web server using WebUI
const char* url = webui_new_server(my_window, "");
// Show the window
if(!webui_open(my_window, url, webui.browser.chrome)) // Run the window on Chrome
webui_open(my_window, url, webui.browser.any); // If not, run on any other installed web browser
// Wait until all windows get closed
webui_wait();
return 0;
}
#if defined(_MSC_VER)
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
main();
}
#endif

View File

@ -1,6 +0,0 @@
var MyModule = require('./my_module');
console.log(
"Welcome!, You are using a WebUI server.\nToday is " + MyModule.date_time()
);

View File

@ -1,5 +0,0 @@
exports.date_time = function () {
return Date();
};

View File

@ -65,13 +65,13 @@ export fn check_the_password(e_opt: ?*c.webui_event_t) callconv(.C) void {
c.webui_script(e.window, &js);
// Check if there is a JavaScript error
if (js.result.@"error") {
std.log.err("JavaScript Error: {s}\n", .{js.result.data});
if (js.@"error") {
std.log.err("JavaScript Error: {s}\n", .{js.data});
return;
}
// Get the password
const password = std.mem.span(js.result.data);
const password = std.mem.span(js.data);
std.log.info("Password: {s}", .{password});
// Check the password

View File

@ -1,4 +1,4 @@
// WebUI Library 2.1.1
// WebUI Library 2.2.0
// Serve a Folder Example
pub fn main() void {

View File

@ -1,46 +1,29 @@
/*
WebUI Library 2.1.1
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
WebUI Library 2.2.0
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
*/
#ifndef _WEBUI_H
#define _WEBUI_H
#define WEBUI_VERSION "2.2.0"
// Dynamic Library Exports
#if defined(_MSC_VER) || defined(__TINYC__)
#define EXPORT __declspec(dllexport)
#ifndef WEBUI_EXPORT
#define WEBUI_EXPORT __declspec(dllexport)
#endif
#else
#define EXPORT extern
#ifndef WEBUI_EXPORT
#define WEBUI_EXPORT extern
#endif
#endif
#define WEBUI_VERSION "2.1.1" // Version
#define WEBUI_HEADER_SIGNATURE 0xFF // All packets should start with this 8bit
#define WEBUI_HEADER_JS 0xFE // Javascript result in frontend
#define WEBUI_HEADER_CLICK 0xFD // Click event
#define WEBUI_HEADER_SWITCH 0xFC // Frontend refresh
#define WEBUI_HEADER_CLOSE 0xFB // Close window
#define WEBUI_HEADER_CALL_FUNC 0xFA // Call a backend function
#define WEBUI_MAX_ARRAY (1024) // Max threads, servers, windows, pointers..
#define WEBUI_MIN_PORT (10000) // Minimum socket port
#define WEBUI_MAX_PORT (65500) // Should be less than 65535
#define WEBUI_MAX_BUF (1024000) // 1024 Kb max dynamic memory allocation
#define WEBUI_DEFAULT_PATH "." // Default root path
#define WEBUI_DEF_TIMEOUT (8) // Default startup timeout in seconds
#define WEBUI_EVENT_CONNECTED (1) // Window connected
#define WEBUI_EVENT_MULTI_CONNECTION (2) // Multi clients connected
#define WEBUI_EVENT_UNWANTED_CONNECTION (3) // Unwanted client connected
#define WEBUI_EVENT_DISCONNECTED (4) // Window disconnected
#define WEBUI_EVENT_MOUSE_CLICK (5) // Mouse Click
#define WEBUI_EVENT_NAVIGATION (6) // The window URL changed
#define WEBUI_EVENT_CALLBACK (7) // Function call
// -- C STD ---------------------------
#include <stdbool.h>
#include <inttypes.h>
@ -63,11 +46,9 @@
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// #include <SDKDDKVer.h> // Fix _WIN32_WINNT warning
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
// #include <iphlpapi.h>
#include <direct.h>
#include <io.h>
#include <tchar.h>
@ -77,24 +58,27 @@
#define WEBUI_PCLOSE _pclose
#define WEBUI_MAX_PATH MAX_PATH
#endif
// -- Linux ---------------------------
#ifdef __linux__
#include <pthread.h> // POSIX threading
#include <pthread.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/time.h>
#define WEBUI_GET_CURRENT_DIR getcwd
#define WEBUI_FILE_EXIST access
#define WEBUI_POPEN popen
#define WEBUI_PCLOSE pclose
#define WEBUI_MAX_PATH PATH_MAX
#endif
// -- Apple ---------------------------
#ifdef __APPLE__
#include <pthread.h> // POSIX threading
#include <pthread.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
@ -102,6 +86,7 @@
#include <fcntl.h>
#include <poll.h>
#include <sys/syslimits.h> // PATH_MAX
#include <sys/time.h>
#define WEBUI_GET_CURRENT_DIR getcwd
#define WEBUI_FILE_EXIST access
#define WEBUI_POPEN popen
@ -109,232 +94,96 @@
#define WEBUI_MAX_PATH PATH_MAX
#endif
// -- Enums ---------------------------
enum webui_browsers {
AnyBrowser = 0, // 0. Default recommended web browser
Chrome, // 1. Google Chrome
Firefox, // 2. Mozilla Firefox
Edge, // 3. Microsoft Edge
Safari, // 4. Apple Safari
Chromium, // 5. The Chromium Project
Opera, // 6. Opera Browser
Brave, // 7. The Brave Browser
Vivaldi, // 8. The Vivaldi Browser
Epic, // 9. The Epic Browser
Yandex, // 10. The Yandex Browser
};
enum webui_runtimes {
None = 0, // 0. Prevent WebUI from using any runtime for .js and .ts files
Deno, // 1. Use Deno runtime for .js and .ts files
NodeJS, // 2. Use Nodejs runtime for .js files
};
enum webui_events {
WEBUI_EVENT_DISCONNECTED = 0, // 0. Window disconnection event
WEBUI_EVENT_CONNECTED, // 1. Window connection event
WEBUI_EVENT_MULTI_CONNECTION, // 2. New window connection event
WEBUI_EVENT_UNWANTED_CONNECTION, // 3. New unwanted window connection event
WEBUI_EVENT_MOUSE_CLICK, // 4. Mouse click event
WEBUI_EVENT_NAVIGATION, // 5. Window navigation event
WEBUI_EVENT_CALLBACK, // 6. Function call event
};
// -- Structs -------------------------
struct webui_event_t;
typedef struct webui_timer_t {
struct timespec start;
struct timespec now;
} webui_timer_t;
typedef struct webui_window_core_t {
unsigned int window_number;
bool server_running;
bool connected;
bool server_handled;
bool multi_access;
bool server_root;
unsigned int server_port;
char* url;
const char* html;
const char* html_cpy;
const char* icon;
const char* icon_type;
unsigned int CurrentBrowser;
char* browser_path;
char* profile_path;
unsigned int connections;
unsigned int runtime;
bool detect_process_close;
bool has_events;
#ifdef _WIN32
HANDLE server_thread;
#else
pthread_t server_thread;
#endif
} webui_window_core_t;
typedef struct webui_window_t {
webui_window_core_t core;
char* path;
} webui_window_t;
typedef struct webui_event_t {
unsigned int window_id;
unsigned int element_id;
char* element_name;
webui_window_t* window;
void* data;
void* response;
int type;
void* window; // Pointer to the window object
unsigned int type; // Event type
char* element; // HTML element ID
char* data; // JavaScript data
char* response; // Callback response
} webui_event_t;
typedef struct webui_javascript_result_t {
bool error;
unsigned int length;
const char* data;
} webui_javascript_result_t;
typedef struct webui_script_t {
const char* script;
unsigned int timeout;
webui_javascript_result_t result;
} webui_script_t;
typedef struct webui_cb_t {
webui_window_t* win;
char* webui_internal_id;
char* element_name;
void* data;
unsigned int data_len;
int event_type;
} webui_cb_t;
typedef struct webui_cmd_async_t {
webui_window_t* win;
char* cmd;
} webui_cmd_async_t;
typedef struct webui_custom_browser_t {
char* app;
char* arg;
bool auto_link;
} webui_custom_browser_t;
typedef struct webui_browser_t {
unsigned int any; // 0
unsigned int chrome; // 1
unsigned int firefox; // 2
unsigned int edge; // 3
unsigned int safari; // 4
unsigned int chromium; // 5
unsigned int opera; // 6
unsigned int brave; // 7
unsigned int vivaldi; // 8
unsigned int epic; // 9
unsigned int yandex; // 10
unsigned int current; // x
unsigned int custom; // 99
} webui_browser_t;
typedef struct webui_runtime_t {
unsigned int none; // 0
unsigned int deno; // 1
unsigned int nodejs; // 2
} webui_runtime_t;
typedef struct webui_t {
unsigned int servers;
unsigned int connections;
unsigned int process;
webui_custom_browser_t *custom_browser;
bool wait_for_socket_window;
char* html_elements[WEBUI_MAX_ARRAY];
unsigned int used_ports[WEBUI_MAX_ARRAY];
unsigned int last_window;
unsigned int startup_timeout;
bool use_timeout;
bool timeout_extra;
bool exit_now;
const char* run_responses[WEBUI_MAX_ARRAY];
bool run_done[WEBUI_MAX_ARRAY];
bool run_error[WEBUI_MAX_ARRAY];
unsigned int run_last_id;
struct mg_mgr* mg_mgrs[WEBUI_MAX_ARRAY];
struct mg_connection* mg_connections[WEBUI_MAX_ARRAY];
webui_browser_t browser;
webui_runtime_t runtime;
bool initialized;
void (*cb[WEBUI_MAX_ARRAY])(webui_event_t* e);
void (*cb_interface[WEBUI_MAX_ARRAY])(unsigned int, unsigned int, char*, webui_window_t*, char*, char**);
char* executable_path;
void *ptr_list[WEBUI_MAX_ARRAY];
unsigned int ptr_position;
size_t ptr_size[WEBUI_MAX_ARRAY];
} webui_t;
// -- Definitions ---------------------
EXPORT webui_t webui;
// Create a new window object
EXPORT webui_window_t* webui_new_window(void);
// Bind a specific html element click event with a function
EXPORT unsigned int webui_bind(webui_window_t* win, const char* element, void (*func)(webui_event_t* e));
// Show a window using a static HTML script, or a file name in the same working directory. If the window is already opened then it will be refreshed with the new content
EXPORT bool webui_show(webui_window_t* win, const char* content);
// Wait until all opened windows get closed
EXPORT void webui_wait(void);
// Close a specific window
EXPORT void webui_close(webui_window_t* win);
// Close all opened windows
EXPORT void webui_exit(void);
// Create a new webui window object.
WEBUI_EXPORT void* webui_new_window(void);
// Bind a specific html element click event with a function. Empty element means all events.
WEBUI_EXPORT unsigned int webui_bind(void* window, const char* element, void (*func)(webui_event_t* e));
// Show a window using a embedded HTML, or a file. If the window is already opened then it will be refreshed.
WEBUI_EXPORT bool webui_show(void* window, const char* content);
// Same as webui_show(). But with a specific web browser.
WEBUI_EXPORT bool webui_show_browser(void* window, const char* content, unsigned int browser);
// Wait until all opened windows get closed.
WEBUI_EXPORT void webui_wait(void);
// Close a specific window.
WEBUI_EXPORT void webui_close(void* window);
// Close all opened windows. webui_wait() will break.
WEBUI_EXPORT void webui_exit(void);
// JavaScript
EXPORT void webui_script(webui_window_t* win, webui_script_t* script);
EXPORT void webui_script_cleanup(webui_script_t* script);
EXPORT void webui_script_runtime(webui_window_t* win, unsigned int runtime);
EXPORT long long int webui_get_int(webui_event_t* e);
EXPORT const char* webui_get_string(webui_event_t* e);
EXPORT bool webui_get_bool(webui_event_t* e);
EXPORT void webui_return_int(webui_event_t* e, long long int n);
EXPORT void webui_return_string(webui_event_t* e, char* s);
EXPORT void webui_return_bool(webui_event_t* e, bool b);
// -- Other ---------------------------
WEBUI_EXPORT bool webui_is_shown(void* window);
WEBUI_EXPORT void webui_set_timeout(unsigned int second);
WEBUI_EXPORT void webui_set_icon(void* window, const char* icon, const char* type);
WEBUI_EXPORT void webui_set_multi_access(void* window, bool status);
// Other
EXPORT const char* webui_new_server(webui_window_t* win, const char* path);
EXPORT bool webui_open(webui_window_t* win, const char* url, unsigned int browser);
EXPORT bool webui_is_any_window_running(void);
EXPORT bool webui_is_app_running(void);
EXPORT bool webui_is_shown(webui_window_t* win);
EXPORT void webui_set_timeout(unsigned int second);
EXPORT void webui_set_icon(webui_window_t* win, const char* icon_s, const char* type_s);
EXPORT void webui_multi_access(webui_window_t* win, bool status);
EXPORT void webui_clean_mem(void* p);
// -- JavaScript ----------------------
// Quickly run a JavaScript.
WEBUI_EXPORT bool webui_run(void* window, const char* script);
// Run a JavaScript, and get the response back (Make sure your local buffer can hold the response).
WEBUI_EXPORT bool webui_script(void* window, const char* script, unsigned int timeout, char* buffer, size_t buffer_length);
// Chose between Deno and Nodejs runtime for .js and .ts files.
WEBUI_EXPORT void webui_set_runtime(void* window, unsigned int runtime);
// Parse argument as integer.
WEBUI_EXPORT long long int webui_get_int(webui_event_t* e);
// Parse argument as string.
WEBUI_EXPORT const char* webui_get_string(webui_event_t* e);
// Parse argument as boolean.
WEBUI_EXPORT bool webui_get_bool(webui_event_t* e);
// Return the response to JavaScript as integer.
WEBUI_EXPORT void webui_return_int(webui_event_t* e, long long int n);
// Return the response to JavaScript as string.
WEBUI_EXPORT void webui_return_string(webui_event_t* e, char* s);
// Return the response to JavaScript as boolean.
WEBUI_EXPORT void webui_return_bool(webui_event_t* e, bool b);
// -- Interface -----------------------
// Used by other languages to create WebUI wrappers
typedef struct webui_script_interface_t {
char* script;
unsigned int timeout;
bool error;
unsigned int length;
const char* data;
} webui_script_interface_t;
EXPORT unsigned int webui_bind_interface(webui_window_t* win, const char* element, void (*func)(unsigned int, unsigned int, char*, webui_window_t*, char*, char**));
EXPORT void webui_script_interface(webui_window_t* win, const char* script, unsigned int timeout, bool* error, unsigned int* length, char** data);
EXPORT void webui_script_interface_struct(webui_window_t* win, webui_script_interface_t* js_int);
// Core
EXPORT void _webui_init(void);
EXPORT unsigned int _webui_get_cb_index(char* webui_internal_id);
EXPORT unsigned int _webui_set_cb_index(char* webui_internal_id);
EXPORT unsigned int _webui_get_free_port(void);
EXPORT unsigned int _webui_get_new_window_number(void);
EXPORT void _webui_wait_for_startup(void);
EXPORT void _webui_free_port(unsigned int port);
EXPORT void _webui_set_custom_browser(webui_custom_browser_t* p);
EXPORT char* _webui_get_current_path(void);
EXPORT void _webui_window_receive(webui_window_t* win, const char* packet, size_t len);
EXPORT void _webui_window_send(webui_window_t* win, char* packet, size_t packets_size);
EXPORT void _webui_window_event(webui_window_t* win, char* element_id, char* element, void* data, unsigned int data_len, int event_type);
EXPORT unsigned int _webui_window_get_number(webui_window_t* win);
EXPORT void _webui_window_open(webui_window_t* win, char* link, unsigned int browser);
EXPORT int _webui_cmd_sync(char* cmd, bool show);
EXPORT int _webui_cmd_async(char* cmd, bool show);
EXPORT int _webui_run_browser(webui_window_t* win, char* cmd);
EXPORT void _webui_clean(void);
EXPORT bool _webui_browser_exist(webui_window_t* win, unsigned int browser);
EXPORT const char* _webui_browser_get_temp_path(unsigned int browser);
EXPORT bool _webui_folder_exist(char* folder);
EXPORT bool _webui_browser_create_profile_folder(webui_window_t* win, unsigned int browser);
EXPORT bool _webui_browser_start_chrome(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_edge(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_epic(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_vivaldi(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_brave(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_firefox(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_yandex(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_chromium(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start_custom(webui_window_t* win, const char* address);
EXPORT bool _webui_browser_start(webui_window_t* win, const char* address, unsigned int browser);
EXPORT long _webui_timer_diff(struct timespec *start, struct timespec *end);
EXPORT void _webui_timer_start(webui_timer_t* t);
EXPORT bool _webui_timer_is_end(webui_timer_t* t, unsigned int ms);
EXPORT void _webui_timer_clock_gettime(struct timespec *spec);
EXPORT bool _webui_set_root_folder(webui_window_t* win, const char* path);
EXPORT void _webui_wait_process(webui_window_t* win, bool status);
EXPORT const char* _webui_generate_js_bridge(webui_window_t* win);
EXPORT void _webui_print_hex(const char* data, size_t len);
EXPORT void _webui_free_mem(void **p);
EXPORT bool _webui_file_exist_mg(void *ev_data);
EXPORT bool _webui_file_exist(char* file);
EXPORT void _webui_free_all_mem(void);
EXPORT bool _webui_show_window(webui_window_t* win, const char* html, unsigned int browser);
EXPORT char* _webui_generate_internal_id(webui_window_t* win, const char* element);
#ifdef _WIN32
EXPORT DWORD WINAPI _webui_cb(LPVOID _arg);
EXPORT DWORD WINAPI _webui_run_browser_task(LPVOID _arg);
EXPORT int _webui_system_win32(char* cmd, bool show);
#else
EXPORT void* _webui_cb(void* _arg);
EXPORT void* _webui_run_browser_task(void* _arg);
#endif
// Bind a specific html element click event with a function. Empty element means all events. This replace webui_bind().
WEBUI_EXPORT unsigned int webui_interface_bind(void* window, const char* element, void (*func)(void*, unsigned int, char*, char*, char*));
// When using `webui_interface_bind()` you need this function to easily set your response.
WEBUI_EXPORT void webui_interface_set_response(char* ptr, const char* response);
// Check if the app still running or not. This replace webui_wait().
WEBUI_EXPORT bool webui_interface_is_app_running(void);
// Get window unique ID
WEBUI_EXPORT unsigned int webui_interface_get_window_id(void* window);
#endif /* _WEBUI_H */

70
scripts/build.bat Normal file
View File

@ -0,0 +1,70 @@
@echo off
set ARG1=%1
IF "%ARG1%"=="debug" (
set MSVC_CMD=nmake debug
set GCC_CMD=mingw32-make debug
) else (
set MSVC_CMD=nmake
set GCC_CMD=mingw32-make
)
echo.
echo - - - - - - - - - - - - - - - - - - - - - - -
echo WebUI v2.2.0 Build Script
echo - - - - - - - - - - - - - - - - - - - - - - -
echo.
echo OS: Micsoroft Windows x64
echo Compiler: Microsoft Visual C
Set RootPath=%CD%\..\
cd "%RootPath%"
echo.
echo - - [Build] - - - - - - - - - - - - - - - - -
REM Build WebUI Library using MSVC
cd "%RootPath%"
cd "build\Windows\MSVC"
%MSVC_CMD%
REM Build WebUI Library using GCC
cd "%RootPath%"
cd "build\Windows\GCC"
%GCC_CMD%
echo.
echo - - [Copy] - - - - - - - - - - - - - - - - -
echo.
cd "%RootPath%"
REM Golang
copy /Y "build\Windows\GCC\libwebui-2-static-x64.a" "examples\Go\hello_world\webui\libwebui-2-static-x64.a"
copy /Y "include\webui.h" "examples\Go\hello_world\webui\webui.h"
REM Deno
copy /Y "build\Windows\MSVC\webui-2-x64.dll" "examples\TypeScript\Deno\webui-2-x64.dll"
REM Python
copy /Y "build\Windows\MSVC\webui-2-x64.dll" "examples\Python\PyPI\Package\src\webui\webui-2-x64.dll"
echo.
IF "%ARG1%"=="" (
echo - - [Clean] - - - - - - - - - - - - - - - - -
DEL /Q /F /S "*.exe" >nul 2>&1
DEL /Q /F /S "*.o" >nul 2>&1
DEL /Q /F /S "*.a" >nul 2>&1
DEL /Q /F /S "*.def" >nul 2>&1
DEL /Q /F /S "*.exp" >nul 2>&1
DEL /Q /F /S "*.pdb" >nul 2>&1
DEL /Q /F /S "*.ilk" >nul 2>&1
DEL /Q /F /S "*.obj" >nul 2>&1
DEL /Q /F /S "*.res" >nul 2>&1
DEL /Q /F /S "*.bak" >nul 2>&1
DEL /Q /F /S "*.DS_Store" >nul 2>&1
)
cd "scripts"

View File

@ -1,22 +0,0 @@
@echo off
Set RootPath=%CD%\..\
cd "%RootPath%"
echo.
echo Clean all...
DEL /Q /F /S "*.exe" >nul 2>&1
DEL /Q /F /S "*.dll" >nul 2>&1
DEL /Q /F /S "*.lib" >nul 2>&1
DEL /Q /F /S "*.o" >nul 2>&1
DEL /Q /F /S "*.a" >nul 2>&1
DEL /Q /F /S "*.def" >nul 2>&1
DEL /Q /F /S "*.exp" >nul 2>&1
DEL /Q /F /S "*.pdb" >nul 2>&1
DEL /Q /F /S "*.ilk" >nul 2>&1
DEL /Q /F /S "*.obj" >nul 2>&1
DEL /Q /F /S "*.res" >nul 2>&1
DEL /Q /F /S "*.bak" >nul 2>&1
DEL /Q /F /S "*.DS_Store" >nul 2>&1

View File

@ -117,6 +117,7 @@ int mg_base64_decode(const char *src, int n, char *dst) {
struct dns_data {
struct dns_data *next;
struct mg_connection *c;
@ -411,9 +412,7 @@ void mg_error(struct mg_connection *c, const char *fmt, ...) {
static bool is_digit(int c) {
return c >= '0' && c <= '9';
}
static bool is_digit(int c) { return c >= '0' && c <= '9'; }
static int addexp(char *buf, int e, int sign) {
int n = 0;
@ -446,7 +445,7 @@ static int xisnan(double x) {
0x7ff00000;
}
static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
char buf[40];
int i, s = 0, n = 0, e = 0;
double t, mul, saved;
@ -468,13 +467,13 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
while (d < 1.0 && d / mul < 1.0) mul /= 10.0, e--;
// printf(" --> %g %d %g %g\n", saved, e, t, mul);
if (e >= width) {
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
if (e >= width && width > 1) {
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
// printf(" --> %.*g %d [%.*s]\n", 10, d / t, e, n, buf);
n += addexp(buf + s + n, e, '+');
return mg_snprintf(dst, dstlen, "%.*s", n, buf);
} else if (e <= -width) {
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width);
} else if (e <= -width && width > 1) {
n = (int) mg_dtoa(buf, sizeof(buf), saved / mul, width, tz);
// printf(" --> %.*g %d [%.*s]\n", 10, d / mul, e, n, buf);
n += addexp(buf + s + n, -e, '-');
return mg_snprintf(dst, dstlen, "%.*s", n, buf);
@ -497,8 +496,8 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width) {
t /= 10.0;
}
}
while (n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeros
if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes
if (n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
n += s;
if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
buf[n] = '\0';
@ -542,9 +541,7 @@ static char mg_esc(int c, bool esc) {
return 0;
}
static char mg_escape(int c) {
return mg_esc(c, true);
}
static char mg_escape(int c) { return mg_esc(c, true); }
static size_t qcpy(void (*out)(char, void *), void *ptr, char *buf,
size_t len) {
@ -631,7 +628,7 @@ size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
if (c == 'g' || c == 'f') {
double v = va_arg(*ap, double);
if (pr == ~0U) pr = 6;
k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr);
k = mg_dtoa(tmp, sizeof(tmp), v, (int) pr, c == 'g');
} else if (is_long == 2) {
int64_t v = va_arg(*ap, int64_t);
k = mg_lld(tmp, v, s, h);
@ -1309,6 +1306,7 @@ struct mg_fs mg_fs_posix = {p_stat, p_list, p_open, p_close, p_read,
// Chunk deletion marker is the MSB in the "processed" counter
#define MG_DMARK ((size_t) 1 << (sizeof(size_t) * 8 - 1))
@ -3247,6 +3245,7 @@ struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list *ap) {
size_t old = c->send.len;
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
@ -3495,7 +3494,6 @@ void mg_mgr_init(struct mg_mgr *mgr) {
size_t mg_queue_vprintf(struct mg_queue *q, const char *fmt, va_list *ap) {
size_t len = mg_snprintf(NULL, 0, fmt, ap);
char *buf;
@ -4107,6 +4105,7 @@ struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url,
#if MG_ENABLE_SOCKET
#ifndef closesocket
@ -4669,7 +4668,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
}
}
#else
struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_zero = {0, 0};
struct timeval tv = {ms / 1000, (ms % 1000) * 1000}, tv_zero = {0, 0}, *tvp;
struct mg_connection *c;
fd_set rset, wset, eset;
MG_SOCKET_TYPE maxfd = 0;
@ -4678,17 +4677,18 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_ZERO(&eset);
tvp = ms < 0 ? NULL : &tv;
for (c = mgr->conns; c != NULL; c = c->next) {
c->is_readable = c->is_writable = 0;
if (skip_iotest(c)) continue;
FD_SET(FD(c), &eset);
if (can_read(c)) FD_SET(FD(c), &rset);
if (can_write(c)) FD_SET(FD(c), &wset);
if (mg_tls_pending(c) > 0) tv = tv_zero;
if (mg_tls_pending(c) > 0) tvp = &tv_zero;
if (FD(c) > maxfd) maxfd = FD(c);
}
if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, &tv)) < 0) {
if ((rc = select((int) maxfd + 1, &rset, &wset, &eset, tvp)) < 0) {
#if MG_ARCH == MG_ARCH_WIN32
if (maxfd == 0) Sleep(ms); // On Windows, select fails if no sockets
#else
@ -5779,6 +5779,7 @@ uint64_t mg_millis(void) {
struct ws_msg {
uint8_t flags;
size_t header_len;

View File

@ -862,14 +862,17 @@ void mg_queue_del(struct mg_queue *, size_t); // Delete oldest message
typedef void (*mg_pfn_t)(char, void *); // Output function
typedef size_t (*mg_pm_t)(mg_pfn_t, void *, va_list *); // %M printer
size_t mg_vxprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
size_t mg_xprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
// Convenience wrappers around mg_xprintf
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
size_t mg_snprintf(char *, size_t, const char *fmt, ...);
@ -989,7 +992,6 @@ bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
#if MG_ENABLE_ASSERT
#include <assert.h>
#elif !defined(assert)

File diff suppressed because it is too large Load Diff

181
src/webui_core.h Normal file
View File

@ -0,0 +1,181 @@
/*
WebUI Library 2.2.0
http://webui.me
https://github.com/alifcommunity/webui
Copyright (c) 2020-2023 Hassan Draga.
Licensed under GNU General Public License v2.0.
All rights reserved.
Canada.
*/
#ifndef _WEBUI_CORE_H
#define _WEBUI_CORE_H
#include "webui.h"
#define WEBUI_HEADER_SIGNATURE 0xDD // All packets should start with this 8bit
#define WEBUI_HEADER_JS 0xFE // JavaScript result in frontend
#define WEBUI_HEADER_JS_QUICK 0xFD // JavaScript result in frontend
#define WEBUI_HEADER_CLICK 0xFC // Click event
#define WEBUI_HEADER_SWITCH 0xFB // Frontend refresh
#define WEBUI_HEADER_CLOSE 0xFA // Close window
#define WEBUI_HEADER_CALL_FUNC 0xF9 // Call a backend function
#define WEBUI_MAX_ARRAY (128) // Max threads, servers, windows, pointers..
#define WEBUI_MIN_PORT (10000) // Minimum socket port
#define WEBUI_MAX_PORT (65500) // Should be less than 65535
#define WEBUI_MAX_BUF (1024000) // 1024 Kb max dynamic memory allocation
#define WEBUI_DEFAULT_PATH "." // Default root path
#define WEBUI_DEF_TIMEOUT (10) // Default startup timeout in seconds
#define WEBUI_MAX_TIMEOUT (30) // Maximum startup timeout in seconds
typedef struct _webui_timer_t {
struct timespec start;
struct timespec now;
} _webui_timer_t;
typedef struct _webui_window_t {
unsigned int window_number;
bool server_running;
bool connected;
bool html_handled;
bool multi_access;
bool is_embedded_html;
unsigned int server_port;
char* url;
const char* html;
const char* icon;
const char* icon_type;
unsigned int current_browser;
char* browser_path;
char* profile_path;
unsigned int connections;
unsigned int runtime;
bool has_events;
char* server_root_path;
#ifdef _WIN32
HANDLE server_thread;
#else
pthread_t server_thread;
#endif
} _webui_window_t;
typedef struct _webui_core_t {
unsigned int servers;
unsigned int connections;
char* html_elements[WEBUI_MAX_ARRAY];
unsigned int used_ports[WEBUI_MAX_ARRAY];
unsigned int last_window;
unsigned int startup_timeout;
bool exit_now;
const char* run_responses[WEBUI_MAX_ARRAY];
bool run_done[WEBUI_MAX_ARRAY];
bool run_error[WEBUI_MAX_ARRAY];
unsigned char run_last_id;
struct mg_mgr* mg_mgrs[WEBUI_MAX_ARRAY];
struct mg_connection* mg_connections[WEBUI_MAX_ARRAY];
bool initialized;
void (*cb[WEBUI_MAX_ARRAY])(webui_event_t* e);
void (*cb_interface[WEBUI_MAX_ARRAY])(void*, unsigned int, char*, char*, char*);
char* executable_path;
void *ptr_list[WEBUI_MAX_ARRAY];
unsigned int ptr_position;
size_t ptr_size[WEBUI_MAX_ARRAY];
unsigned int current_browser;
} _webui_core_t;
typedef struct _webui_cb_t {
_webui_window_t* win;
char* webui_internal_id;
char* element_name;
void* data;
unsigned int data_len;
int event_type;
} _webui_cb_t;
typedef struct _webui_mg_handler_t {
struct mg_connection* c;
int ev;
void* ev_data;
void* fn_data;
} _webui_mg_handler_t;
typedef struct _webui_cmd_async_t {
_webui_window_t* win;
char* cmd;
} _webui_cmd_async_t;
// -- Definitions ---------------------
#ifdef _WIN32
static const char* webui_sep = "\\";
DWORD WINAPI _webui_cb(LPVOID _arg);
DWORD WINAPI _webui_run_browser_task(LPVOID _arg);
int _webui_system_win32(char* cmd, bool show);
bool _webui_socket_test_listen_win32(unsigned int port_num);
bool _webui_get_windows_reg_value(HKEY key, const char* reg, const char* value_name, char value[WEBUI_MAX_PATH]);
#define WEBUI_CB DWORD WINAPI _webui_cb(LPVOID _arg)
#define WEBUI_SERVER_START DWORD WINAPI _webui_server_start(LPVOID arg)
#define THREAD_RETURN return 0;
#else
static const char* webui_sep = "/";
void* _webui_cb(void* _arg);
void* _webui_run_browser_task(void* _arg);
#define WEBUI_CB void* _webui_cb(void* _arg)
#define WEBUI_SERVER_START void* _webui_server_start(void* arg)
#define THREAD_RETURN pthread_exit(NULL);
#endif
static void _webui_init(void);
bool _webui_show(_webui_window_t* window, const char* content, unsigned int browser);
unsigned int _webui_get_cb_index(char* webui_internal_id);
unsigned int _webui_set_cb_index(char* webui_internal_id);
unsigned int _webui_get_free_port(void);
unsigned int _webui_get_new_window_number(void);
static void _webui_wait_for_startup(void);
static void _webui_free_port(unsigned int port);
char* _webui_get_current_path(void);
static void _webui_window_receive(_webui_window_t* win, const char* packet, size_t len);
static void _webui_window_send(_webui_window_t* win, char* packet, size_t packets_size);
static void _webui_window_event(_webui_window_t* win, char* element_id, char* element, void* data, unsigned int data_len, int event_type);
unsigned int _webui_window_get_number(_webui_window_t* win);
static void _webui_window_open(_webui_window_t* win, char* link, unsigned int browser);
int _webui_cmd_sync(char* cmd, bool show);
int _webui_cmd_async(char* cmd, bool show);
int _webui_run_browser(_webui_window_t* win, char* cmd);
static void _webui_clean(void);
bool _webui_browser_exist(_webui_window_t* win, unsigned int browser);
const char* _webui_browser_get_temp_path(unsigned int browser);
bool _webui_folder_exist(char* folder);
bool _webui_browser_create_profile_folder(_webui_window_t* win, unsigned int browser);
bool _webui_browser_start_chrome(_webui_window_t* win, const char* address);
bool _webui_browser_start_edge(_webui_window_t* win, const char* address);
bool _webui_browser_start_epic(_webui_window_t* win, const char* address);
bool _webui_browser_start_vivaldi(_webui_window_t* win, const char* address);
bool _webui_browser_start_brave(_webui_window_t* win, const char* address);
bool _webui_browser_start_firefox(_webui_window_t* win, const char* address);
bool _webui_browser_start_yandex(_webui_window_t* win, const char* address);
bool _webui_browser_start_chromium(_webui_window_t* win, const char* address);
bool _webui_browser_start(_webui_window_t* win, const char* address, unsigned int browser);
long _webui_timer_diff(struct timespec *start, struct timespec *end);
static void _webui_timer_start(_webui_timer_t* t);
bool _webui_timer_is_end(_webui_timer_t* t, unsigned int ms);
static void _webui_timer_clock_gettime(struct timespec *spec);
bool _webui_set_root_folder(_webui_window_t* win, const char* path);
const char* _webui_generate_js_bridge(_webui_window_t* win);
static void _webui_print_hex(const char* data, size_t len);
static void _webui_free_mem(void* ptr);
bool _webui_file_exist_mg(void *ev_data);
bool _webui_file_exist(char* file);
static void _webui_free_all_mem(void);
bool _webui_show_window(_webui_window_t* win, const char* content, bool is_embedded_html, unsigned int browser);
char* _webui_generate_internal_id(_webui_window_t* win, const char* element);
bool _webui_is_empty(const char* s);
unsigned char _webui_get_run_id(void);
void* _webui_malloc(int size);
static void _webui_sleep(long unsigned int ms);
WEBUI_SERVER_START;
WEBUI_CB;
#endif /* _WEBUI_CORE_H */

View File

@ -87,7 +87,7 @@ Please visit [C Examples](https://github.com/alifcommunity/webui/tree/main/examp
To create a new window object, you can use `webui_new_window()`, which returns a pointer to a struct `webui_window_t`. This pointer does *NOT* need to be freed.
```c
webui_window_t* my_window = webui_new_window();
void* my_window = webui_new_window();
```
---
@ -328,10 +328,10 @@ void my_function(webui_event_t* e){
webui_script(e->window, &js);
// Check if there is any JavaScript error
if(js.result.error)
printf("Error: %s\n", js.result.data);
if(js.error)
printf("Error: %s\n", js.data);
else
printf("Output: %s\n", js.result.data);
printf("Output: %s\n", js.data);
// Free resources
webui_script_cleanup(&js);

View File

@ -151,8 +151,8 @@
</div>
<div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow p-6">
<div class="flex items-center justify-center">
<a href="https://github.com/alifcommunity/webui/releases/download/2.1.1/webui_2.1.1.zip" target="_blank" class="mx-auto lg:mx-0 hover:underline gradient-button text-white font-bold my-6 py-2 px-4 shadow-lg no-underline">
Download Windows WebUI v2.1.1
<a href="https://github.com/alifcommunity/webui/releases/download/2.2.0/webui_2.2.0.zip" target="_blank" class="mx-auto lg:mx-0 hover:underline gradient-button text-white font-bold my-6 py-2 px-4 shadow-lg no-underline">
Download Windows WebUI v2.2.0
</a>
</div>
</div>
@ -172,8 +172,8 @@
</div>
<div class="flex-none mt-auto bg-white rounded-b rounded-t-none overflow-hidden shadow p-6">
<div class="flex items-center justify-center">
<a href="https://github.com/alifcommunity/webui/releases/download/2.1.1/webui_2.1.1.zip" target="_blank" class="mx-auto lg:mx-0 hover:underline gradient-button text-white font-bold my-6 py-2 px-4 shadow-lg no-underline">
Download Linux WebUI v2.1.1
<a href="https://github.com/alifcommunity/webui/releases/download/2.2.0/webui_2.2.0.zip" target="_blank" class="mx-auto lg:mx-0 hover:underline gradient-button text-white font-bold my-6 py-2 px-4 shadow-lg no-underline">
Download Linux WebUI v2.2.0
</a>
</div>
</div>