filename | src/gui/ctrl_dlg.c |
changeset | 460:a0c865b74c63 |
prev | 455:3080881d00d4 |
next | 480:d28c2992f5ee |
author | nkeynes |
date | Wed Oct 24 21:23:22 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Fix long standing texcache management bug (invalidate palette was not placing the invalidated entries on the free list). |
view | annotate | diff | log | raw |
1 /**
2 * $Id: ctrl_dlg.c,v 1.4 2007-10-23 10:47:17 nkeynes Exp $
3 *
4 * Define the main (emu) GTK window, along with its menubars,
5 * toolbars, etc.
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
20 #include <assert.h>
21 #include <gtk/gtk.h>
22 #include <gdk/gdkkeysyms.h>
24 #include "dream.h"
25 #include "gui/gtkui.h"
26 #include "maple/maple.h"
28 #define MAX_DEVICES 4
30 static void controller_device_configure(maple_device_t device);
32 struct maple_config_class {
33 const char *name;
34 void (*config_func)(maple_device_t device);
35 };
37 typedef struct maple_slot_data {
38 maple_device_t old_device;
39 maple_device_t new_device;
40 GtkWidget *button;
41 GtkWidget *combo;
42 } *maple_slot_data_t;
44 static struct maple_config_class maple_device_config[] = {
45 { "Sega Controller", controller_device_configure },
46 { NULL, NULL } };
48 static struct maple_slot_data maple_data[MAX_DEVICES];
50 static gboolean config_key_buttonpress( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
51 {
52 gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
53 if( !keypress_mode ) {
54 gtk_entry_set_text( GTK_ENTRY(widget), "<press key>" );
55 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
56 }
57 return FALSE;
58 }
60 static gboolean config_key_keypress( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
61 {
62 gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
63 if( keypress_mode ) {
64 if( event->keyval == GDK_Escape ) {
65 gtk_entry_set_text( GTK_ENTRY(widget), "" );
66 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
67 return TRUE;
68 }
69 GdkKeymap *keymap = gdk_keymap_get_default();
70 guint keyval;
72 gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
73 NULL, NULL, NULL );
74 gtk_entry_set_text( GTK_ENTRY(widget), gdk_keyval_name(keyval) );
75 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
76 return TRUE;
77 } else {
78 switch( event->keyval ) {
79 case GDK_Return:
80 case GDK_KP_Enter:
81 gtk_entry_set_text( GTK_ENTRY(widget), "<press key>" );
82 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
83 return TRUE;
84 case GDK_BackSpace:
85 case GDK_Delete:
86 gtk_entry_set_text( GTK_ENTRY(widget), "" );
87 return TRUE;
88 }
89 return FALSE;
90 }
92 }
94 static void controller_config_done( GtkWidget *panel, gboolean isOK )
95 {
96 if( isOK ) {
97 maple_device_t device = (maple_device_t)gtk_object_get_data( GTK_OBJECT(panel), "maple_device" );
98 lxdream_config_entry_t conf = device->get_config(device);
99 int i;
100 for( i=0; conf[i].key != NULL; i++ ) {
101 char buf[64];
102 GtkWidget *entry1, *entry2;
103 const gchar *key1, *key2;
104 snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
105 entry1 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
106 key1 = gtk_entry_get_text(GTK_ENTRY(entry1));
107 snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
108 entry2 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
109 key2 = gtk_entry_get_text(GTK_ENTRY(entry2));
110 if( key1 == NULL || key1[0] == '\0') {
111 lxdream_set_config_value( &conf[i], key2 );
112 } else if( key2 == NULL || key2[0] == '\0') {
113 lxdream_set_config_value( &conf[i], key1 );
114 } else {
115 char buf[64];
116 snprintf( buf, sizeof(buf), "%s, %s", key1, key2 );
117 lxdream_set_config_value( &conf[i], buf );
118 }
119 }
120 }
122 }
124 static void controller_device_configure( maple_device_t device )
125 {
126 lxdream_config_entry_t conf = device->get_config(device);
127 int count, i;
128 for( count=0; conf[count].key != NULL; count++ );
130 GtkWidget *table = gtk_table_new( (count+1)>>1, 6, FALSE );
131 GList *focus_chain = NULL;
132 gtk_object_set_data( GTK_OBJECT(table), "maple_device", device );
133 for( i=0; i<count; i++ ) {
134 GtkWidget *text, *text2;
135 GQuark quark;
136 char buf[64];
137 int x=0;
138 int y=i;
139 if( i >= (count+1)>>1 ) {
140 x = 3;
141 y -= (count+1)>>1;
142 }
143 gtk_table_attach( GTK_TABLE(table), gtk_label_new(conf[i].key), x, x+1, y, y+1,
144 GTK_SHRINK, GTK_SHRINK, 0, 0 );
145 text = gtk_entry_new();
146 gtk_entry_set_width_chars( GTK_ENTRY(text), 8 );
147 gtk_entry_set_editable( GTK_ENTRY(text), FALSE );
148 g_signal_connect( text, "key_press_event",
149 G_CALLBACK(config_key_keypress), NULL );
150 g_signal_connect( text, "button_press_event",
151 G_CALLBACK(config_key_buttonpress), NULL );
152 snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
153 g_object_set_data( G_OBJECT(text), "keypress_mode", GINT_TO_POINTER(FALSE) );
154 g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text );
155 gtk_table_attach_defaults( GTK_TABLE(table), text, x+1, x+2, y, y+1);
156 focus_chain = g_list_append( focus_chain, text );
157 text2 = gtk_entry_new();
158 gtk_entry_set_width_chars( GTK_ENTRY(text2), 8 );
159 gtk_entry_set_editable( GTK_ENTRY(text2), FALSE );
160 g_signal_connect( text2, "key_press_event",
161 G_CALLBACK(config_key_keypress), NULL );
162 g_signal_connect( text2, "button_press_event",
163 G_CALLBACK(config_key_buttonpress), NULL );
164 snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
165 g_object_set_data( G_OBJECT(text2), "keypress_mode", GINT_TO_POINTER(FALSE) );
166 g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text2 );
167 gtk_table_attach_defaults( GTK_TABLE(table), text2, x+2, x+3, y, y+1);
168 focus_chain = g_list_append( focus_chain, text2 );
169 if( conf[i].value != NULL ) {
170 gchar **parts = g_strsplit(conf[i].value,",",3);
171 if( parts[0] != NULL ) {
172 gtk_entry_set_text( GTK_ENTRY(text), g_strstrip(parts[0]) );
173 if( parts[1] != NULL ) {
174 gtk_entry_set_text( GTK_ENTRY(text2), g_strstrip(parts[1]) );
175 }
176 }
177 g_strfreev(parts);
178 }
179 }
180 gtk_container_set_focus_chain( GTK_CONTAINER(table), focus_chain );
181 gtk_gui_run_property_dialog( "Controller Configuration", table, controller_config_done );
182 }
185 gboolean maple_properties_activated( GtkButton *button, gpointer user_data )
186 {
187 maple_slot_data_t data = (maple_slot_data_t)user_data;
188 if( data->new_device != NULL ) {
189 int i;
190 for( i=0; maple_device_config[i].name != NULL; i++ ) {
191 if( strcmp(data->new_device->device_class->name, maple_device_config[i].name) == 0 ) {
192 if( data->new_device == data->old_device ) {
193 // Make a copy at this point if we haven't already
194 data->new_device = data->old_device->clone(data->old_device);
195 }
196 maple_device_config[i].config_func(data->new_device);
197 break;
198 }
199 }
200 if( maple_device_config[i].name == NULL ) {
201 gui_error_dialog( "No configuration page available for device type" );
202 }
203 }
204 return TRUE;
205 }
207 gboolean maple_device_changed( GtkComboBox *combo, gpointer user_data )
208 {
209 maple_slot_data_t data = (maple_slot_data_t)user_data;
210 int active = gtk_combo_box_get_active(combo);
211 gtk_widget_set_sensitive(data->button, active != 0);
212 if( active != 0 ) {
213 gchar *devname = gtk_combo_box_get_active_text(combo);
214 const maple_device_class_t devclz = maple_get_device_class(devname);
215 assert(devclz != NULL);
216 if( data->new_device != NULL ) {
217 if( data->new_device->device_class != devclz ) {
218 data->new_device->destroy(data->new_device);
219 data->new_device = maple_new_device(devname);
220 }
221 } else {
222 data->new_device = maple_new_device(devname);
223 }
224 } else {
225 if( data->new_device != NULL && data->new_device != data->old_device ) {
226 data->new_device->destroy(data->new_device);
227 }
228 data->new_device = NULL;
229 }
230 return TRUE;
231 }
233 void maple_dialog_done( GtkWidget *panel, gboolean isOK )
234 {
235 if( isOK ) {
236 int i;
237 for( i=0; i<MAX_DEVICES; i++ ) {
238 if( maple_data[i].new_device != maple_data[i].old_device ) {
239 if( maple_data[i].old_device != NULL ) {
240 maple_detach_device(i,0);
241 }
242 if( maple_data[i].new_device != NULL ) {
243 maple_attach_device(maple_data[i].new_device, i, 0 );
244 }
245 }
246 }
247 lxdream_save_config();
248 } else {
249 int i;
250 for( i=0; i<MAX_DEVICES; i++ ) {
251 if( maple_data[i].new_device != NULL &&
252 maple_data[i].new_device != maple_data[i].old_device ) {
253 maple_data[i].new_device->destroy(maple_data[i].new_device);
254 }
255 }
256 }
258 }
260 GtkWidget *maple_panel_new()
261 {
262 GtkWidget *table = gtk_table_new(4, 3, TRUE);
263 GtkTreeIter iter;
264 int i,j;
265 const struct maple_device_class **devices = maple_get_device_classes();
267 for( i=0; i< MAX_DEVICES; i++ ) {
268 char buf[12];
269 GtkWidget *combo, *button;
270 int active = 0;
271 maple_device_t device = maple_get_device(i,0);
272 sprintf( buf, "Slot %d.", i );
273 gtk_table_attach_defaults( GTK_TABLE(table), gtk_label_new(buf), 0, 1, i, i+1 );
274 combo = gtk_combo_box_new_text();
275 gtk_combo_box_append_text( GTK_COMBO_BOX(combo), "<empty>" );
276 for( j=0; devices[j] != NULL; j++ ) {
277 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), devices[j]->name);
278 if( device != NULL && device->device_class == devices[j] ) {
279 active = j+1;
280 }
281 }
282 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), active);
283 gtk_table_attach_defaults( GTK_TABLE(table), combo, 1, 2, i, i+1 );
284 button = gtk_button_new_from_stock( GTK_STOCK_PROPERTIES );
285 gtk_widget_set_sensitive(button, active != 0);
286 gtk_table_attach_defaults( GTK_TABLE(table), button, 2, 3, i, i+1 );
288 maple_data[i].old_device = device;
289 maple_data[i].new_device = device;
290 maple_data[i].combo = combo;
291 maple_data[i].button = button;
292 g_signal_connect( button, "clicked",
293 G_CALLBACK( maple_properties_activated ), &maple_data[i] );
294 g_signal_connect( combo, "changed",
295 G_CALLBACK( maple_device_changed ), &maple_data[i] );
297 }
298 return table;
299 }
301 void maple_dialog_run( )
302 {
303 gtk_gui_run_property_dialog( "Controller Settings", maple_panel_new(), maple_dialog_done );
304 }
.