Last active
March 6, 2023 11:23
-
-
Save aperezdc/621c1ec6bb78923e27fc035fa0689522 to your computer and use it in GitHub Desktop.
Minimal WPE launcher, with user message handler to poweroff/reboot a device
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* SPDX-License-Identifier: MIT | |
* | |
* cc -o minicog minicog.c $(pkg-config wpe-webkit-1.1 cogcore --cflags --libs) | |
*/ | |
#include <cog/cog.h> | |
#include <sys/reboot.h> | |
static const char *s_starturl = NULL; | |
static void | |
handle_power_control_message(WebKitUserContentManager *content_manager, | |
WebKitJavascriptResult *js_result, void *userdata) | |
{ | |
JSCValue *value = webkit_javascript_result_get_js_value(js_result); | |
if (!jsc_value_is_string(value)) { | |
g_warning("Invalid powerControl message: argument is not a string"); | |
return; | |
} | |
g_autofree char *value_as_string = jsc_value_to_string(value); | |
int action; | |
if (strcmp(value_as_string, "poweroff") == 0) { | |
action = RB_POWER_OFF; | |
} else if (strcmp(value_as_string, "reboot") == 0) { | |
action = RB_AUTOBOOT; | |
} else { | |
g_warning("Invalid powerControl message: '%s'", value_as_string); | |
return; | |
} | |
g_message("Device will %s now!", value_as_string); | |
/* | |
* This fails unless the process is run as "root" (not recommended!) | |
* or has been granted the CAP_SYS_BOOT capability. In reality, this | |
* should probably call the org.freedesktop.systemd1.Reboot() method | |
* and friends using D-Bus instead. | |
*/ | |
sync(); | |
reboot(action); | |
} | |
static WebKitUserContentManager* | |
create_content_manager(void) | |
{ | |
g_autoptr(WebKitUserContentManager) content_manager = webkit_user_content_manager_new(); | |
webkit_user_content_manager_register_script_message_handler(content_manager, "powerControl"); | |
g_signal_connect(content_manager, "script-message-received::powerControl", | |
G_CALLBACK(handle_power_control_message), NULL); | |
return g_steal_pointer(&content_manager); | |
} | |
static WebKitWebView* | |
on_create_view(CogShell *shell, CogPlatform *platform) | |
{ | |
g_autoptr(GError) error = NULL; | |
WebKitWebViewBackend *view_backend = cog_platform_get_view_backend(platform, NULL, &error); | |
if (!view_backend) | |
g_error("Cannot obtain view backend: %s", error->message); | |
g_autoptr(WebKitUserContentManager) content_manager = create_content_manager(); | |
WebKitSettings *settings = cog_shell_get_web_settings(shell); | |
webkit_settings_set_enable_write_console_messages_to_stdout(settings, TRUE); | |
g_autoptr(WebKitWebView) web_view = | |
g_object_new(WEBKIT_TYPE_WEB_VIEW, | |
"user-content-manager", content_manager, | |
"settings", settings, | |
"web-context", cog_shell_get_web_context(shell), | |
"backend", view_backend, | |
NULL); | |
cog_platform_init_web_view(platform, web_view); | |
webkit_web_view_load_uri(web_view, s_starturl); | |
return g_steal_pointer(&web_view); | |
} | |
int | |
main(int argc, char *argv[]) | |
{ | |
g_set_application_name("minicog"); | |
if (argc != 2 && argc != 3) { | |
g_printerr("Usage: %s [URL [platform]]\n", argv[0]); | |
return EXIT_FAILURE; | |
} | |
g_autoptr(GError) error = NULL; | |
if (!(s_starturl = cog_uri_guess_from_user_input(argv[1], TRUE, &error))) | |
g_error("Invalid URL '%s': %s", argv[1], error->message); | |
cog_modules_add_directory(COG_MODULEDIR); | |
g_autoptr(GApplication) app = g_application_new(NULL, G_APPLICATION_DEFAULT_FLAGS); | |
g_autoptr(CogShell) shell = cog_shell_new("minicog", FALSE); | |
g_autoptr(CogPlatform) platform = | |
cog_platform_new((argc == 3) ? argv[2] : g_getenv("COG_PLATFORM"), &error); | |
if (!platform) | |
g_error("Cannot create platform: %s", error->message); | |
if (!cog_platform_setup(platform, shell, "", &error)) | |
g_error("Cannot setup platform: %s\n", error->message); | |
g_signal_connect(shell, "create-view", G_CALLBACK(on_create_view), platform); | |
g_signal_connect_swapped(app, "shutdown", G_CALLBACK(cog_shell_shutdown), shell); | |
g_signal_connect_swapped(app, "startup", G_CALLBACK(cog_shell_startup), shell); | |
g_signal_connect(app, "activate", G_CALLBACK(g_application_hold), NULL); | |
return g_application_run(app, 1, argv); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Device Power Control</title> | |
</head> | |
<body> | |
<button id="reboot">Reboot</button> | |
<button id="poweroff">Power Off</button> | |
<script type="text/javascript"> | |
function addHandler(name) { | |
document.getElementById(name).addEventListener("click", (event) => { | |
window.webkit.messageHandlers.powerControl.postMessage(name); | |
return false; | |
}); | |
} | |
addHandler("reboot"); | |
addHandler("poweroff"); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment