~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to gnome/src/config/videoconf.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
 
2
 *  Copyright (C) 2004-2014 Savoir-Faire Linux Inc.
3
3
 *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
 
4
 *  Author: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
4
5
 *
5
6
 *  This program is free software; you can redistribute it and/or modify
6
7
 *  it under the terms of the GNU General Public License as published by
34
35
#include "utils.h"
35
36
#include "dbus.h"
36
37
#include "codeclist.h"
37
 
 
38
 
static GtkWidget *v4l2Device;
39
 
static GtkWidget *v4l2Channel;
40
 
static GtkWidget *v4l2Size;
41
 
static GtkWidget *v4l2Rate;
42
 
 
43
 
static GtkListStore *v4l2DeviceList;
44
 
static GtkListStore *v4l2ChannelList;
45
 
static GtkListStore *v4l2SizeList;
46
 
static GtkListStore *v4l2RateList;
 
38
#include "video/video_capabilities.h"
 
39
 
 
40
typedef struct {
 
41
    VideoCapabilities *cap;
 
42
 
 
43
    /* Video choices */
 
44
    gchar *name;
 
45
    gchar *chan;
 
46
    gchar *size;
 
47
    gchar *rate;
 
48
} VideoDevice;
 
49
 
 
50
static GtkComboBoxText *v4l2Device;
 
51
static GtkComboBoxText *v4l2Channel;
 
52
static GtkComboBoxText *v4l2Size;
 
53
static GtkComboBoxText *v4l2Rate;
47
54
 
48
55
static GtkWidget *v4l2_hbox;
49
56
static GtkWidget *v4l2_nodev;
101
108
static void
102
109
camera_button_toggled(GtkButton *button, G_GNUC_UNUSED gpointer data)
103
110
{
104
 
    camera_button = GTK_WIDGET(button);
105
 
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
106
 
        dbus_start_video_camera();
107
 
    else
108
 
        dbus_stop_video_camera();
 
111
    gchar ** str = dbus_get_call_list();
 
112
 
 
113
    /* we can toggle only if there is no call */
 
114
    if (str == NULL || *str == NULL) {
 
115
 
 
116
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
 
117
            dbus_start_video_camera();
 
118
        } else {
 
119
            dbus_stop_video_camera();
 
120
        }
 
121
 
 
122
    }
 
123
 
 
124
    g_strfreev(str);
109
125
 
110
126
    update_camera_button_label();
111
127
}
513
529
    gtk_container_set_border_width(GTK_CONTAINER(buttonBox), 10);
514
530
    gtk_box_pack_start(GTK_BOX(ret), buttonBox, FALSE, FALSE, 0);
515
531
 
516
 
    codecMoveUpButton = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
 
532
    codecMoveUpButton = gtk_button_new_with_label(_("Up"));
517
533
    gtk_widget_set_sensitive(GTK_WIDGET(codecMoveUpButton), FALSE);
518
534
    gtk_box_pack_start(GTK_BOX(buttonBox), codecMoveUpButton, FALSE, FALSE, 0);
519
535
    g_signal_connect(G_OBJECT(codecMoveUpButton), "clicked", G_CALLBACK(codec_move_up), acc);
520
536
 
521
 
    codecMoveDownButton = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
 
537
    codecMoveDownButton = gtk_button_new_with_label(_("Down"));
522
538
    gtk_widget_set_sensitive(GTK_WIDGET(codecMoveDownButton), FALSE);
523
539
    gtk_box_pack_start(GTK_BOX(buttonBox), codecMoveDownButton, FALSE, FALSE, 0);
524
540
    g_signal_connect(G_OBJECT(codecMoveDownButton), "clicked", G_CALLBACK(codec_move_down), acc);
528
544
    return ret;
529
545
}
530
546
 
531
 
/* Gets a newly allocated string with the active text, the caller must
532
 
 * free this string */
533
 
static gchar *
534
 
get_active_text(GtkComboBox *box)
535
 
