Files
racket-webview/scrbl/rktwebview-api.scrbl

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.