326 lines
12 KiB
C++
326 lines
12 KiB
C++
#include <QThread>
|
|
#include <QFile>
|
|
#include <QApplication>
|
|
|
|
#include "rkt_protocol.h"
|
|
#include "shm.h"
|
|
#include "shmqueue.h"
|
|
#include "command.h"
|
|
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
|
|
#include "rktwebview_qt.h"
|
|
|
|
static void 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);
|
|
}
|
|
}
|
|
|
|
class Handler : public QThread
|
|
{
|
|
public:
|
|
Shm *shm;
|
|
ShmQueue *command_queue;
|
|
ShmQueue *result_queue;
|
|
ShmQueue *event_queue;
|
|
Rktwebview_qt *webview_handler;
|
|
|
|
// QThread interface
|
|
protected:
|
|
void run();
|
|
};
|
|
|
|
static Handler *_handler;
|
|
|
|
static void event_cb(rkt_data_t *data)
|
|
{
|
|
if (data->kind != rkt_data_kind_t::event) {
|
|
return;
|
|
}
|
|
|
|
int wv = data->data.event.wv;
|
|
char *evt = data->data.event.event;
|
|
|
|
std::string evt_d(evt);
|
|
_handler->event_queue->enqueue(wv, evt_d);
|
|
|
|
free_data(data);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
const char *me = argv[0];
|
|
|
|
if (argc < 6) {
|
|
fprintf(stderr, "%s: wrong number of arguments\n", me);
|
|
exit(1);
|
|
}
|
|
|
|
const char *shm_name = argv[1];
|
|
const char *shm_size_str = argv[2];
|
|
const char *cmd_slot_str = argv[3];
|
|
const char *res_slot_str = argv[4];
|
|
const char *evt_slot_str = argv[5];
|
|
|
|
size_t shm_size = atoi(shm_size_str);
|
|
int cmd_slot = atoi(cmd_slot_str);
|
|
int res_slot = atoi(res_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);
|
|
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)) {
|
|
fprintf(stderr, "%s: Invalid shm size or slots\n", me);
|
|
exit(2);
|
|
}
|
|
|
|
Handler *handler = new Handler();
|
|
_handler = handler;
|
|
handler->shm = new Shm(shm_name, shm_size, false);
|
|
handler->command_queue = new ShmQueue(handler->shm, cmd_slot, false);
|
|
handler->result_queue = new ShmQueue(handler->shm, res_slot, false);
|
|
handler->event_queue = new ShmQueue(handler->shm, evt_slot, false);
|
|
handler->webview_handler = new Rktwebview_qt(argc, argv);
|
|
handler->start();
|
|
|
|
handler->webview_handler->initApp();
|
|
handler->webview_handler->execApp();
|
|
|
|
fprintf(stderr, "waiting for thread to end\n");
|
|
handler->wait();
|
|
|
|
fprintf(stderr, "cleaning up shm\n");
|
|
|
|
delete handler->webview_handler;
|
|
delete handler->command_queue;
|
|
delete handler->result_queue;
|
|
delete handler->event_queue;
|
|
delete handler->shm;
|
|
delete handler;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Handler::run()
|
|
{
|
|
bool quit = false;
|
|
while (!quit) {
|
|
int cmd;
|
|
std::string data;
|
|
command_queue->dequeue(cmd, data, true);
|
|
QJsonObject data_obj = QJsonDocument::fromJson(data.c_str()).object();
|
|
|
|
switch(cmd) {
|
|
case CMD_QUIT: {
|
|
fprintf(stderr, "Got quit message\n");
|
|
webview_handler->rktQuit();
|
|
fprintf(stderr, "Enqueing RESULT_QUIT to result queue\n");
|
|
result_queue->enqueue(RESULT_QUIT);
|
|
quit = true;
|
|
}
|
|
break;
|
|
case CMD_HANDLE_IS_VALID: {
|
|
int wv = data_obj["wv"].toInt();
|
|
bool oke = webview_handler->rktValid(wv);
|
|
result_queue->enqueue(oke);
|
|
}
|
|
break;
|
|
case CMD_CONTEXT_NEW: {
|
|
QString boilerplate_js = data_obj["boilerplate_js"].toString();
|
|
bool has_pem_cert = data_obj["has_pem_cert"].toBool();
|
|
QString pem_cert = data_obj["pem_cert"].toString();
|
|
int context = webview_handler->newContext(boilerplate_js, has_pem_cert, pem_cert);
|
|
result_queue->enqueue(context);
|
|
}
|
|
break;
|
|
case CMD_CREATE_WV: {
|
|
int context = data_obj["context"].toInt();
|
|
int parent = data_obj["parent"].toInt();
|
|
|
|
int wv = webview_handler->rktWebViewCreate(context, parent, event_cb);
|
|
result_queue->enqueue(wv);
|
|
}
|
|
break;
|
|
case CMD_CLOSE_WV: {
|
|
int wv = data_obj["wv"].toInt();
|
|
webview_handler->rktWebViewClose(wv);
|
|
}
|
|
break;
|
|
case CMD_SET_URL: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString url = data_obj["url"].toString();
|
|
result_t r = webview_handler->rktSetUrl(wv, url.toUtf8().constData());
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_SET_HTML: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString html = data_obj["html"].toString();
|
|
result_t r = webview_handler->rktSetHtml(wv, html.toUtf8().constData());
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_RUN_JS: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString js = data_obj["js"].toString();
|
|
result_t r = webview_handler->rktRunJs(wv, js);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_CALL_JS: {
|
|
fprintf(stderr, "Calljs\n");
|
|
int wv = data_obj["wv"].toInt();
|
|
QString js = data_obj["js"].toString();
|
|
rkt_data_t *res = webview_handler->rktCallJs(wv, js.toUtf8().constData());
|
|
result_queue->enqueue(res->data.js_result.result, res->data.js_result.value);
|
|
free_data(res);
|
|
}
|
|
break;
|
|
case CMD_OPEN_DEVTOOLS: {
|
|
int wv = data_obj["wv"].toInt();
|
|
result_t r = webview_handler->rktOpenDevtools(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_MOVE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
int x = data_obj["x"].toInt();
|
|
int y = data_obj["y"].toInt();
|
|
result_t r = webview_handler->rktMove(wv, x, y);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_RESIZE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
int w = data_obj["w"].toInt();
|
|
int h = data_obj["h"].toInt();
|
|
result_t r = webview_handler->rktResize(wv, w, h);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_HIDE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
result_t r = webview_handler->rktHideWindow(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_SHOW: {
|
|
int wv = data_obj["wv"].toInt();
|
|
result_t r = webview_handler->rktShowWindow(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_PRESENT: {
|
|
int wv = data_obj["wv"].toInt();
|
|
result_t r = webview_handler->rktPresentWindow(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_MAXIMIZE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
result_t r = webview_handler->rktMaximizeWindow(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_MINIMIZE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
result_t r = webview_handler->rktMinimizeWindow(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_SHOW_NORMAL: {
|
|
int wv = data_obj["wv"].toInt();
|
|
result_t r = webview_handler->rktShowNormalWindow(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_WINDOW_STATE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
window_state_t r = webview_handler->rktWindowState(wv);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_SET_TITLE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString title = data_obj["title"].toString();
|
|
result_t r = webview_handler->rktWindowSetTitle(wv, title.toUtf8().constData());
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_CHOOSE_DIR: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString title = data_obj["title"].toString();
|
|
QString base_dir = data_obj["base_dir"].toString();
|
|
result_t r = webview_handler->rktChooseDir(wv,
|
|
title.toUtf8().constData(),
|
|
base_dir.toUtf8().constData()
|
|
);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_FILE_OPEN: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString title = data_obj["title"].toString();
|
|
QString base_dir = data_obj["base_dir"].toString();
|
|
QString permitted_exts = data_obj["permitted_exts"].toString();
|
|
result_t r = webview_handler->rktFileOpen(wv,
|
|
title.toUtf8().constData(),
|
|
base_dir.toUtf8().constData(),
|
|
permitted_exts.toUtf8().constData()
|
|
);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_FILE_SAVE: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString title = data_obj["title"].toString();
|
|
QString base_dir = data_obj["base_dir"].toString();
|
|
QString permitted_exts = data_obj["permitted_exts"].toString();
|
|
result_t r = webview_handler->rktFileSave(wv,
|
|
title.toUtf8().constData(),
|
|
base_dir.toUtf8().constData(),
|
|
permitted_exts.toUtf8().constData()
|
|
);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
case CMD_SET_OU_TOKEN: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString token = data_obj["token"].toString();
|
|
webview_handler->rktSetOUToken(wv, token.toUtf8().constData());
|
|
}
|
|
break;
|
|
case CMD_MSG_BOX: {
|
|
int wv = data_obj["wv"].toInt();
|
|
QString title = data_obj["title"].toString();
|
|
QString message = data_obj["message"].toString();
|
|
QString submsg = data_obj["submessage"].toString();
|
|
int type = data_obj["type"].toInt();
|
|
result_t r = webview_handler->rktMessageBox(wv,
|
|
title.toUtf8().constData(),
|
|
message.toUtf8().constData(),
|
|
submsg.toUtf8().constData(),
|
|
static_cast<rkt_messagetype_t>(type)
|
|
);
|
|
result_queue->enqueue(r);
|
|
}
|
|
break;
|
|
default: {
|
|
fprintf(stderr, "Unknown command: %d\n", cmd);
|
|
}
|
|
}
|
|
}
|
|
}
|