{
536
 
    gchar *text = NULL;
537
 
    int comboBoxIndex = gtk_combo_box_get_active(box);
538
 
    if (comboBoxIndex >= 0) {
539
 
        GtkTreeIter iter;
540
 
        gtk_combo_box_get_active_iter(box, &iter);
541
 
        gtk_tree_model_get(gtk_combo_box_get_model(box), &iter, 0, &text, -1);
542
 
    }
543
 
    return text;
544
 
}
545
 
 
546
 
/* Return 0 if string was found in the combo box, != 0 if the string was not found */
547
 
static int
548
 
set_combo_index_from_str(GtkComboBox *box, const gchar *str, size_t max)
549
 
{
550
 
    g_assert(str);
551
 
 
552
 
    GtkTreeModel *model = gtk_combo_box_get_model(box);
553
 
    GtkTreeIter iter;
554
 
    unsigned idx = 0;
555
 
    gtk_tree_model_get_iter_first(model, &iter);
556
 
    do {
557
 
        gchar *boxstr = 0;
558
 
        gtk_tree_model_get(model, &iter, 0, &boxstr, -1);
559
 
        if (boxstr && !g_strcmp0(boxstr, str))
560
 
            break;
561
 
    } while (idx++ < max && gtk_tree_model_iter_next(model, &iter));
562
 
 
563
 
    if (idx >= max)
564
 
        return 1;
565
 
 
566
 
    gtk_combo_box_set_active(box, idx);
567
 
    return 0;
568
 
}
569
 
 
570
 
 
571
 
/**
572
 
 * Fill video input device rate store
573
 
 */
574
 
static void
575
 
preferences_dialog_fill_video_input_device_rate_list()
576
 
{
577
 
    GtkTreeIter iter;
578
 
    gchar** list = NULL;
579
 
 
580
 
    if (v4l2RateList)
581
 
        gtk_list_store_clear(v4l2RateList);
582
 
 
583
 
    gchar *dev  = get_active_text(GTK_COMBO_BOX(v4l2Device));
584
 
    gchar *chan = get_active_text(GTK_COMBO_BOX(v4l2Channel));
585
 
    gchar *size = get_active_text(GTK_COMBO_BOX(v4l2Size));
586
 
 
587
 
    // Call dbus to retreive list
588
 
    if (dev && chan && size) {
589
 
        list = dbus_get_video_device_rate_list(dev, chan, size);
590
 
        g_free(size);
591
 
        g_free(chan);
592
 
        g_free(dev);
593
 
    }
594
 
 
595
 
    // For each device name included in list
596
 
    if (list && *list) {
597
 
        gint c = 0;
598
 
        for (gchar **tmp = list; *tmp; c++, tmp++) {
599
 
            gtk_list_store_append(v4l2RateList, &iter);
600
 
            gtk_list_store_set(v4l2RateList, &iter, 0, *tmp, 1, c, -1);
601
 
        }
602
 
        g_strfreev(list);
603
 
 
604
 
        gchar *rate = dbus_get_active_video_device_rate();
605
 
        if (!rate || !*rate || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Rate), rate, c)) {
606
 
            // if setting is invalid, choose first entry
607
 
            gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Rate), 0);
608
 
            gchar *selected = get_active_text(GTK_COMBO_BOX(v4l2Rate));
609
 
            if (selected) {
610
 
                dbus_set_active_video_device_rate(selected);
611
 
                g_free(selected);
612
 
            }
613
 
        }
614
 
        g_free(rate);
615
 
    } else
616
 
        g_warning("No video rate list found for device");
617
 
}
618
 
 
619
 
 
620
 
/**
621
 
 * Set the video input device rate on the server
622
 
 */
623
 
static void
624
 
select_video_input_device_rate_cb(GtkComboBox* comboBox, G_GNUC_UNUSED gpointer data)
625
 
