This commit is contained in:
Martijn Braam
2023-07-16 23:18:14 +02:00
parent 2f48f31b6a
commit 0170544013
4 changed files with 92 additions and 84 deletions

View File

@@ -75,7 +75,7 @@ add_custom_target(
)
file(GLOB srcs src/*.c src/*h)
add_executable(megapixels-gtk ${srcs} ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C})
add_executable(megapixels-gtk ${srcs} ${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C} src/state.h)
set_source_files_properties(
${CMAKE_CURRENT_BINARY_DIR}/${GRESOURCE_C}
PROPERTIES GENERATED TRUE

View File

@@ -1,4 +1,4 @@
project('megapixels', 'c', version: '1.6.1')
project('megapixels', 'c', version: '2.0.0')
gnome = import('gnome')
gtkdep = dependency('gtk4')

View File

@@ -4,6 +4,7 @@
#include "gl_util.h"
#include "io_pipeline.h"
#include "process_pipeline.h"
#include "state.h"
#include <asm/errno.h>
#include <assert.h>
#include <errno.h>
@@ -47,30 +48,11 @@ RENDERDOC_API_1_1_2 *rdoc_api = NULL;
enum user_control { USER_CONTROL_ISO, USER_CONTROL_SHUTTER };
libmegapixels_devconfig *configuration = { 0 };
libmegapixels_camera *camera = NULL;
int current_camera_index = 0;
mp_state_main state;
static bool camera_is_initialized = false;
struct mp_main_state current_state = { 0 };
static int preview_width = -1;
static int preview_height = -1;
static int device_rotation = 0;
static bool gain_is_manual = false;
static int gain;
static int gain_max;
static bool exposure_is_manual = false;
static int exposure;
static bool has_auto_focus_continuous;
static bool has_auto_focus_start;
static bool flash_enabled = false;
static MPProcessPipelineBuffer *current_preview_buffer = NULL;
static int preview_buffer_width = -1;
static int preview_buffer_height = -1;
@@ -79,8 +61,6 @@ static char last_path[260] = "";
static MPZBarScanResult *zbar_result = NULL;
static int burst_length = 4;
// Widgets
GtkWidget *preview;
GtkWidget *main_stack;
@@ -117,22 +97,21 @@ static void
update_io_pipeline()
{
struct mp_io_pipeline_state io_state = {
.camera = camera,
.burst_length = burst_length,
.preview_width = preview_width,
.preview_height = preview_height,
.device_rotation = device_rotation,
.gain_is_manual = gain_is_manual,
.gain = gain,
.exposure_is_manual = exposure_is_manual,
.exposure = exposure,
.flash_enabled = flash_enabled,
.camera = state.camera,
.burst_length = state.burst_length,
.preview_width = state.preview_width,
.preview_height = state.preview_height,
.device_rotation = state.device_rotation,
.gain_is_manual = state.gain_is_manual,
.gain = state.gain,
.exposure_is_manual = state.exposure_is_manual,
.exposure = state.exposure,
.flash_enabled = state.flash_enabled,
};
mp_io_pipeline_update_state(&io_state);
// Make the right settings available for the camera
// TODO: Implement flash again
gtk_widget_set_visible(flash_button, false);
gtk_widget_set_visible(flash_button, state.flash_enabled);
}
static bool
@@ -145,13 +124,13 @@ update_state(const struct mp_main_state *state)
if (current_state.camera == state->camera) {
current_state.mode = state->mode;
if (!gain_is_manual) {
gain = state->gain;
if (!state.gain_is_manual) {
state.gain = state->gain;
}
gain_max = state->gain_max;
state.gain_max = state->gain_max;
if (!exposure_is_manual) {
exposure = state->exposure;
if (!state.exposure_is_manual) {
state.exposure = state->exposure;
}
has_auto_focus_continuous = state->has_auto_focus_continuous;
@@ -328,7 +307,7 @@ static void
position_preview(float *offset_x, float *offset_y, float *size_x, float *size_y)
{
int buffer_width, buffer_height;
if (device_rotation == 0 || device_rotation == 180) {
if (state.device_rotation == 0 || state.device_rotation == 180) {
buffer_width = preview_buffer_width;
buffer_height = preview_buffer_height;
} else {
@@ -341,18 +320,18 @@ position_preview(float *offset_x, float *offset_y, float *size_x, float *size_y)
gtk_widget_get_allocated_height(preview_top_box) * scale_factor;
int bottom_height =
gtk_widget_get_allocated_height(preview_bottom_box) * scale_factor;
int inner_height = preview_height - top_height - bottom_height;
int inner_height = state.preview_height - top_height - bottom_height;
double scale = MIN(preview_width / (float)buffer_width,
preview_height / (float)buffer_height);
double scale = MIN(state.preview_width / (float)buffer_width,
state.preview_height / (float)buffer_height);
*size_x = scale * buffer_width;
*size_y = scale * buffer_height;
*offset_x = (preview_width - *size_x) / 2.0;
*offset_x = (state.preview_width - *size_x) / 2.0;
if (*size_y > inner_height) {
*offset_y = (preview_height - *size_y) / 2.0;
*offset_y = (state.preview_height - *size_y) / 2.0;
} else {
*offset_y = top_height + (inner_height - *size_y) / 2.0;
}
@@ -380,13 +359,14 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
float offset_x, offset_y, size_x, size_y;
position_preview(&offset_x, &offset_y, &size_x, &size_y);
glViewport(offset_x, preview_height - size_y - offset_y, size_x, size_y);
glViewport(
offset_x, state.preview_height - size_y - offset_y, size_x, size_y);
if (current_preview_buffer) {
glUseProgram(blit_program);
GLfloat rotation_list[4] = { 0, -1, 0, 1 };
int rotation_index = device_rotation / 90;
int rotation_index = state.device_rotation / 90;
GLfloat sin_rot = rotation_list[rotation_index];
GLfloat cos_rot = rotation_list[(4 + rotation_index - 1) % 4];
@@ -493,9 +473,9 @@ preview_draw(GtkGLArea *area, GdkGLContext *ctx, gpointer data)
static gboolean
preview_resize(GtkWidget *widget, int width, int height, gpointer data)
{
if (preview_width != width || preview_height != height) {
preview_width = width;
preview_height = height;
if (state.preview_width != width || state.preview_height != height) {
state.preview_width = width;
state.preview_height = height;
update_io_pipeline();
}
@@ -689,7 +669,7 @@ preview_pressed(GtkGestureClick *gesture, int n_press, double x, double y)
}
// Tapped preview image itself, try focussing
if (has_auto_focus_start) {
if (state.has_auto_focus_start) {
mp_io_pipeline_focus();
}
}
@@ -697,11 +677,14 @@ preview_pressed(GtkGestureClick *gesture, int n_press, double x, double y)
static void
run_camera_switch_action(GSimpleAction *action, GVariant *param, gpointer user_data)
{
current_camera_index++;
if (current_camera_index > configuration->count) {
current_camera_index = 0;
int new_index = state.camera->index + 1;
if (new_index > state.configuration->count) {
new_index = 0;
}
camera = configuration->cameras[current_camera_index];
state.camera = state.configuration->cameras[new_index];
// TODO: allow setting burst length in the config
state.burst_length = 5;
update_io_pipeline();
}
@@ -796,8 +779,8 @@ open_controls(GtkWidget *parent,
static void
set_gain(double value)
{
if (gain != (int)value) {
gain = value;
if (state.gain != (int)value) {
state.gain = value;
update_io_pipeline();
}
}
@@ -805,8 +788,8 @@ set_gain(double value)
static void
set_gain_auto(bool is_auto)
{
if (gain_is_manual != !is_auto) {
gain_is_manual = !is_auto;
if (state.gain_is_manual != !is_auto) {
state.gain_is_manual = !is_auto;
update_io_pipeline();
}
}
@@ -817,9 +800,9 @@ open_iso_controls(GtkWidget *button, gpointer user_data)
open_controls(button,
"ISO",
0,
gain_max,
gain,
!gain_is_manual,
state.gain_max,
state.gain,
!state.gain_is_manual,
set_gain,
set_gain_auto);
}
@@ -840,8 +823,8 @@ set_shutter(double value)
static void
set_shutter_auto(bool is_auto)
{
if (exposure_is_manual != !is_auto) {
exposure_is_manual = !is_auto;
if (state.exposure_is_manual != !is_auto) {
state.exposure_is_manual = !is_auto;
update_io_pipeline();
}
}
@@ -853,8 +836,8 @@ open_shutter_controls(GtkWidget *button, gpointer user_data)
"Shutter",
1.0,
360.0,
exposure,
!exposure_is_manual,
state.exposure,
!state.exposure_is_manual,
set_shutter,
set_shutter_auto);
}
@@ -862,11 +845,11 @@ open_shutter_controls(GtkWidget *button, gpointer user_data)
static void
flash_button_clicked(GtkWidget *button, gpointer user_data)
{
flash_enabled = !flash_enabled;
state.flash_enabled = !state.flash_enabled;
update_io_pipeline();
const char *icon_name =
flash_enabled ? "flash-enabled-symbolic" : "flash-disabled-symbolic";
state.flash_enabled ? "flash-enabled-symbolic" : "flash-disabled-symbolic";
gtk_button_set_icon_name(GTK_BUTTON(button), icon_name);
}
@@ -876,8 +859,7 @@ on_realize(GtkWidget *window, gpointer *data)
GtkNative *native = gtk_widget_get_native(window);
mp_process_pipeline_init_gl(gtk_native_get_surface(native));
current_camera_index = 0;
camera = configuration->cameras[0];
state.camera = state.configuration->cameras[0];
update_io_pipeline();
}
@@ -893,7 +875,7 @@ create_simple_action(GtkApplication *app, const char *name, GCallback callback)
static void
update_ui_rotation()
{
if (device_rotation == 0 || device_rotation == 180) {
if (state.device_rotation == 0 || state.device_rotation == 180) {
// Portrait
gtk_widget_set_halign(preview_top_box, GTK_ALIGN_FILL);
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_top_box),
@@ -903,7 +885,7 @@ update_ui_rotation()
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_bottom_box),
GTK_ORIENTATION_HORIZONTAL);
if (device_rotation == 0) {
if (state.device_rotation == 0) {
gtk_widget_set_valign(preview_top_box, GTK_ALIGN_START);
gtk_widget_set_valign(preview_bottom_box, GTK_ALIGN_END);
} else {
@@ -920,7 +902,7 @@ update_ui_rotation()
gtk_orientable_set_orientation(GTK_ORIENTABLE(preview_bottom_box),
GTK_ORIENTATION_VERTICAL);
if (device_rotation == 90) {
if (state.device_rotation == 90) {
gtk_widget_set_halign(preview_top_box, GTK_ALIGN_END);
gtk_widget_set_halign(preview_bottom_box, GTK_ALIGN_START);
} else {
@@ -1036,8 +1018,8 @@ wl_handle_geometry(void *data,
assert(transform < 4);
int new_rotation = transform * 90;
if (new_rotation != device_rotation) {
device_rotation = new_rotation;
if (new_rotation != state.device_rotation) {
state.device_rotation = new_rotation;
update_io_pipeline();
update_ui_rotation();
}
@@ -1110,8 +1092,8 @@ xevent_handler(GdkDisplay *display, XEvent *xevent, gpointer data)
new_rotation = 270;
break;
}
if (new_rotation != device_rotation) {
device_rotation = new_rotation;
if (new_rotation != state.device_rotation) {
state.device_rotation = new_rotation;
update_io_pipeline();
update_ui_rotation();
}
@@ -1281,8 +1263,8 @@ activate(GtkApplication *app, gpointer data)
new_rotation = 270;
break;
}
if (new_rotation != device_rotation) {
device_rotation = new_rotation;
if (new_rotation != state.device_rotation) {
state.device_rotation = new_rotation;
update_ui_rotation();
}
}
@@ -1342,14 +1324,14 @@ main(int argc, char *argv[])
}
#endif
char configfile[PATH_MAX];
libmegapixels_init(&configuration);
libmegapixels_init(&state.configuration);
if (libmegapixels_find_config(configfile)) {
if (!libmegapixels_load_file(configuration, configfile)) {
if (!libmegapixels_load_file(state.configuration, configfile)) {
fprintf(stderr, "Could not load config\n");
return 1;
}
} else {
if (!libmegapixels_load_uvc(configuration)) {
if (!libmegapixels_load_uvc(state.configuration)) {
fprintf(stderr, "No config found\n");
return 1;
}

26
src/state.h Normal file
View File

@@ -0,0 +1,26 @@
#include <libmegapixels.h>
#include <stdbool.h>
typedef struct state_main {
libmegapixels_devconfig *configuration;
libmegapixels_camera *camera;
int preview_width;
int preview_height;
int device_rotation;
int burst_length;
// Control state
bool gain_is_manual;
int gain;
int gain_max;
bool exposure_is_manual;
int exposure;
bool flash_enabled;
bool has_auto_focus_continuous;
bool has_auto_focus_start;
} mp_state_main;