Files
racket-webview/rktwebview_qt/rktwebview.cpp

279 lines
6.6 KiB
C++

#include "rktwebview_internal.h"
#include <malloc.h>
#include <string.h>
#include <chrono>
#include <stdint.h>
//#include <unistd.h>
#include <fcntl.h>
#include "rktwebview_qt.h"
uint64_t current_ms() {
using namespace std::chrono;
return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}
/////////////////////////////////////////////////////////////////////
// Main C Interface
/////////////////////////////////////////////////////////////////////
//static int pipefd[2];
//static bool started = false;
//static pid_t webview_process;
//static bool cannot_fork_or_pipe = false;
Rktwebview_qt *handler = nullptr;
void rkt_webview_cleanup()
{
if (handler != nullptr) {
rkt_webview_process_events(100);
//QTimer app_quit;
//QObject::connect(&app_quit, &QTimer::timeout, handler->app(), &QApplication::quit, Qt::ConnectionType::QueuedConnection);
//app_quit.setSingleShot(true);
//app_quit.start(250);
//handler->app()->exec();
//fprintf(stderr, "cleanup: handler = %p\n", handler);
// TODO
// Do not delete the QApplication, although it will result in QThreadStorage warnings.
// If the app is deleted, QtWebEngineProfileBuilder->createProfile will memory corrupt.
//handler->deleteApp();
//delete handler;
//handler = nullptr;
//fprintf(stderr, "cleanup: handler = %p\n", handler);
}
}
void rkt_webview_init()
{
if (handler == nullptr) {
//fprintf(stderr, "init: handler = %p\n", handler);
handler = new Rktwebview_qt();
//fprintf(stderr, "init: handler = %p\n", handler);
}
if (handler->app() == nullptr) {
handler->initApp();
//QTimer app_exit;
//QObject::connect(&app_exit, &QTimer::timeout, handler->app(), []() {
// handler->app()->exit(0);
//}, Qt::ConnectionType::QueuedConnection);
//app_exit.setSingleShot(true);
//app_exit.start(250);
//QApplication *a = handler->app();
//a->exec();
}
}
rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char *optional_server_cert_pem)
{
rkt_webview_init();
return handler->newContext(boilerplate_js, optional_server_cert_pem);
}
int rkt_webview_create(rkt_wv_context_t context, rktwebview_t parent, event_cb_t js_event_cb)
{
rkt_webview_init();
return handler->rktWebViewCreate(context, parent, js_event_cb);
}
void rkt_webview_close(rktwebview_t wv)
{
rkt_webview_init();
handler->rktWebViewClose(wv);
}
result_t rkt_webview_set_url(rktwebview_t wv, const char *url)
{
rkt_webview_init();
result_t r = handler->rktSetUrl(wv, url);
return r;
}
result_t rkt_webview_set_html(rktwebview_t wv, const char *url)
{
rkt_webview_init();
result_t r = handler->rktSetHtml(wv, url);
return r;
}
result_t rkt_webview_run_js(rktwebview_t wv, const char *js)
{
rkt_webview_init();
result_t r = handler->rktRunJs(wv, js);
return r;
}
rkt_data_t *rkt_webview_call_js(rktwebview_t wv, const char *js)
{
rkt_webview_init();
rkt_data_t *r = handler->rktCallJs(wv, js);
return r;
}
result_t rkt_webview_open_devtools(rktwebview_t wv)
{
rkt_webview_init();
result_t r = handler->rktOpenDevtools(wv);
return r;
}
void rkt_webview_process_events(int for_ms)
{
rkt_webview_init();
uint64_t start_ms = current_ms();
uint64_t end_ms = start_ms + for_ms;
while (current_ms() < end_ms) {
QThread::usleep(500); // sleep 0.5 ms
handler->doEvents();
}
}
result_t rkt_webview_move(rktwebview_t wv, int x, int y)
{
rkt_webview_init();
result_t r = handler->rktMove(wv, x, y);
return r;
}
result_t rkt_webview_resize(rktwebview_t wv, int width, int height)
{
rkt_webview_init();
result_t r = handler->rktResize(wv, width, height);
return r;
}
bool rkt_webview_valid(rktwebview_t wv)
{
rkt_webview_init();
return handler->rktValid(wv);
}
result_t rkt_webview_hide(rktwebview_t w)
{
rkt_webview_init();
return handler->rktHideWindow(w);
}
result_t rkt_webview_show(rktwebview_t w)
{
rkt_webview_init();
return handler->rktShowWindow(w);
}
result_t rkt_webview_present(rktwebview_t w)
{
rkt_webview_init();
return handler->rktPresentWindow(w);
}
result_t rkt_webview_maximize(rktwebview_t w)
{
rkt_webview_init();
return handler->rktMaximizeWindow(w);
}
result_t rkt_webview_minimize(rktwebview_t w)
{
rkt_webview_init();
return handler->rktMinimizeWindow(w);
}
result_t rkt_webview_show_normal(rktwebview_t w)
{
rkt_webview_init();
return handler->rktShowNormalWindow(w);
}
window_state_t rkt_webview_window_state(rktwebview_t w)
{
rkt_webview_init();
return handler->rktWindowState(w);
}
result_t rkt_webview_set_title(rktwebview_t wv, const char *title)
{
rkt_webview_init();
return handler->rktWindowSetTitle(wv, title);
}
result_t rkt_webview_choose_dir(rktwebview_t w, const char *title, const char *base_dir)
{
rkt_webview_init();
return handler->rktChooseDir(w, title, base_dir);
}
result_t rkt_webview_file_open(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
{
rkt_webview_init();
return handler->rktFileOpen(w, title, base_dir, permitted_exts);
}
result_t rkt_webview_file_save(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
{
rkt_webview_init();
return handler->rktFileSave(w, title, base_dir, permitted_exts);
}
void rkt_webview_set_ou_token(rktwebview_t wv, const char *token)
{
rkt_webview_init();
handler->rktSetOUToken(wv, token);
}
void rkt_webview_free_data(rkt_data_t *d)
{
if (d->kind == version) {
free(d);
} else if (d->kind == event) {
free(d->data.event.event);
free(d);
} else if (d->kind == js_result) {
free(d->data.js_result.value);
free(d);
} else {
fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind);
}
}
rkt_data_t *rkt_webview_version()
{
rkt_data_t *d = static_cast<rkt_data_t *>(malloc(sizeof(rkt_data_t)));
d->kind = version;
d->data.version.api_major = RKT_WEBVIEW_API_MAJOR;
d->data.version.api_minor = RKT_WEBVIEW_API_MINOR;
d->data.version.api_patch = RKT_WEBVIEW_API_PATCH;
d->data.version.qt_major = QT_VERSION_MAJOR;
d->data.version.qt_minor = QT_VERSION_MINOR;
d->data.version.qt_patch = QT_VERSION_PATCH;
return d;
}
result_t rkt_webview_message_box(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type)
{
rkt_webview_init();
return handler->rktMessageBox(w, title, message, submessage, type);
}