{
626
 
    gchar *str = get_active_text(comboBox);
627
 
    if (str)
628
 
        dbus_set_active_video_device_rate(str);
629
 
    g_free(str);
630
 
}
631
 
 
632
 
/**
633
 
 * Fill video input device size store
634
 
 */
635
 
static void
636
 
preferences_dialog_fill_video_input_device_size_list()
637
 
{
638
 
    if (v4l2SizeList)
639
 
        gtk_list_store_clear(v4l2SizeList);
640
 
 
641
 
    gchar *dev  = get_active_text(GTK_COMBO_BOX(v4l2Device));
642
 
    gchar *chan = get_active_text(GTK_COMBO_BOX(v4l2Channel));
643
 
 
644
 
    gchar** list = NULL;
645
 
    // Call dbus to retrieve list
646
 
    if (dev && chan) {
647
 
        list = dbus_get_video_device_size_list(dev, chan);
648
 
        g_free(chan);
649
 
        g_free(dev);
650
 
    }
651
 
 
652
 
    if (list && *list) {
653
 
        // For each device name included in list
654
 
        gint c = 0;
655
 
        for (gchar **tmp = list; *tmp; c++, tmp++) {
656
 
            GtkTreeIter iter;
657
 
            gtk_list_store_append(v4l2SizeList, &iter);
658
 
            gtk_list_store_set(v4l2SizeList, &iter, 0, *tmp, 1, c, -1);
659
 
        }
660
 
        g_strfreev(list);
661
 
        gchar *size = dbus_get_active_video_device_size();
662
 
        if (!size || !*size || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Size), size, c)) {
663
 
            // if setting is invalid, choose first entry
664
 
            gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Size), 0);
665
 
            gchar *selected = get_active_text(GTK_COMBO_BOX(v4l2Size));
666
 
            if (selected) {
667
 
                dbus_set_active_video_device_size(selected);
668
 
                g_free(selected);
669
 
            }
670
 
        }
671
 
        g_free(size);
672
 
    } else
673
 
        g_warning("No device size list found");
674
 
}
675
 
 
676
 
/**
677
 
 * Set the video input device size on the server
678
 
 */
679
 
static void
680
 
select_video_input_device_size_cb(GtkComboBox* comboBox, G_GNUC_UNUSED gpointer data)
681
 
{
682
 
    gchar *str = get_active_text(comboBox);
683
 
    if (str) {
684
 
        dbus_set_active_video_device_size(str);
685
 
        preferences_dialog_fill_video_input_device_rate_list();
686
 
        g_free(str);
687
 
    }
688
 
}
689
 
 
690
 
/**
691
 
 * Fill video input device input store
692
 
 */
693
 
static void
694
 
preferences_dialog_fill_video_input_device_channel_list()
695
 
{
696
 
    if (v4l2ChannelList)
697
 
        gtk_list_store_clear(v4l2ChannelList);
698
 
 
699
 
    gchar *dev = get_active_text(GTK_COMBO_BOX(v4l2Device));
700
 
 
701
 
    gchar **list = NULL;
702
 
    // Call dbus to retrieve list
703
 
    if (dev) {
704
 
        list = dbus_get_video_device_channel_list(dev);
705
 
        g_free(dev);
706
 
    }
707
 
 
708
 
    if (list && *list) {
709
 
        // For each device name included in list
710
 
        int c = 0;
711
 
        for (gchar **tmp = list; *tmp; c++, tmp++) {
712
 
            GtkTreeIter iter;
713
 
            gtk_list_store_append(v4l2ChannelList, &iter);
714
 
            gtk_list_store_set(v4l2ChannelList, &iter, 0, *tmp, 1, c, -1);
715
 
        }
716
 
        g_strfreev(list);
717
 
        gchar *channel = dbus_get_active_video_device_channel();
718
 
        if (!channel || !*channel || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Channel), channel, c)) {
719
 
            // if setting is invalid, choose first entry
720
 
            gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Channel), 0);
721
 
            gchar *selected = get_active_text(GTK_COMBO_BOX(v4l2Channel));
