This commit is contained in:
2026-03-26 14:35:10 +01:00
parent b35a982c6f
commit cf28fba3f5
14 changed files with 314 additions and 149 deletions

View File

@@ -655,7 +655,7 @@
(define (webview-call-js wv js) (define (webview-call-js wv js)
(-> wv-win? string? (or/c string? list? boolean? hash?)) (-> wv-win? string? (or/c string? list? boolean? hash?))
(let ((result (rkt-webview-call-js (wv-win-handle wv) js))) (let ((result (rkt-webview-call-js (wv-win-handle wv) js)))
(displayln result) ;(displayln result)
(if (webview-call-js-result? result) (if (webview-call-js-result? result)
(if (eq? (car result) 'oke) (if (eq? (car result) 'oke)
(hash-ref (fromJson (cadr result)) 'result #f) (hash-ref (fromJson (cadr result)) 'result #f)

View File

@@ -22,6 +22,7 @@ add_library(rktwebview SHARED
rktwebview_types.h rktwebview_types.h
json.cpp json.h json.cpp json.h
utils.h utils.h
utils.cpp
) )
add_executable(rktwebview_prg add_executable(rktwebview_prg
@@ -40,6 +41,7 @@ add_executable(rktwebview_prg
rkt_protocol.h rkt_protocol.h
rktwebview_types.h rktwebview_types.h
utils.cpp utils.h
) )
add_executable(rktwebview_test add_executable(rktwebview_test

View File

@@ -27,6 +27,7 @@
#define COMMAND_FILE_SAVE 21 #define COMMAND_FILE_SAVE 21
#define COMMAND_SET_OU_TOKEN 22 #define COMMAND_SET_OU_TOKEN 22
#define COMMAND_NEW_CONTEXT 23 #define COMMAND_NEW_CONTEXT 23
#define COMMAND_MESSAGE 24
class Command class Command
{ {

View File

@@ -6,6 +6,7 @@
#include "shm.h" #include "shm.h"
#include "shmqueue.h" #include "shmqueue.h"
#include "command.h" #include "command.h"
#include "utils.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
@@ -23,7 +24,7 @@ static void free_data(rkt_data_t *d)
free(d->data.js_result.value); free(d->data.js_result.value);
free(d); free(d);
} else { } else {
fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind); ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind);
} }
} }
@@ -62,10 +63,10 @@ int main(int argc, char *argv[])
{ {
const char *me = argv[0]; const char *me = argv[0];
fprintf(stderr, "%s runs\n", argv[0]);fflush(stderr); INFO1("%s runs\n", argv[0]);
if (argc < 6) { if (argc < 6) {
fprintf(stderr, "%s: wrong number of arguments\n", me);fflush(stderr); ERROR1("%s: wrong number of arguments\n", me);
exit(1); exit(1);
} }
@@ -80,11 +81,11 @@ int main(int argc, char *argv[])
int res_slot = atoi(res_slot_str); int res_slot = atoi(res_slot_str);
int evt_slot = atoi(evt_slot_str); int evt_slot = atoi(evt_slot_str);
fprintf(stderr, "%s %s %s %s %s %s\n", me, shm_name, shm_size_str, cmd_slot_str, res_slot_str, evt_slot_str);fflush(stderr); MKLOGSTMT(LOG_INFO, fprintf(stderr, "%s %s %s %s %s %s\n", me, shm_name, shm_size_str, cmd_slot_str, res_slot_str, evt_slot_str));
fprintf(stderr, "%s %s %ld %d %d %d\n", me, shm_name, shm_size, cmd_slot, res_slot, evt_slot);fflush(stderr); MKLOGSTMT(LOG_INFO, fprintf(stderr, "%s %s %ld %d %d %d\n", me, shm_name, shm_size, cmd_slot, res_slot, evt_slot));
if (!(shm_size > 0 && cmd_slot > 0 && res_slot > 0 && evt_slot > 0)) { if (!(shm_size > 0 && cmd_slot > 0 && res_slot > 0 && evt_slot > 0)) {
fprintf(stderr, "%s: Invalid shm size or slots\n", me);fflush(stderr); ERROR1("%s: Invalid shm size or slots\n", me);
exit(2); exit(2);
} }
@@ -100,10 +101,10 @@ int main(int argc, char *argv[])
handler->webview_handler->initApp(); handler->webview_handler->initApp();
handler->webview_handler->execApp(); handler->webview_handler->execApp();
fprintf(stderr, "waiting for thread to end\n");fflush(stderr); INFO0("waiting for thread to end\n");
handler->wait(); handler->wait();
fprintf(stderr, "cleaning up shm\n");fflush(stderr); INFO0("cleaning up shm\n");
delete handler->webview_handler; delete handler->webview_handler;
delete handler->command_queue; delete handler->command_queue;
@@ -126,9 +127,9 @@ void Handler::run()
switch(cmd) { switch(cmd) {
case CMD_QUIT: { case CMD_QUIT: {
fprintf(stderr, "Got quit message\n"); INFO0("Got quit message\n");
webview_handler->rktQuit(); webview_handler->rktQuit();
fprintf(stderr, "Enqueing RESULT_QUIT to result queue\n"); INFO0("Enqueing RESULT_QUIT to result queue\n");
result_queue->enqueue(RESULT_QUIT); result_queue->enqueue(RESULT_QUIT);
quit = true; quit = true;
} }
@@ -182,7 +183,6 @@ void Handler::run()
} }
break; break;
case CMD_CALL_JS: { case CMD_CALL_JS: {
fprintf(stderr, "Calljs\n");
int wv = data_obj["wv"].toInt(); int wv = data_obj["wv"].toInt();
QString js = data_obj["js"].toString(); QString js = data_obj["js"].toString();
rkt_data_t *res = webview_handler->rktCallJs(wv, js.toUtf8().constData()); rkt_data_t *res = webview_handler->rktCallJs(wv, js.toUtf8().constData());
@@ -320,7 +320,7 @@ void Handler::run()
} }
break; break;
default: { default: {
fprintf(stderr, "Unknown command: %d\n", cmd);fflush(stderr); ERROR1("Unknown command: %d\n", cmd);
} }
} }
} }

View File

@@ -2,6 +2,7 @@
#include <chrono> #include <chrono>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include <filesystem> #include <filesystem>
@@ -9,6 +10,7 @@
#include <unistd.h> #include <unistd.h>
#include <spawn.h> #include <spawn.h>
#endif #endif
#include <fcntl.h> #include <fcntl.h>
#include "rktwebview.h" #include "rktwebview.h"
#include "rkt_protocol.h" #include "rkt_protocol.h"
@@ -65,11 +67,11 @@ bool runRktWebview(Handle_t *handler)
{ {
char *rkt_webview_prg_path = getenv("RKT_WEBVIEW_PRG"); char *rkt_webview_prg_path = getenv("RKT_WEBVIEW_PRG");
if (rkt_webview_prg_path == nullptr) { if (rkt_webview_prg_path == nullptr) {
fprintf(stderr, "RKT_WEBVIEW_PRG environment variable not set, cannot start webview program\n");fflush(stderr); ERROR0("RKT_WEBVIEW_PRG environment variable not set, cannot start webview program\n");
return false; return false;
} }
if (!fileExists(rkt_webview_prg_path)) { if (!fileExists(rkt_webview_prg_path)) {
fprintf(stderr, "%s does not exist or is not executable\n", rkt_webview_prg_path);fflush(stderr); ERROR1("%s does not exist or is not executable\n", rkt_webview_prg_path);
return false; return false;
} }
@@ -88,36 +90,50 @@ bool runRktWebview(Handle_t *handler)
// run rktwebview_prg using the environment variable RKT_WEBVIEW_PRG // run rktwebview_prg using the environment variable RKT_WEBVIEW_PRG
#ifdef _WIN32 #ifdef _WIN32
//STARTUPINFO si;
//PROCESS_INFORMATION pi;
//ZeroMemory( &si, sizeof(si) );
//si.cb = sizeof(si);
//ZeroMemory( &pi, sizeof(pi) );
std::string cmdargs = std::string("") + handler->name + " " + shm_size_str + " " + command_slot + " " + command_result_slot + " " + event_slot;
std::string exe = std::string(rkt_webview_prg_path);
const char *td = getenv("TEMP"); const char *td = getenv("TEMP");
if (td == nullptr) { td = "C:\\"; } if (td == nullptr) { td = "C:\\"; }
std::string tmpdir = td; std::string tmpdir = td;
std::string logfile = tmpdir + "\\" + "rktwebview.log"; //handler->name + ".log"; std::string logfile = tmpdir + "\\" + "rktwebview.log"; //handler->name + ".log";
std::string errfile = tmpdir + "\\" + "rktwebview.err";
std::string redirect = " ^>" + logfile + " 2^>" + errfile; SECURITY_ATTRIBUTES sa;
std::string cmdline = "start /b \"\" cmd /c \"" + exe + " " + cmdargs + " " + /*redirect*/ + "\"" + redirect; sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
HANDLE h = CreateFile(logfile.c_str(),
FILE_APPEND_DATA,
FILE_SHARE_WRITE | FILE_SHARE_READ,
&sa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
ZeroMemory( &pi, sizeof(pi) );
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdInput= NULL;
si.hStdOutput = h;
si.hStdError = h;
DWORD flags = CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS;
std::string cmdargs = std::string("") + handler->name + " " + shm_size_str + " " + command_slot + " " + command_result_slot + " " + event_slot;
std::string exe = std::string(rkt_webview_prg_path);
std::string dir = basedir(exe);
std::string cmdline = exe + " " + cmdargs;
char *cmdline_str = const_cast<char *>(cmdline.c_str()); char *cmdline_str = const_cast<char *>(cmdline.c_str());
auto cwd = std::filesystem::current_path(); bool r = CreateProcessA(NULL, cmdline_str, NULL, NULL, TRUE, flags, NULL, path.c_str(), &si, &pi);
std::filesystem::current_path(path); if (!r) {
int r = system(cmdline_str); ERROR2("Cannot create process '%s' (error = %ld)\n", cmdline_str, GetLastError());
std::filesystem::current_path(cwd);
//CreateProcessA(NULL, cmdline_str, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, path.c_str(), &si, &pi);
handler->rkt_webview_prg_pid = 0;
if (r != 0) {
fprintf(stderr, "Cannot create process '%s' (error = %ld)\n", cmdline_str, GetLastError());fflush(stderr);
} }
return (r == 0); return r;
#else #else
char *argv[] = { rkt_webview_prg_path, const_cast<char *>(handler->name.c_str()), shm_size_str, command_slot, command_result_slot, event_slot, nullptr }; char *argv[] = { rkt_webview_prg_path, const_cast<char *>(handler->name.c_str()), shm_size_str, command_slot, command_result_slot, event_slot, nullptr };
@@ -161,16 +177,16 @@ void rkt_webview_cleanup()
*/ */
if (handler->valid) { if (handler->valid) {
fprintf(stderr, "Sending quit message\n");fflush(stderr); INFO0("Sending quit message\n");
handler->command_queue->enqueue(CMD_QUIT); handler->command_queue->enqueue(CMD_QUIT);
fprintf(stderr, "Message sent\n");fflush(stderr); INFO0("Message sent\n");
bool stopped = false; bool stopped = false;
while(!stopped) { while(!stopped) {
int cmd; int cmd;
std::string s; std::string s;
fprintf(stderr, "Getting result of quit message\n");fflush(stderr); INFO0("Getting result of quit message\n");
handler->command_result_queue->dequeue(cmd, s, true); handler->command_result_queue->dequeue(cmd, s, true);
fprintf(stderr, "got %d\n", cmd);fflush(stderr); INFO1("got %d\n", cmd);
if (cmd == RESULT_QUIT) { if (cmd == RESULT_QUIT) {
stopped = true; stopped = true;
} }
@@ -481,7 +497,7 @@ void rkt_webview_free_data(rkt_data_t *d)
free(d->data.js_result.value); free(d->data.js_result.value);
free(d); free(d);
} else { } else {
fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind);fflush(stderr); ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind);
} }
} }

View File

@@ -3,6 +3,7 @@
#include "rktwebview_types.h" #include "rktwebview_types.h"
#include "webviewwindow.h" #include "webviewwindow.h"
#include "rktutils.h" #include "rktutils.h"
#include "utils.h"
#include <QApplication> #include <QApplication>
#include <QTimer> #include <QTimer>
#include <QSemaphore> #include <QSemaphore>
@@ -39,13 +40,13 @@ void Rktwebview_qt::processCommand(Command *cmd)
bool has_pem = cmd->args[1].toBool(); bool has_pem = cmd->args[1].toBool();
QString optional_server_cert_pem = cmd->args[2].toString(); QString optional_server_cert_pem = cmd->args[2].toString();
fprintf(stderr, "bjs: %s\n", boilerplate_js.toUtf8().constData()); DEBUG1("bjs: %s\n", boilerplate_js.toUtf8().constData());
fprintf(stderr, "oscp: %s\n", optional_server_cert_pem.toUtf8().constData()); DEBUG1("oscp: %s\n", optional_server_cert_pem.toUtf8().constData());
QWebEngineProfileBuilder b; QWebEngineProfileBuilder b;
if (has_pem) { if (has_pem) {
QByteArray scp = optional_server_cert_pem.toUtf8(); QByteArray scp = optional_server_cert_pem.toUtf8();
fprintf(stderr, "Installing cert: %s\n", scp.constData()); INFO1("Installing cert: %s\n", scp.constData());
QList<QSslCertificate> certs; QList<QSslCertificate> certs;
QSslCertificate cert(scp); QSslCertificate cert(scp);
certs.append(cert); certs.append(cert);
@@ -238,7 +239,7 @@ void Rktwebview_qt::processCommand(Command *cmd)
QString js = cmd->args[1].toString(); QString js = cmd->args[1].toString();
if (_views.contains(wv)) { if (_views.contains(wv)) {
WebviewWindow *w = _views[wv]; WebviewWindow *w = _views[wv];
fprintf(stderr, "Running %s\n", js.toUtf8().constData()); DEBUG1("Running %s\n", js.toUtf8().constData());
w->runJs(js); w->runJs(js);
cmd->result = true; cmd->result = true;
} else { } else {
@@ -377,19 +378,12 @@ void Rktwebview_qt::processCommand(Command *cmd)
QString title = cmd->args[1].toString(); QString title = cmd->args[1].toString();
QString base_dir = cmd->args[2].toString(); QString base_dir = cmd->args[2].toString();
if (_views.contains(wv)) { if (_views.contains(wv)) {
WebviewWindow *w = _views[wv]; result_t r = fileDlg(wv, title, base_dir, "",
QString dir = QFileDialog::getExistingDirectory(w, title, base_dir, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QFileDialog::Directory, QFileDialog::AcceptOpen,
if (dir == "") { "choose-dir-ok", "choose-dir-cancel"
QJsonObject obj; );
obj["state"] = "canceled"; cmd->js_result_ok = true;
obj["dir"] = base_dir; cmd->result = (r == result_t::oke);
cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact));
} else {
QJsonObject obj;
obj["state"] = "choosen";
obj["dir"] = dir;
cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact));
}
} else { } else {
cmd->js_result_ok = false; cmd->js_result_ok = false;
cmd->result = false; cmd->result = false;
@@ -397,36 +391,57 @@ void Rktwebview_qt::processCommand(Command *cmd)
cmd->done = true; cmd->done = true;
} }
break; break;
case COMMAND_FILE_OPEN: case COMMAND_FILE_OPEN: {
int wv = cmd->args[0].toInt();
QString title = cmd->args[1].toString();
QString base_dir = cmd->args[2].toString();
QString exts = cmd->args[3].toString();
if (_views.contains(wv)) {
result_t r = fileDlg(wv, title, base_dir, exts,
QFileDialog::ExistingFile, QFileDialog::AcceptOpen,
"file-open-ok", "file-open-cancel"
);
cmd->js_result_ok = true;
cmd->result = (r == result_t::oke);
} else {
cmd->js_result_ok = true;
cmd->result = false;
}
cmd->done = true;
}
break;
case COMMAND_FILE_SAVE: { case COMMAND_FILE_SAVE: {
int wv = cmd->args[0].toInt(); int wv = cmd->args[0].toInt();
QString title = cmd->args[1].toString(); QString title = cmd->args[1].toString();
QString base_dir = cmd->args[2].toString(); QString base_dir = cmd->args[2].toString();
QString exts = cmd->args[3].toString(); QString exts = cmd->args[3].toString();
if (_views.contains(wv)) { if (_views.contains(wv)) {
WebviewWindow *w = _views[wv]; result_t r = fileDlg(wv, title, base_dir, exts,
QString file; QFileDialog::AnyFile, QFileDialog::AcceptSave,
QString selected_filter; "file-open-ok", "file-open-cancel"
if (cmd->cmd == COMMAND_FILE_OPEN) { );
file = QFileDialog::getOpenFileName(w, title, base_dir, exts, &selected_filter); cmd->js_result_ok = true;
} else { cmd->result = (r == result_t::oke);
file = QFileDialog::getSaveFileName(w, title, base_dir, exts, &selected_filter);
}
if (file == "") {
QJsonObject obj;
obj["state"] = "canceled";
obj["file"] = "";
obj["used-filter"] = selected_filter;
cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact));
} else {
QJsonObject obj;
obj["state"] = "choosen";
obj["file"] = file;
obj["used-filter"] = selected_filter;
cmd->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact));
}
} else { } else {
cmd->js_result_ok = false; cmd->js_result_ok = true;
cmd->result = false;
}
cmd->done = true;
}
break;
case COMMAND_MESSAGE: {
int wv = cmd->args[0].toInt();
QString title = cmd->args[1].toString();
QString msg = cmd->args[2].toString();
QString submsg = cmd->args[3].toString();
rkt_messagetype_t type = static_cast<rkt_messagetype_t>(cmd->args[4].toInt());
if (_views.contains(wv)) {
msgBox(wv, title, msg, submsg, type);
cmd->js_result_ok = true;
cmd->result = true;
} else {
cmd->js_result_ok = true;
cmd->result = false; cmd->result = false;
} }
cmd->done = true; cmd->done = true;
@@ -542,7 +557,7 @@ result_t Rktwebview_qt::rktSetHtml(rktwebview_t wv, const char *html)
rkt_data_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js) rkt_data_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js)
{ {
fprintf(stderr, "calljs: %s\n", js); DEBUG1("calljs: %s\n", js);
Command c(COMMAND_CALL_JS); Command c(COMMAND_CALL_JS);
QString _js(js); QString _js(js);
@@ -555,14 +570,14 @@ rkt_data_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js)
r->kind = js_result; r->kind = js_result;
r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::eval_js_failed; r->data.js_result.result = c.js_result_ok ? result_t::oke : result_t::eval_js_failed;
r->data.js_result.value = copyString(c.result.toString().toUtf8()); r->data.js_result.value = copyString(c.result.toString().toUtf8());
fprintf(stderr, "js-result: %s\n", r->data.js_result.value); DEBUG1("js-result: %s\n", r->data.js_result.value);
return r; return r;
} }
result_t Rktwebview_qt::rktRunJs(rktwebview_t wv, const QString &js) result_t Rktwebview_qt::rktRunJs(rktwebview_t wv, const QString &js)
{ {
fprintf(stderr, "rktRunJs: %s\n", js.toUtf8().constData()); DEBUG1("rktRunJs: %s\n", js.toUtf8().constData());
Command c(COMMAND_RUN_JS); Command c(COMMAND_RUN_JS);
c.args.push_back(wv); c.args.push_back(wv);
c.args.push_back(js); c.args.push_back(js);
@@ -645,7 +660,14 @@ void Rktwebview_qt::rktQuit()
while(!c.done) { doEvents(); } while(!c.done) { doEvents(); }
} }
result_t Rktwebview_qt::fileDlg(rktwebview_t w, const char *title, const char *base, const char *filters,QFileDialog::FileMode mode, QFileDialog::AcceptMode am, QString evt_ok, QString evt_cancel) result_t Rktwebview_qt::fileDlg(rktwebview_t w,
const QString &title,
const QString &base,
const QString &filters,
QFileDialog::FileMode mode,
QFileDialog::AcceptMode am,
QString evt_ok,
QString evt_cancel)
{ {
if (_views.contains(w)) { if (_views.contains(w)) {
WebviewWindow *win = _views[w]; WebviewWindow *win = _views[w];
@@ -700,17 +722,60 @@ result_t Rktwebview_qt::fileDlg(rktwebview_t w, const char *title, const char *b
result_t Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const char *base_dir) result_t Rktwebview_qt::rktChooseDir(rktwebview_t w, const char *title, const char *base_dir)
{ {
return fileDlg(w, title, base_dir, "", QFileDialog::Directory, QFileDialog::AcceptOpen, "choose-dir-ok", "choose-dir-cancel"); Command c(COMMAND_CHOOSE_DIR);
c.args.push_back(w);
QString s_title(title);
c.args.push_back(s_title);
QString s_base_dir(base_dir);
c.args.push_back(s_base_dir);
postCommand(&c);
while(!c.done) {
doEvents();
}
bool r = c.result.toBool();
return r ? result_t::oke : result_t::resize_failed;
} }
result_t Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) result_t Rktwebview_qt::rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
{ {
return fileDlg(w, title, base_dir, permitted_exts, QFileDialog::ExistingFile, QFileDialog::AcceptOpen, "file-open-ok", "file-open-cancel"); Command c(COMMAND_FILE_OPEN);
c.args.push_back(w);
QString s_title(title);
c.args.push_back(s_title);
QString s_base_dir(base_dir);
c.args.push_back(s_base_dir);
QString s_pe(permitted_exts);
c.args.push_back(s_pe);
postCommand(&c);
while(!c.done) {
doEvents();
}
bool r = c.result.toBool();
return r ? result_t::oke : result_t::resize_failed;
} }
result_t Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts) result_t Rktwebview_qt::rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts)
{ {
return fileDlg(w, title, base_dir, permitted_exts, QFileDialog::AnyFile, QFileDialog::AcceptSave, "file-save-ok", "file-save-cancel"); Command c(COMMAND_FILE_SAVE);
c.args.push_back(w);
QString s_title(title);
c.args.push_back(s_title);
QString s_base_dir(base_dir);
c.args.push_back(s_base_dir);
QString s_pe(permitted_exts);
c.args.push_back(s_pe);
postCommand(&c);
while(!c.done) {
doEvents();
}
bool r = c.result.toBool();
return r ? result_t::oke : result_t::resize_failed;
} }
result_t Rktwebview_qt::rktWindowSetTitle(rktwebview_t wv, const char *title) result_t Rktwebview_qt::rktWindowSetTitle(rktwebview_t wv, const char *title)
@@ -724,65 +789,82 @@ result_t Rktwebview_qt::rktWindowSetTitle(rktwebview_t wv, const char *title)
return r ? result_t::oke : result_t::failed; return r ? result_t::oke : result_t::failed;
} }
result_t Rktwebview_qt::rktMessageBox(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type) void Rktwebview_qt::msgBox(rktwebview_t w, const QString &title, const QString &message, const QString &submessage, rkt_messagetype_t type)
{ {
if (_views.contains(w)) {
WebviewWindow *win = _views[w]; WebviewWindow *win = _views[w];
QMessageBox *msg = new QMessageBox(win); QMessageBox *msg = new QMessageBox(win);
auto prepButton = [msg, w, this](QMessageBox::StandardButton b, QString event) { auto prepButton = [msg, w, this](QMessageBox::StandardButton b, QString event) {
msg->addButton(b); msg->addButton(b);
QAbstractButton *btn = msg->button(b); QAbstractButton *btn = msg->button(b);
QVariant v = QVariant::fromValue(msg); QVariant v = QVariant::fromValue(msg);
btn->setProperty("messagebox", v); btn->setProperty("messagebox", v);
btn->setProperty("event", event); btn->setProperty("event", event);
btn->setProperty("rktwebview", w); btn->setProperty("rktwebview", w);
connect(btn, &QAbstractButton::clicked, this, [this]() { connect(btn, &QAbstractButton::clicked, this, [this]() {
QAbstractButton *btn = static_cast<QAbstractButton *>(sender()); QAbstractButton *btn = static_cast<QAbstractButton *>(sender());
QMessageBox *mb = btn->property("messagebox").value<QMessageBox *>(); QMessageBox *mb = btn->property("messagebox").value<QMessageBox *>();
rktwebview_t w = btn->property("rktwebview").toInt(); rktwebview_t w = btn->property("rktwebview").toInt();
EventContainer e(btn->property("event").toString()); EventContainer e(btn->property("event").toString());
this->triggerEvent(w, e); this->triggerEvent(w, e);
mb->close(); mb->close();
}); });
}; };
msg->setWindowTitle(title); msg->setWindowTitle(title);
QString m = QString("<p>") + message + "</p>"; QString m = QString("<p>") + message + "</p>";
m += QString::asprintf("<p><small>%s</small></p>", submessage); m += QString::asprintf("<p><small>%s</small></p>", submessage.toUtf8().constData());
msg->setInformativeText(m); msg->setInformativeText(m);
QMessageBox::Icon icn; QMessageBox::Icon icn;
if (type == rkt_messagetype_t::error) { if (type == rkt_messagetype_t::error) {
icn = QMessageBox::Icon::Critical; icn = QMessageBox::Icon::Critical;
prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok");
} else if (type == rkt_messagetype_t::warning) { } else if (type == rkt_messagetype_t::warning) {
icn = QMessageBox::Icon::Warning; icn = QMessageBox::Icon::Warning;
prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok");
} else if (type == rkt_messagetype_t::yes_no || type == rkt_messagetype_t::oke_cancel) { } else if (type == rkt_messagetype_t::yes_no || type == rkt_messagetype_t::oke_cancel) {
icn = QMessageBox::Icon::Question; icn = QMessageBox::Icon::Question;
if (type == rkt_messagetype_t::yes_no) { if (type == rkt_messagetype_t::yes_no) {
prepButton(QMessageBox::StandardButton::No, "msgbox-no"); prepButton(QMessageBox::StandardButton::No, "msgbox-no");
prepButton(QMessageBox::StandardButton::Yes, "msgbox-yes"); prepButton(QMessageBox::StandardButton::Yes, "msgbox-yes");
} else { } else {
prepButton(QMessageBox::StandardButton::Cancel, "msgbox-cancel"); prepButton(QMessageBox::StandardButton::Cancel, "msgbox-cancel");
prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok");
}
} else { // informatio
icn = QMessageBox::Icon::Information;
prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok"); prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok");
} }
msg->setIcon(icn); } else { // informatio
msg->show(); icn = QMessageBox::Icon::Information;
return result_t::oke; prepButton(QMessageBox::StandardButton::Ok, "msgbox-ok");
} else {
return result_t::failed;
} }
msg->setIcon(icn);
msg->show();
}
result_t Rktwebview_qt::rktMessageBox(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type)
{
Command c(COMMAND_MESSAGE);
c.args.push_back(w);
QString s_title(title);
c.args.push_back(s_title);
QString s_msg(message);
c.args.push_back(s_msg);
QString s_submsg(submessage);
c.args.push_back(s_submsg);
c.args.push_back(static_cast<int>(type));
postCommand(&c);
while(!c.done) {
doEvents();
}
bool r = c.result.toBool();
return r ? result_t::oke : result_t::failed;
} }
result_t Rktwebview_qt::doWindow(rktwebview_t w, int cmd, result_t on_error) result_t Rktwebview_qt::doWindow(rktwebview_t w, int cmd, result_t on_error)

