From 92d4cbe15cef2d3cf721655a952095a9c83d5c55 Mon Sep 17 00:00:00 2001 From: Hassan DRAGA Date: Wed, 19 Oct 2022 19:48:47 -0400 Subject: [PATCH] New interface --- .gitignore | 4 + examples/Go/{ => hello_world}/go.mod | 0 examples/Go/hello_world/main.go | 116 ++++++ examples/Go/{ => hello_world}/webui/webui.go | 21 +- examples/Go/main.go | 92 ----- examples/Python/hello_world/main.py | 118 ++++++ examples/Python/{ => hello_world}/webui.py | 10 +- examples/Python/main.py | 91 ----- examples/Rust/hello_world/Cargo.toml | 6 + examples/Rust/hello_world/build.rs | 21 ++ examples/Rust/hello_world/src/Webui.rs | 370 +++++++++++++++++++ examples/Rust/hello_world/src/main.rs | 75 ++++ include/webui.h | 45 +-- src/webui.c | 66 ++-- 14 files changed, 796 insertions(+), 239 deletions(-) rename examples/Go/{ => hello_world}/go.mod (100%) create mode 100644 examples/Go/hello_world/main.go rename examples/Go/{ => hello_world}/webui/webui.go (81%) delete mode 100644 examples/Go/main.go create mode 100644 examples/Python/hello_world/main.py rename examples/Python/{ => hello_world}/webui.py (94%) delete mode 100644 examples/Python/main.py create mode 100644 examples/Rust/hello_world/Cargo.toml create mode 100644 examples/Rust/hello_world/build.rs create mode 100644 examples/Rust/hello_world/src/Webui.rs create mode 100644 examples/Rust/hello_world/src/main.rs diff --git a/.gitignore b/.gitignore index 52c6499e..f800b09b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,7 @@ # Python __pycache__/ + +# Rust +target/ +*.lock diff --git a/examples/Go/go.mod b/examples/Go/hello_world/go.mod similarity index 100% rename from examples/Go/go.mod rename to examples/Go/hello_world/go.mod diff --git a/examples/Go/hello_world/main.go b/examples/Go/hello_world/main.go new file mode 100644 index 00000000..0d7c9043 --- /dev/null +++ b/examples/Go/hello_world/main.go @@ -0,0 +1,116 @@ +// WebUI Go Hello World Example +// https://github.com/alifcommunity/webui + +package main + +import ( + "fmt" + + "github.com/alifcommunity/webui/webui" +) + +const login_html string = ` + + + WebUI 2 - Go Example + + + +

WebUI 2 - Go Example

+
+ +
+

 

+
+ - + +` + +const dashboard_html string = ` + + + Dashboard + + + +

Welcome !

+
+
+ + +` + +func Exit(e webui.Event) { + + webui.Exit() +} + +func Check(e webui.Event) { + + // Script to get the text value + MyScript := webui.JavaScript{ + Timeout: 10, + Script: " return document.getElementById('MyInput').value; ", + } + + // 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, webui.AnyBrowser) + } else { + + MyScript.Script = " document.getElementById('err').innerHTML = 'Sorry. Wrong password'; " + webui.RunJavaScript(e.Window, &MyScript) + } + } else { + + // There is an error in our script + fmt.Printf("JavaScript Error: %s\n", MyScript.Data) + } +} + +func main() { + + // New window + var my_window = webui.NewWindow() + + // Bind + webui.Bind(my_window, "CheckPassword", Check) + webui.Bind(my_window, "Exit", Exit) + + // Show window + webui.Show(my_window, login_html, webui.AnyBrowser) + + // Loop + webui.Loop() + + fmt.Println("Bye.") +} diff --git a/examples/Go/webui/webui.go b/examples/Go/hello_world/webui/webui.go similarity index 81% rename from examples/Go/webui/webui.go rename to examples/Go/hello_world/webui/webui.go index dc5d24d6..53d2b98a 100644 --- a/examples/Go/webui/webui.go +++ b/examples/Go/hello_world/webui/webui.go @@ -9,10 +9,10 @@ package webui // Copyright (C)2022 Hassan DRAGA . /* -#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 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 #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) { @@ -26,6 +26,14 @@ import ( "C" ) +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 @@ -66,7 +74,8 @@ func webui_go_handler(_window *C.webui_window_t, _element_id C.uint, _window_id func RunJavaScript(window *C.webui_window_t, js *JavaScript) { - c_js := C.webui_javascript_py_t{ + // Interface + c_js := C.webui_javascript_int_t{ script: C.CString(js.Script), timeout: 30, // uint(js.Timeout), error: C.bool(false), @@ -74,7 +83,7 @@ func RunJavaScript(window *C.webui_window_t, js *JavaScript) { // data: C.CString(nil), } - C.webui_run_js_py(window, &c_js) + C.webui_run_js_int_struct(window, &c_js) js.Error = bool(c_js.error) js.Data = C.GoString(c_js.data) diff --git a/examples/Go/main.go b/examples/Go/main.go deleted file mode 100644 index 4ab3b2fa..00000000 --- a/examples/Go/main.go +++ /dev/null @@ -1,92 +0,0 @@ -// WebUI Go Example -// https://github.com/alifcommunity/webui - -package main - -import ( - "fmt" - - "github.com/alifcommunity/webui/webui" -) - -const my_html string = ` - - - WebUI 2 - Go Example - - - -

WebUI 2 - Go Example