722
 
            if (selected) {
723
 
                dbus_set_active_video_device_channel(selected);
724
 
                g_free(selected);
725
 
            }
726
 
        }
727
 
        g_free(channel);
728
 
    } else
729
 
        g_warning("No channel list found");
730
 
}
731
 
 
732
 
/**
733
 
 * Set the video input device input on the server
734
 
 */
735
 
static void
736
 
select_video_input_device_channel_cb(GtkComboBox* comboBox, G_GNUC_UNUSED gpointer data)
737
 
{
738
 
    gchar *str = get_active_text(comboBox);
739
 
    if (str) {
740
 
        dbus_set_active_video_device_channel(str);
741
 
        preferences_dialog_fill_video_input_device_size_list();
742
 
        g_free(str);
743
 
    }
744
 
}
745
 
 
746
 
/**
747
 
 * Fill video input device store
748
 
 */
749
 
static gboolean
750
 
preferences_dialog_fill_video_input_device_list()
751
 
{
752
 
    gtk_list_store_clear(v4l2DeviceList);
753
 
 
754
 
    // Call dbus to retrieve list
755
 
    gchar **list = dbus_get_video_device_list();
756
 
    if (!list || !*list) {
757
 
        g_warning("No device list found");
758
 
        return FALSE;
759
 
    } else {
760
 
        // For each device name included in list
761
 
        gint c = 0;
762
 
        for (gchar **tmp = list; *tmp; c++, tmp++) {
763
 
            GtkTreeIter iter;
764
 
            gtk_list_store_append(v4l2DeviceList, &iter);
765
 
            gtk_list_store_set(v4l2DeviceList, &iter, 0, *tmp, 1, c, -1);
766
 
        }
767
 
        g_strfreev(list);
768
 
        gchar *dev = dbus_get_active_video_device();
769
 
        if (!dev || !*dev || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Device), dev, c)) {
770
 
            // if setting is invalid, choose first entry
771
 
            gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Device), 0);
772
 
            gchar *selected = get_active_text(GTK_COMBO_BOX(v4l2Device));
773
 
            if (selected) {
774
 
                dbus_set_active_video_device(selected);
775
 
                g_free(selected);
776
 
            }
777
 
        }
778
 
        g_free(dev);
779
 
        return TRUE;
780
 
    }
781
 
}
782
 
 
783
 
/**
784
 
 * Set the video input device on the server
785
 
 */
786
 
static void
787
 
select_video_input_device_cb(GtkComboBox* comboBox, G_GNUC_UNUSED gpointer data)
788
 
{
789
 
    gchar *str = get_active_text(comboBox);
790
 
    if (str) {
791
 
        g_debug("Setting video input device to %s", str);
792
 
        dbus_set_active_video_device(str);
793
 
        preferences_dialog_fill_video_input_device_channel_list();
794
 
        g_free(str);
795
 
    }
796
 
}
797
 
 
798
 
static void
799
 
fill_devices()
800
 