View File

@@ -52,7 +52,15 @@ private:
void handleCommandEvent(CommandEvent *e); void handleCommandEvent(CommandEvent *e);
void processCommand(Command *cmd); void processCommand(Command *cmd);
result_t fileDlg(rktwebview_t w, const char *title, const char *base, const char *filters, QFileDialog::FileMode mode, QFileDialog::AcceptMode am, QString evt_ok, QString evt_cancel); result_t fileDlg(rktwebview_t w,
const QString &title, const QString &base,
const QString &filters,
QFileDialog::FileMode mode, QFileDialog::AcceptMode am,
QString evt_ok, QString evt_cancel);
void msgBox(rktwebview_t w,
const QString &title, const QString &message, const QString &submessage,
rkt_messagetype_t type);
public: public:
void execApp(); void execApp();

View File

@@ -1,4 +1,5 @@
#include "shm.h" #include "shm.h"
#include "utils.h"
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@@ -306,14 +307,14 @@ class ShmSemApi {
void wait() { void wait() {
int r = sem_wait(_sem); int r = sem_wait(_sem);
if (r != 0) { if (r != 0) {
fprintf(stderr, "sem_wait error: %d, %s\n", errno, strerror(errno)); ERROR2("sem_wait error: %d, %s\n", errno, strerror(errno));
} }
} }
bool trywait() { bool trywait() {
int r = sem_trywait(reinterpret_cast<sem_t *>(_sem)); int r = sem_trywait(reinterpret_cast<sem_t *>(_sem));
if (r != 0 && r != EAGAIN) { if (r != 0 && r != EAGAIN) {
fprintf(stderr, "sem_wait error: %d, %s\n", errno, strerror(errno)); ERROR2("sem_wait error: %d, %s\n", errno, strerror(errno));
} }
return (r == 0); return (r == 0);
@@ -373,7 +374,7 @@ public:
name); name);
if (_shm_handle == NULL) { if (_shm_handle == NULL) {
fprintf(stderr, "Cannot create shared memory with name %s and size %lld\n", name, size); ERROR2("Cannot create shared memory with name %s and size %lld\n", name, size);
_valid = false; _valid = false;
} }
} else { } else {
@@ -381,7 +382,7 @@ public:
FALSE, FALSE,
name); name);
if (_shm_handle == NULL) { if (_shm_handle == NULL) {
fprintf(stderr, "Cannot open shared memory with name %s\n", name); ERROR1("Cannot open shared memory with name %s\n", name);
_valid = false; _valid = false;
} }
} }
@@ -393,7 +394,7 @@ public:
0, 0,
size)); size));
if (_mem == NULL) { if (_mem == NULL) {
fprintf(stderr, "Cannot map shared memory, errorcode = %ld\n", GetLastError()); ERROR1("Cannot map shared memory, errorcode = %ld\n", GetLastError());
_valid = false; _valid = false;
CloseHandle(_shm_handle); CloseHandle(_shm_handle);
} }
@@ -410,7 +411,7 @@ public:
_sem_handle = OpenSemaphoreA(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, FALSE, _sem_name); _sem_handle = OpenSemaphoreA(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, FALSE, _sem_name);
} }
if (_sem_handle == NULL) { if (_sem_handle == NULL) {
fprintf(stderr, "Cannot create or open semaphore with name '%s' (%ld)\n", _sem_name, GetLastError()); ERROR2("Cannot create or open semaphore with name '%s' (%ld)\n", _sem_name, GetLastError());
UnmapViewOfFile(_mem); UnmapViewOfFile(_mem);
CloseHandle(_shm_handle); CloseHandle(_shm_handle);
_valid = false; _valid = false;
@@ -486,14 +487,14 @@ public:
void wait() { void wait() {
DWORD r = WaitForSingleObject(_sem, INFINITE); DWORD r = WaitForSingleObject(_sem, INFINITE);
if (r != WAIT_OBJECT_0) { if (r != WAIT_OBJECT_0) {
fprintf(stderr, "sem_wait error: %ld\n", r); ERROR1("sem_wait error: %ld\n", r);
} }
} }
bool trywait() { bool trywait() {
DWORD r = WaitForSingleObject(_sem , 0); DWORD r = WaitForSingleObject(_sem , 0);
if (r != WAIT_OBJECT_0 && r != WAIT_TIMEOUT) { if (r != WAIT_OBJECT_0 && r != WAIT_TIMEOUT) {
fprintf(stderr, "sem_wait error: %ld\n", r); ERROR1("sem_wait error: %ld\n", r);
} }
return r == WAIT_OBJECT_0; return r == WAIT_OBJECT_0;
} }
@@ -512,7 +513,7 @@ public:
} }
if (_sem == NULL) { if (_sem == NULL) {
fprintf(stderr, "Cannot create or open semaphore with name '%s'\n", _name); ERROR1("Cannot create or open semaphore with name '%s'\n", _name);
} }
_owner = owner; _owner = owner;
} }