-
- -
-
- - - -` - -func Exit(e webui.Event) { - - webui.Exit() -} - -func Check(e webui.Event) { - - // Script to get the text value - js := webui.JavaScript{ - Timeout: 10, - Script: "return document.getElementById(\"MyInput\").value;", - } - - // Run the script - webui.RunJavaScript(e.Window, &js) - - // Check if any error - if !js.Error { - - fmt.Printf("Password: %s\n", js.Data) - - // Check the password - if js.Data == "123456" { - - js.Script = "alert('Good. Password is correct.')" - webui.RunJavaScript(e.Window, &js) - } else { - - js.Script = "alert('Sorry. Wrong password.')" - webui.RunJavaScript(e.Window, &js) - } - } else { - - // There is an error in our script - fmt.Printf("JavaScript Error: %s\n", js.Data) - } -} - -func main() { - - // New window - var my_window = webui.NewWindow() - - // Bind - webui.Bind(my_window, "CheckPassword", Check) - webui.Bind(my_window, "Exit", Exit) - - // Show window - webui.Show(my_window, my_html, 0) - - // Loop - webui.Loop() - - fmt.Println("Bye.") -} diff --git a/examples/Python/hello_world/main.py b/examples/Python/hello_world/main.py new file mode 100644 index 00000000..cd0e6476 --- /dev/null +++ b/examples/Python/hello_world/main.py @@ -0,0 +1,118 @@ + +# WebUI Library 2.x +# Python Example +# +# http://webui.me +# https://github.com/alifcommunity/webui +# +# Licensed under GNU General Public License v3.0. +# Copyright (C)2022 Hassan DRAGA . + +import webui + +# Set the WebUI dynamic library location (Optional) +# Default is the same folder, otherwise use this option +webui.set_library_path("../../../build/Windows/MSVC") + +# Create a global window object +MyWindow = webui.window() + +# HTML +login_html = """ + + + + WebUI 2 - Python Example + + + +

WebUI 2 - Python Example

+
+ +
+

 

+
+ - + + +""" + +dashboard_html = """ + + + + Dashboard + + + +

Welcome !

+
+
+ + + +""" + +# This function get called every time the user click on "MyButton1" +def check_the_password(e : webui.event): + + # Print some info (optional) + # print('Element_id: ' + str(e.element_id)) + # print('Window_id: ' + str(e.window_id)) + # print('Element_name: ' + e.element_name.decode('utf-8')) + + # Run JavaScript to get the password + res = MyWindow.run_js("return document.getElementById(\"MyInput\").value;") + + # Check for any error + if res.error is True: + print("JavaScript Error: " + res.data) + return + + # Check the password + if res.data == "123456": + print("Password is correct.") + MyWindow.show(dashboard_html) + else: + print("Wrong password: " + res.data) + MyWindow.run_js(" document.getElementById('err').innerHTML = 'Sorry. Wrong password'; ") + +def close_the_application(e : webui.event): + webui.exit() + +def main(): + + # Bind am HTML element ID with a python function + MyWindow.bind('CheckPassword', check_the_password) + MyWindow.bind('Exit', close_the_application) + + # Show the window + MyWindow.show(login_html) + + # Wait until all windows are closed + webui.loop() + + print('Bye.') + +if __name__ == "__main__": + main() diff --git a/examples/Python/webui.py b/examples/Python/hello_world/webui.py similarity index 94% rename from examples/Python/webui.py rename to examples/Python/hello_world/webui.py index 1f01970d..ddafa494 100644 --- a/examples/Python/webui.py +++ b/examples/Python/hello_world/webui.py @@ -23,7 +23,7 @@ class event: element_name = "" # WebUI C-Struct -class webui_javascript_py_t(ctypes.Structure): +class webui_javascript_int_t(ctypes.Structure): _fields_ = [ ("script", c_char_p), ("timeout", c_uint), @@ -90,7 +90,7 @@ class window: if WebUI is None: err_library_not_found('bind') return - cb_index = int(WebUI.webui_bind_py(self.window, element.encode('utf-8'), self.c_events)) + cb_index = int(WebUI.webui_bind_int(self.window, element.encode('utf-8'), self.c_events)) self.cb_fun_list.insert(cb_index, func) def show(self, html): @@ -119,7 +119,7 @@ class window: err_library_not_found('show') return # Create Struct - js = webui_javascript_py_t() + js = webui_javascript_int_t() # Initializing js.script = ctypes.c_char_p(script.encode('utf-8')) js.timeout = ctypes.c_uint(timeout) @@ -134,7 +134,7 @@ class window: res.length = 7 res.data = "UNKNOWN" # Run JavaScript - WebUI.webui_run_js_py(self.window, ctypes.byref(js)) + WebUI.webui_run_js_int_struct(self.window, ctypes.byref(js)) res.length = int(js.length) res.data = js.data.decode('utf-8') res.error = js.error @@ -214,7 +214,7 @@ def loop(): return WebUI.webui_loop() try: - shutil.rmtree(os.getcwd() + '/__pycache__/') + shutil.rmtree(os.getcwd() + '/__intcache__/') except OSError: pass diff --git a/examples/Python/main.py b/examples/Python/main.py deleted file mode 100644 index 22c22f53..00000000 --- a/examples/Python/main.py +++ /dev/null @@ -1,91 +0,0 @@ - -# WebUI Library 2.x -# Python Example -# -# http://webui.me -# https://github.com/alifcommunity/webui -# -# Licensed under GNU General Public License v3.0. -# Copyright (C)2022 Hassan DRAGA . - -import webui - -# Set the WebUI dynamic library location (Optional) -# Default is the same folder, otherwise use this option -webui.set_library_path("../../build/Windows/MSVC") - -# Create a global window object -MyWindow = webui.window() - -# HTML -my_html = """ - - - - WebUI 2 - Python Example - - - -

WebUI 2 - Python Example

-
- -
-
- - - - -""" - -# This function get called every time the user click on "MyButton1" -def check_the_password(e : webui.event): - - # Print some info (optional) - # print('Element_id: ' + str(e.element_id)) - # print('Window_id: ' + str(e.window_id)) - # print('Element_name: ' + e.element_name.decode('utf-8')) - - # Run JavaScript to get the password - res = MyWindow.run_js("return document.getElementById(\"MyInput\").value;") - - # Check for any error - if res.error is True: - print("JavaScript Error: " + res.data) - return - - # Check the password - if res.data == "123456": - print("Password is correct.") - MyWindow.run_js("alert('Good. Password is correct.')") - else: - print("Wrong password: " + res.data) - MyWindow.run_js("alert('Sorry. Wrong password.')") - -def close_the_application(e : webui.event): - webui.exit() - -def main(): - - # Bind am HTML element ID with a python function - MyWindow.bind('MyButton1', check_the_password) - MyWindow.bind('MyButton2', close_the_application) - - # Show the window - MyWindow.show(my_html) - - # Wait until all windows are closed - webui.loop() - - print('Bye.') - -if __name__ == "__main__": - main() diff --git a/examples/Rust/hello_world/Cargo.toml b/examples/Rust/hello_world/Cargo.toml new file mode 100644 index 00000000..3789e707 --- /dev/null +++ b/examples/Rust/hello_world/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "my-webui-application" +version = "0.1.0" +build = "build.rs" + +[dependencies] diff --git a/examples/Rust/hello_world/build.rs b/examples/Rust/hello_world/build.rs new file mode 100644 index 00000000..ea7d2156 --- /dev/null +++ b/examples/Rust/hello_world/build.rs @@ -0,0 +1,21 @@ +/* + WebUI Library 2.0.1 + + http://webui.me + https://github.com/alifcommunity/webui + + Licensed under GNU General Public License v3.0. + Copyright (C)2022 Hassan DRAGA . +*/ + +fn main() { + + // Path to prebuilt WebUI static library + println!("cargo:rustc-link-search=../../../build/Windows/MSVC/"); + + // Path to WebUI include folder (Optional) + println!("cargo:rustc-link-search=../../../include/"); + + // WebUI static library name + println!("cargo:rustc-link-lib=webui-2-static-x64"); +} diff --git a/examples/Rust/hello_world/src/Webui.rs b/examples/Rust/hello_world/src/Webui.rs new file mode 100644 index 00000000..f36d651b --- /dev/null +++ b/examples/Rust/hello_world/src/Webui.rs @@ -0,0 +1,370 @@ +/* + WebUI Library 2.0.1 + + http://webui.me + https://github.com/alifcommunity/webui + + Licensed under GNU General Public License v3.0. + Copyright (C)2022 Hassan DRAGA . +*/ + +// Flags +#![allow(non_camel_case_types)] +#![allow(unsafe_code)] +#![allow(dead_code)] +#![allow(non_snake_case)] +#![allow(improper_ctypes)] +#![allow(non_upper_case_globals)] + +// Modules +use std::os::raw::c_char; +use std::ffi::CString; +use std::ffi::CStr; + +// --[WebUI Library References]------------------------------- + +pub type size_t = ::std::os::raw::c_ulonglong; + +#[repr(C)] +pub struct webui_event_t { + pub window: *mut webui_window_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, +} + +#[repr(C)] +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)] +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 is_bind_all: bool, + pub url: *mut ::std::os::raw::c_char, + pub cb_all: [::std::option::Option; 1usize], + pub html: *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, + pub server_thread: ::std::os::raw::c_int, +} + +#[repr(C)] +pub struct webui_window_t { + pub core: webui_window_core_t, + pub path: *mut ::std::os::raw::c_char, +} + +#[repr(C)] +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)] +pub struct webui_javascript_t { + pub script: *mut ::std::os::raw::c_char, + pub timeout: ::std::os::raw::c_uint, + pub result: webui_javascript_result_t, +} + +#[repr(C)] +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)] +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: [*mut ::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 runtime: webui_runtime_t, + pub initialized: bool, + pub cb: [::std::option::Option; 32usize], + pub cb_int: [::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_uint, + arg2: ::std::os::raw::c_uint, + arg3: *mut ::std::os::raw::c_char, + ), + >; 32usize], + pub executable_path: *mut ::std::os::raw::c_char, + pub ptr_list: [*mut ::std::os::raw::c_void; 32usize], + pub ptr_position: size_t, + pub ptr_size: [size_t; 32usize], +} + +extern "C" { + pub static mut webui: webui_t; +} + +extern "C" { + pub fn webui_loop(); +} + +extern "C" { + pub fn webui_exit(); +} + +extern "C" { + pub fn webui_any_window_is_open() -> 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, + html: *const ::std::os::raw::c_char, + browser: ::std::os::raw::c_uint, + ) -> bool; +} + +extern "C" { + pub fn webui_copy_show( + win: *mut webui_window_t, + html: *const ::std::os::raw::c_char, + browser: ::std::os::raw::c_uint, + ) -> 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, + ); +} + +extern "C" { + pub fn webui_allow_multi_access(win: *mut webui_window_t, status: bool); +} + +extern "C" { + pub fn webui_set_root_folder( + win: *mut webui_window_t, + path: *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, + index_html: *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_show(win: *mut webui_window_t) -> bool; +} + +extern "C" { + pub fn webui_run_js(win: *mut webui_window_t, javascript: *mut webui_javascript_t); +} + +extern "C" { + pub fn webui_run_js_int( + win: *mut webui_window_t, + 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, + ); +} + +extern "C" { + pub fn webui_bind( + win: *mut webui_window_t, + element: *const ::std::os::raw::c_char, + func: ::std::option::Option ()>, + ) -> ::std::os::raw::c_uint; +} + +extern "C" { + pub fn webui_bind_all( + win: *mut webui_window_t, + func: ::std::option::Option, + ); +} + +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_free_js(javascript: *mut webui_javascript_t); +} + +extern "C" { + pub fn webui_runtime(win: *mut webui_window_t, runtime: ::std::os::raw::c_uint); +} + +extern "C" { + pub fn webui_detect_process_close(win: *mut webui_window_t, status: bool); +} + +// --[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]------------------------------------------------ + +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 Custom: u32 = 99; + +pub struct JavaScript { + pub timeout: u32, + pub script: String, + pub error: bool, + pub data: String, +} + +pub fn RunJavaScript(win: *mut webui_window_t, 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(); + let script_c_char: *const c_char = script_c_str.as_ptr() as *const c_char; + + // Interface + let script: *const ::std::os::raw::c_char = script_c_char; + let timeout: ::std::os::raw::c_uint = js.timeout; + let mut error: bool = false; + let mut length: ::std::os::raw::c_uint = 0; + let data = CString::new("").expect(""); + + // Pointers + let error_ptr: *mut bool = &mut error; + let length_ptr: *mut ::std::os::raw::c_uint = &mut length; + let data_ptr = data.into_raw(); + + webui_run_js_int(win, script, timeout, error_ptr, length_ptr, data_ptr); + + js.error = error; + js.data = char_to_string(data_ptr); + } +} + +pub fn NewWindow() -> *mut webui_window_t { + + unsafe { + + return webui_new_window(); + } +} + +pub fn Loop() { + + unsafe { + + webui_loop(); + } +} + +pub fn Exit() { + + unsafe { + + webui_exit(); + } +} + +pub fn Show(win: *mut webui_window_t, html: &str, b: u32) -> bool { + + unsafe { + + // HTML String to i8/u8 + let html_c_str = CString::new(html).unwrap(); + let html_c_char: *const c_char = html_c_str.as_ptr() as *const c_char; + + return webui_copy_show(win, html_c_char, b); + } +} + +pub fn Bind(win: *mut webui_window_t, element: &str, func: fn(e: webui_event_t)) -> u32 { + + // 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; + + // Func to Option + let f: Option = Some(func); + + // Bind + unsafe { + + webui_bind(win, element_c_char, f); + } + + return 0; +} diff --git a/examples/Rust/hello_world/src/main.rs b/examples/Rust/hello_world/src/main.rs new file mode 100644 index 00000000..a460a783 --- /dev/null +++ b/examples/Rust/hello_world/src/main.rs @@ -0,0 +1,75 @@ +/* + WebUI Library 2.x + Rust Example + + http://webui.me + https://github.com/alifcommunity/webui + + Licensed under GNU General Public License v3.0. + Copyright (C)2022 Hassan DRAGA . +*/ + +mod Webui; + +fn close_the_application (_e: Webui::webui_event_t) { + + Webui::Exit(); +} + +fn check_the_password (e: Webui::webui_event_t) { + + // Script to get the text value + let mut js = Webui::JavaScript { + + timeout: 10, + script: "return document.getElementById(\"MyInput\").value;".to_string(), + + data: "".to_string(), + error: false, + }; + + // Run the script + Webui::RunJavaScript(e.window, &mut js); + + // Check if any error + if !js.error { + + // Check the password + println!("Password: {}", js.data); + } + else { + + // There is an error in our script + println!("JavaScript Error: {}", js.data); + } +} + +fn main() { + + // UI HTML + let my_html = " + WebUI 2 - Rust Example + +

WebUI 2 - Rust Example


+

+ - + "; + + // Create new window + let my_window = Webui::NewWindow(); + + // Bind an HTML element with a function + Webui::Bind(my_window, "MyButton1", check_the_password); + Webui::Bind(my_window, "MyButton2", close_the_application); + + // Show the window + Webui::Show(my_window, my_html, Webui::Chrome); + + // Wait until all windows get closed + Webui::Loop(); + + println!("Bye."); +} diff --git a/include/webui.h b/include/webui.h index 2540cd8d..f85bbc7f 100644 --- a/include/webui.h +++ b/include/webui.h @@ -29,7 +29,7 @@ #define WEBUI_MAX_BUF (512000) // 512 Kb max dynamic memory allocation #define WEBUI_DEFAULT_PATH "." // Default root path -// -- C STD ----------------------------------- +// -- C STD --------------------------- #include #include #include @@ -45,7 +45,7 @@ #include #endif -// -- Windows --------------------------------- +// -- Windows ------------------------- #ifdef _WIN32 // #include // Fix _WIN32_WINNT warning #include @@ -60,7 +60,7 @@ #define WEBUI_PCLOSE _pclose #endif -// -- Linux ----------------------------------- +// -- Linux --------------------------- #ifdef __linux__ #include // POSIX threading #include @@ -70,7 +70,7 @@ #define WEBUI_PCLOSE pclose #endif -// -- macOS ----------------------------------- +// -- macOS --------------------------- // ... struct webui_window_t; @@ -131,7 +131,7 @@ typedef struct webui_javascript_result_t { typedef struct webui_javascript_t { - char* script; + const char* script; unsigned int timeout; webui_javascript_result_t result; @@ -203,27 +203,15 @@ typedef struct webui_t { webui_runtime_t runtime; bool initialized; void (*cb[WEBUI_MAX_ARRAY]) (webui_event_t* e); - void (*cb_py[WEBUI_MAX_ARRAY])(unsigned int, unsigned int, char*); + void (*cb_int[WEBUI_MAX_ARRAY])(unsigned int, unsigned int, char*); char* executable_path; - - // Pointers Tracker void *ptr_list[WEBUI_MAX_ARRAY]; size_t ptr_position; size_t ptr_size[WEBUI_MAX_ARRAY]; } webui_t; -typedef struct webui_javascript_py_t { - - char* script; - unsigned int timeout; - bool error; - unsigned int length; - const char* data; - -} webui_javascript_py_t; - -// -- Definitions -------------------- +// -- Definitions --------------------- EXPORT webui_t webui; EXPORT void webui_loop(); @@ -247,9 +235,22 @@ EXPORT void webui_free_js(webui_javascript_t* javascript); EXPORT void webui_runtime(webui_window_t* win, unsigned int runtime); EXPORT void webui_detect_process_close(webui_window_t* win, bool status); -// Python Interface -EXPORT unsigned int webui_bind_py(webui_window_t* win, const char* element, void (*func)(unsigned int, unsigned int, char*)); -EXPORT void webui_run_js_py(webui_window_t* win, webui_javascript_py_t* js_py); +// -- Interface ----------------------- +// To help other languages to use WebUI + +typedef struct webui_javascript_int_t { + + char* script; + unsigned int timeout; + 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); // Core EXPORT void _webui_ini(); diff --git a/src/webui.c b/src/webui.c index e0b6eb7d..1ddbd0cc 100644 --- a/src/webui.c +++ b/src/webui.c @@ -451,14 +451,16 @@ void _webui_sleep(long unsigned int ms) { #endif } -void _webui_print_hex(const char* data, size_t len) { +#ifdef WEBUI_LOG + void _webui_print_hex(const char* data, size_t len) { - for(size_t i = 0; i < len; i++) { + for(size_t i = 0; i < len; i++) { - printf("0x%02X ", (unsigned char) *data); - data++; + printf("0x%02X ", (unsigned char) *data); + data++; + } } -} +#endif bool _webui_is_empty(const char* s) { @@ -1084,8 +1086,6 @@ static void _webui_server_event_handler(struct mg_connection *c, int ev, void *e // Send main HTML - - #ifdef WEBUI_LOG printf("[%d] _webui_server_event_handler()... HTML Main\n", win->core.window_number); #endif @@ -2262,8 +2262,6 @@ void webui_set_icon(webui_window_t* win, const char* icon_s, const char* type_s) bool webui_show(webui_window_t* win, const char* html, unsigned int browser) { - - #ifdef WEBUI_LOG printf("[%d] webui_show([%.*s..], [%d])... \n", win->core.window_number, 3, html, browser); #endif @@ -2327,7 +2325,7 @@ bool webui_copy_show(webui_window_t* win, const char* html, unsigned int browser size_t len = strlen(html); if(len > 1) { - char* cpy = _webui_malloc(len + 1); + cpy = _webui_malloc(len + 1); memcpy(cpy, html, len); } @@ -2879,34 +2877,56 @@ unsigned int _webui_set_cb_index(char* element_id) { return 0; } -// --[Python Interface]--------------- +// --[Interface]--------------- -void webui_bind_py_handler(webui_event_t* e) { +void webui_bind_int_handler(webui_event_t* e) { unsigned int cb_index = e->element_id; - if(cb_index > 0 && webui.cb_py[cb_index] != NULL) - webui.cb_py[cb_index](e->element_id, e->window_id, e->element_name); + if(cb_index > 0 && webui.cb_int[cb_index] != NULL) + webui.cb_int[cb_index](e->element_id, e->window_id, e->element_name); } -unsigned int webui_bind_py(webui_window_t* win, const char* element, void (*func)(unsigned int, unsigned int, char*)) { +unsigned int webui_bind_int(webui_window_t* win, const char* element, void (*func)(unsigned int, unsigned int, char*)) { - unsigned int cb_index = webui_bind(win, element, webui_bind_py_handler); - webui.cb_py[cb_index] = func; + unsigned int cb_index = webui_bind(win, element, webui_bind_int_handler); + webui.cb_int[cb_index] = func; return cb_index; } -void webui_run_js_py(webui_window_t* win, webui_javascript_py_t* js_py) { +void webui_run_js_int(webui_window_t* win, const char* script, unsigned int timeout, bool* error, unsigned int* length, char* data) { + + #ifdef WEBUI_LOG + printf("[%d] webui_run_js_int()... \n", win->core.window_number); + #endif webui_javascript_t js = { - .script = js_py->script, - .timeout = js_py->timeout + .script = script, + .timeout = timeout }; webui_run_js(win, &js); - js_py->data = js.result.data; - js_py->error = js.result.error; - js_py->length = js.result.length; + data = (char*) js.result.data; + *error = js.result.error; + *length = js.result.length; +} + +void webui_run_js_int_struct(webui_window_t* win, webui_javascript_int_t* js_int) { + + #ifdef WEBUI_LOG + printf("[%d] webui_run_js_int_struct()... \n", win->core.window_number); + #endif + + webui_javascript_t js = { + .script = js_int->script, + .timeout = js_int->timeout + }; + + webui_run_js(win, &js); + + js_int->data = js.result.data; + js_int->error = js.result.error; + js_int->length = js.result.length; }