{
801
 
    if (preferences_dialog_fill_video_input_device_list()) {
 
547
static void
 
548
reset_combo_box(GtkComboBoxText *combo, gchar **entries, const gchar *preferred)
 
549
{
 
550
    g_assert(GTK_IS_WIDGET(combo));
 
551
 
 
552
    guint index = 0; /* first one if not found */
 
553
 
 
554
    /* Temporarily deactivate the "changed" signal to clear the list */
 
555
    const guint signal_id = g_signal_lookup("changed", G_OBJECT_TYPE(combo));
 
556
    const gulong handler_id = g_signal_handler_find(combo, G_SIGNAL_MATCH_ID, signal_id, 0, NULL, NULL, NULL);
 
557
    g_signal_handler_block(combo, handler_id);
 
558
    gtk_combo_box_text_remove_all(combo);
 
559
    g_signal_handler_unblock(combo, handler_id);
 
560
 
 
561
    for (guint i = 0; entries[i]; ++i) {
 
562
        gtk_combo_box_text_insert_text(combo, i, entries[i]);
 
563
        if (g_strcmp0(entries[i], preferred) == 0)
 
564
            index = i;
 
565
    }
 
566
 
 
567
    /* NOTE This will invoke the combo box's "changed" callback */
 
568
    gtk_combo_box_set_active(GTK_COMBO_BOX(combo), index);
 
569
}
 
570
 
 
571
static void
 
572
fill_devices(void)
 
573
{
 
574
    gchar **devices = dbus_video_get_device_list();
 
575
    g_assert(devices);
 
576
 
 
577
    if (*devices) {
 
578
        gchar *default_device = dbus_video_get_default_device();
 
579
        reset_combo_box(v4l2Device, devices, default_device);
 
580
        g_free(default_device);
 
581
 
802
582
        gtk_widget_show_all(v4l2_hbox);
803
583
        gtk_widget_hide(v4l2_nodev);
804
584
        gtk_widget_set_sensitive(camera_button, TRUE);
805
585
    } else if (GTK_IS_WIDGET(v4l2_hbox)) {
 
586
        g_warning("No video devices");
806
587
        gtk_widget_hide(v4l2_hbox);
807
588
        gtk_widget_show(v4l2_nodev);
808
589
        gtk_widget_set_sensitive(camera_button, FALSE);
809
590
    }
 
591
 
 
592
    g_strfreev(devices);
 
593
}
 
594
 
 
595
static void
 
596
combo_box_device_changed_cb(G_GNUC_UNUSED GtkComboBoxText* combo, gpointer data)
 
597
{
 
598
    VideoDevice *dev = (VideoDevice *) data;
 
599
    gchar *name = gtk_combo_box_text_get_active_text(v4l2Device);
 
600
    g_assert(name);
 
601
 
 
602
    /* Clear the video device */
 
603
    if (dev->cap)
 
604
        video_capabilities_free(dev->cap);
 
605
    g_free(dev->name);
 
606
    g_free(dev->chan);
 
607
    g_free(dev->size);
 
608
    g_free(dev->rate);
 
609
 
 
610
    dev->name = name;
 
611
    dev->cap = video_capabilities_new(name);
 
612
 
 
613
    /* Fetch user preferences for this device */
 
614
    GHashTable *hash = dbus_video_get_settings(name);
 
615
    dev->chan = g_strdup(g_hash_table_lookup(hash, "channel"));
 
616
    dev->size = g_strdup(g_hash_table_lookup(hash, "size"));
 
617
    dev->rate = g_strdup(g_hash_table_lookup(hash, "rate"));
 
618
    g_hash_table_destroy(hash);
 
619
 
 
620
    /* Start the cascade into the channel combo box */
 
621
    gchar **channels = video_capabilities_get_channels(dev->cap);
 
622
    reset_combo_box(v4l2Channel, channels, dev->chan);
 
623
    g_strfreev(channels);
 
624
}
 
625
 
 
626
static void
 
627
combo_box_channel_changed_cb(G_GNUC_UNUSED GtkComboBoxText *combo, gpointer data)
 
628
{
 
629
    VideoDevice *dev = (VideoDevice *) data;
 
630
    gchar *chan = gtk_combo_box_text_get_active_text(v4l2Channel);
 
631
    g_assert(chan);
 
632
    g_free(dev->chan);
 
633
    dev->chan = chan;
 
634
 
 
635
    /* Cascade into the size combo box */
 
636
    gchar** sizes = video_capabilities_get_sizes(dev->cap, dev->chan);
 
637
    reset_combo_box(v4l2Size, sizes, dev->size);
 
638
    g_strfreev(sizes);
 
639
}
 
640
 
 
641
static void
 
642
combo_box_size_changed_cb(G_GNUC_UNUSED GtkComboBoxText *combo, gpointer data)
 
643
{
 
644
    VideoDevice *dev = (VideoDevice *) data;
 
645
    gchar *size = gtk_combo_box_text_get_active_text(v4l2Size);
 
646
    g_assert(size);
 
647
    g_free(dev->size);
 
648
    dev->size = size;
 
649
 
 
650
    /* Cascade into the rate combo box */
 
651
    gchar **rates = video_capabilities_get_rates(dev->cap, dev->chan, dev->size);
 
652
    reset_combo_box(v4l2Rate, rates, dev->rate);
 
653
    g_strfreev(rates);
 
654
}
 
655
 
 
656
static void
 
657
combo_box_rate_changed_cb(G_GNUC_UNUSED GtkComboBoxText *combo, gpointer data)
 
658
{
 
659
    VideoDevice *dev = (VideoDevice *) data;
 
660
    gchar *rate = gtk_combo_box_text_get_active_text(v4l2Rate);
 
661
    g_assert(rate);
 
662
    g_free(dev->rate);
 
663
    dev->rate = rate;
 
664
 
 
665
    /* End of the cascade, save the default device and its settings */
 
666
    dbus_video_set_default_device(dev->name);
 
667
    GHashTable *hash = g_hash_table_new(g_str_hash, g_str_equal);
 
668
    g_hash_table_insert(hash, "channel", dev->chan);
 
669
    g_hash_table_insert(hash, "size", dev->size);
 
670
    g_hash_table_insert(hash, "rate", dev->rate);
 
671
    dbus_video_apply_settings(dev->name, hash);
 
672
    g_hash_table_destroy(hash);
810
673
}
811
674
 
812
675
void
813
676
video_device_event_cb(G_GNUC_UNUSED DBusGProxy *proxy, G_GNUC_UNUSED gpointer foo)
814
677
{
 
678
    /* FIXME: get rid of these global widgets */
 
679
    g_return_if_fail(GTK_IS_WIDGET(v4l2Device));
815
680
    fill_devices();
816
681
}
817
682
 
 
683
static GtkComboBoxText *
 
684
attach_combo_box(GtkGrid *grid, const guint row, const gchar *label, GCallback callback, gpointer data)
 
685
{
 
686
    /* Attach the label on left */
 
687
    GtkWidget *item = gtk_label_new(_(label));
 
688
    gtk_grid_attach(grid, item, 0, row, 1, 1);
 
689
 
 
690
    /* Attach the combo combo on right */
 
691
    GtkWidget *combo = gtk_combo_box_text_new();
 
692
    g_signal_connect(G_OBJECT(combo), "changed", callback, data);
 
693
    gtk_grid_attach(grid, combo, 1, row, 1, 1);
 
694
 
 
695
    return GTK_COMBO_BOX_TEXT(combo);
 
696
}
818
697
 
819
698
static GtkWidget *
820
699
v4l2_box()
831
710
    gtk_grid_set_column_spacing(GTK_GRID(grid), 40);
832
711
    gtk_box_pack_start(GTK_BOX(v4l2_hbox), grid, TRUE, TRUE, 1);
833
712
 
834
 
    // Set choices of input devices
835
 
    GtkWidget *item = gtk_label_new(_("Device"));
836
 
    v4l2DeviceList = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
837
 
    v4l2Device = gtk_combo_box_new_with_model(GTK_TREE_MODEL(v4l2DeviceList));
838
 
    gtk_label_set_mnemonic_widget(GTK_LABEL(item), v4l2Device);
839
 
 
840
 
    g_signal_connect(G_OBJECT(v4l2Device), "changed", G_CALLBACK(select_video_input_device_cb), NULL);
841
 
    gtk_grid_attach(GTK_GRID(grid), item, 0, 0, 1, 1);
842
 
 
843
 
    // Set rendering
844
 
    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
845
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(v4l2Device), renderer, TRUE);
846
 
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(v4l2Device), renderer, "text", 0, NULL);
847
 
    gtk_grid_attach(GTK_GRID(grid), v4l2Device, 1, 0, 1, 1);