25
rktwebview_qt/utils.cpp Normal file
View File

@@ -0,0 +1,25 @@
#include "utils.h"
static int _log_level = LOG_INFO;
int logLevel()
{
return _log_level;
}
void setLogLevel(int l)
{
_log_level = l;
}
const char *logIndicator(int l)
{
switch(l) {
case LOG_ERROR: return "ERROR ";
case LOG_INFO: return "INFO ";
case LOG_DEBUG: return "DEBUG ";
case LOG_WARNING: return "WARNING";
}
return "UNKNOWN";
}

View File

@@ -5,8 +5,8 @@
inline std::string basedir(const std::string &path) inline std::string basedir(const std::string &path)
{ {
int idx1 = path.rfind("/"); int idx1 = static_cast<int>(path.rfind("/"));
int idx2 = path.rfind("\\"); int idx2 = static_cast<int>(path.rfind("\\"));
std::string r; std::string r;
if (idx1 == std::string::npos && idx2 == std::string::npos) { if (idx1 == std::string::npos && idx2 == std::string::npos) {
r = ""; r = "";
@@ -26,4 +26,33 @@ inline std::string basedir(const std::string &path)
return r; return r;
} }
int logLevel();
void setLogLevel(int l);
const char *logIndicator(int l);
#define LOG_ERROR 1
#define LOG_WARNING 2
#define LOG_INFO 3
#define LOG_DEBUG 4
#define MKLOGSTMT(level, code) if (logLevel() >= level) { fprintf(stderr, "%s: ", logIndicator(level));code;fflush(stderr); }
#define MKL0(level, msg) MKLOGSTMT(level, fprintf(stderr, msg))
#define MKL1(level, msg, a) MKLOGSTMT(level, fprintf(stderr, msg, a))
#define MKL2(level, msg, a, b) MKLOGSTMT(level, fprintf(stderr, msg, a, b))
#define ERROR0(msg) MKL0(LOG_ERROR, msg)
#define WARN0(msg) MKL0(LOG_WARNING, msg)
#define INFO0(msg) MKL0(LOG_INFO, msg)
#define DEBUG0(msg) MKL0(LOG_DEBUG, msg)
#define ERROR1(msg, a) MKL1(LOG_ERROR, msg, a)
#define WARN1(msg, a) MKL1(LOG_WARNING, msg, a)
#define INFO1(msg, a) MKL1(LOG_INFO, msg, a)
#define DEBUG1(msg, a) MKL1(LOG_DEBUG, msg, a)
#define ERROR2(msg, a, b) MKL2(LOG_ERROR, msg, a, b)
#define WARN2(msg, a, b) MKL2(LOG_WARNING, msg, a, b)
#define INFO2(msg, a, b) MKL2(LOG_INFO, msg, a, b)
#define DEBUG2(msg, a, b) MKL2(LOG_DEBUG, msg, a, b)
#endif // UTILS_H #endif // UTILS_H

View File

@@ -1,4 +1,5 @@
#include "webviewwindow.h" #include "webviewwindow.h"
#include "utils.h"
#include "webviewqt.h" #include "webviewqt.h"
#include "rktwebview_qt.h" #include "rktwebview_qt.h"
@@ -126,7 +127,7 @@ void WebviewWindow::handleCertificate(const QWebEngineCertificateError &certific
dodisp(certificateError.certificateChain()); dodisp(certificateError.certificateChain());
*/ */
fprintf(stderr, "Certificate Error: %s\n", certificateError.description().toUtf8().constData()); ERROR1("Certificate Error: %s\n", certificateError.description().toUtf8().constData());
QList<QSslCertificate> chain = certificateError.certificateChain(); QList<QSslCertificate> chain = certificateError.certificateChain();
int i; int i;
for(i = 0; i < chain.size(); i++) { for(i = 0; i < chain.size(); i++) {