123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- #include "flash.h"
- #include "gtk/gtk.h"
- #include <fcntl.h>
- #include <inttypes.h>
- #include <stdio.h>
- #include <unistd.h>
- typedef enum {
- FLASH_TYPE_LED,
- FLASH_TYPE_DISPLAY,
- } FlashType;
- typedef struct {
- char path[260];
- int fd;
- } MPLEDFlash;
- typedef struct {
- } MPDisplayFlash;
- struct _MPFlash {
- FlashType type;
- union {
- MPLEDFlash led;
- MPDisplayFlash display;
- };
- };
- MPFlash *
- mp_led_flash_from_path(const char *path)
- {
- MPFlash *flash = malloc(sizeof(MPFlash));
- flash->type = FLASH_TYPE_LED;
- strncpy(flash->led.path, path, 259);
- char mpath[275];
- snprintf(mpath, 275, "%s/flash_strobe", path);
- flash->led.fd = open(mpath, O_WRONLY);
- if (flash->led.fd == -1) {
- g_printerr("Failed to open %s\n", mpath);
- free(flash);
- return NULL;
- }
- return flash;
- }
- static GtkWidget *flash_window = NULL;
- static GDBusProxy *dbus_brightness_proxy = NULL;
- static int dbus_old_brightness = 0;
- static void
- dbus_brightness_init(GObject *src, GAsyncResult *res, gpointer *user_data)
- {
- g_autoptr(GError) err = NULL;
- dbus_brightness_proxy = g_dbus_proxy_new_finish(res, &err);
- if (!dbus_brightness_proxy || err) {
- printf("Failed to connect to dbus brightness service %s\n",
- err->message);
- return;
- }
- }
- void
- mp_flash_gtk_init(GDBusConnection *conn)
- {
- g_dbus_proxy_new(conn,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.gnome.SettingsDaemon.Power",
- "/org/gnome/SettingsDaemon/Power",
- "org.gnome.SettingsDaemon.Power.Screen",
- NULL,
- (GAsyncReadyCallback)dbus_brightness_init,
- NULL);
- // Create a full screen full white window as a flash
- GtkWidget *window = gtk_window_new();
- // gtk_window_set_accept_focus(GTK_WINDOW(flash->display.window), FALSE);
- gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
- gtk_window_fullscreen(GTK_WINDOW(window));
- gtk_widget_add_css_class(window, "flash");
- flash_window = window;
- }
- void
- mp_flash_gtk_clean()
- {
- gtk_window_destroy(GTK_WINDOW(flash_window));
- g_object_unref(dbus_brightness_proxy);
- }
- MPFlash *
- mp_create_display_flash()
- {
- MPFlash *flash = malloc(sizeof(MPFlash));
- flash->type = FLASH_TYPE_DISPLAY;
- return flash;
- }
- void
- mp_flash_free(MPFlash *flash)
- {
- switch (flash->type) {
- case FLASH_TYPE_LED:
- close(flash->led.fd);
- break;
- case FLASH_TYPE_DISPLAY:
- break;
- }
- free(flash);
- }
- static void
- set_display_brightness(int brightness)
- {
- g_dbus_proxy_call(dbus_brightness_proxy,
- "org.freedesktop.DBus.Properties.Set",
- g_variant_new("(ssv)",
- "org.gnome.SettingsDaemon.Power.Screen",
- "Brightness",
- g_variant_new("i", brightness)),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- NULL,
- NULL);
- }
- static void
- brightness_received(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
- {
- g_autoptr(GError) error = NULL;
- g_autoptr(GVariant) result = g_dbus_proxy_call_finish(proxy, res, &error);
- if (!result) {
- printf("Failed to get display brightness: %s\n", error->message);
- return;
- }
- g_autoptr(GVariant) values = g_variant_get_child_value(result, 0);
- if (g_variant_n_children(values) == 0) {
- return;
- }
- g_autoptr(GVariant) brightness = g_variant_get_child_value(values, 0);
- dbus_old_brightness = g_variant_get_int32(brightness);
- }
- static bool
- show_display_flash(MPFlash *flash)
- {
- if (!flash_window)
- return false;
- gtk_widget_set_visible(flash_window, true);
- // First get brightness and then set brightness to 100%
- if (!dbus_brightness_proxy)
- return false;
- g_dbus_proxy_call(dbus_brightness_proxy,
- "org.freedesktop.DBus.Properties.Get",
- g_variant_new("(ss)",
- "org.gnome.SettingsDaemon.Power.Screen",
- "Brightness"),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- (GAsyncReadyCallback)brightness_received,
- NULL);
- set_display_brightness(100);
- return false;
- }
- void
- mp_flash_enable(MPFlash *flash)
- {
- switch (flash->type) {
- case FLASH_TYPE_LED:
- lseek(flash->led.fd, 0, SEEK_SET);
- dprintf(flash->led.fd, "1\n");
- break;
- case FLASH_TYPE_DISPLAY:
- g_main_context_invoke(NULL, (GSourceFunc)show_display_flash, flash);
- break;
- }
- }
- static bool
- hide_display_flash(MPFlash *flash)
- {
- if (!flash_window)
- return false;
- gtk_widget_set_visible(flash_window, false);
- set_display_brightness(dbus_old_brightness);
- return false;
- }
- void
- mp_flash_disable(MPFlash *flash)
- {
- switch (flash->type) {
- case FLASH_TYPE_LED:
- // Flash gets reset automatically
- break;
- case FLASH_TYPE_DISPLAY:
- g_main_context_invoke(NULL, (GSourceFunc)hide_display_flash, flash);
- break;
- }
- }
|