848
 
 
849
 
    // Set choices of input
850
 
    item = gtk_label_new(_("Channel"));
851
 
    v4l2ChannelList = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
852
 
    v4l2Channel = gtk_combo_box_new_with_model(GTK_TREE_MODEL(v4l2ChannelList));
853
 
    gtk_label_set_mnemonic_widget(GTK_LABEL(item), v4l2Channel);
854
 
    g_signal_connect(G_OBJECT(v4l2Channel), "changed", G_CALLBACK(select_video_input_device_channel_cb), NULL);
855
 
    gtk_grid_attach(GTK_GRID(grid), item, 0, 1, 1, 1);
856
 
 
857
 
    // Set rendering
858
 
    renderer = gtk_cell_renderer_text_new();
859
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(v4l2Channel), renderer, TRUE);
860
 
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(v4l2Channel), renderer, "text", 0, NULL);
861
 
    gtk_grid_attach(GTK_GRID(grid), v4l2Channel, 1, 1, 1, 1);
862
 
 
863
 
    // Set choices of sizes
864
 
    item = gtk_label_new(_("Size"));
865
 
    v4l2SizeList = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
866
 
    v4l2Size = gtk_combo_box_new_with_model(GTK_TREE_MODEL(v4l2SizeList));
867
 
    gtk_label_set_mnemonic_widget(GTK_LABEL(item), v4l2Size);
