Search
lxdream.org :: lxdream/src/gtkui/gtk_ctrl.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/gtkui/gtk_ctrl.c
changeset 763:b3ce4448f200
prev736:a02d1475ccfd
next764:44f5670ada62
author nkeynes
date Tue Jul 22 04:40:55 2008 +0000 (12 years ago)
permissions -rw-r--r--
last change Rename GTK UI files to follow the same scheme as the cocoa ones
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/gtkui/gtk_ctrl.c Tue Jul 22 04:40:55 2008 +0000
1.3 @@ -0,0 +1,318 @@
1.4 +/**
1.5 + * $Id$
1.6 + *
1.7 + * Define the main (emu) GTK window, along with its menubars,
1.8 + * toolbars, etc.
1.9 + *
1.10 + * Copyright (c) 2005 Nathan Keynes.
1.11 + *
1.12 + * This program is free software; you can redistribute it and/or modify
1.13 + * it under the terms of the GNU General Public License as published by
1.14 + * the Free Software Foundation; either version 2 of the License, or
1.15 + * (at your option) any later version.
1.16 + *
1.17 + * This program is distributed in the hope that it will be useful,
1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.20 + * GNU General Public License for more details.
1.21 + */
1.22 +
1.23 +#include <assert.h>
1.24 +#include <string.h>
1.25 +#include <gtk/gtk.h>
1.26 +#include <gdk/gdkkeysyms.h>
1.27 +
1.28 +#include "lxdream.h"
1.29 +#include "display.h"
1.30 +#include "gtkui/gtkui.h"
1.31 +#include "maple/maple.h"
1.32 +
1.33 +#define MAX_DEVICES 4
1.34 +
1.35 +static void controller_device_configure(maple_device_t device);
1.36 +
1.37 +struct maple_config_class {
1.38 + const char *name;
1.39 + void (*config_func)(maple_device_t device);
1.40 +};
1.41 +
1.42 +typedef struct maple_slot_data {
1.43 + maple_device_t old_device;
1.44 + maple_device_t new_device;
1.45 + GtkWidget *button;
1.46 + GtkWidget *combo;
1.47 +} *maple_slot_data_t;
1.48 +
1.49 +static struct maple_config_class maple_device_config[] = {
1.50 + { "Sega Controller", controller_device_configure },
1.51 + { NULL, NULL } };
1.52 +
1.53 +static struct maple_slot_data maple_data[MAX_DEVICES];
1.54 +
1.55 +static void config_keysym_hook( void *data, const gchar *keysym )
1.56 +{
1.57 + GtkWidget *widget = (GtkWidget *)data;
1.58 + gtk_entry_set_text( GTK_ENTRY(widget), keysym );
1.59 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
1.60 + input_set_keysym_hook(NULL, NULL);
1.61 +}
1.62 +
1.63 +static gboolean config_key_buttonpress( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
1.64 +{
1.65 + gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
1.66 + if( !keypress_mode ) {
1.67 + gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
1.68 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
1.69 + input_set_keysym_hook(config_keysym_hook, widget);
1.70 + }
1.71 + return FALSE;
1.72 +}
1.73 +
1.74 +static gboolean config_key_keypress( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
1.75 +{
1.76 + gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
1.77 + if( keypress_mode ) {
1.78 + if( event->keyval == GDK_Escape ) {
1.79 + gtk_entry_set_text( GTK_ENTRY(widget), "" );
1.80 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
1.81 + return TRUE;
1.82 + }
1.83 + GdkKeymap *keymap = gdk_keymap_get_default();
1.84 + guint keyval;
1.85 +
1.86 + gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
1.87 + NULL, NULL, NULL );
1.88 + gtk_entry_set_text( GTK_ENTRY(widget), gdk_keyval_name(keyval) );
1.89 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
1.90 + input_set_keysym_hook(NULL, NULL);
1.91 + return TRUE;
1.92 + } else {
1.93 + switch( event->keyval ) {
1.94 + case GDK_Return:
1.95 + case GDK_KP_Enter:
1.96 + gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
1.97 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
1.98 + input_set_keysym_hook(config_keysym_hook, widget);
1.99 + return TRUE;
1.100 + case GDK_BackSpace:
1.101 + case GDK_Delete:
1.102 + gtk_entry_set_text( GTK_ENTRY(widget), "" );
1.103 + return TRUE;
1.104 + }
1.105 + return FALSE;
1.106 + }
1.107 +
1.108 +}
1.109 +
1.110 +static void controller_config_done( GtkWidget *panel, gboolean isOK )
1.111 +{
1.112 + if( isOK ) {
1.113 + maple_device_t device = (maple_device_t)gtk_object_get_data( GTK_OBJECT(panel), "maple_device" );
1.114 + lxdream_config_entry_t conf = device->get_config(device);
1.115 + int i;
1.116 + for( i=0; conf[i].key != NULL; i++ ) {
1.117 + char buf[64];
1.118 + GtkWidget *entry1, *entry2;
1.119 + const gchar *key1, *key2;
1.120 + snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
1.121 + entry1 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
1.122 + key1 = gtk_entry_get_text(GTK_ENTRY(entry1));
1.123 + snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
1.124 + entry2 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
1.125 + key2 = gtk_entry_get_text(GTK_ENTRY(entry2));
1.126 + if( key1 == NULL || key1[0] == '\0') {
1.127 + lxdream_set_config_value( &conf[i], key2 );
1.128 + } else if( key2 == NULL || key2[0] == '\0') {
1.129 + lxdream_set_config_value( &conf[i], key1 );
1.130 + } else {
1.131 + char buf[64];
1.132 + snprintf( buf, sizeof(buf), "%s, %s", key1, key2 );
1.133 + lxdream_set_config_value( &conf[i], buf );
1.134 + }
1.135 + }
1.136 + }
1.137 + input_set_keysym_hook(NULL, NULL);
1.138 +}
1.139 +
1.140 +static void controller_device_configure( maple_device_t device )
1.141 +{
1.142 + lxdream_config_entry_t conf = device->get_config(device);
1.143 + int count, i;
1.144 + for( count=0; conf[count].key != NULL; count++ );
1.145 +
1.146 + GtkWidget *table = gtk_table_new( (count+1)>>1, 6, FALSE );
1.147 + GList *focus_chain = NULL;
1.148 + gtk_object_set_data( GTK_OBJECT(table), "maple_device", device );
1.149 + for( i=0; i<count; i++ ) {
1.150 + GtkWidget *text, *text2;
1.151 + char buf[64];
1.152 + int x=0;
1.153 + int y=i;
1.154 + if( i >= (count+1)>>1 ) {
1.155 + x = 3;
1.156 + y -= (count+1)>>1;
1.157 + }
1.158 + gtk_table_attach( GTK_TABLE(table), gtk_label_new(conf[i].key), x, x+1, y, y+1,
1.159 + GTK_SHRINK, GTK_SHRINK, 0, 0 );
1.160 + text = gtk_entry_new();
1.161 + gtk_entry_set_width_chars( GTK_ENTRY(text), 11 );
1.162 + gtk_entry_set_editable( GTK_ENTRY(text), FALSE );
1.163 + g_signal_connect( text, "key_press_event",
1.164 + G_CALLBACK(config_key_keypress), NULL );
1.165 + g_signal_connect( text, "button_press_event",
1.166 + G_CALLBACK(config_key_buttonpress), NULL );
1.167 + snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
1.168 + g_object_set_data( G_OBJECT(text), "keypress_mode", GINT_TO_POINTER(FALSE) );
1.169 + g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text );
1.170 + gtk_table_attach_defaults( GTK_TABLE(table), text, x+1, x+2, y, y+1);
1.171 + focus_chain = g_list_append( focus_chain, text );
1.172 + text2 = gtk_entry_new();
1.173 + gtk_entry_set_width_chars( GTK_ENTRY(text2), 11 );
1.174 + gtk_entry_set_editable( GTK_ENTRY(text2), FALSE );
1.175 + g_signal_connect( text2, "key_press_event",
1.176 + G_CALLBACK(config_key_keypress), NULL );
1.177 + g_signal_connect( text2, "button_press_event",
1.178 + G_CALLBACK(config_key_buttonpress), NULL );
1.179 + snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
1.180 + g_object_set_data( G_OBJECT(text2), "keypress_mode", GINT_TO_POINTER(FALSE) );
1.181 + g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text2 );
1.182 + gtk_table_attach_defaults( GTK_TABLE(table), text2, x+2, x+3, y, y+1);
1.183 + focus_chain = g_list_append( focus_chain, text2 );
1.184 + if( conf[i].value != NULL ) {
1.185 + gchar **parts = g_strsplit(conf[i].value,",",3);
1.186 + if( parts[0] != NULL ) {
1.187 + gtk_entry_set_text( GTK_ENTRY(text), g_strstrip(parts[0]) );
1.188 + if( parts[1] != NULL ) {
1.189 + gtk_entry_set_text( GTK_ENTRY(text2), g_strstrip(parts[1]) );
1.190 + }
1.191 + }
1.192 + g_strfreev(parts);
1.193 + }
1.194 + }
1.195 + gtk_container_set_focus_chain( GTK_CONTAINER(table), focus_chain );
1.196 + gtk_gui_run_property_dialog( _("Controller Configuration"), table, controller_config_done );
1.197 +}
1.198 +
1.199 +gboolean maple_properties_activated( GtkButton *button, gpointer user_data )
1.200 +{
1.201 + maple_slot_data_t data = (maple_slot_data_t)user_data;
1.202 + if( data->new_device != NULL ) {
1.203 + int i;
1.204 + for( i=0; maple_device_config[i].name != NULL; i++ ) {
1.205 + if( strcmp(data->new_device->device_class->name, maple_device_config[i].name) == 0 ) {
1.206 + if( data->new_device == data->old_device ) {
1.207 + // Make a copy at this point if we haven't already
1.208 + data->new_device = data->old_device->clone(data->old_device);
1.209 + }
1.210 + maple_device_config[i].config_func(data->new_device);
1.211 + break;
1.212 + }
1.213 + }
1.214 + if( maple_device_config[i].name == NULL ) {
1.215 + gui_error_dialog( _("No configuration page available for device type") );
1.216 + }
1.217 + }
1.218 + return TRUE;
1.219 +}
1.220 +
1.221 +gboolean maple_device_changed( GtkComboBox *combo, gpointer user_data )
1.222 +{
1.223 + maple_slot_data_t data = (maple_slot_data_t)user_data;
1.224 + int active = gtk_combo_box_get_active(combo);
1.225 + gboolean has_config = FALSE;
1.226 + if( active != 0 ) {
1.227 + gchar *devname = gtk_combo_box_get_active_text(combo);
1.228 + const maple_device_class_t devclz = maple_get_device_class(devname);
1.229 + assert(devclz != NULL);
1.230 + if( data->new_device != NULL ) {
1.231 + if( data->new_device->device_class != devclz ) {
1.232 + if( data->new_device != data->old_device ) {
1.233 + data->new_device->destroy(data->new_device);
1.234 + }
1.235 + data->new_device = maple_new_device(devname);
1.236 + }
1.237 + } else {
1.238 + data->new_device = maple_new_device(devname);
1.239 + }
1.240 + has_config = data->new_device != NULL && data->new_device->get_config != NULL;
1.241 + } else {
1.242 + if( data->new_device != NULL && data->new_device != data->old_device ) {
1.243 + data->new_device->destroy(data->new_device);
1.244 + }
1.245 + data->new_device = NULL;
1.246 + }
1.247 + gtk_widget_set_sensitive(data->button, has_config);
1.248 + return TRUE;
1.249 +}
1.250 +
1.251 +void maple_dialog_done( GtkWidget *panel, gboolean isOK )
1.252 +{
1.253 + if( isOK ) {
1.254 + int i;
1.255 + for( i=0; i<MAX_DEVICES; i++ ) {
1.256 + if( maple_data[i].new_device != maple_data[i].old_device ) {
1.257 + if( maple_data[i].old_device != NULL ) {
1.258 + maple_detach_device(i,0);
1.259 + }
1.260 + if( maple_data[i].new_device != NULL ) {
1.261 + maple_attach_device(maple_data[i].new_device, i, 0 );
1.262 + }
1.263 + }
1.264 + }
1.265 + lxdream_save_config();
1.266 + } else {
1.267 + int i;
1.268 + for( i=0; i<MAX_DEVICES; i++ ) {
1.269 + if( maple_data[i].new_device != NULL &&
1.270 + maple_data[i].new_device != maple_data[i].old_device ) {
1.271 + maple_data[i].new_device->destroy(maple_data[i].new_device);
1.272 + }
1.273 + }
1.274 + }
1.275 +
1.276 +}
1.277 +
1.278 +GtkWidget *maple_panel_new()
1.279 +{
1.280 + GtkWidget *table = gtk_table_new(4, 3, TRUE);
1.281 + int i,j;
1.282 + const struct maple_device_class **devices = maple_get_device_classes();
1.283 +
1.284 + for( i=0; i< MAX_DEVICES; i++ ) {
1.285 + char buf[12];
1.286 + GtkWidget *combo, *button;
1.287 + int active = 0;
1.288 + maple_device_t device = maple_get_device(i,0);
1.289 + sprintf( buf, _("Slot %d."), i );
1.290 + gtk_table_attach_defaults( GTK_TABLE(table), gtk_label_new(buf), 0, 1, i, i+1 );
1.291 + combo = gtk_combo_box_new_text();
1.292 + gtk_combo_box_append_text( GTK_COMBO_BOX(combo), _("<empty>") );
1.293 + for( j=0; devices[j] != NULL; j++ ) {
1.294 + gtk_combo_box_append_text(GTK_COMBO_BOX(combo), devices[j]->name);
1.295 + if( device != NULL && device->device_class == devices[j] ) {
1.296 + active = j+1;
1.297 + }
1.298 + }
1.299 + gtk_combo_box_set_active(GTK_COMBO_BOX(combo), active);
1.300 + gtk_table_attach_defaults( GTK_TABLE(table), combo, 1, 2, i, i+1 );
1.301 + button = gtk_button_new_from_stock( GTK_STOCK_PROPERTIES );
1.302 + gtk_widget_set_sensitive(button, active != 0 && device->get_config != NULL);
1.303 + gtk_table_attach_defaults( GTK_TABLE(table), button, 2, 3, i, i+1 );
1.304 +
1.305 + maple_data[i].old_device = device;
1.306 + maple_data[i].new_device = device;
1.307 + maple_data[i].combo = combo;
1.308 + maple_data[i].button = button;
1.309 + g_signal_connect( button, "clicked",
1.310 + G_CALLBACK( maple_properties_activated ), &maple_data[i] );
1.311 + g_signal_connect( combo, "changed",
1.312 + G_CALLBACK( maple_device_changed ), &maple_data[i] );
1.313 +
1.314 + }
1.315 + return table;
1.316 +}
1.317 +
1.318 +void maple_dialog_run( )
1.319 +{
1.320 + gtk_gui_run_property_dialog( _("Controller Settings"), maple_panel_new(), maple_dialog_done );
1.321 +}
.