diff --git a/build/Linux/Clang/Makefile b/build/Linux/Clang/Makefile new file mode 100644 index 00000000..c133fd4c --- /dev/null +++ b/build/Linux/Clang/Makefile @@ -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 diff --git a/build/Linux/GCC/Makefile b/build/Linux/GCC/Makefile new file mode 100644 index 00000000..cea91dc3 --- /dev/null +++ b/build/Linux/GCC/Makefile @@ -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 diff --git a/examples/C/Linux/Clang/Makefile b/examples/C/Linux/Clang/Makefile new file mode 100644 index 00000000..986cfcd6 --- /dev/null +++ b/examples/C/Linux/Clang/Makefile @@ -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 diff --git a/examples/C/Linux/GCC/Makefile b/examples/C/Linux/GCC/Makefile new file mode 100644 index 00000000..5ddabfa0 --- /dev/null +++ b/examples/C/Linux/GCC/Makefile @@ -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 diff --git a/examples/Go/hello_world/webui/webui.go b/examples/Go/hello_world/webui/webui.go index 53d2b98a..95fd401d 100644 --- a/examples/Go/hello_world/webui/webui.go +++ b/examples/Go/hello_world/webui/webui.go @@ -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 . /* +// [?] 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 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) { diff --git a/examples/Rust/hello_world/build.rs b/examples/Rust/hello_world/build.rs index ea7d2156..e1e5e7ac 100644 --- a/examples/Rust/hello_world/build.rs +++ b/examples/Rust/hello_world/build.rs @@ -1,5 +1,5 @@ /* - WebUI Library 2.0.1 + WebUI Library 2.0.2 http://webui.me https://github.com/alifcommunity/webui diff --git a/examples/Rust/hello_world/src/Webui.rs b/examples/Rust/hello_world/src/Webui.rs index f36d651b..f2743d67 100644 --- a/examples/Rust/hello_world/src/Webui.rs +++ b/examples/Rust/hello_world/src/Webui.rs @@ -1,5 +1,5 @@ /* - WebUI Library 2.0.1 + WebUI Library 2.0.2 http://webui.me https://github.com/alifcommunity/webui diff --git a/include/webui.h b/include/webui.h index 766444f8..48371181 100644 --- a/include/webui.h +++ b/include/webui.h @@ -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 // 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 { @@ -117,15 +120,13 @@ typedef struct webui_window_core_t { HANDLE server_thread; #else pthread_t server_thread; - #endif - + #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); diff --git a/packages/PyPI/pyproject.toml b/packages/PyPI/pyproject.toml index 29a33fa2..160553cb 100644 --- a/packages/PyPI/pyproject.toml +++ b/packages/PyPI/pyproject.toml @@ -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" }, ] diff --git a/packages/PyPI/src/webui/webui.py b/packages/PyPI/src/webui/webui.py index 6e0d5e58..99e80e72 100644 --- a/packages/PyPI/src/webui/webui.py +++ b/packages/PyPI/src/webui/webui.py @@ -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 diff --git a/src/webui.c b/src/webui.c index 3b026e24..adfe8e53 100644 --- a/src/webui.c +++ b/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; + + // Stop if timer is finished + if(_webui_timer_is_end(&timer, (timeout * 1000))) + break; + } + + if(!win->core.connected && webui.timeout_extra && win->core.server_handled) { + + // 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 - if(webui.timeout_extra && win->core.server_handled && !extra_used) { + _webui_timer_start(&timer); + while(1) { - // 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 + // Stop if window is connected + mg_mgr_poll(&mgr, 1); + if(win->core.connected) + break; - n = 0; - extra_used = true; + // 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) { diff --git a/website/index.html b/website/index.html index 136d6010..858f9996 100644 --- a/website/index.html +++ b/website/index.html @@ -149,8 +149,7 @@ @@ -171,7 +170,7 @@