ソースを参照

Set brightness to 100% when using display flash

Benjamin Schaaf 3 年 前
コミット
4e7120f609
3 ファイル変更127 行追加35 行削除
  1. 105 23
      src/flash.c
  2. 5 0
      src/flash.h
  3. 17 12
      src/main.c

+ 105 - 23
src/flash.c

@@ -17,7 +17,6 @@ typedef struct {
 } MPLEDFlash;
 
 typedef struct {
-	GtkWidget *window;
 } MPDisplayFlash;
 
 struct _MPFlash {
@@ -49,8 +48,33 @@ mp_led_flash_from_path(const char * path)
 	return flash;
 }
 
-static bool create_display(MPFlash *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)
+{
+	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);
+		g_object_unref(err);
+		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);
@@ -61,9 +85,13 @@ static bool create_display(MPFlash *flash)
 	context = gtk_widget_get_style_context(window);
 	gtk_style_context_add_class(context, "flash");
 
-	flash->display.window = window;
+	flash_window = window;
+}
 
-	return false;
+void mp_flash_gtk_clean()
+{
+	gtk_window_destroy(GTK_WINDOW(flash_window));
+	g_object_unref(dbus_brightness_proxy);
 }
 
 MPFlash *
@@ -71,38 +99,87 @@ mp_create_display_flash()
 {
 	MPFlash *flash = malloc(sizeof(MPFlash));
 	flash->type = FLASH_TYPE_DISPLAY;
-	flash->display.window = NULL;
-
-	// All GTK functions must be called on the main thread
-	g_main_context_invoke(NULL, (GSourceFunc)create_display, flash);
 
 	return flash;
 }
 
-static bool flash_free(MPFlash *flash)
-{
-	gtk_window_destroy(GTK_WINDOW(flash->display.window));
-	free(flash);
-	return false;
-}
-
 void
 mp_flash_free(MPFlash *flash)
 {
 	switch (flash->type) {
 		case FLASH_TYPE_LED:
 			close(flash->led.fd);
-			free(flash);
 			break;
 		case FLASH_TYPE_DISPLAY:
-			g_main_context_invoke(NULL, (GSourceFunc)flash_free, flash);
 			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)
+{
+	GError *error = NULL;
+	GVariant *result = g_dbus_proxy_call_finish(proxy, res, &error);
+
+	if (!result) {
+		printf("Failed to get display brightness: %s\n", error->message);
+		g_object_unref(error);
+		return;
+	}
+
+	GVariant *values = g_variant_get_child_value(result, 0);
+	if (g_variant_n_children(values) == 0) {
+		return;
+	}
+
+	GVariant *brightness = g_variant_get_child_value(values, 0);
+	dbus_old_brightness = g_variant_get_int32(brightness);
+
+	g_variant_unref(result);
 }
 
-static bool show_flash_window(MPFlash *flash)
+static bool show_display_flash(MPFlash *flash)
 {
-	gtk_widget_show(flash->display.window);
+	if (!flash_window)
+		return false;
+
+	gtk_widget_show(flash_window);
+
+	// 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;
 }
 
@@ -115,14 +192,19 @@ mp_flash_enable(MPFlash *flash)
 			dprintf(flash->led.fd, "1\n");
 			break;
 		case FLASH_TYPE_DISPLAY:
-			g_main_context_invoke(NULL, (GSourceFunc)show_flash_window, flash);
+			g_main_context_invoke(NULL, (GSourceFunc)show_display_flash, flash);
 			break;
 	}
 }
 
-static bool hide_flash_window(MPFlash *flash)
+static bool hide_display_flash(MPFlash *flash)
 {
-	gtk_widget_hide(flash->display.window);
+	if (!flash_window)
+		return false;
+
+	gtk_widget_hide(flash_window);
+	set_display_brightness(dbus_old_brightness);
+
 	return false;
 }
 
@@ -134,7 +216,7 @@ mp_flash_disable(MPFlash *flash)
 			// Flash gets reset automatically
 			break;
 		case FLASH_TYPE_DISPLAY:
-			g_main_context_invoke(NULL, (GSourceFunc)hide_flash_window, flash);
+			g_main_context_invoke(NULL, (GSourceFunc)hide_display_flash, flash);
 			break;
 	}
 }

+ 5 - 0
src/flash.h

@@ -1,5 +1,10 @@
+#include "gio/gio.h"
+
 typedef struct _MPFlash MPFlash;
 
+void mp_flash_gtk_init(GDBusConnection *conn);
+void mp_flash_gtk_clean();
+
 MPFlash *mp_led_flash_from_path(const char *path);
 MPFlash *mp_create_display_flash();
 void mp_flash_free(MPFlash *flash);

+ 17 - 12
src/main.c

@@ -1,27 +1,28 @@
 #include "main.h"
 
+#include "camera_config.h"
+#include "flash.h"
+#include "gl_util.h"
+#include "io_pipeline.h"
+#include "process_pipeline.h"
+#include <asm/errno.h>
+#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <linux/videodev2.h>
+#include <gtk/gtk.h>
+#include <limits.h>
+#include <linux/kdev_t.h>
 #include <linux/media.h>
 #include <linux/v4l2-subdev.h>
+#include <linux/videodev2.h>
+#include <locale.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include <time.h>
-#include <assert.h>
-#include <limits.h>
-#include <linux/kdev_t.h>
 #include <sys/sysmacros.h>
-#include <asm/errno.h>
+#include <time.h>
 #include <wordexp.h>
-#include <gtk/gtk.h>
-#include <locale.h>
 #include <zbar.h>
-#include "gl_util.h"
-#include "camera_config.h"
-#include "io_pipeline.h"
-#include "process_pipeline.h"
 
 #define RENDERDOC
 
@@ -970,6 +971,9 @@ activate(GtkApplication *app, gpointer data)
 		NULL);
 	update_screen_rotation(conn);
 
+	// Initialize display flash
+	mp_flash_gtk_init(conn);
+
 	mp_io_pipeline_start();
 
 	gtk_application_add_window(app, GTK_WINDOW(window));
@@ -982,6 +986,7 @@ shutdown(GApplication *app, gpointer data)
 	// Only do cleanup in development, let the OS clean up otherwise
 #ifdef DEBUG
 	mp_io_pipeline_stop();
+	mp_flash_gtk_clean();
 #endif
 }