+ gtk_tree_path_free (treepath);
+}
+
+void
+debug_log_handler(const gchar *domain, GLogLevelFlags flags, const gchar *msg, gpointer data)
+{
+ signal_user_data_t *ud = (signal_user_data_t*)data;
+
+ if (ud->debug)
+ {
+ printf("%s: %s\n", domain, msg);
+ }
+}
+
+void
+warn_log_handler(const gchar *domain, GLogLevelFlags flags, const gchar *msg, gpointer data)
+{
+ printf("%s: %s\n", domain, msg);
+}
+
+void
+ghb_hbfd(signal_user_data_t *ud, gboolean hbfd)
+{
+ GtkWidget *widget;
+ g_debug("ghb_hbfd");
+ widget = GHB_WIDGET(ud->builder, "queue_pause1");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET(ud->builder, "queue_add");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET(ud->builder, "show_queue");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET(ud->builder, "show_activity");
+ set_visible(widget, !hbfd);
+
+ widget = GHB_WIDGET(ud->builder, "chapter_box");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET(ud->builder, "container_box");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET(ud->builder, "settings_box");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET(ud->builder, "presets_save");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET(ud->builder, "presets_remove");
+ set_visible(widget, !hbfd);
+ widget = GHB_WIDGET (ud->builder, "hb_window");
+ gtk_window_resize(GTK_WINDOW(widget), 16, 16);
+
+}
+
+G_MODULE_EXPORT void
+hbfd_toggled_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("hbfd_toggled_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ gboolean hbfd = ghb_settings_get_boolean(ud->settings, "hbfd");
+ ghb_hbfd(ud, hbfd);
+ ghb_pref_save(ud->settings, "hbfd");
+}
+
+G_MODULE_EXPORT void
+pref_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("pref_changed_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ ghb_check_dependency(ud, widget, NULL);
+ const gchar *name = ghb_get_setting_key(widget);
+ ghb_pref_save(ud->settings, name);
+}
+
+G_MODULE_EXPORT void
+use_m4v_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("use_m4v_changed_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ ghb_check_dependency(ud, widget, NULL);
+ const gchar *name = ghb_get_setting_key(widget);
+ ghb_pref_save(ud->settings, name);
+ ghb_update_destination_extension(ud);
+}
+
+G_MODULE_EXPORT void
+show_status_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("show_status_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ ghb_check_dependency(ud, widget, NULL);
+ const gchar *name = ghb_get_setting_key(widget);
+ ghb_pref_save(ud->settings, name);
+
+ GtkStatusIcon *si;
+
+ si = GTK_STATUS_ICON(GHB_OBJECT (ud->builder, "hb_status"));
+ gtk_status_icon_set_visible(si,
+ ghb_settings_get_boolean(ud->settings, "show_status"));
+}
+
+G_MODULE_EXPORT void
+vqual_granularity_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("vqual_granularity_changed_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ ghb_check_dependency(ud, widget, NULL);
+
+ const gchar *name = ghb_get_setting_key(widget);
+ ghb_pref_save(ud->settings, name);
+
+ gdouble vqmin, vqmax, step, page;
+ gboolean inverted;
+ gint digits;
+
+ ghb_vquality_range(ud, &vqmin, &vqmax, &step, &page, &digits, &inverted);
+ GtkWidget *qp = GHB_WIDGET(ud->builder, "VideoQualitySlider");
+ gtk_range_set_increments (GTK_RANGE(qp), step, page);
+}
+
+G_MODULE_EXPORT void
+tweaks_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("tweaks_changed_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ const gchar *name = ghb_get_setting_key(widget);
+ ghb_pref_save(ud->settings, name);
+}
+
+G_MODULE_EXPORT void
+hbfd_feature_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
+{
+ g_debug("hbfd_feature_changed_cb");
+ ghb_widget_to_setting (ud->settings, widget);
+ const gchar *name = ghb_get_setting_key(widget);
+ ghb_pref_save(ud->settings, name);
+
+ gboolean hbfd = ghb_settings_get_boolean(ud->settings, "hbfd_feature");
+ GtkAction *action;
+ if (hbfd)
+ {
+ const GValue *val;
+ val = ghb_settings_get_value(ud->settings, "hbfd");
+ ghb_ui_update(ud, "hbfd", val);
+ }
+ action = GHB_ACTION (ud->builder, "hbfd");
+ gtk_action_set_visible(action, hbfd);
+}
+
+gboolean
+ghb_file_menu_add_dvd(signal_user_data_t *ud)
+{
+ GList *link, *drives;
+ static GtkActionGroup *agroup = NULL;
+ static gint merge_id;
+
+ g_debug("ghb_file_menu_add_dvd()");
+ link = drives = dvd_device_list();
+ if (drives != NULL)
+ {
+ GtkUIManager *ui = GTK_UI_MANAGER(
+ gtk_builder_get_object(ud->builder, "uimanager1"));
+
+ if (agroup == NULL)
+ {
+ agroup = gtk_action_group_new("dvdgroup");
+ gtk_ui_manager_insert_action_group(ui, agroup, 0);
+ }
+ else
+ gtk_ui_manager_remove_ui(ui, merge_id);
+
+ merge_id = gtk_ui_manager_new_merge_id(ui);
+ // Add separator
+ gtk_ui_manager_add_ui(ui, merge_id,
+ "ui/menubar1/menuitem1/quit1", "dvdsep", NULL,
+ GTK_UI_MANAGER_SEPARATOR, TRUE);
+
+ while (link != NULL)
+ {
+ GtkAction *action;
+ gchar *drive = get_dvd_device_name(link->data);
+ gchar *name = get_dvd_volume_name(link->data);
+
+ action = gtk_action_group_get_action(agroup, drive);
+ if (action != NULL)
+ {
+ gtk_action_group_remove_action(agroup, action);
+ g_object_unref(G_OBJECT(action));
+ }
+ // Create action for this drive
+ action = gtk_action_new(drive, name,
+ "Scan this DVD source", "gtk-cdrom");
+ // Add action to action group
+ gtk_action_group_add_action_with_accel(agroup, action, NULL);
+ // Add to ui manager
+ gtk_ui_manager_add_ui(ui, merge_id,
+ "ui/menubar1/menuitem1/dvdsep", drive, drive,
+ GTK_UI_MANAGER_AUTO, TRUE);
+ // Connect signal to action (menu item)
+ g_signal_connect(action, "activate",
+ (GCallback)dvd_source_activate_cb, ud);
+ g_free(name);
+ g_free(drive);
+ free_drive(link->data);
+ link = link->next;
+ }
+ g_list_free(drives);
+ }
+ return FALSE;
+}
+
+gboolean ghb_is_cd(GDrive *gd);
+
+static GList*
+dvd_device_list()
+{
+ GList *dvd_devices = NULL;
+
+#if defined(_WIN32)
+ gint ii, drives;
+ gchar drive[5];
+
+ strcpy(drive, "A:" G_DIR_SEPARATOR_S);
+ drives = GetLogicalDrives();
+ for (ii = 0; ii < 26; ii++)
+ {
+ if (drives & 0x01)
+ {
+ guint dtype;
+
+ drive[0] = 'A' + ii;
+ dtype = GetDriveType(drive);
+ if (dtype == DRIVE_CDROM)
+ {
+ dvd_devices = g_list_append(dvd_devices,
+ (gpointer)g_strdup(drive));
+ }
+ }
+ drives >>= 1;
+ }
+#else
+ GVolumeMonitor *gvm;
+ GList *drives, *link;
+
+ gvm = g_volume_monitor_get ();
+ drives = g_volume_monitor_get_connected_drives (gvm);
+ link = drives;
+ while (link != NULL)