From 5d872860f911626884b3ca548598a9b2bf5f27b7 Mon Sep 17 00:00:00 2001 From: Martijn Braam Date: Sat, 3 Oct 2020 17:05:10 +0200 Subject: [PATCH] Implement manual controls --- camera.glade | 75 +++++++++++++++++++++++++++++++++++ main.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 179 insertions(+), 5 deletions(-) diff --git a/camera.glade b/camera.glade index 2bbd269..cab5fcc 100644 --- a/camera.glade +++ b/camera.glade @@ -2,6 +2,11 @@ + + 100 + 1 + 10 + False Camera @@ -42,6 +47,76 @@ 0 + + + False + + + True + False + 10 + 10 + 10 + 10 + + + True + False + 10 + ISO + + + False + True + 0 + + + + + True + True + control_adj + 1 + False + + + True + True + 1 + + + + + Auto + True + True + True + 10 + + + False + True + end + 2 + + + + + True + True + 0 + + + + + + False + True + 1 + + True diff --git a/main.c b/main.c index 317571b..c4ffdd7 100644 --- a/main.c +++ b/main.c @@ -19,10 +19,9 @@ #include "ini.h" #include "quickdebayer.h" -enum io_method { - IO_METHOD_READ, - IO_METHOD_MMAP, - IO_METHOD_USERPTR, +enum user_control { + USER_CONTROL_ISO, + USER_CONTROL_SHUTTER }; #define TIFFTAG_FORWARDMATRIX1 50964 @@ -95,13 +94,17 @@ static int gain = 1; static int burst_length = 5; static char burst_dir[23]; static char processing_script[512]; - +static enum user_control current_control; // Widgets GtkWidget *preview; GtkWidget *error_box; GtkWidget *error_message; GtkWidget *main_stack; GtkWidget *thumb_last; +GtkWidget *control_box; +GtkWidget *control_name; +GtkWidget *control_slider; +GtkWidget *control_auto; static int xioctl(int fd, int request, void *arg) @@ -1113,6 +1116,50 @@ on_shutter_clicked(GtkWidget *widget, gpointer user_data) capture = burst_length; } +void +on_preview_tap(GtkWidget *widget, GdkEventButton *event, gpointer user_data) +{ + if (event->type != GDK_BUTTON_PRESS) + return; + + // Handle taps on the controls + if (event->y < 32) { + if (gtk_widget_is_visible(control_box)) { + gtk_widget_hide(control_box); + return; + } else { + gtk_widget_show(control_box); + } + + if (event->x < 60 ) { + // ISO + current_control = USER_CONTROL_ISO; + gtk_label_set_text(GTK_LABEL(control_name), "ISO"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto), auto_gain); + gtk_adjustment_set_lower(GTK_ADJUSTMENT(control_slider), 1.0); + gtk_adjustment_set_upper(GTK_ADJUSTMENT(control_slider), 1024.0); + gtk_adjustment_set_value(GTK_ADJUSTMENT(control_slider), (double)gain); + + } else if (event->x > 60 && event->x < 120) { + // Shutter angle + current_control = USER_CONTROL_SHUTTER; + gtk_label_set_text(GTK_LABEL(control_name), "Shutter"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto), auto_exposure); + gtk_adjustment_set_lower(GTK_ADJUSTMENT(control_slider), 1.0); + gtk_adjustment_set_upper(GTK_ADJUSTMENT(control_slider), 360.0); + gtk_adjustment_set_value(GTK_ADJUSTMENT(control_slider), (double)exposure); + } + + return; + } + + // Tapped preview image itself, try focussing + if (current.has_af_s) { + v4l2_ctrl_set(current.fd, V4L2_CID_AUTO_FOCUS_STOP, 1); + v4l2_ctrl_set(current.fd, V4L2_CID_AUTO_FOCUS_START, 1); + } +} + void on_error_close_clicked(GtkWidget *widget, gpointer user_data) { @@ -1153,6 +1200,49 @@ on_back_clicked(GtkWidget *widget, gpointer user_data) gtk_stack_set_visible_child_name(GTK_STACK(main_stack), "main"); } +void +on_control_auto_toggled(GtkToggleButton *widget, gpointer user_data) +{ + int fd = current.fd; + switch (current_control) { + case USER_CONTROL_ISO: + auto_gain = gtk_toggle_button_get_active(widget); + if (auto_gain) { + v4l2_ctrl_set(fd, V4L2_CID_AUTOGAIN, 1); + } else { + v4l2_ctrl_set(fd, V4L2_CID_AUTOGAIN, 0); + } + break; + case USER_CONTROL_SHUTTER: + auto_exposure = gtk_toggle_button_get_active(widget); + if (auto_exposure) { + v4l2_ctrl_set(fd, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_AUTO); + } else { + v4l2_ctrl_set(fd, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL); + } + break; + } + draw_controls(); +} + +void +on_control_slider_changed(GtkAdjustment *widget, gpointer user_data) +{ + double value = gtk_adjustment_get_value(widget); + + switch (current_control) { + case USER_CONTROL_ISO: + gain = (int)value; + v4l2_ctrl_set(current.fd, V4L2_CID_GAIN, gain); + break; + case USER_CONTROL_SHUTTER: + exposure = (int)(value / 360.0 * current.height); + v4l2_ctrl_set(current.fd, V4L2_CID_EXPOSURE, exposure); + break; + } + draw_controls(); +} + int find_config(char *conffile) { @@ -1300,6 +1390,10 @@ main(int argc, char *argv[]) error_message = GTK_WIDGET(gtk_builder_get_object(builder, "error_message")); main_stack = GTK_WIDGET(gtk_builder_get_object(builder, "main_stack")); thumb_last = GTK_WIDGET(gtk_builder_get_object(builder, "thumb_last")); + control_box = GTK_WIDGET(gtk_builder_get_object(builder, "control_box")); + control_name = GTK_WIDGET(gtk_builder_get_object(builder, "control_name")); + control_slider = GTK_WIDGET(gtk_builder_get_object(builder, "control_adj")); + control_auto = GTK_WIDGET(gtk_builder_get_object(builder, "control_auto")); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(shutter, "clicked", G_CALLBACK(on_shutter_clicked), NULL); g_signal_connect(error_close, "clicked", G_CALLBACK(on_error_close_clicked), NULL); @@ -1310,6 +1404,11 @@ main(int argc, char *argv[]) g_signal_connect(open_directory, "clicked", G_CALLBACK(on_open_directory_clicked), NULL); g_signal_connect(preview, "draw", G_CALLBACK(preview_draw), NULL); g_signal_connect(preview, "configure-event", G_CALLBACK(preview_configure), NULL); + gtk_widget_set_events(preview, gtk_widget_get_events(preview) | + GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); + g_signal_connect(preview, "button-press-event", G_CALLBACK(on_preview_tap), NULL); + g_signal_connect(control_auto, "toggled", G_CALLBACK(on_control_auto_toggled), NULL); + g_signal_connect(control_slider, "value-changed", G_CALLBACK(on_control_slider_changed), NULL); GtkCssProvider *provider = gtk_css_provider_new(); if (access("camera.css", F_OK) != -1) {