Switch preview rendering to cairo
This commit is contained in:
parent
db131f2cb0
commit
70519058e6
408
camera.glade
408
camera.glade
|
@ -1,32 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<!-- Generated with glade 3.37.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="title" translatable="yes">Camera</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="main_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkBox" id="page_main">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="preview_box">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="preview">
|
||||
<object class="GtkDrawingArea" id="preview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
@ -47,59 +43,19 @@
|
|||
<child>
|
||||
<object class="GtkBox" id="controls_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">8</property>
|
||||
<property name="margin_bottom">8</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-preferences</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">10</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="can-focus">False</property>
|
||||
<child type="center">
|
||||
<object class="GtkButton" id="shutter">
|
||||
<property name="width_request">48</property>
|
||||
<property name="height_request">48</property>
|
||||
<property name="width-request">48</property>
|
||||
<property name="height-request">48</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="always-show-image">True</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="stock">gtk-cdrom</property>
|
||||
</object>
|
||||
</child>
|
||||
|
@ -117,9 +73,65 @@
|
|||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">8</property>
|
||||
<property name="margin_bottom">8</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">8</property>
|
||||
<property name="margin-bottom">8</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="settings">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="stock">gtk-preferences</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="switch_camera">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="stock">gtk-refresh</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">10</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">8</property>
|
||||
<property name="margin-bottom">8</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
|
@ -135,7 +147,7 @@
|
|||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">10</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -153,6 +165,274 @@
|
|||
<property name="title" translatable="yes">page0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="page_settings">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="shadow-type">none</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>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">4</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Photos</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label-xalign">0</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkAlignment">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="left-padding">12</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Resolution</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Preview mode</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="preview_simple">
|
||||
<property name="label" translatable="yes">Full resolution (slowest)</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="preview_downsample">
|
||||
<property name="label" translatable="yes">Quarter resolution debayered</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<property name="group">preview_simple</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="preview_grayscale">
|
||||
<property name="label" translatable="yes">Grayscale</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<property name="group">preview_simple</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Storage mode</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="store_vng">
|
||||
<property name="label" translatable="yes">Debayer with VNG (slowest)</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="store_simple">
|
||||
<property name="label" translatable="yes">Debayer with linear interpolation</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<property name="group">store_vng</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="store_raw">
|
||||
<property name="label" translatable="yes">Raw</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<property name="group">store_vng</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label_item">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<style>
|
||||
<class name="view"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page1</property>
|
||||
<property name="title" translatable="yes">page1</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
67
main.c
67
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) {
|
||||
|
|
Loading…
Reference in New Issue