revision 770:429ff505c450
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 770:429ff505c450 |
parent | 769:f7f62bea4cad |
child | 771:749f0f4575d2 |
author | nkeynes |
date | Mon Jul 28 03:41:25 2008 +0000 (15 years ago) |
Implement key-binding configuration pane for Cocoa UI
Minor tweaks for consistency and static-correctness
Minor tweaks for consistency and static-correctness
1.1 --- a/src/cocoaui/cocoa_ctrl.c Mon Jul 28 00:27:32 2008 +00001.2 +++ b/src/cocoaui/cocoa_ctrl.c Mon Jul 28 03:41:25 2008 +00001.3 @@ -18,10 +18,254 @@1.5 #include "cocoaui.h"1.6 #include "config.h"1.7 +#include "display.h"1.8 #include "maple/maple.h"1.10 +#include <glib/gstrfuncs.h>1.11 +1.12 #define MAX_DEVICES 41.14 +static void cocoa_config_keysym_hook(void *data, const gchar *keysym);1.15 +1.16 +@interface KeyBindingEditor (Private)1.17 +- (void)updateKeysym: (const gchar *)sym;1.18 +@end1.19 +1.20 +@implementation KeyBindingEditor1.21 +- (id)init1.22 +{1.23 + self = [super init];1.24 + isPrimed = NO;1.25 + lastValue = nil;1.26 + [self setFieldEditor: YES];1.27 + [self setEditable: FALSE];1.28 + return self;1.29 +}1.30 +- (void)dealloc1.31 +{1.32 + if( lastValue != nil ) {1.33 + [lastValue release];1.34 + lastValue = nil;1.35 + }1.36 + [super dealloc];1.37 +}1.38 +- (void)setPrimed: (BOOL)primed1.39 +{1.40 + if( primed != isPrimed ) {1.41 + isPrimed = primed;1.42 + if( primed ) {1.43 + lastValue = [[NSString stringWithString: [self string]] retain];1.44 + [self setString: @"<press key>"];1.45 + input_set_keysym_hook(cocoa_config_keysym_hook, self);1.46 + } else {1.47 + [lastValue release];1.48 + lastValue = nil;1.49 + input_set_keysym_hook(NULL,NULL);1.50 + }1.51 + }1.52 +}1.53 +- (void)fireBindingChanged1.54 +{1.55 + id delegate = [self delegate];1.56 + if( delegate != nil && [delegate respondsToSelector:@selector(textDidChange:)] ) {1.57 + [delegate textDidChange: [NSNotification notificationWithName: NSTextDidChangeNotification object: self]];1.58 + }1.59 +}1.60 +1.61 +- (void)updateKeysym: (const gchar *)sym1.62 +{1.63 + if( sym != NULL ) {1.64 + [self setString: [NSString stringWithCString: sym]];1.65 + [self setPrimed: NO];1.66 + [self fireBindingChanged];1.67 + }1.68 +}1.69 +- (void)keyPressed: (int)keycode1.70 +{1.71 + gchar *keysym = input_keycode_to_keysym(NULL, keycode);1.72 + if( keysym != NULL ) {1.73 + [self updateKeysym: keysym];1.74 + g_free(keysym);1.75 + }1.76 +}1.77 +- (void)insertText:(id)string1.78 +{1.79 + // Do nothing1.80 +}1.81 +- (void)mouseDown: (NSEvent *)event1.82 +{1.83 + [self setPrimed: YES];1.84 + [super mouseDown: event];1.85 +}1.86 +- (void)keyDown: (NSEvent *) event1.87 +{1.88 + NSString *chars = [event characters];1.89 + if( isPrimed ) {1.90 + if( chars != NULL && [chars length] == 1 && [chars characterAtIndex: 0] == 27 ) {1.91 + // Escape char = abort change1.92 + [self setString: lastValue];1.93 + [self setPrimed: NO];1.94 + } else {1.95 + [self keyPressed: ([event keyCode]+1)];1.96 + }1.97 + } else {1.98 + if( chars != NULL && [chars length] == 1 ) {1.99 + int ch = [chars characterAtIndex: 0];1.100 + switch( ch ) {1.101 + case 0x7F:1.102 + [self setString: @""];1.103 + [self fireBindingChanged];1.104 + break;1.105 + case '\r':1.106 + [self setPrimed: YES];1.107 + break;1.108 + default:1.109 + [super keyDown: event];1.110 + break;1.111 + }1.112 + } else {1.113 + [super keyDown: event];1.114 + }1.115 + }1.116 +}1.117 +- (void)flagsChanged: (NSEvent *) event1.118 +{1.119 + if( isPrimed ) {1.120 + [self keyPressed: ([event keyCode]+1)];1.121 + }1.122 + [super flagsChanged: event];1.123 +}1.124 +@end1.125 +1.126 +static void cocoa_config_keysym_hook(void *data, const gchar *keysym)1.127 +{1.128 + KeyBindingEditor *editor = (KeyBindingEditor *)data;1.129 + [editor updateKeysym: keysym];1.130 +}1.131 +1.132 +1.133 +@implementation KeyBindingField1.134 +@end1.135 +1.136 +/*************************** Key-binding sub-view ***********************/1.137 +1.138 +#define MAX_KEY_BINDINGS 321.139 +1.140 +@interface ControllerKeyBindingView : NSView1.141 +{1.142 + maple_device_t device;1.143 + KeyBindingField *field[MAX_KEY_BINDINGS][2];1.144 +}1.145 +- (id)initWithFrame: (NSRect)frameRect;1.146 +- (void)setDevice: (maple_device_t)device;1.147 +@end1.148 +1.149 +@implementation ControllerKeyBindingView1.150 +- (id)initWithFrame: (NSRect)frameRect1.151 +{1.152 + if( [super initWithFrame: frameRect] == nil ) {1.153 + return nil;1.154 + } else {1.155 + device = NULL;1.156 + return self;1.157 + }1.158 +}1.159 +- (BOOL)isFlipped1.160 +{1.161 + return YES;1.162 +}1.163 +- (void)removeSubviews1.164 +{1.165 + [[self subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];1.166 +}1.167 +- (void)controlTextDidChange: (NSNotification *)notify1.168 +{1.169 + int binding = [[notify object] tag];1.170 + NSString *val1 = [field[binding][0] stringValue];1.171 + NSString *val2 = [field[binding][1] stringValue];1.172 + char buf[ [val1 length] + [val2 length] + 2 ];1.173 + const gchar *p = NULL;1.174 +1.175 + if( [val1 length] == 0 ) {1.176 + if( [val2 length] != 0 ) {1.177 + p = [val2 UTF8String];1.178 + }1.179 + } else if( [val2 length] == 0 ) {1.180 + p = [val1 UTF8String];1.181 + } else {1.182 + sprintf( buf, "%s,%s", [val1 UTF8String], [val2 UTF8String] );1.183 + p = buf;1.184 + }1.185 + maple_set_device_config_value( device, binding, p );1.186 + lxdream_save_config();1.187 +}1.188 +- (void)setDevice: (maple_device_t)newDevice1.189 +{1.190 + device = newDevice;1.191 + [self removeSubviews];1.192 + if( device != NULL ) {1.193 + lxdream_config_entry_t config = maple_get_device_config(device);1.194 + if( config != NULL ) {1.195 + int count, i, y, x;1.196 +1.197 + for( count=0; config[count].key != NULL; count++ );1.198 + x = TEXT_GAP;1.199 + NSSize size = NSMakeSize(85*3+TEXT_GAP*4, count*(TEXT_HEIGHT+TEXT_GAP)+TEXT_GAP);1.200 + [self setFrameSize: size];1.201 + [self scrollRectToVisible: NSMakeRect(0,0,1,1)];1.202 + y = TEXT_GAP;1.203 + for( i=0; config[i].key != NULL; i++ ) {1.204 + NSRect frame = NSMakeRect(x, y + 2, 85, LABEL_HEIGHT);1.205 + NSTextField *label = cocoa_gui_add_label(self, NS_(config[i].label), frame);1.206 + [label setAlignment: NSRightTextAlignment];1.207 +1.208 + frame = NSMakeRect( x + 85 + TEXT_GAP, y, 85, TEXT_HEIGHT);1.209 + field[i][0] = [[KeyBindingField alloc] initWithFrame: frame];1.210 + [field[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];1.211 + [field[i][0] setTag: i];1.212 + [field[i][0] setDelegate: self];1.213 + [self addSubview: field[i][0]];1.214 +1.215 + frame = NSMakeRect( x + (85*2) + (TEXT_GAP*2), y, 85, TEXT_HEIGHT);1.216 + field[i][1] = [[KeyBindingField alloc] initWithFrame: frame];1.217 + [field[i][1] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];1.218 + [field[i][1] setTag: i];1.219 + [field[i][1] setDelegate: self];1.220 + [self addSubview: field[i][1]];1.221 +1.222 + if( config[i].value != NULL ) {1.223 + gchar **parts = g_strsplit(config[i].value,",",3);1.224 + if( parts[0] != NULL ) {1.225 + [field[i][0] setStringValue: [NSString stringWithCString: parts[0]]];1.226 + if( parts[1] != NULL ) {1.227 + [field[i][1] setStringValue: [NSString stringWithCString: parts[1]]];1.228 + }1.229 + }1.230 + g_strfreev(parts);1.231 + }1.232 +1.233 + y += (TEXT_HEIGHT + TEXT_GAP);1.234 + }1.235 + } else {1.236 + [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];1.237 + }1.238 + } else {1.239 + [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];1.240 + }1.241 +}1.242 +@end1.243 +1.244 +/*************************** Top-level controller pane ***********************/1.245 +1.246 +@interface LxdreamPrefsControllerPane: LxdreamPrefsPane1.247 +{1.248 + struct maple_device *save_controller[4];1.249 + NSButton *radio[4];1.250 + ControllerKeyBindingView *key_bindings;1.251 +}1.252 ++ (LxdreamPrefsControllerPane *)new;1.253 +@end1.254 +1.255 @implementation LxdreamPrefsControllerPane1.256 + (LxdreamPrefsControllerPane *)new1.257 {1.258 @@ -35,19 +279,46 @@1.259 const struct maple_device_class **devices = maple_get_device_classes();1.260 char buf[16];1.261 int i,j;1.262 - int height = [self contentHeight] - TEXT_HEIGHT - TEXT_GAP;1.263 + int y = [self contentHeight] - TEXT_HEIGHT - TEXT_GAP;1.264 +1.265 + NSBox *rule = [[NSBox alloc] initWithFrame:1.266 + NSMakeRect(210+(TEXT_GAP*3), 1, 1, [self contentHeight] + TEXT_GAP - 2)];1.267 + [rule setAutoresizingMask: (NSViewMaxXMargin|NSViewHeightSizable)];1.268 + [rule setBoxType: NSBoxSeparator];1.269 + [self addSubview: rule];1.270 +1.271 + NSRect bindingFrame = NSMakeRect(210+(TEXT_GAP*4), 0,1.272 + frameRect.size.width - (210+(TEXT_GAP*4)), [self contentHeight] + TEXT_GAP );1.273 + NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame: bindingFrame];1.274 + key_bindings = [[ControllerKeyBindingView alloc] initWithFrame: bindingFrame ];1.275 + [scrollView setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];1.276 + [scrollView setDocumentView: key_bindings];1.277 + [scrollView setDrawsBackground: NO];1.278 + [scrollView setHasVerticalScroller: YES];1.279 + [scrollView setAutohidesScrollers: YES];1.280 +1.281 + [self addSubview: scrollView];1.282 + [key_bindings setDevice: maple_get_device(0,0)];1.283 +1.284 for( i=0; i<MAX_DEVICES; i++ ) {1.285 + int x = TEXT_GAP;1.286 save_controller[i] = NULL;1.287 maple_device_t device = maple_get_device(i,0);1.288 - NSRect frame = NSMakeRect( TEXT_GAP, height -((TEXT_HEIGHT+TEXT_GAP)*i - 2),1.289 - 50, LABEL_HEIGHT );1.290 +1.291 snprintf( buf, sizeof(buf), _("Slot %d."), i );1.292 - NSTextField *label = [self addLabel: [NSString stringWithUTF8String: buf]1.293 - withFrame: frame ];1.294 - [label setAlignment: NSRightTextAlignment];1.295 - frame = NSMakeRect( 50 + (TEXT_GAP*2), height - ((TEXT_HEIGHT+TEXT_GAP)*i),1.296 - 150, TEXT_HEIGHT );1.297 - NSPopUpButton *popup = [[NSPopUpButton alloc] initWithFrame: frame pullsDown: NO];1.298 + radio[i] = [[NSButton alloc] initWithFrame: NSMakeRect( x, y, 60, TEXT_HEIGHT )];1.299 + [radio[i] setTitle: [NSString stringWithUTF8String: buf]];1.300 + [radio[i] setTag: i];1.301 + [radio[i] setButtonType: NSRadioButton];1.302 + [radio[i] setAlignment: NSRightTextAlignment];1.303 + [radio[i] setTarget: self];1.304 + [radio[i] setAction: @selector(radioChanged:)];1.305 + [radio[i] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];1.306 + [self addSubview: radio[i]];1.307 + x += 60 + TEXT_GAP;1.308 +1.309 + NSPopUpButton *popup = [[NSPopUpButton alloc] initWithFrame: NSMakeRect(x,y,150,TEXT_HEIGHT)1.310 + pullsDown: NO];1.311 [popup addItemWithTitle: NS_("<empty>")];1.312 [popup setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];1.313 [[popup itemAtIndex: 0] setTag: 0];1.314 @@ -62,16 +333,38 @@1.315 [popup setAction: @selector(deviceChanged:)];1.316 [popup setTag: i];1.317 [self addSubview: popup];1.318 + y -= (TEXT_HEIGHT+TEXT_GAP);1.319 }1.320 +1.321 + [radio[0] setState: NSOnState];1.322 return self;1.323 }1.324 }1.325 +- (void)radioChanged: (id)sender1.326 +{1.327 + int slot = [sender tag];1.328 + int i;1.329 + for( i=0; i<MAX_DEVICES; i++ ) {1.330 + if( i != slot ) {1.331 + [radio[i] setState: NSOffState];1.332 + }1.333 + }1.334 + [key_bindings setDevice: maple_get_device(slot,0)];1.335 +}1.336 - (void)deviceChanged: (id)sender1.337 {1.338 int slot = [sender tag];1.339 - int new_device_idx = [sender indexOfSelectedItem] - 1;1.340 + int new_device_idx = [sender indexOfSelectedItem] - 1, i;1.341 maple_device_class_t new_device_class = NULL;1.343 + for( i=0; i<MAX_DEVICES; i++ ) {1.344 + if( i == slot ) {1.345 + [radio[i] setState: NSOnState];1.346 + } else {1.347 + [radio[i] setState: NSOffState];1.348 + }1.349 + }1.350 +1.351 maple_device_t current = maple_get_device(slot,0);1.352 maple_device_t new_device = NULL;1.353 if( new_device_idx != -1 ) {1.354 @@ -79,6 +372,7 @@1.355 }1.356 if( current == NULL ? new_device_class == NULL : current->device_class == new_device_class ) {1.357 // No change1.358 + [key_bindings setDevice: current];1.359 return;1.360 }1.361 if( current != NULL && current->device_class == &controller_class ) {1.362 @@ -95,7 +389,12 @@1.363 }1.364 maple_attach_device(new_device,slot,0);1.365 }1.366 -1.367 + [key_bindings setDevice: maple_get_device(slot,0)];1.368 lxdream_save_config();1.369 }1.370 @end1.371 +1.372 +NSView *cocoa_gui_create_prefs_controller_pane()1.373 +{1.374 + return [LxdreamPrefsControllerPane new];1.375 +}
2.1 --- a/src/cocoaui/cocoa_path.c Mon Jul 28 00:27:32 2008 +00002.2 +++ b/src/cocoaui/cocoa_path.c Mon Jul 28 03:41:25 2008 +00002.3 @@ -19,7 +19,11 @@2.4 #include "cocoaui.h"2.5 #include "config.h"2.7 -2.8 +@interface LxdreamPrefsPathPane: LxdreamPrefsPane2.9 +{2.10 +}2.11 ++ (LxdreamPrefsPathPane *)new;2.12 +@end2.14 @implementation LxdreamPrefsPathPane2.15 + (LxdreamPrefsPathPane *)new2.16 @@ -39,7 +43,7 @@2.17 if( entry->label != NULL ) {2.18 NSRect frame = NSMakeRect( TEXT_GAP, height -((TEXT_HEIGHT+TEXT_GAP)*i - 2),2.19 150, LABEL_HEIGHT );2.20 - NSTextField *label = [self addLabel: NS_(entry->label) withFrame: frame];2.21 + NSTextField *label = cocoa_gui_add_label(self, NS_(entry->label), frame);2.22 [label setAlignment: NSRightTextAlignment];2.24 frame = NSMakeRect( 150 + (TEXT_GAP*2),2.25 @@ -70,3 +74,9 @@2.26 }2.27 }2.28 @end2.29 +2.30 +2.31 +NSView *cocoa_gui_create_prefs_path_pane()2.32 +{2.33 + return [LxdreamPrefsPathPane new];2.34 +}
3.1 --- a/src/cocoaui/cocoa_prefs.c Mon Jul 28 00:27:32 2008 +00003.2 +++ b/src/cocoaui/cocoa_prefs.c Mon Jul 28 03:41:25 2008 +00003.3 @@ -23,17 +23,6 @@3.4 static LxdreamPrefsPanel *prefs_panel = NULL;3.6 @implementation LxdreamPrefsPane3.7 -- (NSTextField *)addLabel: (NSString *)text withFrame: (NSRect)frame3.8 -{3.9 - NSTextField *label = [[NSTextField alloc] initWithFrame: frame];3.10 - [label setStringValue: text];3.11 - [label setBordered: NO];3.12 - [label setDrawsBackground: NO];3.13 - [label setEditable: NO];3.14 - [label setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];3.15 - [self addSubview: label];3.16 - return label;3.17 -}3.18 - (int)contentHeight3.19 {3.20 return [self frame].size.height - headerHeight;3.21 @@ -49,9 +38,9 @@3.22 NSFont *titleFont = [NSFont fontWithName: @"Helvetica-Bold" size: 16.0];3.23 NSRect fontRect = [titleFont boundingRectForFont];3.24 int titleHeight = fontRect.size.height + [titleFont descender];3.25 - NSTextField *label = [self addLabel: title withFrame:3.26 + NSTextField *label = cocoa_gui_add_label(self, title,3.27 NSMakeRect( TEXT_GAP, height-titleHeight,3.28 - frameRect.size.width - (TEXT_GAP*2), titleHeight )];3.29 + frameRect.size.width - (TEXT_GAP*2), titleHeight ));3.30 [label setFont: titleFont];3.31 height -= (titleHeight + TEXT_GAP);3.33 @@ -67,6 +56,7 @@3.34 }3.35 @end3.37 +/**************************** Main preferences window ************************/3.39 @interface LxdreamPrefsPanel (Private)3.40 - (void) initToolbar;3.41 @@ -93,18 +83,37 @@3.42 } else {3.43 [self setTitle: NS_("Preferences")];3.44 [self setDelegate: self];3.45 + [self setMinSize: NSMakeSize(400,300)];3.46 [self initToolbar];3.47 - path_pane = [LxdreamPrefsPathPane new];3.48 - ctrl_pane = [LxdreamPrefsControllerPane new];3.49 -3.50 + path_pane = cocoa_gui_create_prefs_path_pane();3.51 + ctrl_pane = cocoa_gui_create_prefs_controller_pane();3.52 + binding_editor = nil;3.53 [self setContentView: path_pane];3.54 return self;3.55 }3.56 }3.57 +- (void)dealloc3.58 +{3.59 + if( binding_editor != nil ) {3.60 + [binding_editor release];3.61 + binding_editor = nil;3.62 + }3.63 + [super dealloc];3.64 +}3.65 - (void)windowWillClose: (NSNotification *)notice3.66 {3.67 prefs_panel = NULL;3.68 }3.69 +- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)view3.70 +{3.71 + if( [view isKindOfClass: [KeyBindingField class]] ) {3.72 + if( binding_editor == nil ) {3.73 + binding_editor = [[[KeyBindingEditor alloc] init] retain];3.74 + }3.75 + return binding_editor;3.76 + }3.77 + return nil;3.78 +}3.79 - (void) initToolbar3.80 {3.81 NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier: @"LxdreamPrefsToolbar"];
4.1 --- a/src/cocoaui/cocoaui.c Mon Jul 28 00:27:32 2008 +00004.2 +++ b/src/cocoaui/cocoaui.c Mon Jul 28 03:41:25 2008 +00004.3 @@ -378,6 +378,8 @@4.4 modes: [NSArray arrayWithObject: NSDefaultRunLoopMode] ];4.5 }4.7 +/*************************** Convenience methods ***************************/4.8 +4.9 NSImage *NSImage_new_from_framebuffer( frame_buffer_t buffer )4.10 {4.11 NSBitmapImageRep *rep =4.12 @@ -392,3 +394,18 @@4.13 [image addRepresentation: rep];4.14 return image;4.15 }4.16 +4.17 +4.18 +NSTextField *cocoa_gui_add_label( NSView *parent, NSString *text, NSRect frame )4.19 +{4.20 + NSTextField *label = [[NSTextField alloc] initWithFrame: frame];4.21 + [label setStringValue: text];4.22 + [label setBordered: NO];4.23 + [label setDrawsBackground: NO];4.24 + [label setEditable: NO];4.25 + [label setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];4.26 + if( parent != NULL ) {4.27 + [parent addSubview: label];4.28 + }4.29 + return label;4.30 +}
5.1 --- a/src/cocoaui/cocoaui.h Mon Jul 28 00:27:32 2008 +00005.2 +++ b/src/cocoaui/cocoaui.h Mon Jul 28 03:41:25 2008 +00005.3 @@ -38,6 +38,13 @@5.4 NSMenu *cocoa_gdrom_menu_new();5.5 NSView *video_osx_create_drawable();5.6 void cocoa_gui_show_preferences();5.7 +NSView *cocoa_gui_create_prefs_controller_pane();5.8 +NSView *cocoa_gui_create_prefs_path_pane();5.9 +5.10 +/**5.11 + * Convenience method to create a new text label in the specified parent.5.12 + */5.13 +NSTextField *cocoa_gui_add_label(NSView *parent, NSString *title, NSRect frame);5.15 @interface LxdreamMainWindow : NSWindow5.16 {5.17 @@ -57,36 +64,32 @@5.18 int headerHeight;5.19 }5.20 - (id)initWithFrame: (NSRect)frameRect title:(NSString *)title;5.21 -/**5.22 - * Create a text label and add it to the pane5.23 - */5.24 -- (NSTextField *)addLabel: (NSString *)text withFrame: (NSRect)frame;5.25 - (int)contentHeight;5.26 @end5.28 +@interface KeyBindingEditor: NSTextView5.29 +{5.30 + BOOL isPrimed;5.31 + NSString *lastValue;5.32 +}5.33 +@end5.34 +5.35 +@interface KeyBindingField : NSTextField5.36 +{5.37 +}5.38 +@end5.39 +5.40 @interface LxdreamPrefsPanel : NSPanel5.41 {5.42 NSArray *toolbar_ids;5.43 NSArray *toolbar_defaults;5.44 NSDictionary *toolbar_items;5.45 NSView *path_pane, *ctrl_pane;5.46 + KeyBindingEditor *binding_editor;5.47 }5.48 - (id)initWithContentRect:(NSRect)contentRect;5.49 @end5.51 -@interface LxdreamPrefsPathPane: LxdreamPrefsPane5.52 -{5.53 -}5.54 -+ (LxdreamPrefsPathPane *)new;5.55 -@end5.56 -5.57 -@interface LxdreamPrefsControllerPane: LxdreamPrefsPane5.58 -{5.59 - struct maple_device *save_controller[4];5.60 -}5.61 -+ (LxdreamPrefsControllerPane *)new;5.62 -@end5.63 -5.64 #ifdef __cplusplus5.65 }5.66 #endif
6.1 --- a/src/display.c Mon Jul 28 00:27:32 2008 +00006.2 +++ b/src/display.c Mon Jul 28 03:41:25 2008 +00006.3 @@ -218,7 +218,7 @@6.4 return NULL;6.5 }6.7 -static gchar *input_keysym_for_keycode( input_driver_t driver, uint16_t keycode )6.8 +gchar *input_keycode_to_keysym( input_driver_t driver, uint16_t keycode )6.9 {6.10 if( keycode == 0 ) {6.11 return NULL;6.12 @@ -386,7 +386,7 @@6.13 }6.14 }6.15 if( display_keysym_hook != NULL ) {6.16 - gchar *sym = input_keysym_for_keycode( driver, keycode );6.17 + gchar *sym = input_keycode_to_keysym( driver, keycode );6.18 if( sym != NULL ) {6.19 display_keysym_hook(display_keysym_hook_data, sym);6.20 g_free(sym);
7.1 --- a/src/display.h Mon Jul 28 00:27:32 2008 +00007.2 +++ b/src/display.h Mon Jul 28 03:41:25 2008 +00007.3 @@ -314,6 +314,12 @@7.5 void input_event_mouse( uint32_t buttons, int32_t x_axis, int32_t y_axis );7.7 +/**7.8 + * Given a keycode and the originating input driver, return the corresponding7.9 + * keysym. The caller is responsible for freeing the string.7.10 + * @return a newly allocated string, or NULL of the keycode is unresolvable.7.11 + */7.12 +gchar *input_keycode_to_keysym( input_driver_t driver, uint16_t keycode );7.14 typedef void (*display_keysym_callback_t)( void *data, const gchar *keysym );
8.1 --- a/src/drivers/video_gtk.c Mon Jul 28 00:27:32 2008 +00008.2 +++ b/src/drivers/video_gtk.c Mon Jul 28 03:41:25 2008 +00008.3 @@ -123,8 +123,9 @@8.4 gboolean video_gtk_init();8.5 void video_gtk_shutdown();8.6 void video_gtk_display_blank( uint32_t colour );8.7 -uint16_t video_gtk_resolve_keysym( const gchar *keysym );8.8 -uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode);8.9 +static uint16_t video_gtk_resolve_keysym( const gchar *keysym );8.10 +static uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode);8.11 +static gchar *video_gtk_get_keysym_for_keycode(uint16_t keycode);8.13 struct display_driver display_gtk_driver = {8.14 "gtk",8.15 @@ -133,18 +134,10 @@8.16 video_gtk_shutdown,8.17 video_gtk_resolve_keysym,8.18 video_gtk_keycode_to_dckeysym,8.19 - NULL,8.20 + video_gtk_keycode_to_keysym,8.21 NULL, NULL, NULL, NULL, NULL,8.22 video_gtk_display_blank, NULL };8.24 -uint16_t video_gtk_resolve_keysym( const gchar *keysym )8.25 -{8.26 - int val = gdk_keyval_from_name( keysym );8.27 - if( val == GDK_VoidSymbol )8.28 - return 0;8.29 - return (uint16_t)val;8.30 -}8.31 -8.32 gboolean video_gtk_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data )8.33 {8.34 pvr2_redraw_display();8.35 @@ -159,7 +152,20 @@8.36 return TRUE;8.37 }8.39 -uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode)8.40 +static uint16_t video_gtk_resolve_keysym( const gchar *keysym )8.41 +{8.42 + int val = gdk_keyval_from_name( keysym );8.43 + if( val == GDK_VoidSymbol )8.44 + return 0;8.45 + return (uint16_t)val;8.46 +}8.47 +8.48 +static gchar *video_gtk_get_keycode_to_keysym( uint16_t keycode )8.49 +{8.50 + return g_strdup(gdk_keyval_name(keycode));8.51 +}8.52 +8.53 +static uint16_t video_gtk_keycode_to_dckeysym(uint16_t keycode)8.54 {8.55 if( keycode >= 'a' && keycode <= 'z' ) {8.56 return (keycode - 'a') + DCKB_a;
9.1 --- a/src/drivers/video_osx.c Mon Jul 28 00:27:32 2008 +00009.2 +++ b/src/drivers/video_osx.c Mon Jul 28 03:41:25 2008 +00009.3 @@ -35,6 +35,7 @@9.4 static void video_osx_display_blank( uint32_t colour );9.5 static uint16_t video_osx_resolve_keysym( const gchar *keysym );9.6 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode);9.7 +static gchar *video_osx_keycode_to_keysym(uint16_t keycode);9.9 struct display_driver display_osx_driver = {9.10 "osx",9.11 @@ -42,7 +43,7 @@9.12 video_osx_init, video_osx_shutdown,9.13 video_osx_resolve_keysym,9.14 video_osx_keycode_to_dckeysym,9.15 - NULL,9.16 + video_osx_keycode_to_keysym,9.17 NULL, NULL, NULL, NULL, NULL,9.18 video_osx_display_blank, NULL };9.20 @@ -250,3 +251,11 @@9.21 }9.22 }9.24 +static gchar *video_osx_keycode_to_keysym(uint16_t keycode)9.25 +{9.26 + if( keycode < 1 || keycode > 128 ) {9.27 + return NULL;9.28 + } else {9.29 + return g_strdup(mac_keysyms_by_keycode[keycode-1]);9.30 + }9.31 +}9.32 \ No newline at end of file
10.1 --- a/src/gtkui/gtk_ctrl.c Mon Jul 28 00:27:32 2008 +000010.2 +++ b/src/gtkui/gtk_ctrl.c Mon Jul 28 03:41:25 2008 +000010.3 @@ -136,7 +136,7 @@10.5 static void controller_device_configure( maple_device_t device )10.6 {10.7 - lxdream_config_entry_t conf = device->get_config(device);10.8 + lxdream_config_entry_t conf = maple_get_device_config(device);10.9 int count, i;10.10 for( count=0; conf[count].key != NULL; count++ );10.12 @@ -152,7 +152,7 @@10.13 x = 3;10.14 y -= (count+1)>>1;10.15 }10.16 - gtk_table_attach( GTK_TABLE(table), gtk_label_new(conf[i].key), x, x+1, y, y+1,10.17 + gtk_table_attach( GTK_TABLE(table), gtk_label_new(gettext(conf[i].label)), x, x+1, y, y+1,10.18 GTK_SHRINK, GTK_SHRINK, 0, 0 );10.19 text = gtk_entry_new();10.20 gtk_entry_set_width_chars( GTK_ENTRY(text), 11 );
11.1 --- a/src/maple/controller.c Mon Jul 28 00:27:32 2008 +000011.2 +++ b/src/maple/controller.c Mon Jul 28 03:41:25 2008 +000011.3 @@ -17,34 +17,37 @@11.4 */11.6 #include <stdlib.h>11.7 +#include <assert.h>11.8 #include "dream.h"11.9 #include "dreamcast.h"11.10 #include "display.h"11.11 #include "maple.h"11.12 #include "maple/controller.h"11.14 -#define CONTROLLER_CONFIG_ENTRIES 1611.15 +#define CONTROLLER_CONFIG_ENTRIES 1511.17 -void controller_attach( maple_device_t dev );11.18 -void controller_detach( maple_device_t dev );11.19 -void controller_destroy( maple_device_t dev );11.20 -maple_device_t controller_clone( maple_device_t dev );11.21 -maple_device_t controller_new();11.22 -lxdream_config_entry_t controller_get_config( maple_device_t dev );11.23 -int controller_get_cond( maple_device_t dev, int function, unsigned char *outbuf,11.24 +static void controller_attach( maple_device_t dev );11.25 +static void controller_detach( maple_device_t dev );11.26 +static void controller_destroy( maple_device_t dev );11.27 +static maple_device_t controller_clone( maple_device_t dev );11.28 +static maple_device_t controller_new();11.29 +static lxdream_config_entry_t controller_get_config( maple_device_t dev );11.30 +static void controller_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );11.31 +static int controller_get_cond( maple_device_t dev, int function, unsigned char *outbuf,11.32 unsigned int *outlen );11.34 typedef struct controller_device {11.35 struct maple_device dev;11.36 uint32_t condition[2];11.37 - struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES];11.38 + struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES+1];11.39 } *controller_device_t;11.41 struct maple_device_class controller_class = { "Sega Controller", controller_new };11.43 static struct controller_device base_controller = {11.44 { MAPLE_DEVICE_TAG, &controller_class, CONTROLLER_IDENT, CONTROLLER_VERSION,11.45 - controller_get_config, controller_attach, controller_detach, controller_destroy,11.46 + controller_get_config, controller_set_config_value,11.47 + controller_attach, controller_detach, controller_destroy,11.48 controller_clone, NULL, NULL, controller_get_cond, NULL, NULL, NULL },11.49 {0x0000FFFF, 0x80808080},11.50 {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },11.51 @@ -64,16 +67,21 @@11.52 { "start", N_("Start button"), CONFIG_TYPE_KEY },11.53 { NULL, CONFIG_TYPE_NONE }} };11.55 +static int config_button_map[] = {11.56 + BUTTON_DPAD_LEFT, BUTTON_DPAD_RIGHT, BUTTON_DPAD_UP, BUTTON_DPAD_DOWN,11.57 + JOY_LEFT, JOY_RIGHT, JOY_UP, JOY_DOWN, BUTTON_X, BUTTON_Y, BUTTON_A,11.58 + BUTTON_B, BUTTON_LEFT_TRIGGER, BUTTON_RIGHT_TRIGGER, BUTTON_START };11.59 +11.60 #define CONTROLLER(x) ((controller_device_t)(x))11.62 -maple_device_t controller_new( )11.63 +static maple_device_t controller_new( )11.64 {11.65 controller_device_t dev = malloc( sizeof(struct controller_device) );11.66 memcpy( dev, &base_controller, sizeof(base_controller) );11.67 return MAPLE_DEVICE(dev);11.68 }11.70 -maple_device_t controller_clone( maple_device_t srcdevice )11.71 +static maple_device_t controller_clone( maple_device_t srcdevice )11.72 {11.73 controller_device_t src = (controller_device_t)srcdevice;11.74 controller_device_t dev = (controller_device_t)controller_new();11.75 @@ -85,7 +93,7 @@11.76 /**11.77 * Input callback11.78 */11.79 -void controller_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )11.80 +static void controller_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )11.81 {11.82 controller_device_t dev = (controller_device_t)mdev;11.83 if( isKeyDown ) {11.84 @@ -129,13 +137,23 @@11.85 }11.86 }11.88 -lxdream_config_entry_t controller_get_config( maple_device_t mdev )11.89 +static lxdream_config_entry_t controller_get_config( maple_device_t mdev )11.90 {11.91 controller_device_t dev = (controller_device_t)mdev;11.92 return dev->config;11.93 }11.95 -void controller_destroy( maple_device_t mdev )11.96 +static void controller_set_config_value( maple_device_t mdev, unsigned int key, const gchar *value )11.97 +{11.98 + controller_device_t dev = (controller_device_t)mdev;11.99 + assert( key < CONTROLLER_CONFIG_ENTRIES );11.100 +11.101 + input_unregister_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );11.102 + lxdream_set_config_value( &dev->config[key], value );11.103 + input_register_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );11.104 +}11.105 +11.106 +static void controller_destroy( maple_device_t mdev )11.107 {11.108 free( mdev );11.109 }11.110 @@ -144,49 +162,27 @@11.111 * Device is being attached to the bus. Go through the config and reserve the11.112 * keys we need.11.113 */11.114 -void controller_attach( maple_device_t mdev )11.115 +static void controller_attach( maple_device_t mdev )11.116 {11.117 controller_device_t dev = (controller_device_t)mdev;11.118 - input_register_key( dev->config[0].value, controller_key_callback, dev, BUTTON_DPAD_LEFT );11.119 - input_register_key( dev->config[1].value, controller_key_callback, dev, BUTTON_DPAD_RIGHT );11.120 - input_register_key( dev->config[2].value, controller_key_callback, dev, BUTTON_DPAD_UP );11.121 - input_register_key( dev->config[3].value, controller_key_callback, dev, BUTTON_DPAD_DOWN );11.122 - input_register_key( dev->config[4].value, controller_key_callback, dev, JOY_LEFT );11.123 - input_register_key( dev->config[5].value, controller_key_callback, dev, JOY_RIGHT );11.124 - input_register_key( dev->config[6].value, controller_key_callback, dev, JOY_UP );11.125 - input_register_key( dev->config[7].value, controller_key_callback, dev, JOY_DOWN );11.126 - input_register_key( dev->config[8].value, controller_key_callback, dev, BUTTON_X );11.127 - input_register_key( dev->config[9].value, controller_key_callback, dev, BUTTON_Y );11.128 - input_register_key( dev->config[10].value, controller_key_callback, dev, BUTTON_A );11.129 - input_register_key( dev->config[11].value, controller_key_callback, dev, BUTTON_B );11.130 - input_register_key( dev->config[12].value, controller_key_callback, dev, BUTTON_LEFT_TRIGGER );11.131 - input_register_key( dev->config[13].value, controller_key_callback, dev, BUTTON_RIGHT_TRIGGER );11.132 - input_register_key( dev->config[14].value, controller_key_callback, dev, BUTTON_START );11.133 + int i;11.134 + for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {11.135 + input_register_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );11.136 + }11.137 }11.139 -void controller_detach( maple_device_t mdev )11.140 +static void controller_detach( maple_device_t mdev )11.141 {11.142 controller_device_t dev = (controller_device_t)mdev;11.143 - input_unregister_key( dev->config[0].value, controller_key_callback, dev, BUTTON_DPAD_LEFT );11.144 - input_unregister_key( dev->config[1].value, controller_key_callback, dev, BUTTON_DPAD_RIGHT );11.145 - input_unregister_key( dev->config[2].value, controller_key_callback, dev, BUTTON_DPAD_UP );11.146 - input_unregister_key( dev->config[3].value, controller_key_callback, dev, BUTTON_DPAD_DOWN );11.147 - input_unregister_key( dev->config[4].value, controller_key_callback, dev, JOY_LEFT );11.148 - input_unregister_key( dev->config[5].value, controller_key_callback, dev, JOY_RIGHT );11.149 - input_unregister_key( dev->config[6].value, controller_key_callback, dev, JOY_UP );11.150 - input_unregister_key( dev->config[7].value, controller_key_callback, dev, JOY_DOWN );11.151 - input_unregister_key( dev->config[8].value, controller_key_callback, dev, BUTTON_X );11.152 - input_unregister_key( dev->config[9].value, controller_key_callback, dev, BUTTON_Y );11.153 - input_unregister_key( dev->config[10].value, controller_key_callback, dev, BUTTON_A );11.154 - input_unregister_key( dev->config[11].value, controller_key_callback, dev, BUTTON_B );11.155 - input_unregister_key( dev->config[12].value, controller_key_callback, dev, BUTTON_LEFT_TRIGGER );11.156 - input_unregister_key( dev->config[13].value, controller_key_callback, dev, BUTTON_RIGHT_TRIGGER );11.157 - input_unregister_key( dev->config[14].value, controller_key_callback, dev, BUTTON_START );11.158 + int i;11.159 + for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {11.160 + input_unregister_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );11.161 + }11.163 }11.166 -int controller_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,11.167 +static int controller_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,11.168 unsigned int *outlen )11.169 {11.170 controller_device_t dev = (controller_device_t)mdev;
12.1 --- a/src/maple/kbd.c Mon Jul 28 00:27:32 2008 +000012.2 +++ b/src/maple/kbd.c Mon Jul 28 03:41:25 2008 +000012.3 @@ -55,7 +55,7 @@12.5 static struct keyboard_device base_keyboard = {12.6 { MAPLE_DEVICE_TAG, &keyboard_class, KEYBOARD_IDENT, KEYBOARD_VERSION,12.7 - NULL, keyboard_attach, keyboard_detach, maple_default_destroy,12.8 + NULL, NULL, keyboard_attach, keyboard_detach, maple_default_destroy,12.9 keyboard_clone, NULL, NULL, keyboard_get_cond, NULL, NULL, NULL },12.10 {0,0,0,0,0,0,0,0},12.11 };
13.1 --- a/src/maple/maple.c Mon Jul 28 00:27:32 2008 +000013.2 +++ b/src/maple/maple.c Mon Jul 28 03:41:25 2008 +000013.3 @@ -332,6 +332,13 @@13.4 }13.5 }13.7 +void maple_set_device_config_value( maple_device_t dev, unsigned int key, const gchar *value )13.8 +{13.9 + if( dev != NULL && dev->set_config_value != NULL ) {13.10 + dev->set_config_value( dev, key, value );13.11 + }13.12 +}13.13 +13.14 void maple_default_destroy( maple_device_t mdev )13.15 {13.16 free(mdev);
14.1 --- a/src/maple/maple.h Mon Jul 28 00:27:32 2008 +000014.2 +++ b/src/maple/maple.h Mon Jul 28 03:41:25 2008 +000014.3 @@ -76,6 +76,7 @@14.4 unsigned char ident[112];14.5 unsigned char version[80];14.6 lxdream_config_entry_t (*get_config)(struct maple_device *dev);14.7 + void (*set_config_value)(struct maple_device *dev, unsigned int key, const gchar *value);14.8 void (*attach)(struct maple_device *dev);14.9 void (*detach)(struct maple_device *dev);14.10 void (*destroy)(struct maple_device *dev);14.11 @@ -101,6 +102,7 @@14.12 const struct maple_device_class *maple_get_device_class( const gchar *name );14.13 const struct maple_device_class **maple_get_device_classes();14.14 lxdream_config_entry_t maple_get_device_config( maple_device_t dev );14.15 +void maple_set_device_config_value( maple_device_t dev, unsigned int key, const gchar *value );14.17 void maple_handle_buffer( uint32_t buffer );14.18 void maple_attach_device( maple_device_t dev, unsigned int port, unsigned int periph );
15.1 --- a/src/maple/mouse.c Mon Jul 28 00:27:32 2008 +000015.2 +++ b/src/maple/mouse.c Mon Jul 28 03:41:25 2008 +000015.3 @@ -58,7 +58,7 @@15.5 static struct mouse_device base_mouse = {15.6 { MAPLE_DEVICE_TAG, &mouse_class, MOUSE_IDENT, MOUSE_VERSION,15.7 - NULL, mouse_attach, mouse_detach, maple_default_destroy,15.8 + NULL, NULL, mouse_attach, mouse_detach, maple_default_destroy,15.9 mouse_clone, NULL, NULL, mouse_get_cond, NULL, NULL, NULL },15.10 0, {0,0,0,0,0,0,0,0},15.11 };
.