868
 
    g_signal_connect(G_OBJECT(v4l2Size), "changed", G_CALLBACK(select_video_input_device_size_cb), NULL);
869
 
    gtk_grid_attach(GTK_GRID(grid), item, 0, 2, 1, 1);
870
 
 
871
 
    // Set rendering
872
 
    renderer = gtk_cell_renderer_text_new();
873
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(v4l2Size), renderer, TRUE);
874
 
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(v4l2Size), renderer, "text", 0, NULL);
875
 
    gtk_grid_attach(GTK_GRID(grid), v4l2Size, 1, 2, 1, 1);
876
 
 
877
 
    // Set choices of rates
878
 
    item = gtk_label_new(_("Rate"));
879
 
    v4l2RateList = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
880
 
    v4l2Rate = gtk_combo_box_new_with_model(GTK_TREE_MODEL(v4l2RateList));
881
 
    gtk_label_set_mnemonic_widget(GTK_LABEL(item), v4l2Rate);
882
 
    g_signal_connect(G_OBJECT(v4l2Rate), "changed", G_CALLBACK(select_video_input_device_rate_cb), NULL);
883
 
    gtk_grid_attach(GTK_GRID(grid), item, 0, 3, 1, 1);
884
 
 
885
 
    // Set rendering
886
 
    renderer = gtk_cell_renderer_text_new();
887
 
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(v4l2Rate), renderer, TRUE);
888
 
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(v4l2Rate), renderer, "text", 0, NULL);
889
 
    gtk_grid_attach(GTK_GRID(grid), v4l2Rate, 1, 3, 1, 1);
 
713
    VideoDevice *dev = g_new0(VideoDevice, 1);
 
714
 
 
715
    v4l2Device = attach_combo_box(GTK_GRID(grid), 0, "Device", G_CALLBACK(combo_box_device_changed_cb), dev);
 
716
    v4l2Channel = attach_combo_box(GTK_GRID(grid), 1, "Channel", G_CALLBACK(combo_box_channel_changed_cb), dev);
 
717
    v4l2Size = attach_combo_box(GTK_GRID(grid), 2, "Size", G_CALLBACK(combo_box_size_changed_cb), dev);
 
718
    v4l2Rate = attach_combo_box(GTK_GRID(grid), 3, "Rate", G_CALLBACK(combo_box_rate_changed_cb), dev);
890
719
 
891
720
    return ret;
892
721
}
893
722
 
894
 
 
895
723
GtkWidget *
896
724
create_video_configuration()
897
725
{