mirror of
https://github.com/webui-dev/webui.git
synced 2024-11-05 01:01:52 +03:00
v2.0.2 With full Linux support
This commit is contained in:
parent
2856dffbdf
commit
5fc7fb2455
44
build/Linux/Clang/Makefile
Normal file
44
build/Linux/Clang/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
# WebUI Library
|
||||
# Linux - Clang
|
||||
|
||||
SOURCE=../../../src
|
||||
INCLUDE=../../../include
|
||||
|
||||
all: release
|
||||
|
||||
debug:
|
||||
# Static with Debug info
|
||||
@echo "Build WebUI Library (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)..."
|
||||
@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
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
release:
|
||||
# Static Release
|
||||
@echo "Build WebUI Library (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)..."
|
||||
@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
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
clean:
|
||||
- rm -f *.o
|
||||
- rm -f *.so
|
||||
- rm -f *.a
|
44
build/Linux/GCC/Makefile
Normal file
44
build/Linux/GCC/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
# WebUI Library
|
||||
# Linux - GCC
|
||||
|
||||
SOURCE=../../../src
|
||||
INCLUDE=../../../include
|
||||
|
||||
all: release
|
||||
|
||||
debug:
|
||||
# Static with Debug info
|
||||
@echo "Build WebUI Library (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)..."
|
||||
@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
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
release:
|
||||
# Static Release
|
||||
@echo "Build WebUI Library (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)..."
|
||||
@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
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
clean:
|
||||
- rm -f *.o
|
||||
- rm -f *.so
|
||||
- rm -f *.a
|
42
examples/C/Linux/Clang/Makefile
Normal file
42
examples/C/Linux/Clang/Makefile
Normal file
@ -0,0 +1,42 @@
|
||||
# WebUI Library 2.x
|
||||
# C99 Example
|
||||
# Linux - Clang
|
||||
|
||||
LIB=../../../../build/Linux/Clang
|
||||
INCLUDE=../../../../include
|
||||
SOURCE=../..
|
||||
|
||||
all: release
|
||||
|
||||
debug:
|
||||
# Build Lib
|
||||
@cd "$(LIB)" && $(MAKE) debug
|
||||
# Static with Debug info
|
||||
@echo "Build C99 Example (Static Debug)..."
|
||||
@clang -g -static -m64 -o main "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" -lwebui-2-static-x64 -lpthread
|
||||
# Dynamic with Debug info
|
||||
@echo "Build C99 Example (Dynamic Debug)..."
|
||||
@clang -g -m64 -o main-dyn "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" "$(LIB)/webui-2-x64.so" -lpthread
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
release:
|
||||
# Build Lib
|
||||
@cd "$(LIB)" && $(MAKE)
|
||||
# Static Release
|
||||
@echo "Build C99 Example (Static Release)..."
|
||||
@clang -static -Os -m64 -o main "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" -lwebui-2-static-x64 -lpthread
|
||||
@llvm-strip --strip-all main
|
||||
# Dynamic Release
|
||||
@echo "Build C99 Example (Dynamic Release)..."
|
||||
@clang -m64 -o main-dyn "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" "$(LIB)/webui-2-x64.so" -lpthread
|
||||
@llvm-strip --strip-all main-dyn
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
clean:
|
||||
- rm -f *.o
|
||||
- rm -f *.so
|
||||
- rm -f *.a
|
42
examples/C/Linux/GCC/Makefile
Normal file
42
examples/C/Linux/GCC/Makefile
Normal file
@ -0,0 +1,42 @@
|
||||
# WebUI Library 2.x
|
||||
# C99 Example
|
||||
# Linux - GCC
|
||||
|
||||
LIB=../../../../build/Linux/GCC
|
||||
INCLUDE=../../../../include
|
||||
SOURCE=../..
|
||||
|
||||
all: release
|
||||
|
||||
debug:
|
||||
# Build Lib
|
||||
@cd "$(LIB)" && $(MAKE) debug
|
||||
# Static with Debug info
|
||||
@echo "Build C99 Example (Static Debug)..."
|
||||
@gcc -g -static -m64 -o main "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" -lwebui-2-static-x64 -lpthread
|
||||
# Dynamic with Debug info
|
||||
@echo "Build C99 Example (Dynamic Debug)..."
|
||||
@gcc -g -m64 -o main-dyn "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" "$(LIB)/webui-2-x64.so" -lpthread
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
release:
|
||||
# Build Lib
|
||||
@cd "$(LIB)" && $(MAKE)
|
||||
# Static Release
|
||||
@echo "Build C99 Example (Static Release)..."
|
||||
@gcc -static -Os -m64 -o main "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" -lwebui-2-static-x64 -lpthread
|
||||
@strip --strip-all main
|
||||
# Dynamic Release
|
||||
@echo "Build C99 Example (Dynamic Release)..."
|
||||
@gcc -m64 -o main-dyn "$(SOURCE)/main.c" -I "$(INCLUDE)" -L "$(LIB)" "$(LIB)/webui-2-x64.so" -lpthread
|
||||
@strip --strip-all main-dyn
|
||||
# Clean
|
||||
@- rm -f *.o
|
||||
@echo "Done."
|
||||
|
||||
clean:
|
||||
- rm -f *.o
|
||||
- rm -f *.so
|
||||
- rm -f *.a
|
@ -1,6 +1,6 @@
|
||||
package webui
|
||||
|
||||
// WebUI Library 2.0.1
|
||||
// WebUI Library 2.0.2
|
||||
//
|
||||
// http://webui.me
|
||||
// https://github.com/alifcommunity/webui
|
||||
@ -9,10 +9,11 @@ package webui
|
||||
// Copyright (C)2022 Hassan DRAGA <https://github.com/hassandraga>.
|
||||
|
||||
/*
|
||||
// [?] Change the library path as you need
|
||||
#cgo CFLAGS: -I ./ -I ../../../../include
|
||||
#cgo windows LDFLAGS: -L ./ -L ../../../../build/Windows/GCC/ -lwebui-2-static-x64 -lws2_32
|
||||
#cgo darwin LDFLAGS: -L ./ -L ../../../../build/macOS/Clang/ -lwebui-2-static-x64
|
||||
#cgo linux LDFLAGS: -L ./ -L ../../../../build/Linux/GCC/ -lwebui-2-static-x64
|
||||
#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
|
||||
#cgo linux LDFLAGS: -L ./ -L ../../../../build/Linux/GCC/ -L ../../../../build/Linux/Clang/ -lwebui-2-static-x64 -lpthread
|
||||
#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) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
WebUI Library 2.0.1
|
||||
WebUI Library 2.0.2
|
||||
|
||||
http://webui.me
|
||||
https://github.com/alifcommunity/webui
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
WebUI Library 2.0.1
|
||||
WebUI Library 2.0.2
|
||||
|
||||
http://webui.me
|
||||
https://github.com/alifcommunity/webui
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
WebUI Library 2.0.1
|
||||
WebUI Library 2.0.2
|
||||
|
||||
http://webui.me
|
||||
https://github.com/alifcommunity/webui
|
||||
@ -60,7 +60,6 @@
|
||||
#define WEBUI_PCLOSE _pclose
|
||||
#define WEBUI_MAX_PATH MAX_PATH
|
||||
#endif
|
||||
|
||||
// -- Linux ---------------------------
|
||||
#ifdef __linux__
|
||||
#include <pthread.h> // POSIX threading
|
||||
@ -76,19 +75,23 @@
|
||||
#define WEBUI_PCLOSE pclose
|
||||
#define WEBUI_MAX_PATH PATH_MAX
|
||||
#endif
|
||||
|
||||
// -- macOS ---------------------------
|
||||
// ...
|
||||
|
||||
struct webui_window_t;
|
||||
|
||||
typedef struct webui_timer_t {
|
||||
|
||||
struct timespec start;
|
||||
struct timespec now;
|
||||
} webui_timer_t;
|
||||
|
||||
typedef struct webui_event_t {
|
||||
|
||||
unsigned int window_id;
|
||||
unsigned int element_id;
|
||||
char* element_name;
|
||||
struct webui_window_t* window;
|
||||
|
||||
} webui_event_t;
|
||||
|
||||
typedef struct webui_window_core_t {
|
||||
@ -118,14 +121,12 @@ typedef struct webui_window_core_t {
|
||||
#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_javascript_result_t {
|
||||
@ -133,7 +134,6 @@ typedef struct webui_javascript_result_t {
|
||||
bool error;
|
||||
unsigned int length;
|
||||
const char* data;
|
||||
|
||||
} webui_javascript_result_t;
|
||||
|
||||
typedef struct webui_javascript_t {
|
||||
@ -141,7 +141,6 @@ typedef struct webui_javascript_t {
|
||||
const char* script;
|
||||
unsigned int timeout;
|
||||
webui_javascript_result_t result;
|
||||
|
||||
} webui_javascript_t;
|
||||
|
||||
typedef struct webui_cb_t {
|
||||
@ -149,14 +148,12 @@ typedef struct webui_cb_t {
|
||||
webui_window_t* win;
|
||||
char* element_id;
|
||||
char* element_name;
|
||||
|
||||
} 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 {
|
||||
@ -164,7 +161,6 @@ typedef struct webui_custom_browser_t {
|
||||
char* app;
|
||||
char* arg;
|
||||
bool auto_link;
|
||||
|
||||
} webui_custom_browser_t;
|
||||
|
||||
typedef struct webui_browser_t {
|
||||
@ -176,7 +172,6 @@ typedef struct webui_browser_t {
|
||||
unsigned int safari; // 4
|
||||
unsigned int chromium; // 5
|
||||
unsigned int custom; // 99
|
||||
|
||||
} webui_browser_t;
|
||||
|
||||
typedef struct webui_runtime_t {
|
||||
@ -184,7 +179,6 @@ typedef struct webui_runtime_t {
|
||||
unsigned int none; // 0
|
||||
unsigned int deno; // 1
|
||||
unsigned int nodejs; // 2
|
||||
|
||||
} webui_runtime_t;
|
||||
|
||||
typedef struct webui_t {
|
||||
@ -215,7 +209,6 @@ typedef struct webui_t {
|
||||
void *ptr_list[WEBUI_MAX_ARRAY];
|
||||
unsigned int ptr_position;
|
||||
size_t ptr_size[WEBUI_MAX_ARRAY];
|
||||
|
||||
} webui_t;
|
||||
|
||||
// -- Definitions ---------------------
|
||||
@ -244,7 +237,6 @@ EXPORT void webui_detect_process_close(webui_window_t* win, bool status);
|
||||
|
||||
// -- Interface -----------------------
|
||||
// To help other languages to use WebUI
|
||||
|
||||
typedef struct webui_javascript_int_t {
|
||||
|
||||
char* script;
|
||||
@ -252,9 +244,7 @@ typedef struct webui_javascript_int_t {
|
||||
bool error;
|
||||
unsigned int length;
|
||||
const char* data;
|
||||
|
||||
} webui_javascript_int_t;
|
||||
|
||||
EXPORT unsigned int webui_bind_int(webui_window_t* win, const char* element, void (*func)(unsigned int, unsigned int, char*));
|
||||
EXPORT void webui_run_js_int(webui_window_t* win, const char* script, unsigned int timeout, bool* error, unsigned int* length, char* data);
|
||||
EXPORT void webui_run_js_int_struct(webui_window_t* win, webui_javascript_int_t* js_int);
|
||||
@ -287,6 +277,10 @@ EXPORT bool _webui_browser_start_firefox(webui_window_t* win, const char* addres
|
||||
EXPORT bool _webui_browser_start_custom(webui_window_t* win, const char* address);
|
||||
EXPORT bool _webui_browser_start_chrome(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);
|
||||
#ifdef _WIN32
|
||||
EXPORT DWORD WINAPI _webui_cb(LPVOID _arg);
|
||||
EXPORT DWORD WINAPI _webui_run_browser_task(LPVOID _arg);
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "webui2"
|
||||
version = "2.0.1.1"
|
||||
version = "2.0.2"
|
||||
authors = [
|
||||
{ name="Hassan Draga" },
|
||||
]
|
||||
|
@ -1,4 +1,4 @@
|
||||
# WebUI Library 2.0.1
|
||||
# WebUI Library 2.0.2
|
||||
#
|
||||
# http://webui.me
|
||||
# https://github.com/alifcommunity/webui
|
||||
@ -102,7 +102,7 @@ class window:
|
||||
if WebUI is None:
|
||||
err_library_not_found('show')
|
||||
return
|
||||
WebUI.webui_show(self.window, html.encode('utf-8'))
|
||||
WebUI.webui_show(self.window, html.encode('utf-8'), 0)
|
||||
|
||||
def close(self):
|
||||
global WebUI
|
||||
|
400
src/webui.c
400
src/webui.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
WebUI Library 2.0.1
|
||||
WebUI Library 2.0.2
|
||||
|
||||
http://webui.me
|
||||
https://github.com/alifcommunity/webui
|
||||
@ -445,6 +445,42 @@ void _webui_sleep(long unsigned int ms) {
|
||||
#endif
|
||||
}
|
||||
|
||||
long _webui_timer_diff(struct timespec *start, struct timespec *end) {
|
||||
|
||||
return ((end->tv_sec * 1000) +
|
||||
(end->tv_nsec / 1000000)) -
|
||||
((start->tv_sec * 1000) +
|
||||
(start->tv_nsec / 1000000));
|
||||
}
|
||||
|
||||
void _webui_timer_clock_gettime(struct timespec *spec) {
|
||||
|
||||
#ifdef _WIN32
|
||||
__int64 wintime;
|
||||
GetSystemTimeAsFileTime((FILETIME*)&wintime);
|
||||
wintime -= ((__int64)116444736000000000);
|
||||
spec->tv_sec = wintime / ((__int64)10000000);
|
||||
spec->tv_nsec = wintime % ((__int64)10000000) * 100;
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, spec);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _webui_timer_start(webui_timer_t* t) {
|
||||
|
||||
_webui_timer_clock_gettime(&t->start);
|
||||
}
|
||||
|
||||
bool _webui_timer_is_end(webui_timer_t* t, unsigned int ms) {
|
||||
|
||||
_webui_timer_clock_gettime(&t->now);
|
||||
|
||||
long def = _webui_timer_diff(&t->start, &t->now);
|
||||
if (def > ms)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WEBUI_LOG
|
||||
void _webui_print_hex(const char* data, size_t len) {
|
||||
|
||||
@ -502,224 +538,45 @@ unsigned int _webui_get_run_id() {
|
||||
return ++webui.run_last_id;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
bool _webui_socket_test_connect_mg(unsigned int port_num) {
|
||||
|
||||
struct mg_mgr mgr;
|
||||
struct mg_connection *c;
|
||||
mg_mgr_init(&mgr);
|
||||
|
||||
char url[32];
|
||||
sprintf(url, "localhost:%d", port_num);
|
||||
|
||||
c = mg_connect(&mgr, url, NULL, NULL);
|
||||
if(c == NULL) {
|
||||
|
||||
mg_close_conn(c);
|
||||
mg_mgr_free(&mgr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cleaning
|
||||
mg_close_conn(c);
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
// Connection Success
|
||||
return true;
|
||||
}
|
||||
|
||||
int connect_ms(int sockfd, const struct sockaddr *addr, socklen_t addrlen, unsigned int timeout_ms) {
|
||||
|
||||
#ifdef WEBUI_LOG
|
||||
printf("[0] connect_ms([%d] ms)... \n", timeout_ms);
|
||||
#endif
|
||||
|
||||
int rc = 0;
|
||||
int sockfd_flags_before = 0;
|
||||
|
||||
if((sockfd_flags_before = fcntl(sockfd, F_GETFL, 0) < 0))
|
||||
return -1;
|
||||
|
||||
if(fcntl(sockfd, F_SETFL, sockfd_flags_before | O_NONBLOCK) < 0)
|
||||
return -1;
|
||||
|
||||
// Start connecting (asynchronously)
|
||||
do {
|
||||
|
||||
if (connect(sockfd, addr, addrlen)<0) {
|
||||
|
||||
// Did connect return an error? If so, we'll fail.
|
||||
if ((errno != EWOULDBLOCK) && (errno != EINPROGRESS))
|
||||
rc = -1;
|
||||
else {
|
||||
|
||||
// Otherwise, we'll wait for it to complete.
|
||||
// Set a deadline timestamp 'timeout' ms from now (needed b/c poll can be interrupted)
|
||||
|
||||
struct timespec now;
|
||||
if(clock_gettime(CLOCK_MONOTONIC, &now) < 0) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
struct timespec deadline = {
|
||||
.tv_sec = now.tv_sec,
|
||||
.tv_nsec = now.tv_nsec + timeout_ms * 1000000l
|
||||
};
|
||||
|
||||
// Wait for the connection to complete.
|
||||
do {
|
||||
|
||||
// Calculate how long until the deadline
|
||||
if(clock_gettime(CLOCK_MONOTONIC, &now) < 0) {
|
||||
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
int ms_until_deadline = (int)((deadline.tv_sec - now.tv_sec)*1000l + (deadline.tv_nsec - now.tv_nsec)/1000000l);
|
||||
|
||||
if(ms_until_deadline<0) {
|
||||
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for connect to complete (or for the timeout deadline)
|
||||
struct pollfd pfds[] = {
|
||||
{
|
||||
.fd = sockfd,
|
||||
.events = POLLOUT
|
||||
}
|
||||
};
|
||||
|
||||
rc = poll(pfds, 1, ms_until_deadline);
|
||||
|
||||
// If poll 'succeeded', make sure it *really* succeeded
|
||||
if( rc > 0) {
|
||||
|
||||
int error = 0;
|
||||
socklen_t len = sizeof(error);
|
||||
int retval = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
|
||||
|
||||
if(retval==0)
|
||||
errno = error;
|
||||
|
||||
if(error!=0)
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// If poll was interrupted, try again.
|
||||
while(rc == -1 && errno == EINTR);
|
||||
|
||||
// Did poll timeout? If so, fail.
|
||||
if(rc == 0) {
|
||||
|
||||
errno = ETIMEDOUT;
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(0);
|
||||
|
||||
// Restore original O_NONBLOCK state
|
||||
if(fcntl(sockfd, F_SETFL, sockfd_flags_before) < 0)
|
||||
return -1;
|
||||
|
||||
// Success
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool _webui_socket_test_connect(unsigned int port_num) {
|
||||
bool _webui_socket_test_listen_mg(unsigned int port_num) {
|
||||
|
||||
#ifdef WEBUI_LOG
|
||||
printf("[0] _webui_socket_test_connect([%d])... \n", port_num);
|
||||
printf("[0] _webui_socket_test_listen_mg([%d])... \n", port_num);
|
||||
#endif
|
||||
|
||||
// TODO: Detect if port is failed to connect but it's used
|
||||
// We should tray to bind() to make sure.
|
||||
struct mg_connection *c;
|
||||
struct mg_mgr mgr;
|
||||
mg_mgr_init(&mgr);
|
||||
|
||||
#ifdef _WIN32
|
||||
// -- Win32 ---------------------
|
||||
WSADATA wsaData;
|
||||
SOCKET ConnectSocket = INVALID_SOCKET;
|
||||
struct addrinfo *result = NULL, hints;
|
||||
unsigned int iResult;
|
||||
// Initialize Winsock
|
||||
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
||||
if(iResult != 0)
|
||||
return false;
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
char the_port[16];
|
||||
sprintf(the_port, "%d", port_num);
|
||||
iResult = getaddrinfo("localhost", the_port, &hints, &result);
|
||||
if(iResult != 0) {
|
||||
freeaddrinfo(result);
|
||||
WSACleanup();
|
||||
return false;
|
||||
}
|
||||
ConnectSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
||||
if(ConnectSocket == INVALID_SOCKET) {
|
||||
freeaddrinfo(result);
|
||||
WSACleanup();
|
||||
return false;
|
||||
}
|
||||
iResult = connect(ConnectSocket, result->ai_addr, (unsigned int)result->ai_addrlen);
|
||||
if(iResult == SOCKET_ERROR || ConnectSocket == INVALID_SOCKET) {
|
||||
closesocket(ConnectSocket);
|
||||
freeaddrinfo(result);
|
||||
WSACleanup();
|
||||
return false;
|
||||
}
|
||||
// Cleaning
|
||||
closesocket(ConnectSocket);
|
||||
freeaddrinfo(result);
|
||||
WSACleanup();
|
||||
// Connection Success
|
||||
return true;
|
||||
#else
|
||||
int sockfd;
|
||||
struct sockaddr_in serv_addr;
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
// Opening socket failed
|
||||
return false;
|
||||
}
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
// Leave [serv_addr.sin_addr.s_addr] empty to use localhost
|
||||
serv_addr.sin_port = htons(port_num);
|
||||
if(connect_ms(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr), 100) != 0) {
|
||||
// Connection Failed
|
||||
close(sockfd);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// Connection Success
|
||||
close(sockfd);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
char url[32];
|
||||
sprintf(url, "http://localhost:%d", port_num);
|
||||
|
||||
if((c = mg_http_listen(&mgr, url, NULL, &mgr)) == NULL) {
|
||||
|
||||
// Cannot listen
|
||||
mg_mgr_free(&mgr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Listening success
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _webui_socket_test_listen(unsigned int port_num) {
|
||||
#ifdef _WIN32
|
||||
bool _webui_socket_test_listen_win32(unsigned int port_num) {
|
||||
|
||||
#ifdef WEBUI_LOG
|
||||
printf("[0] _webui_socket_test_listen([%d])... \n", port_num);
|
||||
#endif
|
||||
#ifdef WEBUI_LOG
|
||||
printf("[0] _webui_socket_test_listen_win32([%d])... \n", port_num);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// -- Win32 ---------------------
|
||||
WSADATA wsaData;
|
||||
unsigned int iResult;
|
||||
SOCKET ListenSocket = INVALID_SOCKET;
|
||||
struct addrinfo *result = NULL;
|
||||
struct addrinfo hints;
|
||||
|
||||
// Initialize Winsock
|
||||
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
||||
if(iResult != 0) {
|
||||
@ -731,6 +588,7 @@ bool _webui_socket_test_listen(unsigned int port_num) {
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
// Resolve the server address and port
|
||||
char the_port[16];
|
||||
sprintf(the_port, "%d", port_num);
|
||||
@ -739,6 +597,7 @@ bool _webui_socket_test_listen(unsigned int port_num) {
|
||||
WSACleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a SOCKET for the server to listen for client connections.
|
||||
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
||||
if(ListenSocket == INVALID_SOCKET) {
|
||||
@ -746,6 +605,7 @@ bool _webui_socket_test_listen(unsigned int port_num) {
|
||||
WSACleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup the TCP listening socket
|
||||
iResult = bind(ListenSocket, result->ai_addr, (unsigned int)result->ai_addrlen);
|
||||
if(iResult == SOCKET_ERROR) {
|
||||
@ -754,36 +614,16 @@ bool _webui_socket_test_listen(unsigned int port_num) {
|
||||
WSACleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clean
|
||||
freeaddrinfo(result);
|
||||
closesocket(ListenSocket);
|
||||
WSACleanup();
|
||||
|
||||
// Listening Success
|
||||
return true;
|
||||
#else
|
||||
int sockfd, connfd, len;
|
||||
struct sockaddr_in servaddr, cli;
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sockfd < 0) {
|
||||
return false;
|
||||
}
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(port_num);
|
||||
if((bind(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr))) != 0) {
|
||||
close(sockfd);
|
||||
return false;
|
||||
}
|
||||
if((listen(sockfd, 5)) != 0) {
|
||||
close(sockfd);
|
||||
return false;
|
||||
}
|
||||
// Listening Success
|
||||
return true;
|
||||
close(sockfd);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool _webui_port_is_used(unsigned int port_num) {
|
||||
|
||||
@ -792,34 +632,15 @@ bool _webui_port_is_used(unsigned int port_num) {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// -- Win32 ---------------------
|
||||
|
||||
// Connect test
|
||||
// if(_webui_socket_test_connect(port_num))
|
||||
// return true;
|
||||
|
||||
// Connect test MG
|
||||
// if(_webui_socket_test_connect_mg(port_num))
|
||||
// return true;
|
||||
|
||||
// Listener test
|
||||
if(!_webui_socket_test_listen(port_num))
|
||||
return true; // Port is busy
|
||||
|
||||
// Port is not in use
|
||||
return false;
|
||||
if(!_webui_socket_test_listen_win32(port_num))
|
||||
return true; // Port is already used
|
||||
return false; // Port is not in use
|
||||
#else
|
||||
// Connect test
|
||||
// if(_webui_socket_test_connect(port_num))
|
||||
// return true;
|
||||
|
||||
// Connect test MG
|
||||
// if(_webui_socket_test_connect_mg(port_num))
|
||||
// return true;
|
||||
|
||||
// Listener test
|
||||
if(!_webui_socket_test_listen(port_num))
|
||||
return true; // Port is busy
|
||||
// Listener test MG
|
||||
if(!_webui_socket_test_listen_mg(port_num))
|
||||
return true; // Port is already used
|
||||
return false; // Port is not in use
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1410,37 +1231,54 @@ static void _webui_server_event_handler(struct mg_connection *c, int ev, void *e
|
||||
mg_mgr_init(&mgr);
|
||||
webui.mg_mgrs[win->core.window_number] = &mgr;
|
||||
|
||||
if(mg_http_listen(&mgr, win->core.url, _webui_server_event_handler, (void *) win) != NULL) {
|
||||
if(mg_http_listen(&mgr, win->core.url, _webui_server_event_handler, (void *)win) != NULL) {
|
||||
|
||||
#ifdef WEBUI_LOG
|
||||
printf("[%d] [Thread] webui_server_start(%s)... Listening success\n", win->core.window_number, win->core.url);
|
||||
#endif
|
||||
|
||||
if(webui.use_timeout) {
|
||||
|
||||
bool stop = false;
|
||||
bool extra_used = false;
|
||||
|
||||
for(;;) {
|
||||
|
||||
if(!win->core.server_handled) {
|
||||
|
||||
// Wait for first connection
|
||||
unsigned int n = 0;
|
||||
do {
|
||||
webui_timer_t timer;
|
||||
_webui_timer_start(&timer);
|
||||
while(1) {
|
||||
|
||||
// Stop if window is connected
|
||||
mg_mgr_poll(&mgr, 1);
|
||||
if(win->core.connected)
|
||||
break;
|
||||
|
||||
if(webui.timeout_extra && win->core.server_handled && !extra_used) {
|
||||
// Stop if timer is finished
|
||||
if(_webui_timer_is_end(&timer, (timeout * 1000)))
|
||||
break;
|
||||
}
|
||||
|
||||
// At this moment the browser is started and HTML
|
||||
// is handled, so, let's reset the timer to give
|
||||
// the WebSocket an extra time to connect
|
||||
if(!win->core.connected && webui.timeout_extra && win->core.server_handled) {
|
||||
|
||||
n = 0;
|
||||
extra_used = true;
|
||||
// At this moment the browser is already started and HTML
|
||||
// is already handled, so, let's wait more time to give
|
||||
// the WebSocket an extra time to connect
|
||||
|
||||
_webui_timer_start(&timer);
|
||||
while(1) {
|
||||
|
||||
// Stop if window is connected
|
||||
mg_mgr_poll(&mgr, 1);
|
||||
if(win->core.connected)
|
||||
break;
|
||||
|
||||
// Stop if timer is finished
|
||||
if(_webui_timer_is_end(&timer, (timeout * 1000)))
|
||||
break;
|
||||
}
|
||||
else n++;
|
||||
|
||||
} while(n <= (timeout * 100));
|
||||
}
|
||||
|
||||
if(!win->core.connected)
|
||||
stop = true;
|
||||
@ -1470,6 +1308,12 @@ static void _webui_server_event_handler(struct mg_connection *c, int ev, void *e
|
||||
mg_mgr_poll(&mgr, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
#ifdef WEBUI_LOG
|
||||
printf("[%d] [Thread] webui_server_start(%s)... Listening failed\n", win->core.window_number, win->core.url);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Stop server
|
||||
mg_mgr_free(&mgr);
|
||||
@ -1608,11 +1452,9 @@ bool _webui_folder_exist(char* folder) {
|
||||
#else
|
||||
DIR* dir = opendir(folder);
|
||||
if(dir) {
|
||||
printf("[0] _webui_folder_exist([%s])... TTTTTTTTTTTTTTT \n", folder);
|
||||
closedir(dir);
|
||||
return true;
|
||||
}
|
||||
printf("[0] _webui_folder_exist([%s])... NOOOOOOOOOOOOOOOOO \n", folder);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
@ -2042,7 +1884,7 @@ bool _webui_browser_start_chrome(webui_window_t* win, const char* address) {
|
||||
return false;
|
||||
|
||||
char arg[1024];
|
||||
sprintf(arg, " --user-data-dir=\"%s\" --disable-gpu --disable-software-rasterizer --no-proxy-server --safe-mode --disable-extensions --app=", win->core.profile_path);
|
||||
sprintf(arg, " --user-data-dir=\"%s\" --disable-gpu --disable-software-rasterizer --no-proxy-server --safe-mode --disable-extensions --disable-background-mode --disable-plugins --disable-plugins-discovery --disable-translate --bwsi --app=", win->core.profile_path);
|
||||
|
||||
char full[1024];
|
||||
sprintf(full, "%s%s%s", win->core.browser_path, arg, address);
|
||||
@ -2998,7 +2840,7 @@ unsigned int _webui_get_free_port() {
|
||||
if(_webui_port_is_used(port))
|
||||
port++; // Port used by an external app
|
||||
else
|
||||
break; // Port ready to use
|
||||
break; // Port is free
|
||||
}
|
||||
}
|
||||
|
||||
@ -3111,9 +2953,9 @@ void webui_run_js_int(webui_window_t* win, const char* script, unsigned int time
|
||||
#endif
|
||||
|
||||
webui_javascript_t js = {
|
||||
.script = script,
|
||||
.timeout = timeout
|
||||
};
|
||||
.script = script,
|
||||
.timeout = timeout
|
||||
};
|
||||
|
||||
webui_run_js(win, &js);
|
||||
|
||||
@ -3129,9 +2971,9 @@ void webui_run_js_int_struct(webui_window_t* win, webui_javascript_int_t* js_int
|
||||
#endif
|
||||
|
||||
webui_javascript_t js = {
|
||||
.script = js_int->script,
|
||||
.timeout = js_int->timeout
|
||||
};
|
||||
.script = js_int->script,
|
||||
.timeout = js_int->timeout
|
||||
};
|
||||
|
||||
webui_run_js(win, &js);
|
||||
|
||||
@ -3141,7 +2983,7 @@ void webui_run_js_int_struct(webui_window_t* win, webui_javascript_int_t* js_int
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
|
||||
|
||||
switch(fdwReason) {
|
||||
|
||||
|
@ -149,8 +149,7 @@
|
||||
<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="#" 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">
|
||||
Coming Soon
|
||||
<!-- Download Windows WebUI v2.0.1 -->
|
||||
Download Windows WebUI v2.0.2
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -171,7 +170,7 @@
|
||||
<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="#" 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">
|
||||
Coming Soon
|
||||
Download Linux WebUI v2.0.2
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user