diff --git a/camera.glade b/camera.glade index c20f4ba..308ebc1 100644 --- a/camera.glade +++ b/camera.glade @@ -1,32 +1,28 @@ - + - False + False Camera - - - True - False + False - + True - False + False vertical - + True - False + False vertical - + True - False - gtk-missing-image + False True @@ -47,59 +43,19 @@ True - False - - - True - False - 8 - 8 - 10 - - - True - True - True - - - True - False - gtk-preferences - - - - - False - True - 0 - - - - - - - - - - - True - True - 10 - 0 - - + False - 48 - 48 + 48 + 48 True - True - True - True + True + True + True True - False + False gtk-cdrom @@ -117,9 +73,65 @@ True - False - 8 - 8 + False + 8 + 8 + 10 + + + True + True + True + + + True + False + gtk-preferences + + + + + False + True + 0 + + + + + True + True + True + + + True + False + gtk-refresh + + + + + False + True + 1 + + + + + + + + True + True + 10 + 0 + + + + + True + False + 8 + 8 10 @@ -135,7 +147,7 @@ True True 10 - end + end 1 @@ -153,6 +165,274 @@ page0 + + + True + True + in + + + True + False + none + + + True + False + 10 + 10 + 10 + 10 + vertical + 10 + + + True + False + vertical + 4 + + + True + False + start + Photos + + + + False + True + 0 + + + + + True + False + 0 + in + + + True + False + 12 + + + True + False + vertical + 6 + + + True + False + start + Resolution + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + True + False + start + Preview mode + + + False + True + 2 + + + + + True + False + vertical + + + Full resolution (slowest) + True + True + False + True + True + + + False + True + 0 + + + + + Quarter resolution debayered + True + True + False + True + True + preview_simple + + + False + True + 1 + + + + + Grayscale + True + True + False + True + True + preview_simple + + + False + True + 2 + + + + + False + True + 3 + + + + + True + False + start + Storage mode + + + False + True + 4 + + + + + True + False + vertical + + + Debayer with VNG (slowest) + True + True + False + True + True + + + False + True + 0 + + + + + Debayer with linear interpolation + True + True + False + True + True + store_vng + + + False + True + 1 + + + + + Raw + True + True + False + True + True + store_vng + + + False + True + 2 + + + + + False + True + 5 + + + + + + + + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + + + + + + + + + + + page1 + page1 + 1 + + diff --git a/main.c b/main.c index d54c076..7584d63 100644 --- a/main.c +++ b/main.c @@ -62,8 +62,12 @@ static int current_height = -1; static int current_fmt = 0; static int current_rotate = 0; static int capture = 0; +static cairo_surface_t *surface = NULL; +static int preview_width = -1; +static int preview_height = -1; -GObject *preview_image; +// Widgets +GObject *preview; static int xioctl(int fd, int request, void *arg) @@ -142,7 +146,7 @@ init_mmap(int fd) if (xioctl(fd, VIDIOC_REQBUFS, &req) == -1) { if (errno == EINVAL) { fprintf(stderr, "%s does not support memory mapping", - dev_name); + *dev_name); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_REQBUFS"); @@ -151,7 +155,7 @@ init_mmap(int fd) if (req.count < 2) { fprintf(stderr, "Insufficient buffer memory on %s\n", - dev_name); + *dev_name); exit(EXIT_FAILURE); } @@ -219,7 +223,7 @@ init_device(int fd) if (xioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) { if (errno == EINVAL) { fprintf(stderr, "%s is no V4L2 device\n", - dev_name); + *dev_name); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_QUERYCAP"); @@ -228,7 +232,7 @@ init_device(int fd) if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { fprintf(stderr, "%s is no video capture device\n", - dev_name); + *dev_name); exit(EXIT_FAILURE); } @@ -236,7 +240,7 @@ init_device(int fd) case IO_METHOD_READ: if (!(cap.capabilities & V4L2_CAP_READWRITE)) { fprintf(stderr, "%s does not support read i/o\n", - dev_name); + *dev_name); exit(EXIT_FAILURE); } break; @@ -244,7 +248,7 @@ init_device(int fd) case IO_METHOD_USERPTR: if (!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf(stderr, "%s does not support streaming i/o\n", - dev_name); + *dev_name); exit(EXIT_FAILURE); } break; @@ -346,6 +350,8 @@ process_image(const int *p, int size) GdkPixbuf *pixbuf; GdkPixbuf *pixbufrot; GError *error = NULL; + double scale; + cairo_t *cr; t = clock(); dc1394bayer_method_t method = DC1394_BAYER_METHOD_DOWNSAMPLE; @@ -380,7 +386,15 @@ process_image(const int *p, int size) g_clear_error(&error); } } else { - gtk_image_set_from_pixbuf(preview_image, pixbufrot); + scale = (double)preview_width/gdk_pixbuf_get_width(pixbufrot); + cr = cairo_create(surface); + cairo_set_source_rgb(cr, 0,0,0); + cairo_paint(cr); + gdk_cairo_set_source_pixbuf(cr, pixbufrot, 0, 0); + cairo_scale(cr, scale, scale); + cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_NONE); + cairo_paint(cr); + gtk_widget_queue_draw_area(preview, 0, 0, preview_width, preview_height); } capture = 0; t = clock() - t; @@ -388,6 +402,37 @@ process_image(const int *p, int size) printf("%f fps\n", 1.0/time_taken); } +static gboolean +preview_draw (GtkWidget *widget, cairo_t *cr, gpointer data) +{ + cairo_set_source_surface(cr, surface, 0,0); + cairo_paint(cr); + return FALSE; +} + +static gboolean +preview_configure (GtkWidget *widget, GdkEventConfigure *event) +{ + cairo_t *cr; + + if (surface) + cairo_surface_destroy(surface); + + surface = gdk_window_create_similar_surface (gtk_widget_get_window(widget), + CAIRO_CONTENT_COLOR, + gtk_widget_get_allocated_width (widget), + gtk_widget_get_allocated_height (widget)); + + preview_width = gtk_widget_get_allocated_width(widget); + preview_height = gtk_widget_get_allocated_height(widget); + + cr = cairo_create(surface); + cairo_set_source_rgb(cr, 0, 0, 0); + cairo_paint(cr); + cairo_destroy(cr); + return TRUE; +} + static int read_frame(int fd) { @@ -786,6 +831,7 @@ main(int argc, char *argv[]) GError *error = NULL; gtk_init(&argc, &argv); + g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", TRUE, NULL); GtkBuilder *builder = gtk_builder_new(); char *glade_file = "/usr/share/camera/ui/camera.glade"; if (access("camera.glade", F_OK) != -1) { @@ -800,9 +846,12 @@ main(int argc, char *argv[]) GObject *window = gtk_builder_get_object(builder, "window"); GObject *preview_box = gtk_builder_get_object(builder, "preview_box"); GObject *shutter = gtk_builder_get_object(builder, "shutter"); - preview_image = gtk_builder_get_object(builder, "preview"); + GObject *settings_btn = gtk_builder_get_object(builder, "settings"); + preview = gtk_builder_get_object(builder, "preview"); 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(preview, "draw", G_CALLBACK(preview_draw), NULL); + g_signal_connect(preview, "configure-event", G_CALLBACK(preview_configure), NULL); GtkCssProvider *provider = gtk_css_provider_new(); if (access("camera.css", F_OK) != -1) {