Implement manual controls
This commit is contained in:
parent
d891f44937
commit
5d872860f9
75
camera.glade
75
camera.glade
|
@ -2,6 +2,11 @@
|
||||||
<!-- Generated with glade 3.37.0 -->
|
<!-- Generated with glade 3.37.0 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.20"/>
|
<requires lib="gtk+" version="3.20"/>
|
||||||
|
<object class="GtkAdjustment" id="control_adj">
|
||||||
|
<property name="upper">100</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
|
</object>
|
||||||
<object class="GtkWindow" id="window">
|
<object class="GtkWindow" id="window">
|
||||||
<property name="can-focus">False</property>
|
<property name="can-focus">False</property>
|
||||||
<property name="title" translatable="yes">Camera</property>
|
<property name="title" translatable="yes">Camera</property>
|
||||||
|
@ -42,6 +47,76 @@
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="control_box">
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="margin-start">10</property>
|
||||||
|
<property name="margin-end">10</property>
|
||||||
|
<property name="margin-top">10</property>
|
||||||
|
<property name="margin-bottom">10</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="control_name">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">False</property>
|
||||||
|
<property name="margin-end">10</property>
|
||||||
|
<property name="label" translatable="yes">ISO</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScale" id="control_slider">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="adjustment">control_adj</property>
|
||||||
|
<property name="round-digits">1</property>
|
||||||
|
<property name="draw-value">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToggleButton" id="control_auto">
|
||||||
|
<property name="label" translatable="yes">Auto</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">True</property>
|
||||||
|
<property name="margin-start">10</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack-type">end</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="controlbox"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="controls_box">
|
<object class="GtkBox" id="controls_box">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
109
main.c
109
main.c
|
@ -19,10 +19,9 @@
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
#include "quickdebayer.h"
|
#include "quickdebayer.h"
|
||||||
|
|
||||||
enum io_method {
|
enum user_control {
|
||||||
IO_METHOD_READ,
|
USER_CONTROL_ISO,
|
||||||
IO_METHOD_MMAP,
|
USER_CONTROL_SHUTTER
|
||||||
IO_METHOD_USERPTR,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TIFFTAG_FORWARDMATRIX1 50964
|
#define TIFFTAG_FORWARDMATRIX1 50964
|
||||||
|
@ -95,13 +94,17 @@ static int gain = 1;
|
||||||
static int burst_length = 5;
|
static int burst_length = 5;
|
||||||
static char burst_dir[23];
|
static char burst_dir[23];
|
||||||
static char processing_script[512];
|
static char processing_script[512];
|
||||||
|
static enum user_control current_control;
|
||||||
// Widgets
|
// Widgets
|
||||||
GtkWidget *preview;
|
GtkWidget *preview;
|
||||||
GtkWidget *error_box;
|
GtkWidget *error_box;
|
||||||
GtkWidget *error_message;
|
GtkWidget *error_message;
|
||||||
GtkWidget *main_stack;
|
GtkWidget *main_stack;
|
||||||
GtkWidget *thumb_last;
|
GtkWidget *thumb_last;
|
||||||
|
GtkWidget *control_box;
|
||||||
|
GtkWidget *control_name;
|
||||||
|
GtkWidget *control_slider;
|
||||||
|
GtkWidget *control_auto;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xioctl(int fd, int request, void *arg)
|
xioctl(int fd, int request, void *arg)
|
||||||
|
@ -1113,6 +1116,50 @@ on_shutter_clicked(GtkWidget *widget, gpointer user_data)
|
||||||
capture = burst_length;
|
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
|
void
|
||||||
on_error_close_clicked(GtkWidget *widget, gpointer user_data)
|
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");
|
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
|
int
|
||||||
find_config(char *conffile)
|
find_config(char *conffile)
|
||||||
{
|
{
|
||||||
|
@ -1300,6 +1390,10 @@ main(int argc, char *argv[])
|
||||||
error_message = GTK_WIDGET(gtk_builder_get_object(builder, "error_message"));
|
error_message = GTK_WIDGET(gtk_builder_get_object(builder, "error_message"));
|
||||||
main_stack = GTK_WIDGET(gtk_builder_get_object(builder, "main_stack"));
|
main_stack = GTK_WIDGET(gtk_builder_get_object(builder, "main_stack"));
|
||||||
thumb_last = GTK_WIDGET(gtk_builder_get_object(builder, "thumb_last"));
|
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(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
g_signal_connect(shutter, "clicked", G_CALLBACK(on_shutter_clicked), 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);
|
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(open_directory, "clicked", G_CALLBACK(on_open_directory_clicked), NULL);
|
||||||
g_signal_connect(preview, "draw", G_CALLBACK(preview_draw), NULL);
|
g_signal_connect(preview, "draw", G_CALLBACK(preview_draw), NULL);
|
||||||
g_signal_connect(preview, "configure-event", G_CALLBACK(preview_configure), 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();
|
GtkCssProvider *provider = gtk_css_provider_new();
|
||||||
if (access("camera.css", F_OK) != -1) {
|
if (access("camera.css", F_OK) != -1) {
|
||||||
|
|
Loading…
Reference in New Issue