588 lines
14 KiB
Racket
588 lines
14 KiB
Racket
#lang scribble/manual
|
|
|
|
@;@defmodule[racket-webview]
|
|
|
|
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
|
|
|
|
@title{C API for Racket Integration}
|
|
|
|
This section describes the C API exactly as defined in @tt{rktwebview.h} and
|
|
@tt{rktwebview_types.h}. The API is used from Racket through FFI, but is
|
|
documented here in its native C/C++ form.
|
|
|
|
The interface is deliberately small. Handles are integers, most operations
|
|
return a @tt{result_t}, and structured values are returned as @tt{rkt_data_t *}.
|
|
The latter are caller-owned and must be released with
|
|
@tt{rkt_webview_free_data()}.
|
|
|
|
@section{Version, Export, and Basic Types}
|
|
|
|
The public API version is:
|
|
|
|
@verbatim{
|
|
#define RKT_WEBVIEW_API_MAJOR 0
|
|
#define RKT_WEBVIEW_API_MINOR 1
|
|
#define RKT_WEBVIEW_API_PATCH 1
|
|
}
|
|
|
|
The export macro @tt{RKTWEBVIEW_EXPORT} expands to
|
|
@tt{__declspec(dllexport)} or @tt{__declspec(dllimport)} on Windows, and to an
|
|
empty definition on other platforms.
|
|
|
|
The two basic handle types are:
|
|
|
|
@verbatim{
|
|
typedef int rktwebview_t;
|
|
typedef int rkt_wv_context_t;
|
|
}
|
|
|
|
@tt{rktwebview_t} identifies a webview. @tt{rkt_wv_context_t} identifies a
|
|
context.
|
|
|
|
@section{Enums and Structured Data}
|
|
|
|
The API defines the following enums: @tt{rkt_webview_loglevel_t},
|
|
@tt{result_t}, @tt{window_state_t}, @tt{rkt_messagetype_t}, and
|
|
@tt{rkt_data_kind_t}. The corresponding values are exactly those given in
|
|
@tt{rktwebview_types.h}.
|
|
|
|
Structured return data uses these types:
|
|
|
|
@verbatim{
|
|
typedef struct {
|
|
rktwebview_t wv;
|
|
char *event;
|
|
} rkt_event_t;
|
|
|
|
typedef struct {
|
|
result_t result;
|
|
char *value;
|
|
} rkt_js_result_t;
|
|
|
|
typedef struct {
|
|
int api_major;
|
|
int api_minor;
|
|
int api_patch;
|
|
} rkt_version_t;
|
|
|
|
typedef struct {
|
|
int shm_usage;
|
|
int shm_free_depth;
|
|
int shm_free_size;
|
|
int shm_item_depth;
|
|
int shm_item_size;
|
|
double shm_item_usage_factor;
|
|
int open_windows;
|
|
int function_calls;
|
|
int events;
|
|
char *log_file;
|
|
} rkt_metrics_t;
|
|
|
|
typedef struct {
|
|
rkt_data_kind_t kind;
|
|
union {
|
|
rkt_version_t version;
|
|
rkt_event_t event;
|
|
rkt_js_result_t js_result;
|
|
rkt_metrics_t metrics;
|
|
} data;
|
|
} rkt_data_t;
|
|
}
|
|
|
|
The @tt{kind} field determines which member of @tt{data} is valid.
|
|
|
|
@section{Ownership}
|
|
|
|
Any function returning @tt{rkt_data_t *} returns allocated memory. The caller
|
|
must release it using:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT void rkt_webview_free_data(rkt_data_t *d);
|
|
}
|
|
|
|
This applies to values returned by @tt{rkt_webview_info()},
|
|
@tt{rkt_webview_version()}, @tt{rkt_webview_get_event()}, and
|
|
@tt{rkt_webview_call_js()}.
|
|
|
|
@section{Environment and Runtime Control}
|
|
|
|
@defproc[(rkt_webview_env [env_cmds any/c]) void?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT void rkt_webview_env(const char *env_cmds[]);
|
|
}
|
|
|
|
Sets environment variables before the backend is initialized. The argument is a
|
|
null-terminated array of @tt{const char *}, each string typically having the
|
|
form @tt{"NAME=value"}.
|
|
|
|
Return value: none.
|
|
}
|
|
|
|
@defproc[(rkt_webview_init) void?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT void rkt_webview_init();
|
|
}
|
|
|
|
Initializes the backend, creates the shared memory transport, and starts the
|
|
helper process.
|
|
|
|
Return value: none.
|
|
}
|
|
|
|
@defproc[(rkt_webview_cleanup) void?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT void rkt_webview_cleanup();
|
|
}
|
|
|
|
Stops the backend and releases its shared resources. After this call, all
|
|
previously returned context and webview handles are invalid.
|
|
|
|
Return value: none.
|
|
}
|
|
|
|
@defproc[(rkt_webview_set_loglevel [l any/c]) void?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT void rkt_webview_set_loglevel(rkt_webview_loglevel_t l);
|
|
}
|
|
|
|
Sets the backend log level.
|
|
|
|
Return value: none.
|
|
}
|
|
|
|
@defproc[(rkt_webview_info) any/c]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT rkt_data_t *rkt_webview_info();
|
|
}
|
|
|
|
Returns a pointer to @tt{rkt_data_t}. The returned object has
|
|
@tt{kind == metrics}; the valid payload is therefore @tt{data.metrics}.
|
|
|
|
Return value: @tt{rkt_data_t *}, caller-owned.
|
|
}
|
|
|
|
@defproc[(rkt_webview_version) any/c]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT rkt_data_t *rkt_webview_version();
|
|
}
|
|
|
|
Returns a pointer to @tt{rkt_data_t}. The returned object has
|
|
@tt{kind == version}; the valid payload is therefore @tt{data.version}.
|
|
|
|
Return value: @tt{rkt_data_t *}, caller-owned.
|
|
}
|
|
|
|
@subsection{Events}
|
|
|
|
@defproc[(rkt_webview_events_waiting) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT int rkt_webview_events_waiting();
|
|
}
|
|
|
|
Returns the number of events currently waiting in the event queue.
|
|
|
|
Return value: @tt{int}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_get_event) any/c]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT rkt_data_t *rkt_webview_get_event();
|
|
}
|
|
|
|
Returns the next pending event. The returned object has @tt{kind == event}; the
|
|
valid payload is therefore @tt{data.event}. If no event is available, the
|
|
returned pointer may be null.
|
|
|
|
Return value: @tt{rkt_data_t *}, caller-owned, or null.
|
|
}
|
|
|
|
@subsubsection{Event Polling}
|
|
|
|
Events are retrieved explicitly by polling. In normal use, polling should be
|
|
performed regularly; a polling interval of about 10 ms is appropriate.
|
|
|
|
This keeps the event queue flowing, allows asynchronous operations such as
|
|
dialogs to complete in a timely manner, and avoids the impression that the system
|
|
has stalled while the Racket side is simply not looking.
|
|
|
|
@section{Contexts}
|
|
|
|
@defproc[(rkt_webview_new_context [boilerplate_js string?]
|
|
[optional_server_cert_pem string?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char *optional_server_cert_pem);
|
|
}
|
|
|
|
Creates a new context. A context corresponds to a @tt{QWebEngineProfile}; it
|
|
defines injected JavaScript and optional trust configuration using a trusted
|
|
self-signed certificate.
|
|
|
|
Return value: @tt{rkt_wv_context_t}.
|
|
}
|
|
|
|
@section{Webviews}
|
|
|
|
@defproc[(rkt_webview_create [context exact-integer?]
|
|
[parent exact-integer?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT int rkt_webview_create(rkt_wv_context_t context, rktwebview_t parent);
|
|
}
|
|
|
|
Creates a new webview in the given context. If @tt{parent} refers to an
|
|
existing webview, the new webview is created as a modal child of that parent;
|
|
otherwise it is created as a top-level window.
|
|
|
|
Return value: webview handle as @tt{int}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_close [wv exact-integer?]) void?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT void rkt_webview_close(rktwebview_t wv);
|
|
}
|
|
|
|
Closes the specified webview.
|
|
|
|
Return value: none.
|
|
}
|
|
|
|
@defproc[(rkt_webview_valid [wv exact-integer?]) boolean?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT bool rkt_webview_valid(rktwebview_t wv);
|
|
}
|
|
|
|
Checks whether @tt{wv} is a valid webview handle.
|
|
|
|
Return value: @tt{bool}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_set_title [wv exact-integer?] [title string?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_set_title(rktwebview_t wv, const char *title);
|
|
}
|
|
|
|
Sets the window title of the specified webview.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_set_ou_token [wv exact-integer?] [token string?]) void?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT void rkt_webview_set_ou_token(rktwebview_t wv, const char *token);
|
|
}
|
|
|
|
Sets the organizational-unit token used during certificate validation for the
|
|
specified webview.
|
|
|
|
Return value: none.
|
|
}
|
|
|
|
@section{Navigation and JavaScript}
|
|
|
|
@defproc[(rkt_webview_set_url [wv exact-integer?] [url string?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_set_url(rktwebview_t wv, const char *url);
|
|
}
|
|
|
|
Navigates the specified webview to the given URL.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_set_html [wv exact-integer?] [html string?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_set_html(rktwebview_t wv, const char *html);
|
|
}
|
|
|
|
Loads raw HTML into the specified webview.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_run_js [wv exact-integer?] [js string?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_run_js(rktwebview_t wv, const char *js);
|
|
}
|
|
|
|
Executes JavaScript asynchronously in the specified webview.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_call_js [wv exact-integer?] [js string?]) any/c]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT rkt_data_t *rkt_webview_call_js(rktwebview_t wv, const char *js);
|
|
}
|
|
|
|
Executes JavaScript synchronously in the specified webview.
|
|
|
|
The provided JavaScript must end with a @tt{return} statement. The returned value
|
|
must be convertible to JSON using @tt{JSON.stringify}, as the result is
|
|
serialized and returned as a JSON string.
|
|
|
|
The returned object has @tt{kind == js_result}; the valid payload is therefore
|
|
@tt{data.js_result}. The field @tt{data.js_result.value} contains the JSON
|
|
result string.
|
|
|
|
Return value: @tt{rkt_data_t *}, caller-owned.
|
|
}
|
|
|
|
@defproc[(rkt_webview_open_devtools [wv exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_open_devtools(rktwebview_t wv);
|
|
}
|
|
|
|
Opens developer tools for the specified webview.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@section{Window Management}
|
|
|
|
@defproc[(rkt_webview_move [w exact-integer?] [x exact-integer?] [y exact-integer?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_move(rktwebview_t w, int x, int y);
|
|
}
|
|
|
|
Moves the specified window to the given screen coordinates.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_resize [w exact-integer?]
|
|
[width exact-integer?]
|
|
[height exact-integer?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_resize(rktwebview_t w, int width, int height);
|
|
}
|
|
|
|
Resizes the specified window.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_hide [w exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_hide(rktwebview_t w);
|
|
}
|
|
|
|
Hides the specified window.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_show [w exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_show(rktwebview_t w);
|
|
}
|
|
|
|
Shows the specified window.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_show_normal [w exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_show_normal(rktwebview_t w);
|
|
}
|
|
|
|
Restores the specified window to its normal state.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_present [w exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_present(rktwebview_t w);
|
|
}
|
|
|
|
Presents the specified window to the user.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_maximize [w exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_maximize(rktwebview_t w);
|
|
}
|
|
|
|
Maximizes the specified window.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_minimize [w exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_minimize(rktwebview_t w);
|
|
}
|
|
|
|
Minimizes the specified window.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_window_state [w exact-integer?]) exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT window_state_t rkt_webview_window_state(rktwebview_t w);
|
|
}
|
|
|
|
Returns the current state of the specified window.
|
|
|
|
Return value: @tt{window_state_t}.
|
|
}
|
|
|
|
@section{Dialogs}
|
|
|
|
The dialog functions are asynchronous. They request that the dialog be opened on
|
|
the Qt side, but do not block the Racket side while the dialog is shown. This is
|
|
intentional: the Qt event loop and the Racket runtime should not stall each
|
|
other.
|
|
|
|
Completion of a dialog is therefore observed through events, not by blocking the
|
|
calling thread.
|
|
|
|
|
|
@defproc[(rkt_webview_choose_dir [w exact-integer?]
|
|
[title string?]
|
|
[base_dir string?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir);
|
|
}
|
|
|
|
Opens a directory chooser associated with the specified webview.
|
|
This call is asynchronous. The function returns immediately; dialog completion is
|
|
reported through events.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_file_open [w exact-integer?]
|
|
[title string?]
|
|
[base_dir string?]
|
|
[permitted_exts string?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
|
}
|
|
|
|
Opens a file-open dialog associated with the specified webview.
|
|
This call is asynchronous. The function returns immediately; dialog completion is
|
|
reported through events.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_file_save [w exact-integer?]
|
|
[title string?]
|
|
[base_dir string?]
|
|
[permitted_exts string?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
|
|
}
|
|
|
|
Opens a file-save dialog associated with the specified webview.
|
|
This call is asynchronous. The function returns immediately; dialog completion is
|
|
reported through events.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@defproc[(rkt_webview_message_box [w exact-integer?]
|
|
[title string?]
|
|
[message string?]
|
|
[submessage string?]
|
|
[type exact-integer?])
|
|
exact-integer?]{
|
|
C signature:
|
|
|
|
@verbatim{
|
|
RKTWEBVIEW_EXPORT result_t rkt_webview_message_box(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type);
|
|
}
|
|
|
|
Opens a message box of the given type, associated with the specified webview.
|
|
This call is asynchronous. The function returns immediately; dialog completion is
|
|
reported through events.
|
|
|
|
Return value: @tt{result_t}.
|
|
}
|
|
|
|
@section{Remarks}
|
|
|
|
The API is queue-based. Commands are issued through function calls; events are
|
|
retrieved explicitly using @tt{rkt_webview_events_waiting()} and
|
|
@tt{rkt_webview_get_event()}. The boundary stays clear: integer handles on the
|
|
outside, Qt objects on the inside.
|
|
|
|
Dialog functions are asynchronous and do not block the Racket side while a
|
|
dialog is shown. Their completion is observed through events.
|
|
|
|
In normal use, event polling should be performed regularly. A polling interval
|
|
of about 10 ms is appropriate. |