windows....sigh
This commit is contained in:
@@ -2,13 +2,19 @@
|
||||
#include <chrono>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <filesystem>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <spawn.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include "rktwebview.h"
|
||||
#include "rkt_protocol.h"
|
||||
#include <spawn.h>
|
||||
#include "shmqueue.h"
|
||||
#include "json.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define SHM_SIZE (10 * 1024 * 1024) // 10MB
|
||||
#define COMMAND_SLOT 1
|
||||
@@ -28,14 +34,26 @@ typedef struct {
|
||||
ShmQueue *command_queue;
|
||||
ShmQueue *command_result_queue;
|
||||
ShmQueue *event_queue;
|
||||
#ifdef _WIN32
|
||||
HANDLE rkt_webview_prg_pid;
|
||||
#else
|
||||
pid_t rkt_webview_prg_pid;
|
||||
#endif
|
||||
|
||||
bool rkt_webview_prg_started;
|
||||
bool valid;
|
||||
} Handle_t;
|
||||
|
||||
Handle_t *handler = nullptr;
|
||||
|
||||
static bool fileExists(const char *filename) {
|
||||
#ifdef _WIN32
|
||||
DWORD dwAttrib = GetFileAttributes(filename);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
|
||||
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
#else
|
||||
return access(filename, X_OK) != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t current_ms() {
|
||||
@@ -45,29 +63,62 @@ uint64_t current_ms() {
|
||||
|
||||
bool runRktWebview(Handle_t *handler)
|
||||
{
|
||||
// run rktwebview_prg using the environment variable RKT_WEBVIEW_PRG
|
||||
#ifdef _WIN32
|
||||
#else
|
||||
char *rkt_webview_prg_path = getenv("RKT_WEBVIEW_PRG");
|
||||
if (rkt_webview_prg_path == nullptr) {
|
||||
fprintf(stderr, "RKT_WEBVIEW_PRG environment variable not set, cannot start webview program\n");
|
||||
fprintf(stderr, "RKT_WEBVIEW_PRG environment variable not set, cannot start webview program\n");fflush(stderr);
|
||||
return false;
|
||||
}
|
||||
if (!fileExists(rkt_webview_prg_path)) {
|
||||
fprintf(stderr, "%s does not exist or is not executable\n", rkt_webview_prg_path);
|
||||
fprintf(stderr, "%s does not exist or is not executable\n", rkt_webview_prg_path);fflush(stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string path = basedir(rkt_webview_prg_path);
|
||||
|
||||
char shm_size_str[30];
|
||||
char command_slot[10];
|
||||
char command_result_slot[10];
|
||||
char event_slot[10];
|
||||
|
||||
sprintf(shm_size_str, "%ld", handler->shm_size);
|
||||
sprintf(shm_size_str, "%d", static_cast<int>(handler->shm_size));
|
||||
sprintf(command_slot, "%d", COMMAND_SLOT);
|
||||
sprintf(command_result_slot, "%d", COMMAND_RESULT_SLOT);
|
||||
sprintf(event_slot, "%d", EVENT_SLOT);
|
||||
|
||||
// run rktwebview_prg using the environment variable RKT_WEBVIEW_PRG
|
||||
#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");
|
||||
if (td == nullptr) { td = "C:\\"; }
|
||||
std::string tmpdir = td;
|
||||
std::string logfile = tmpdir + "\\" + "rktwebview.log"; //handler->name + ".log";
|
||||
std::string errfile = tmpdir + "\\" + "rktwebview.err";
|
||||
std::string redirect = " ^>" + logfile + " 2^>" + errfile;
|
||||
std::string cmdline = "start /b \"\" cmd /c \"" + exe + " " + cmdargs + " " + /*redirect*/ + "\"" + redirect;
|
||||
|
||||
char *cmdline_str = const_cast<char *>(cmdline.c_str());
|
||||
|
||||
auto cwd = std::filesystem::current_path();
|
||||
std::filesystem::current_path(path);
|
||||
int r = system(cmdline_str);
|
||||
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);
|
||||
#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 };
|
||||
|
||||
int r = posix_spawn(&handler->rkt_webview_prg_pid, rkt_webview_prg_path, nullptr, nullptr, argv, environ);
|
||||
@@ -108,18 +159,21 @@ void rkt_webview_cleanup()
|
||||
handler = nullptr;
|
||||
}
|
||||
*/
|
||||
fprintf(stderr, "Sending quit message\n");
|
||||
handler->command_queue->enqueue(CMD_QUIT);
|
||||
fprintf(stderr, "Message sent\n");
|
||||
bool stopped = false;
|
||||
while(!stopped) {
|
||||
int cmd;
|
||||
std::string s;
|
||||
fprintf(stderr, "Getting result of quit message\n");
|
||||
handler->command_result_queue->dequeue(cmd, s, true);
|
||||
fprintf(stderr, "got %d\n", cmd);
|
||||
if (cmd == RESULT_QUIT) {
|
||||
stopped = true;
|
||||
|
||||
if (handler->valid) {
|
||||
fprintf(stderr, "Sending quit message\n");fflush(stderr);
|
||||
handler->command_queue->enqueue(CMD_QUIT);
|
||||
fprintf(stderr, "Message sent\n");fflush(stderr);
|
||||
bool stopped = false;
|
||||
while(!stopped) {
|
||||
int cmd;
|
||||
std::string s;
|
||||
fprintf(stderr, "Getting result of quit message\n");fflush(stderr);
|
||||
handler->command_result_queue->dequeue(cmd, s, true);
|
||||
fprintf(stderr, "got %d\n", cmd);fflush(stderr);
|
||||
if (cmd == RESULT_QUIT) {
|
||||
stopped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,16 +194,23 @@ void rkt_webview_init()
|
||||
char buf[1024];
|
||||
#ifdef DEBUG
|
||||
sprintf(buf, "rktwebview-dbg");
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
DWORD p = GetCurrentProcessId();
|
||||
sprintf(buf, "rktwebview-%ld", p);
|
||||
#else
|
||||
pid_t p = getpid();
|
||||
sprintf(buf, "rktwebview-%x", p);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
handler = new Handle_t;
|
||||
handler->valid = true;
|
||||
handler->name = buf;
|
||||
|
||||
handler->shm_size = SHM_SIZE;
|
||||
handler->shm = new Shm(handler->name.data(), handler->shm_size, true);
|
||||
if (!handler->shm->isValid()) { handler->valid = false; }
|
||||
handler->command_queue = new ShmQueue(handler->shm, COMMAND_SLOT, true);
|
||||
handler->command_result_queue = new ShmQueue(handler->shm, COMMAND_RESULT_SLOT, true);
|
||||
handler->event_queue = new ShmQueue(handler->shm, EVENT_SLOT, true);
|
||||
@@ -157,6 +218,7 @@ void rkt_webview_init()
|
||||
// Start rktwebview_prg application with the right information
|
||||
#ifndef DEBUG
|
||||
handler->rkt_webview_prg_started = runRktWebview(handler);
|
||||
if (!handler->rkt_webview_prg_started) { handler->valid = false; }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -164,7 +226,7 @@ void rkt_webview_init()
|
||||
bool rkt_webview_valid(rktwebview_t wv)
|
||||
{
|
||||
rkt_webview_init();
|
||||
if (handler != nullptr && handler->rkt_webview_prg_started) {
|
||||
if (handler != nullptr && handler->valid) {
|
||||
handler->command_queue->enqueue(CMD_HANDLE_IS_VALID);
|
||||
int result;
|
||||
std::string json_result;
|
||||
@@ -175,9 +237,21 @@ bool rkt_webview_valid(rktwebview_t wv)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool validHandle()
|
||||
{
|
||||
return (handler != nullptr) && handler->valid;
|
||||
}
|
||||
|
||||
#define FAIL_HANDLE if (!validHandle()) { return result_t::invalid_handle; }
|
||||
#define FAIL_CONTEXT if (!validHandle()) { return 0; }
|
||||
#define FAIL_WV if (!validHandle()) { return 0; }
|
||||
#define NOOP_HANDLE if (!validHandle()) { return; }
|
||||
#define FAIL_CALL_JS if (!validHandle()) { return nullptr; }
|
||||
|
||||
rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char *optional_server_cert_pem)
|
||||
{
|
||||
rkt_webview_init();
|
||||
FAIL_CONTEXT
|
||||
|
||||
JSON j;
|
||||
|
||||
@@ -200,6 +274,8 @@ rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char
|
||||
int rkt_webview_create(rkt_wv_context_t context, rktwebview_t parent)
|
||||
{
|
||||
rkt_webview_init();
|
||||
FAIL_WV
|
||||
|
||||
JSON j;
|
||||
j["context"] = context;
|
||||
j["parent"] = parent;
|
||||
@@ -216,6 +292,7 @@ int rkt_webview_create(rkt_wv_context_t context, rktwebview_t parent)
|
||||
void rkt_webview_close(rktwebview_t wv)
|
||||
{
|
||||
rkt_webview_init();
|
||||
NOOP_HANDLE
|
||||
|
||||
JSON j;
|
||||
j["wv"] = wv;
|
||||
@@ -224,6 +301,7 @@ void rkt_webview_close(rktwebview_t wv)
|
||||
|
||||
#define CMDRES4(cmd, wv, key, val, key2, val2, key3, val3, key4, val4) \
|
||||
rkt_webview_init(); \
|
||||
FAIL_HANDLE \
|
||||
JSON j; \
|
||||
j["wv"] = wv; \
|
||||
j[key] = val; \
|
||||
@@ -268,6 +346,7 @@ result_t rkt_webview_run_js(rktwebview_t wv, const char *js)
|
||||
rkt_data_t *rkt_webview_call_js(rktwebview_t wv, const char *js)
|
||||
{
|
||||
rkt_webview_init();
|
||||
FAIL_CALL_JS
|
||||
|
||||
JSON j;
|
||||
j["wv"] = wv;
|
||||
@@ -380,6 +459,7 @@ result_t rkt_webview_file_save(rktwebview_t w, const char *title, const char *ba
|
||||
void rkt_webview_set_ou_token(rktwebview_t wv, const char *token)
|
||||
{
|
||||
rkt_webview_init();
|
||||
NOOP_HANDLE
|
||||
|
||||
JSON j;
|
||||
j["wv"] = wv;
|
||||
@@ -401,7 +481,7 @@ void rkt_webview_free_data(rkt_data_t *d)
|
||||
free(d->data.js_result.value);
|
||||
free(d);
|
||||
} else {
|
||||
fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind);
|
||||
fprintf(stderr, "UNEXPECTED: data kind %d cannot be freed\n", d->kind);fflush(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +520,7 @@ rkt_data_t *rkt_webview_get_event()
|
||||
memcpy(d->data.event.event, data.c_str(), ds);
|
||||
d->data.event.event[ds] = '\0';
|
||||
d->data.event.wv = wv;
|
||||
fprintf(stderr, "event: %d - '%s'\n", d->data.event.wv, d->data.event.event);
|
||||
//fprintf(stderr, "event: %d - '%s'\n", d->data.event.wv, d->data.event.event);fflush(stderr);
|
||||
return d;
|
||||
} else {
|
||||
return nullptr;
|
||||
|
||||
Reference in New Issue
Block a user