diff --git a/test/cef_base.lua b/test/cef_base.lua new file mode 100644 index 0000000..5523e80 --- /dev/null +++ b/test/cef_base.lua @@ -0,0 +1,80 @@ +-- CEF C API example +-- Project website: https://github.com/cztomczak/cefcapi + +local ffi = require( "ffi" ) +local cef = require( "../cef" ) + +-- Set to 1 to check if add_ref() and release() +-- are called and to track the total number of calls. +-- add_ref will be printed as "+", release as "-". +DEBUG_REFERENCE_COUNTING = false + +-- Print only the first execution of the callback, +-- ignore the subsequent. +function DEBUG_CALLBACK(x) + first_call = first_call or {} + if (first_call[x] == nil) then + first_call[x] = 1; + ffi.C.printf(x); + end +end + +-- ---------------------------------------------------------------------------- +-- cef_base_ref_counted_t +-- ---------------------------------------------------------------------------- + +--- +-- Structure defining the reference count implementation functions. +-- All framework structures must include the cef_base_ref_counted_t +-- structure first. +--- + +--- +-- Increment the reference count. +--- +function add_ref(self) + DEBUG_CALLBACK("cef_base_ref_counted_t.add_ref\n"); + if (DEBUG_REFERENCE_COUNTING) then + ffi.C.printf("+"); + end +end + +--- +-- Decrement the reference count. Delete this object when no references +-- remain. +--- +function release(self) + DEBUG_CALLBACK("cef_base_ref_counted_t.release\n"); + if (DEBUG_REFERENCE_COUNTING) then + ffi.C.printf("-"); + end + return 1; +end + +--- +-- Returns the current number of references. +--- +function has_one_ref(self) + DEBUG_CALLBACK("cef_base_ref_counted_t.has_one_ref\n"); + if (DEBUG_REFERENCE_COUNTING) then + ffi.C.printf("="); + end + return 1; +end + +function initialize_cef_base_ref_counted(base) + ffi.C.printf("initialize_cef_base_ref_counted\n"); + -- Check if "size" member was set. + local size = base.size; + -- Let's print the size in case sizeof was used + -- on a pointer instead of a structure. In such + -- case the number will be very high. + ffi.C.printf("cef_base_ref_counted_t.size = %lu\n", size); + if (size <= 0) then + ffi.C.printf("FATAL: initialize_cef_base failed, size member not set\n"); + os.exit(1); + end + base.add_ref = add_ref; + base.release = release; + base.has_one_ref = has_one_ref; +end diff --git a/test/cef_client.lua b/test/cef_client.lua new file mode 100644 index 0000000..0b7444b --- /dev/null +++ b/test/cef_client.lua @@ -0,0 +1,156 @@ +-- CEF C API example +-- Project website: https://github.com/cztomczak/cefcapi + +local ffi = require( "ffi" ) +local cef = require( "../cef" ) + + +-- ---------------------------------------------------------------------------- +-- struct cef_client_t +-- ---------------------------------------------------------------------------- + +--- +-- Implement this structure to provide handler implementations. +--- + +--- +-- Return the handler for context menus. If no handler is +-- provided the default implementation will be used. +--- + +function get_context_menu_handler(self) + DEBUG_CALLBACK("get_context_menu_handler\n"); + return nil; +end + +--- +-- Return the handler for dialogs. If no handler is provided the default +-- implementation will be used. +--- +function get_dialog_handler(self) + DEBUG_CALLBACK("get_dialog_handler\n"); + return nil; +end + +--- +-- Return the handler for browser display state events. +--- +function get_display_handler(self) + DEBUG_CALLBACK("get_display_handler\n"); + return nil; +end + +--- +-- Return the handler for download events. If no handler is returned downloads +-- will not be allowed. +--- +function get_download_handler(self) + DEBUG_CALLBACK("get_download_handler\n"); + return nil; +end + +--- +-- Return the handler for drag events. +--- +function get_drag_handler(self) + DEBUG_CALLBACK("get_drag_handler\n"); + return nil; +end + +--- +-- Return the handler for focus events. +--- +function get_focus_handler(self) + DEBUG_CALLBACK("get_focus_handler\n"); + return nil; +end + +--- +-- Return the handler for geolocation permissions requests. If no handler is +-- provided geolocation access will be denied by default. +--- +function get_geolocation_handler(self) + DEBUG_CALLBACK("get_geolocation_handler\n"); + return nil; +end + +--- +-- Return the handler for JavaScript dialogs. If no handler is provided the +-- default implementation will be used. +--- +function get_jsdialog_handler(self) + DEBUG_CALLBACK("get_jsdialog_handler\n"); + return nil; +end + +--- +-- Return the handler for keyboard events. +--- +function get_keyboard_handler(self) + DEBUG_CALLBACK("get_keyboard_handler\n"); + return nil; +end + +--- +-- Return the handler for browser life span events. +--- +function get_life_span_handler(self) + DEBUG_CALLBACK("get_life_span_handler\n"); + -- Implemented! + return g_life_span_handler; +end + +--- +-- Return the handler for browser load status events. +--- +function get_load_handler(self) + DEBUG_CALLBACK("get_load_handler\n"); + return nil; +end + +--- +-- Return the handler for off-screen rendering events. +--- +function get_render_handler(self) + DEBUG_CALLBACK("get_render_handler\n"); + return nil; +end + +--- +-- Return the handler for browser request events. +--- +function get_request_handler(self) + DEBUG_CALLBACK("get_request_handler\n"); + return nil; +end + +--- +-- Called when a new message is received from a different process. Return true +-- (1) if the message was handled or false (0) otherwise. Do not keep a +-- reference to or attempt to access the message outside of this callback. +--- +function on_process_message_received(self, browser, source_process, message) + DEBUG_CALLBACK("on_process_message_received\n"); + return 0; +end + +function initialize_cef_client(client) + DEBUG_CALLBACK("initialize_client_handler\n"); + client.base.size = ffi.sizeof(client); + initialize_cef_base_ref_counted(ffi.cast( "cef_base_ref_counted_t*", client )); + -- callbacks + client.get_context_menu_handler = get_context_menu_handler; + client.get_dialog_handler = get_dialog_handler; + client.get_display_handler = get_display_handler; + client.get_download_handler = get_download_handler; + client.get_drag_handler = get_drag_handler; + client.get_focus_handler = get_focus_handler; + client.get_geolocation_handler = get_geolocation_handler; + client.get_jsdialog_handler = get_jsdialog_handler; + client.get_keyboard_handler = get_keyboard_handler; + client.get_life_span_handler = get_life_span_handler; -- Implemented! + client.get_load_handler = get_load_handler; + client.get_render_handler = get_render_handler; + client.get_request_handler = get_request_handler; + client.on_process_message_received = on_process_message_received; +end diff --git a/test/cef_life_span_handler.lua b/test/cef_life_span_handler.lua new file mode 100644 index 0000000..a99ca5f --- /dev/null +++ b/test/cef_life_span_handler.lua @@ -0,0 +1,42 @@ +-- CEF C API example +-- Project website: https://github.com/cztomczak/cefcapi + +local ffi = require( "ffi" ) +local cef = require( "../cef" ) + +-- ---------------------------------------------------------------------------- +-- struct cef_life_span_handler_t +-- ---------------------------------------------------------------------------- + +--- +-- Implement this structure to handle events related to browser life span. The +-- functions of this structure will be called on the UI thread unless otherwise +-- indicated. +--- + +-- NOTE: There are many more callbacks in cef_life_span_handler, +-- but only on_before_close is implemented here. + +--- +-- Called just before a browser is destroyed. Release all references to the +-- browser object and do not attempt to execute any functions on the browser +-- object after this callback returns. This callback will be the last +-- notification that references |browser|. See do_close() documentation for +-- additional usage information. +--- +function on_before_close(self, browser) + DEBUG_CALLBACK("on_before_close\n"); + -- TODO: Check how many browsers do exist and quit message + -- loop only when last browser is closed. Otherwise + -- closing a popup window will exit app while main + -- window shouldn't be closed. + cef.cef_quit_message_loop(); +end + +function initialize_cef_life_span_handler(handler) + DEBUG_CALLBACK("initialize_cef_life_span_handler\n"); + handler.base.size = ffi.sizeof(handler); + initialize_cef_base_ref_counted(ffi.cast( "cef_base_ref_counted_t*", handler )); + -- callbacks - there are many, but implementing only one + handler.on_before_close = on_before_close; +end diff --git a/test/main_win.lua b/test/main_win.lua index 14df77a..b9ab254 100644 --- a/test/main_win.lua +++ b/test/main_win.lua @@ -17,9 +17,12 @@ ffi.cdef [[ ]] local cef = require( "../cef" ) +require( "test.cef_base" ) +require( "test.cef_client" ) +require( "test.cef_life_span_handler" ) -- Globals -local g_life_span_handler = ffi.new( "cef_life_span_handler_t" ); +g_life_span_handler = ffi.new( "cef_life_span_handler_t" ); -- This executable is called many times, because it @@ -56,11 +59,14 @@ main_args.instance = ffi.C.GetModuleHandleW(nil); -- Cef app local app = ffi.new( "cef_app_t" ); --- initialize_cef_app(&app); +-- initialize_cef_app(app); -- Application settings. It is mandatory to set the -- "size" member. local settings = ffi.new( "cef_settings_t" ); +settings.size = ffi.sizeof( settings ); +settings.log_severity = ffi.C.LOGSEVERITY_WARNING; -- Show only warnings/errors +settings.no_sandbox = 1; -- Specify the path for the sub-process executable. local browser_subprocess_path = "cef.exe"; local cef_browser_subprocess_path = ffi.new( "cef_string_t" ); @@ -68,9 +74,6 @@ cef.cef_string_utf8_to_utf16(browser_subprocess_path, string.len(browser_subprocess_path), cef_browser_subprocess_path); settings.browser_subprocess_path = cef_browser_subprocess_path; -settings.size = ffi.sizeof( settings ); -settings.log_severity = ffi.C.LOGSEVERITY_WARNING; -- Show only warnings/errors -settings.no_sandbox = 1; -- Initialize CEF ffi.C.printf("cef_initialize\n"); @@ -106,8 +109,8 @@ browser_settings.size = ffi.sizeof( browser_settings ); -- Client handlers local client = ffi.new( "cef_client_t" ); --- initialize_cef_client(&client); --- initialize_cef_life_span_handler(&g_life_span_handler); +initialize_cef_client(client); +initialize_cef_life_span_handler(g_life_span_handler); -- Create browser asynchronously. There is also a -- synchronous version of this function available.