filename | src/gtkui/ctrl_dlg.c |
changeset | 616:527ab167712b |
prev | 614:a2d239d4438a |
next | 628:bd46e2c4c479 |
author | nkeynes |
date | Thu Feb 14 13:54:11 2008 +0000 (16 years ago) |
branch | lxdream-render |
permissions | -rw-r--r-- |
last change | Commit render work in progress. Main changes: * Preliminary OSMesa support * Move the generic gl code out to pvr2/ * Implement scene data structure + reader * Remove the 1/z adjustments |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
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 "lxdream.h"
25 #include "display.h"
26 #include "gtkui/gtkui.h"
27 #include "maple/maple.h"
29 #define MAX_DEVICES 4
31 static void controller_device_configure(maple_device_t device);
33 struct maple_config_class {
34 const char *name;
35 void (*config_func)(maple_device_t device);
36 };
38 typedef struct maple_slot_data {
39 maple_device_t old_device;
40 maple_device_t new_device;
41 GtkWidget *button;
42 GtkWidget *combo;
43 } *maple_slot_data_t;
45 static struct maple_config_class maple_device_config[] = {
46 { "Sega Controller", controller_device_configure },
47 { NULL, NULL } };
49 static struct maple_slot_data maple_data[MAX_DEVICES];
51 static void config_keysym_hook( void *data, const gchar *keysym )
52 {
53 GtkWidget *widget = (GtkWidget *)data;
54 gtk_entry_set_text( GTK_ENTRY(widget), keysym );
55 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
56 input_set_keysym_hook(NULL, NULL);
57 }
59 static gboolean config_key_buttonpress( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
60 {
61 gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
62 if( !keypress_mode ) {
63 gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
64 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
65 input_set_keysym_hook(config_keysym_hook, widget);
66 }
67 return FALSE;
68 }
70 static gboolean config_key_keypress( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
71 {
72 gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
73 if( keypress_mode ) {
74 if( event->keyval == GDK_Escape ) {
75 gtk_entry_set_text( GTK_ENTRY(widget), "" );
76 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
77 return TRUE;
78 }
79 GdkKeymap *keymap = gdk_keymap_get_default();
80 guint keyval;
82 gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
83 NULL, NULL, NULL );
84 gtk_entry_set_text( GTK_ENTRY(widget), gdk_keyval_name(keyval) );
85 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
86 input_set_keysym_hook(NULL, NULL);
87 return TRUE;
88 } else {
89 switch( event->keyval ) {
90 case GDK_Return:
91 case GDK_KP_Enter:
92 gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
93 g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
94 input_set_keysym_hook(config_keysym_hook, widget);
95 return TRUE;
96 case GDK_BackSpace:
97 case GDK_Delete:
98 gtk_entry_set_text( GTK_ENTRY(widget), "" );
99 return TRUE;
100 }
101 return FALSE;
102 }
104 }
106 static void controller_config_done( GtkWidget *panel, gboolean isOK )
107 {
108 if( isOK ) {
109 maple_device_t device = (maple_device_t)gtk_object_get_data( GTK_OBJECT(panel), "maple_device" );
110 lxdream_config_entry_t conf = device->get_config(device);
111 int i;
112 for( i=0; conf[i].key != NULL; i++ ) {
113 char buf[64];
114 GtkWidget *entry1, *entry2;
115 const gchar *key1, *key2;
116 snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
117 entry1 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
118 key1 = gtk_entry_get_text(GTK_ENTRY(entry1));
119 snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
120 entry2 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
121 key2 = gtk_entry_get_text(GTK_ENTRY(entry2));
122 if( key1 == NULL || key1[0] == '\0') {
123 lxdream_set_config_value( &conf[i], key2 );
124 } else if( key2 == NULL || key2[0] == '\0') {
125 lxdream_set_config_value( &conf[i], key1 );
126 } else {
127 char buf[64];
128 snprintf( buf, sizeof(buf), "%s, %s", key1, key2 );
129 lxdream_set_config_value( &conf[i], buf );
130 }
131 }
132 }
133 input_set_keysym_hook(NULL, NULL);
134 }
136 static void controller_device_configure( maple_device_t device )
137 {
138 lxdream_config_entry_t conf = device->get_config(device);
139 int count, i;
140 for( count=0; conf[count].key != NULL; count++ );
142 GtkWidget *table = gtk_table_new( (count+1)>>1, 6, FALSE );
143 GList *focus_chain = NULL;
144 gtk_object_set_data( GTK_OBJECT(table), "maple_device", device );
145 for( i=0; i<count; i++ ) {
146 GtkWidget *text, *text2;
147 char buf[64];
148 int x=0;
149 int y=i;
150 if( i >= (count+1)>>1 ) {
151 x = 3;
152 y -= (count+1)>>1;
153 }
154 gtk_table_attach( GTK_TABLE(table), gtk_label_new(conf[i].key), x, x+1, y, y+1,
155 GTK_SHRINK, GTK_SHRINK, 0, 0 );
156 text = gtk_entry_new();
157 gtk_entry_set_width_chars( GTK_ENTRY(text), 11 );
158 gtk_entry_set_editable( GTK_ENTRY(text), FALSE );
159 g_signal_connect( text, "key_press_event",
160 G_CALLBACK(config_key_keypress), NULL );
161 g_signal_connect( text, "button_press_event",
162 G_CALLBACK(config_key_buttonpress), NULL );
163 snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
164 g_object_set_data( G_OBJECT(text), "keypress_mode", GINT_TO_POINTER(FALSE) );
165 g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text );
166 gtk_table_attach_defaults( GTK_TABLE(table), text, x+1, x+2, y, y+1);
167 focus_chain = g_list_append( focus_chain, text );
168 text2 = gtk_entry_new();
169 gtk_entry_set_width_chars( GTK_ENTRY(text2), 11 );
170 gtk_entry_set_editable( GTK_ENTRY(text2), FALSE );
171 g_signal_connect( text2, "key_press_event",
172 G_CALLBACK(config_key_keypress), NULL );
173 g_signal_connect( text2, "button_press_event",
174 G_CALLBACK(config_key_buttonpress), NULL );
175 snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
176 g_object_set_data( G_OBJECT(text2), "keypress_mode", GINT_TO_POINTER(FALSE) );
177 g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text2 );
178 gtk_table_attach_defaults( GTK_TABLE(table), text2, x+2, x+3, y, y+1);
179 focus_chain = g_list_append( focus_chain, text2 );
180 if( conf[i].value != NULL ) {
181 gchar **parts = g_strsplit(conf[i].value,",",3);
182 if( parts[0] != NULL ) {
183 gtk_entry_set_text( GTK_ENTRY(text), g_strstrip(parts[0]) );
184 if( parts[1] != NULL ) {
185 gtk_entry_set_text( GTK_ENTRY(text2), g_strstrip(parts[1]) );
186 }
187 }
188 g_strfreev(parts);
189 }
190 }
191 gtk_container_set_focus_chain( GTK_CONTAINER(table), focus_chain );
192 gtk_gui_run_property_dialog( _("Controller Configuration"), table, controller_config_done );
193 }
195 gboolean maple_properties_activated( GtkButton *button, gpointer user_data )
196 {
197 maple_slot_data_t data = (maple_slot_data_t)user_data;
198 if( data->new_device != NULL ) {
199 int i;
200 for( i=0; maple_device_config[i].name != NULL; i++ ) {
201 if( strcmp(data->new_device->device_class->name, maple_device_config[i].name) == 0 ) {
202 if( data->new_device == data->old_device ) {
203 // Make a copy at this point if we haven't already
204 data->new_device = data->old_device->clone(data->old_device);
205 }
206 maple_device_config[i].config_func(data->new_device);
207 break;
208 }
209 }
210 if( maple_device_config[i].name == NULL ) {
211 gui_error_dialog( _("No configuration page available for device type") );
212 }
213 }
214 return TRUE;
215 }
217 gboolean maple_device_changed( GtkComboBox *combo, gpointer user_data )
218 {
219 maple_slot_data_t data = (maple_slot_data_t)user_data;
220 int active = gtk_combo_box_get_active(combo);
221 gboolean has_config = FALSE;
222 if( active != 0 ) {
223 gchar *devname = gtk_combo_box_get_active_text(combo);
224 const maple_device_class_t devclz = maple_get_device_class(devname);
225 assert(devclz != NULL);
226 if( data->new_device != NULL ) {
227 if( data->new_device->device_class != devclz ) {
228 data->new_device->destroy(data->new_device);
229 data->new_device = maple_new_device(devname);
230 }
231 } else {
232 data->new_device = maple_new_device(devname);
233 }
234 has_config = data->new_device != NULL && data->new_device->get_config != NULL;
235 } else {
236 if( data->new_device != NULL && data->new_device != data->old_device ) {
237 data->new_device->destroy(data->new_device);
238 }
239 data->new_device = NULL;
240 }
241 gtk_widget_set_sensitive(data->button, has_config);
242 return TRUE;
243 }
245 void maple_dialog_done( GtkWidget *panel, gboolean isOK )
246 {
247 if( isOK ) {
248 int i;
249 for( i=0; i<MAX_DEVICES; i++ ) {
250 if( maple_data[i].new_device != maple_data[i].old_device ) {
251 if( maple_data[i].old_device != NULL ) {
252 maple_detach_device(i,0);
253 }
254 if( maple_data[i].new_device != NULL ) {
255 maple_attach_device(maple_data[i].new_device, i, 0 );
256 }
257 }
258 }
259 lxdream_save_config();
260 } else {
261 int i;
262 for( i=0; i<MAX_DEVICES; i++ ) {
263 if( maple_data[i].new_device != NULL &&
264 maple_data[i].new_device != maple_data[i].old_device ) {
265 maple_data[i].new_device->destroy(maple_data[i].new_device);
266 }
267 }
268 }
270 }
272 GtkWidget *maple_panel_new()
273 {
274 GtkWidget *table = gtk_table_new(4, 3, TRUE);
275 int i,j;
276 const struct maple_device_class **devices = maple_get_device_classes();
278 for( i=0; i< MAX_DEVICES; i++ ) {
279 char buf[12];
280 GtkWidget *combo, *button;
281 int active = 0;
282 maple_device_t device = maple_get_device(i,0);
283 sprintf( buf, _("Slot %d."), i );
284 gtk_table_attach_defaults( GTK_TABLE(table), gtk_label_new(buf), 0, 1, i, i+1 );
285 combo = gtk_combo_box_new_text();
286 gtk_combo_box_append_text( GTK_COMBO_BOX(combo), _("<empty>") );
287 for( j=0; devices[j] != NULL; j++ ) {
288 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), devices[j]->name);
289 if( device != NULL && device->device_class == devices[j] ) {
290 active = j+1;
291 }
292 }
293 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), active);
294 gtk_table_attach_defaults( GTK_TABLE(table), combo, 1, 2, i, i+1 );
295 button = gtk_button_new_from_stock( GTK_STOCK_PROPERTIES );
296 gtk_widget_set_sensitive(button, active != 0 && device->get_config != NULL);
297 gtk_table_attach_defaults( GTK_TABLE(table), button, 2, 3, i, i+1 );
299 maple_data[i].old_device = device;
300 maple_data[i].new_device = device;
301 maple_data[i].combo = combo;
302 maple_data[i].button = button;
303 g_signal_connect( button, "clicked",
304 G_CALLBACK( maple_properties_activated ), &maple_data[i] );
305 g_signal_connect( combo, "changed",
306 G_CALLBACK( maple_device_changed ), &maple_data[i] );
308 }
309 return table;
310 }
312 void maple_dialog_run( )
313 {
314 gtk_gui_run_property_dialog( _("Controller Settings"), maple_panel_new(), maple_dialog_done );
315 }
.