// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later #include "native_internal.h" enum { PROGRAM }; static GtkListStore *wine_programs; static int wine_changed; static void wine_edited(GtkCellRendererText *renderer, gchar *path, gchar *text, gpointer data) { (void)renderer; (void)data; GtkTreeIter iter; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(wine_programs), &iter, path)) { gtk_list_store_set(wine_programs, &iter, PROGRAM, text, -1); wine_changed = 1; } } static void wine_add(GtkButton *button, gpointer data) { (void)button; (void)data; GtkTreeIter iter; gtk_list_store_append(wine_programs, &iter); gtk_list_store_set(wine_programs, &iter, PROGRAM, "", -1); wine_changed = 1; GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(wine_programs), &iter); GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("wineTreeView")); gtk_widget_grab_focus(GTK_WIDGET(view)); gtk_tree_view_set_cursor(view, path, gtk_tree_view_get_column(view, PROGRAM), TRUE); gtk_tree_path_free(path); } static void wine_delete(GtkButton *button, gpointer data) { (void)button; (void)data; GtkTreeIter iter; GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(prefs_widget("wineTreeView"))); if (gtk_tree_selection_get_selected(selection, NULL, &iter)) { gtk_list_store_remove(wine_programs, &iter); wine_changed = 1; } gtk_widget_grab_focus(prefs_widget("wineTreeView")); } static gboolean wine_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { (void)data; if (event->keyval != GDK_KEY_Return && event->keyval != GDK_KEY_KP_Enter && event->keyval != GDK_KEY_F2) return FALSE; GtkTreePath *path = NULL; GtkTreeViewColumn *column = NULL; gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, &column); if (!path) return FALSE; gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), path, column ? column : gtk_tree_view_get_column(GTK_TREE_VIEW(widget), 0), TRUE); gtk_tree_path_free(path); return TRUE; } void prefs_init_wine(void) { GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("wineTreeView")); wine_programs = gtk_list_store_new(1, G_TYPE_STRING); gtk_tree_view_set_model(view, GTK_TREE_MODEL(wine_programs)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); g_object_set(renderer, "editable", TRUE, NULL); g_signal_connect(renderer, "edited", G_CALLBACK(wine_edited), NULL); gtk_tree_view_append_column(view, gtk_tree_view_column_new_with_attributes("Program", renderer, "text", PROGRAM, NULL)); atk_object_set_name(gtk_widget_get_accessible(GTK_WIDGET(view)), "Controller-only programs"); atk_object_set_description(gtk_widget_get_accessible(GTK_WIDGET(view)), "Select a cell and press Enter to edit it. Tab moves to the next control."); g_signal_connect(view, "key-press-event", G_CALLBACK(wine_key), NULL); g_signal_connect(prefs_widget("wineAddButton"), "clicked", G_CALLBACK(wine_add), NULL); g_signal_connect(prefs_widget("wineDeleteButton"), "clicked", G_CALLBACK(wine_delete), NULL); g_object_unref(wine_programs); } int prefs_wine_changed(void) { int result = wine_changed; wine_changed = 0; return result; } void prefs_wine_clear(void) { gtk_list_store_clear(wine_programs); } void prefs_wine_append(const char *program) { GtkTreeIter iter; gtk_list_store_append(wine_programs, &iter); gtk_list_store_set(wine_programs, &iter, PROGRAM, program, -1); } int prefs_wine_count(void) { return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(wine_programs), NULL); } char *prefs_wine_value(int row) { GtkTreeIter iter; if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(wine_programs), &iter, NULL, row)) return NULL; char *value = NULL; gtk_tree_model_get(GTK_TREE_MODEL(wine_programs), &iter, PROGRAM, &value, -1); return value; }