WIP
This commit is contained in:
@@ -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
|
||||
|
@@ -1,4 +1,4 @@
|
||||
project('megapixels', 'c', version: '1.6.1')
|
||||
project('megapixels', 'c', version: '2.0.0')
|
||||
|
||||
gnome = import('gnome')
|
||||
gtkdep = dependency('gtk4')
|
||||
|
146
src/main.c
146
src/main.c
@@ -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
26
src/state.h
Normal 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;
|
Reference in New Issue
Block a user