Search
lxdream.org :: lxdream :: r1036:af7b0c5905dd
lxdream 0.9.1
released Jun 29
Download Now
changeset1036:af7b0c5905dd
parent1035:e3093fd7d1da
child1037:297a73940eb6
authornkeynes
dateWed Jun 24 06:06:40 2009 +0000 (14 years ago)
Support shell substitutions in config paths
Keep track of last folder in file dialogs
Fix out-of-dateness in GTK path dialog
src/Makefile.am
src/Makefile.in
src/cocoaui/cocoa_ctrl.m
src/cocoaui/cocoa_path.m
src/cocoaui/cocoaui.h
src/cocoaui/cocoaui.m
src/config.c
src/config.h
src/dreamcast.c
src/gdlist.c
src/gtkui/gtk_ctrl.c
src/gtkui/gtk_gd.c
src/gtkui/gtk_path.c
src/gtkui/gtkcb.c
src/gtkui/gtkui.c
src/gtkui/gtkui.h
src/gui.h
src/guiutil.c
src/loader.c
src/main.c
1.1 --- a/src/Makefile.am Wed Jun 24 05:10:25 2009 +0000
1.2 +++ b/src/Makefile.am Wed Jun 24 06:06:40 2009 +0000
1.3 @@ -44,7 +44,7 @@
1.4 gettext.h mem.c mem.h sdram.c mmio.h watch.c \
1.5 asic.c asic.h clock.h serial.h \
1.6 syscall.c syscall.h bios.c dcload.c gdbserver.c \
1.7 - netutil.c netutil.h \
1.8 + netutil.c netutil.h guiutil.c \
1.9 gdrom/ide.c gdrom/ide.h gdrom/packet.h gdrom/gdimage.c \
1.10 gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/gdi.c \
1.11 gdrom/edc_ecc.c gdrom/ecc.h gdrom/edc_crctable.h gdrom/edc_encoder.h \
2.1 --- a/src/Makefile.in Wed Jun 24 05:10:25 2009 +0000
2.2 +++ b/src/Makefile.in Wed Jun 24 06:06:40 2009 +0000
2.3 @@ -142,7 +142,7 @@
2.4 lxdream.h dream.h gui.h cpu.h hook.h gettext.h mem.c mem.h \
2.5 sdram.c mmio.h watch.c asic.c asic.h clock.h serial.h \
2.6 syscall.c syscall.h bios.c dcload.c gdbserver.c netutil.c \
2.7 - netutil.h gdrom/ide.c gdrom/ide.h gdrom/packet.h \
2.8 + netutil.h guiutil.c gdrom/ide.c gdrom/ide.h gdrom/packet.h \
2.9 gdrom/gdimage.c gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c \
2.10 gdrom/cdi.c gdrom/gdi.c gdrom/edc_ecc.c gdrom/ecc.h \
2.11 gdrom/edc_crctable.h gdrom/edc_encoder.h gdrom/edc_l2sq.h \
2.12 @@ -238,42 +238,42 @@
2.13 lxdream-asic.$(OBJEXT) lxdream-syscall.$(OBJEXT) \
2.14 lxdream-bios.$(OBJEXT) lxdream-dcload.$(OBJEXT) \
2.15 lxdream-gdbserver.$(OBJEXT) lxdream-netutil.$(OBJEXT) \
2.16 - lxdream-ide.$(OBJEXT) lxdream-gdimage.$(OBJEXT) \
2.17 - lxdream-gdrom.$(OBJEXT) lxdream-nrg.$(OBJEXT) \
2.18 - lxdream-cdi.$(OBJEXT) lxdream-gdi.$(OBJEXT) \
2.19 - lxdream-edc_ecc.$(OBJEXT) lxdream-dreamcast.$(OBJEXT) \
2.20 - lxdream-eventq.$(OBJEXT) lxdream-sh4.$(OBJEXT) \
2.21 - lxdream-intc.$(OBJEXT) lxdream-sh4mem.$(OBJEXT) \
2.22 - lxdream-timer.$(OBJEXT) lxdream-dmac.$(OBJEXT) \
2.23 - lxdream-mmu.$(OBJEXT) lxdream-sh4core.$(OBJEXT) \
2.24 - lxdream-sh4dasm.$(OBJEXT) lxdream-sh4mmio.$(OBJEXT) \
2.25 - lxdream-scif.$(OBJEXT) lxdream-sh4stat.$(OBJEXT) \
2.26 - lxdream-xltcache.$(OBJEXT) lxdream-pmm.$(OBJEXT) \
2.27 - lxdream-cache.$(OBJEXT) lxdream-armcore.$(OBJEXT) \
2.28 - lxdream-armdasm.$(OBJEXT) lxdream-armmem.$(OBJEXT) \
2.29 - lxdream-aica.$(OBJEXT) lxdream-audio.$(OBJEXT) \
2.30 - lxdream-pvr2.$(OBJEXT) lxdream-pvr2mem.$(OBJEXT) \
2.31 - lxdream-tacore.$(OBJEXT) lxdream-rendsort.$(OBJEXT) \
2.32 - lxdream-texcache.$(OBJEXT) lxdream-yuv.$(OBJEXT) \
2.33 - lxdream-rendsave.$(OBJEXT) lxdream-scene.$(OBJEXT) \
2.34 - lxdream-gl_sl.$(OBJEXT) lxdream-gl_slsrc.$(OBJEXT) \
2.35 - lxdream-glutil.$(OBJEXT) lxdream-glrender.$(OBJEXT) \
2.36 - lxdream-maple.$(OBJEXT) lxdream-controller.$(OBJEXT) \
2.37 - lxdream-kbd.$(OBJEXT) lxdream-mouse.$(OBJEXT) \
2.38 - lxdream-lightgun.$(OBJEXT) lxdream-vmu.$(OBJEXT) \
2.39 - lxdream-loader.$(OBJEXT) lxdream-bootstrap.$(OBJEXT) \
2.40 - lxdream-util.$(OBJEXT) lxdream-gdlist.$(OBJEXT) \
2.41 - lxdream-vmuvol.$(OBJEXT) lxdream-vmulist.$(OBJEXT) \
2.42 - lxdream-display.$(OBJEXT) lxdream-audio_null.$(OBJEXT) \
2.43 - lxdream-video_null.$(OBJEXT) lxdream-cd_mmc.$(OBJEXT) \
2.44 - lxdream-video_gl.$(OBJEXT) lxdream-gl_fbo.$(OBJEXT) \
2.45 - lxdream-hotkeys.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
2.46 - $(am__objects_3) $(am__objects_4) $(am__objects_5) \
2.47 - $(am__objects_6) $(am__objects_7) $(am__objects_8) \
2.48 - $(am__objects_9) $(am__objects_10) $(am__objects_11) \
2.49 - $(am__objects_12) $(am__objects_13) $(am__objects_14) \
2.50 - $(am__objects_15) $(am__objects_16) $(am__objects_17) \
2.51 - $(am__objects_18)
2.52 + lxdream-guiutil.$(OBJEXT) lxdream-ide.$(OBJEXT) \
2.53 + lxdream-gdimage.$(OBJEXT) lxdream-gdrom.$(OBJEXT) \
2.54 + lxdream-nrg.$(OBJEXT) lxdream-cdi.$(OBJEXT) \
2.55 + lxdream-gdi.$(OBJEXT) lxdream-edc_ecc.$(OBJEXT) \
2.56 + lxdream-dreamcast.$(OBJEXT) lxdream-eventq.$(OBJEXT) \
2.57 + lxdream-sh4.$(OBJEXT) lxdream-intc.$(OBJEXT) \
2.58 + lxdream-sh4mem.$(OBJEXT) lxdream-timer.$(OBJEXT) \
2.59 + lxdream-dmac.$(OBJEXT) lxdream-mmu.$(OBJEXT) \
2.60 + lxdream-sh4core.$(OBJEXT) lxdream-sh4dasm.$(OBJEXT) \
2.61 + lxdream-sh4mmio.$(OBJEXT) lxdream-scif.$(OBJEXT) \
2.62 + lxdream-sh4stat.$(OBJEXT) lxdream-xltcache.$(OBJEXT) \
2.63 + lxdream-pmm.$(OBJEXT) lxdream-cache.$(OBJEXT) \
2.64 + lxdream-armcore.$(OBJEXT) lxdream-armdasm.$(OBJEXT) \
2.65 + lxdream-armmem.$(OBJEXT) lxdream-aica.$(OBJEXT) \
2.66 + lxdream-audio.$(OBJEXT) lxdream-pvr2.$(OBJEXT) \
2.67 + lxdream-pvr2mem.$(OBJEXT) lxdream-tacore.$(OBJEXT) \
2.68 + lxdream-rendsort.$(OBJEXT) lxdream-texcache.$(OBJEXT) \
2.69 + lxdream-yuv.$(OBJEXT) lxdream-rendsave.$(OBJEXT) \
2.70 + lxdream-scene.$(OBJEXT) lxdream-gl_sl.$(OBJEXT) \
2.71 + lxdream-gl_slsrc.$(OBJEXT) lxdream-glutil.$(OBJEXT) \
2.72 + lxdream-glrender.$(OBJEXT) lxdream-maple.$(OBJEXT) \
2.73 + lxdream-controller.$(OBJEXT) lxdream-kbd.$(OBJEXT) \
2.74 + lxdream-mouse.$(OBJEXT) lxdream-lightgun.$(OBJEXT) \
2.75 + lxdream-vmu.$(OBJEXT) lxdream-loader.$(OBJEXT) \
2.76 + lxdream-bootstrap.$(OBJEXT) lxdream-util.$(OBJEXT) \
2.77 + lxdream-gdlist.$(OBJEXT) lxdream-vmuvol.$(OBJEXT) \
2.78 + lxdream-vmulist.$(OBJEXT) lxdream-display.$(OBJEXT) \
2.79 + lxdream-audio_null.$(OBJEXT) lxdream-video_null.$(OBJEXT) \
2.80 + lxdream-cd_mmc.$(OBJEXT) lxdream-video_gl.$(OBJEXT) \
2.81 + lxdream-gl_fbo.$(OBJEXT) lxdream-hotkeys.$(OBJEXT) \
2.82 + $(am__objects_1) $(am__objects_2) $(am__objects_3) \
2.83 + $(am__objects_4) $(am__objects_5) $(am__objects_6) \
2.84 + $(am__objects_7) $(am__objects_8) $(am__objects_9) \
2.85 + $(am__objects_10) $(am__objects_11) $(am__objects_12) \
2.86 + $(am__objects_13) $(am__objects_14) $(am__objects_15) \
2.87 + $(am__objects_16) $(am__objects_17) $(am__objects_18)
2.88 lxdream_OBJECTS = $(am_lxdream_OBJECTS)
2.89 lxdream_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
2.90 $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
2.91 @@ -542,10 +542,10 @@
2.92 lxdream_SOURCES = main.c version.c config.c config.h lxdream.h dream.h \
2.93 gui.h cpu.h hook.h gettext.h mem.c mem.h sdram.c mmio.h \
2.94 watch.c asic.c asic.h clock.h serial.h syscall.c syscall.h \
2.95 - bios.c dcload.c gdbserver.c netutil.c netutil.h gdrom/ide.c \
2.96 - gdrom/ide.h gdrom/packet.h gdrom/gdimage.c gdrom/gdrom.c \
2.97 - gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/gdi.c \
2.98 - gdrom/edc_ecc.c gdrom/ecc.h gdrom/edc_crctable.h \
2.99 + bios.c dcload.c gdbserver.c netutil.c netutil.h guiutil.c \
2.100 + gdrom/ide.c gdrom/ide.h gdrom/packet.h gdrom/gdimage.c \
2.101 + gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c \
2.102 + gdrom/gdi.c gdrom/edc_ecc.c gdrom/ecc.h gdrom/edc_crctable.h \
2.103 gdrom/edc_encoder.h gdrom/edc_l2sq.h gdrom/edc_scramble.h \
2.104 gdrom/gddriver.h dreamcast.c dreamcast.h eventq.c eventq.h \
2.105 sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c \
2.106 @@ -793,6 +793,7 @@
2.107 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_win.Po@am__quote@
2.108 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtkcb.Po@am__quote@
2.109 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtkui.Po@am__quote@
2.110 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-guiutil.Po@am__quote@
2.111 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-hotkeys.Po@am__quote@
2.112 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-i386-dis.Po@am__quote@
2.113 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-ide.Po@am__quote@
2.114 @@ -1103,6 +1104,20 @@
2.115 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.116 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-netutil.obj `if test -f 'netutil.c'; then $(CYGPATH_W) 'netutil.c'; else $(CYGPATH_W) '$(srcdir)/netutil.c'; fi`
2.117
2.118 +lxdream-guiutil.o: guiutil.c
2.119 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-guiutil.o -MD -MP -MF "$(DEPDIR)/lxdream-guiutil.Tpo" -c -o lxdream-guiutil.o `test -f 'guiutil.c' || echo '$(srcdir)/'`guiutil.c; \
2.120 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-guiutil.Tpo" "$(DEPDIR)/lxdream-guiutil.Po"; else rm -f "$(DEPDIR)/lxdream-guiutil.Tpo"; exit 1; fi
2.121 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='guiutil.c' object='lxdream-guiutil.o' libtool=no @AMDEPBACKSLASH@
2.122 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.123 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-guiutil.o `test -f 'guiutil.c' || echo '$(srcdir)/'`guiutil.c
2.124 +
2.125 +lxdream-guiutil.obj: guiutil.c
2.126 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-guiutil.obj -MD -MP -MF "$(DEPDIR)/lxdream-guiutil.Tpo" -c -o lxdream-guiutil.obj `if test -f 'guiutil.c'; then $(CYGPATH_W) 'guiutil.c'; else $(CYGPATH_W) '$(srcdir)/guiutil.c'; fi`; \
2.127 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-guiutil.Tpo" "$(DEPDIR)/lxdream-guiutil.Po"; else rm -f "$(DEPDIR)/lxdream-guiutil.Tpo"; exit 1; fi
2.128 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='guiutil.c' object='lxdream-guiutil.obj' libtool=no @AMDEPBACKSLASH@
2.129 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.130 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-guiutil.obj `if test -f 'guiutil.c'; then $(CYGPATH_W) 'guiutil.c'; else $(CYGPATH_W) '$(srcdir)/guiutil.c'; fi`
2.131 +
2.132 lxdream-ide.o: gdrom/ide.c
2.133 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-ide.o -MD -MP -MF "$(DEPDIR)/lxdream-ide.Tpo" -c -o lxdream-ide.o `test -f 'gdrom/ide.c' || echo '$(srcdir)/'`gdrom/ide.c; \
2.134 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-ide.Tpo" "$(DEPDIR)/lxdream-ide.Po"; else rm -f "$(DEPDIR)/lxdream-ide.Tpo"; exit 1; fi
3.1 --- a/src/cocoaui/cocoa_ctrl.m Wed Jun 24 05:10:25 2009 +0000
3.2 +++ b/src/cocoaui/cocoa_ctrl.m Wed Jun 24 06:06:40 2009 +0000
3.3 @@ -596,13 +596,14 @@
3.4 NSOpenPanel *panel = [NSOpenPanel openPanel];
3.5 VMULoadValidator *valid = [[VMULoadValidator alloc] autorelease];
3.6 [panel setDelegate: valid];
3.7 - NSInteger result = [panel runModalForDirectory: [NSString stringWithUTF8String: lxdream_get_config_value(CONFIG_VMU_PATH)]
3.8 + NSInteger result = [panel runModalForDirectory: [NSString stringWithUTF8String: gui_get_configurable_path(CONFIG_VMU_PATH)]
3.9 file: nil types: array];
3.10 if( result == NSOKButton ) {
3.11 vmu_filename = [[panel filename] UTF8String];
3.12 int idx = vmulist_get_index_by_filename(vmu_filename);
3.13 [sender selectItemWithTag: (FIRST_VMU_TAG+idx)];
3.14 new_device_class = &vmu_class;
3.15 + gui_set_configurable_path(CONFIG_VMU_PATH, [[panel directory] UTF8String]);
3.16 } else {
3.17 /* Cancelled - restore previous value */
3.18 setDevicePopupSelection( sender, current );
3.19 @@ -615,7 +616,7 @@
3.20 [panel setRequiredFileType: @"vmu"];
3.21 VMUCreateValidator *valid = [[VMUCreateValidator alloc] autorelease];
3.22 [panel setDelegate: valid];
3.23 - NSInteger result = [panel runModalForDirectory: [NSString stringWithUTF8String: lxdream_get_config_value(CONFIG_VMU_PATH)]
3.24 + NSInteger result = [panel runModalForDirectory: [NSString stringWithUTF8String: gui_get_configurable_path(CONFIG_VMU_PATH)]
3.25 file: nil];
3.26 if( result == NSFileHandlingPanelOKButton ) {
3.27 /* Validator has already created the file by now */
3.28 @@ -623,6 +624,7 @@
3.29 int idx = vmulist_get_index_by_filename(vmu_filename);
3.30 [sender selectItemWithTag: (FIRST_VMU_TAG+idx)];
3.31 new_device_class = &vmu_class;
3.32 + gui_set_configurable_path(CONFIG_VMU_PATH, [[panel directory] UTF8String]);
3.33 } else {
3.34 setDevicePopupSelection( sender, current );
3.35 return;
4.1 --- a/src/cocoaui/cocoa_path.m Wed Jun 24 05:10:25 2009 +0000
4.2 +++ b/src/cocoaui/cocoa_path.m Wed Jun 24 06:06:40 2009 +0000
4.3 @@ -40,7 +40,7 @@
4.4 int height = [self contentHeight] - TEXT_HEIGHT - TEXT_GAP;
4.5
4.6 for( i=0; i<=CONFIG_KEY_MAX; i++ ) {
4.7 - const struct lxdream_config_entry *entry = lxdream_get_config_entry(i);
4.8 + const struct lxdream_config_entry *entry = lxdream_get_global_config_entry(i);
4.9 if( entry->label != NULL ) {
4.10 NSRect frame = NSMakeRect( TEXT_GAP, height -((TEXT_HEIGHT+TEXT_GAP)*i - 2),
4.11 150, LABEL_HEIGHT );
4.12 @@ -66,7 +66,7 @@
4.13 {
4.14 int tag = [[notify object] tag];
4.15 const char *str = [[[notify object] stringValue] UTF8String];
4.16 - const char *oldval = lxdream_get_config_value(tag);
4.17 + const char *oldval = lxdream_get_global_config_value(tag);
4.18 if( str[0] == '\0' )
4.19 str = NULL;
4.20 if( oldval == NULL ? str != NULL : (str == NULL || strcmp(oldval,str) != 0 ) ) {
5.1 --- a/src/cocoaui/cocoaui.h Wed Jun 24 05:10:25 2009 +0000
5.2 +++ b/src/cocoaui/cocoaui.h Wed Jun 24 06:06:40 2009 +0000
5.3 @@ -21,6 +21,7 @@
5.4
5.5 #import <AppKit/AppKit.h>
5.6 #include "lxdream.h"
5.7 +#include "gui.h"
5.8 #include "gettext.h"
5.9
5.10 #ifdef __cplusplus
6.1 --- a/src/cocoaui/cocoaui.m Wed Jun 24 05:10:25 2009 +0000
6.2 +++ b/src/cocoaui/cocoaui.m Wed Jun 24 06:06:40 2009 +0000
6.3 @@ -220,47 +220,47 @@
6.4 - (void) load_action: (id)sender
6.5 {
6.6 NSOpenPanel *panel = [NSOpenPanel openPanel];
6.7 - const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH);
6.8 - NSString *path = (dir == NULL ? NSHomeDirectory() : [NSString stringWithCString: dir]);
6.9 + NSString *path = [NSString stringWithCString: gui_get_configurable_path(CONFIG_SAVE_PATH)];
6.10 NSArray *fileTypes = [NSArray arrayWithObject: @"dst"];
6.11 int result = [panel runModalForDirectory: path file: nil types: fileTypes];
6.12 if( result == NSOKButton && [[panel filenames] count] > 0 ) {
6.13 NSString *filename = [[panel filenames] objectAtIndex: 0];
6.14 dreamcast_load_state( [filename UTF8String] );
6.15 + gui_set_configurable_path(CONFIG_SAVE_PATH, [[panel directory] UTF8String]);
6.16 }
6.17 }
6.18 - (void) save_action: (id)sender
6.19 {
6.20 NSSavePanel *panel = [NSSavePanel savePanel];
6.21 - const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH);
6.22 - NSString *path = (dir == NULL ? NSHomeDirectory() : [NSString stringWithCString: dir]);
6.23 + NSString *path = [NSString stringWithCString: gui_get_configurable_path(CONFIG_SAVE_PATH)];
6.24 [panel setRequiredFileType: @"dst"];
6.25 int result = [panel runModalForDirectory: path file:@""];
6.26 if( result == NSOKButton ) {
6.27 NSString *filename = [panel filename];
6.28 dreamcast_save_state( [filename UTF8String] );
6.29 + gui_set_configurable_path(CONFIG_SAVE_PATH, [[panel directory] UTF8String]);
6.30 }
6.31 }
6.32 - (void) load_binary_action: (id)sender
6.33 {
6.34 NSOpenPanel *panel = [NSOpenPanel openPanel];
6.35 - const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);
6.36 - NSString *path = (dir == NULL ? NSHomeDirectory() : [NSString stringWithCString: dir]);
6.37 + NSString *path = [NSString stringWithCString: gui_get_configurable_path(CONFIG_DEFAULT_PATH)];
6.38 int result = [panel runModalForDirectory: path file: nil types: nil];
6.39 if( result == NSOKButton && [[panel filenames] count] > 0 ) {
6.40 NSString *filename = [[panel filenames] objectAtIndex: 0];
6.41 file_load_magic( [filename UTF8String] );
6.42 + gui_set_configurable_path(CONFIG_DEFAULT_PATH, [[panel directory] UTF8String]);
6.43 }
6.44 }
6.45 - (void) mount_action: (id)sender
6.46 {
6.47 NSOpenPanel *panel = [NSOpenPanel openPanel];
6.48 - const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);
6.49 - NSString *path = (dir == NULL ? NSHomeDirectory() : [NSString stringWithCString: dir]);
6.50 + NSString *path = [NSString stringWithCString: gui_get_configurable_path(CONFIG_DEFAULT_PATH)];
6.51 int result = [panel runModalForDirectory: path file: nil types: nil];
6.52 if( result == NSOKButton && [[panel filenames] count] > 0 ) {
6.53 NSString *filename = [[panel filenames] objectAtIndex: 0];
6.54 gdrom_mount_image( [filename UTF8String] );
6.55 + gui_set_configurable_path(CONFIG_DEFAULT_PATH, [[panel directory] UTF8String]);
6.56 }
6.57 }
6.58 - (void) pause_action: (id)sender
7.1 --- a/src/config.c Wed Jun 24 05:10:25 2009 +0000
7.2 +++ b/src/config.c Wed Jun 24 06:06:40 2009 +0000
7.3 @@ -18,9 +18,11 @@
7.4
7.5 #include <unistd.h>
7.6 #include <stdio.h>
7.7 +#include <ctype.h>
7.8 #include <errno.h>
7.9 #include <stdlib.h>
7.10 #include <string.h>
7.11 +#include <wordexp.h>
7.12 #include <glib/gmem.h>
7.13 #include <glib/gstrfuncs.h>
7.14 #include "dream.h"
7.15 @@ -136,7 +138,7 @@
7.16 maple_detach_all();
7.17 }
7.18
7.19 -const gchar *lxdream_get_config_value( int key )
7.20 +const gchar *lxdream_get_global_config_value( int key )
7.21 {
7.22 return global_config[key].value;
7.23 }
7.24 @@ -144,7 +146,7 @@
7.25 GList *lxdream_get_global_config_list_value( int key )
7.26 {
7.27 GList *result = NULL;
7.28 - const gchar *str = lxdream_get_config_value( key );
7.29 + const gchar *str = lxdream_get_global_config_value( key );
7.30 if( str != NULL ) {
7.31 gchar **strv = g_strsplit(str, ":",0);
7.32 int i;
7.33 @@ -161,7 +163,7 @@
7.34 if( list == NULL ) {
7.35 lxdream_set_global_config_value( key, NULL );
7.36 } else {
7.37 - GList *ptr;
7.38 + const GList *ptr;
7.39 int size = 0;
7.40
7.41 for( ptr = list; ptr != NULL; ptr = g_list_next(ptr) ) {
7.42 @@ -177,6 +179,100 @@
7.43 }
7.44 }
7.45
7.46 +gchar *get_expanded_path( const gchar *input )
7.47 +{
7.48 + wordexp_t we;
7.49 + if( input == NULL ) {
7.50 + return NULL;
7.51 + }
7.52 + memset(&we,0,sizeof(we));
7.53 + int result = wordexp(input, &we, WRDE_NOCMD);
7.54 + if( result != 0 || we.we_wordc == 0 ) {
7.55 + /* On failure, return the original input unchanged */
7.56 + return g_strdup(input);
7.57 + } else {
7.58 + /* On success, concatenate all 'words' together into a single
7.59 + * space-separated string
7.60 + */
7.61 + int length = we.we_wordc, i;
7.62 + gchar *result, *p;
7.63 +
7.64 + for( i=0; i<we.we_wordc; i++ ) {
7.65 + length += strlen(we.we_wordv[i]);
7.66 + }
7.67 + p = result = g_malloc(length);
7.68 + for( i=0; i<we.we_wordc; i++ ) {
7.69 + if( i != 0 )
7.70 + *p++ = ' ';
7.71 + strcpy( p, we.we_wordv[i] );
7.72 + p += strlen(p);
7.73 + }
7.74 + wordfree(&we);
7.75 + return result;
7.76 + }
7.77 +}
7.78 +
7.79 +/**
7.80 + * Test if we need to escape a path to prevent substitution mangling.
7.81 + * @return TRUE if the input value contains any character that doesn't
7.82 + * match [a-zA-Z0-9._@%/] (this will escape slightly more than it needs to,
7.83 + * but is safe)
7.84 + */
7.85 +gboolean path_needs_escaping( const gchar *value )
7.86 +{
7.87 + const gchar *p = value;
7.88 + while( *p ) {
7.89 + if( !isalnum(*p) && *p != '.' && *p != '_' &&
7.90 + *p != '@' && *p != '%' && *p != '/' ) {
7.91 + return TRUE;
7.92 + }
7.93 + p++;
7.94 + }
7.95 + return FALSE;
7.96 +}
7.97 +
7.98 +gchar *get_escaped_path( const gchar *value )
7.99 +{
7.100 + if( value != NULL && path_needs_escaping(value) ) {
7.101 + /* Escape with "", and backslash the remaining characters:
7.102 + * \ " $ `
7.103 + */
7.104 + char buf[strlen(value)*2+3];
7.105 + const char *s = value;
7.106 + char *p = buf;
7.107 + *p++ = '\"';
7.108 + while( *s ) {
7.109 + if( *s == '\\' || *s == '"' || *s == '$' || *s == '`' ) {
7.110 + *p++ = '\\';
7.111 + }
7.112 + *p++ = *s++;
7.113 + }
7.114 + *p++ = '\"';
7.115 + *p = '\0';
7.116 + return g_strdup(buf);
7.117 + } else {
7.118 + return g_strdup(value);
7.119 + }
7.120 +}
7.121 +
7.122 +gchar *lxdream_get_global_config_path_value( int key )
7.123 +{
7.124 + const gchar *str = lxdream_get_global_config_value(key);
7.125 + if( str == NULL ) {
7.126 + return NULL;
7.127 + } else {
7.128 + return get_expanded_path(str);
7.129 + }
7.130 +}
7.131 +
7.132 +const gchar *lxdream_set_global_config_path_value( int key, const gchar *value )
7.133 +{
7.134 + gchar *temp = get_escaped_path(value);
7.135 + lxdream_set_global_config_value(key,temp);
7.136 + g_free(temp);
7.137 + return lxdream_get_global_config_value(key);
7.138 +}
7.139 +
7.140 void lxdream_set_config_value( lxdream_config_entry_t param, const gchar *value )
7.141 {
7.142 if( param->value != value ) {
7.143 @@ -192,7 +288,7 @@
7.144 lxdream_set_config_value(&global_config[key], value);
7.145 }
7.146
7.147 -const struct lxdream_config_entry * lxdream_get_config_entry( int key )
7.148 +const struct lxdream_config_entry * lxdream_get_global_config_entry( int key )
7.149 {
7.150 return &global_config[key];
7.151 }
8.1 --- a/src/config.h Wed Jun 24 05:10:25 2009 +0000
8.2 +++ b/src/config.h Wed Jun 24 06:06:40 2009 +0000
8.3 @@ -62,15 +62,32 @@
8.4 extern struct lxdream_config_group lxdream_config_root[];
8.5
8.6 /* Global config values */
8.7 -const gchar *lxdream_get_config_value( int key );
8.8 -const struct lxdream_config_entry * lxdream_get_config_entry( int key );
8.9 +const gchar *lxdream_get_global_config_value( int key );
8.10 +const struct lxdream_config_entry * lxdream_get_global_config_entry( int key );
8.11 +void lxdream_set_global_config_value( int key, const gchar *value );
8.12 +
8.13 void lxdream_register_config_group( const gchar *key, lxdream_config_entry_t group );
8.14 -void lxdream_set_global_config_value( int key, const gchar *value );
8.15 void lxdream_set_config_value( lxdream_config_entry_t entry, const gchar *value );
8.16 gboolean lxdream_set_group_value( lxdream_config_group_t group, const gchar *key, const gchar *value );
8.17 void lxdream_copy_config_list( lxdream_config_entry_t dest, lxdream_config_entry_t src );
8.18
8.19 /**
8.20 + * Return a fully expanded path value for a key - this performs substitutions
8.21 + * for ~ and simple shell variables ($VAR and ${VAR})
8.22 + *
8.23 + * The returned string is newly allocated and must be freed by the caller
8.24 + */
8.25 +gchar *lxdream_get_global_config_path_value( int key );
8.26 +
8.27 +/**
8.28 + * Set a path value for a key, escaping if necessary to protect against
8.29 + * shell-substitution on the round trip.
8.30 + *
8.31 + * @return the resultant config value.
8.32 + */
8.33 +const gchar *lxdream_set_global_config_path_value( int key, const gchar *value );
8.34 +
8.35 +/**
8.36 * Construct a list of strings for the given config key - The caller is
8.37 * responsible for freeing the list and its values.
8.38 */
8.39 @@ -106,6 +123,19 @@
8.40 */
8.41 gboolean lxdream_save_config( );
8.42
8.43 +/**
8.44 + * Escape a pathname if needed to prevent shell substitution.
8.45 + * @return a newly allocated string (or NULL if the input is NULL)
8.46 + */
8.47 +gchar *get_escaped_path( const gchar *name );
8.48 +
8.49 +/**
8.50 + * Expand a pathname according to standard shell substitution rules
8.51 + * (excluding command substitutions).
8.52 + * @return a newly allocated string (or NULL if the input is NULL)
8.53 + */
8.54 +gchar *get_expanded_path( const gchar *name );
8.55 +
8.56 #ifdef __cplusplus
8.57 }
8.58 #endif
9.1 --- a/src/dreamcast.c Wed Jun 24 05:10:25 2009 +0000
9.2 +++ b/src/dreamcast.c Wed Jun 24 06:06:40 2009 +0000
9.3 @@ -85,8 +85,8 @@
9.4 */
9.5 void dreamcast_configure( )
9.6 {
9.7 - const char *bios_path = lxdream_get_config_value(CONFIG_BIOS_PATH);
9.8 - const char *flash_path = lxdream_get_config_value(CONFIG_FLASH_PATH);
9.9 + char *bios_path = lxdream_get_global_config_path_value(CONFIG_BIOS_PATH);
9.10 + char *flash_path = lxdream_get_global_config_path_value(CONFIG_FLASH_PATH);
9.11
9.12 dreamcast_register_module( &eventq_module );
9.13 /* Register the memory framework */
9.14 @@ -118,23 +118,29 @@
9.15 dreamcast_register_module( &aica_module );
9.16 dreamcast_register_module( &maple_module );
9.17 dreamcast_register_module( &ide_module );
9.18 +
9.19 + g_free(bios_path);
9.20 + g_free(flash_path);
9.21 }
9.22
9.23 void dreamcast_config_changed(void)
9.24 {
9.25 - const char *bios_path = lxdream_get_config_value(CONFIG_BIOS_PATH);
9.26 - const char *flash_path = lxdream_get_config_value(CONFIG_FLASH_PATH);
9.27 + char *bios_path = lxdream_get_global_config_path_value(CONFIG_BIOS_PATH);
9.28 + char *flash_path = lxdream_get_global_config_path_value(CONFIG_FLASH_PATH);
9.29 dreamcast_has_bios = mem_load_rom( dc_boot_rom, bios_path, 2 MB, 0x89f2b1a1 );
9.30 if( flash_path != NULL && flash_path[0] != '\0' ) {
9.31 mem_load_block( flash_path, 0x00200000, 0x00020000 );
9.32 }
9.33 + g_free(bios_path);
9.34 + g_free(flash_path);
9.35 }
9.36
9.37 void dreamcast_save_flash()
9.38 {
9.39 if( dreamcast_has_flash ) {
9.40 - const char *file = lxdream_get_config_value(CONFIG_FLASH_PATH);
9.41 + char *file = lxdream_get_global_config_path_value(CONFIG_FLASH_PATH);
9.42 mem_save_block( file, 0x00200000, 0x00020000 );
9.43 + g_free(file);
9.44 }
9.45 }
9.46
10.1 --- a/src/gdlist.c Wed Jun 24 05:10:25 2009 +0000
10.2 +++ b/src/gdlist.c Wed Jun 24 06:06:40 2009 +0000
10.3 @@ -116,7 +116,7 @@
10.4 }
10.5 }
10.6
10.7 - lxdream_set_global_config_value( CONFIG_GDROM, disc_name );
10.8 + lxdream_set_global_config_path_value( CONFIG_GDROM, disc_name );
10.9 lxdream_save_config();
10.10
10.11 CALL_HOOKS( gdrom_list_change_hook, list_changed, posn );
11.1 --- a/src/gtkui/gtk_ctrl.c Wed Jun 24 05:10:25 2009 +0000
11.2 +++ b/src/gtkui/gtk_ctrl.c Wed Jun 24 06:06:40 2009 +0000
11.3 @@ -249,8 +249,8 @@
11.4
11.5 if( devclz == LOAD_VMU_TAG ) {
11.6 devclz = NULL;
11.7 - vmu_filename = open_file_dialog( _("Load VMU"), "*.vmu", "VMU Files",
11.8 - lxdream_get_config_value(CONFIG_VMU_PATH) );
11.9 + vmu_filename = open_file_dialog( _("Load VMU"), "*.vmu", "VMU Files",
11.10 + CONFIG_VMU_PATH );
11.11 if( vmu_filename != NULL ) {
11.12 vmu_volume_t vol = vmu_volume_load( vmu_filename );
11.13 if( vol != NULL ) {
11.14 @@ -264,7 +264,7 @@
11.15 } else if( devclz == CREATE_VMU_TAG ) {
11.16 devclz = NULL;
11.17 vmu_filename = save_file_dialog( _("Create VMU"), "*.vmu", "VMU Files",
11.18 - lxdream_get_config_value(CONFIG_VMU_PATH) );
11.19 + CONFIG_VMU_PATH );
11.20 if( vmu_filename != NULL ) {
11.21 devclz = &vmu_class;
11.22 set_selection = TRUE;
12.1 --- a/src/gtkui/gtk_gd.c Wed Jun 24 05:10:25 2009 +0000
12.2 +++ b/src/gtkui/gtk_gd.c Wed Jun 24 06:06:40 2009 +0000
12.3 @@ -30,8 +30,7 @@
12.4 static void gdrom_menu_open_image_callback( GtkWidget *widget, gpointer user_data )
12.5 {
12.6 if( !gdrom_menu_adjusting ) {
12.7 - const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);
12.8 - open_file_dialog_cb( _("Open..."), gdrom_mount_image, NULL, NULL, dir );
12.9 + open_file_dialog_cb( _("Open..."), gdrom_mount_image, NULL, NULL, CONFIG_DEFAULT_PATH );
12.10 }
12.11 }
12.12
13.1 --- a/src/gtkui/gtk_path.c Wed Jun 24 05:10:25 2009 +0000
13.2 +++ b/src/gtkui/gtk_path.c Wed Jun 24 06:06:40 2009 +0000
13.3 @@ -25,18 +25,7 @@
13.4 #include "config.h"
13.5 #include "gtkui/gtkui.h"
13.6
13.7 -static const gchar *path_label[] = { N_("Bios rom"), N_("Flash rom"), N_("Default disc path"),
13.8 - N_("Save state path"), N_("Bootstrap IP.BIN") };
13.9 -static const int path_id[] = { CONFIG_BIOS_PATH, CONFIG_FLASH_PATH, CONFIG_DEFAULT_PATH,
13.10 - CONFIG_SAVE_PATH, CONFIG_BOOTSTRAP };
13.11 -static GtkFileChooserAction path_action[] = {
13.12 - GTK_FILE_CHOOSER_ACTION_OPEN,
13.13 - GTK_FILE_CHOOSER_ACTION_OPEN,
13.14 - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
13.15 - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
13.16 - GTK_FILE_CHOOSER_ACTION_OPEN };
13.17 -
13.18 -static GtkWidget *path_entry[5];
13.19 +static GtkWidget *path_entry[CONFIG_KEY_MAX];
13.20
13.21 static gboolean path_file_button_clicked( GtkWidget *button, gpointer user_data )
13.22 {
13.23 @@ -46,14 +35,16 @@
13.24 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
13.25 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
13.26 NULL );
13.27 - const gchar *filename = gtk_entry_get_text(GTK_ENTRY(entry));
13.28 + gchar *filename = get_expanded_path(gtk_entry_get_text(GTK_ENTRY(entry)));
13.29 gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename );
13.30 gtk_window_set_modal( GTK_WINDOW(file), TRUE );
13.31 gtk_widget_show_all( file );
13.32 gint result = gtk_dialog_run(GTK_DIALOG(file));
13.33 + g_free(filename);
13.34 if( result == GTK_RESPONSE_ACCEPT ) {
13.35 - filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );
13.36 + filename = get_escaped_path(gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ));
13.37 gtk_entry_set_text(GTK_ENTRY(entry), filename);
13.38 + g_free(filename);
13.39 }
13.40 gtk_widget_destroy(file);
13.41 return TRUE;
13.42 @@ -67,15 +58,17 @@
13.43 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
13.44 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
13.45 NULL );
13.46 - const gchar *filename = gtk_entry_get_text(GTK_ENTRY(entry));
13.47 + gchar *filename = get_expanded_path(gtk_entry_get_text(GTK_ENTRY(entry)));
13.48 gtk_file_chooser_set_action( GTK_FILE_CHOOSER(file), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER );
13.49 gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename );
13.50 gtk_window_set_modal( GTK_WINDOW(file), TRUE );
13.51 gtk_widget_show_all( file );
13.52 gint result = gtk_dialog_run(GTK_DIALOG(file));
13.53 + g_free(filename);
13.54 if( result == GTK_RESPONSE_ACCEPT ) {
13.55 - filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );
13.56 + filename = get_escaped_path(gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ));
13.57 gtk_entry_set_text(GTK_ENTRY(entry), filename);
13.58 + g_free(filename);
13.59 }
13.60 gtk_widget_destroy(file);
13.61 return TRUE;
13.62 @@ -83,27 +76,32 @@
13.63
13.64 GtkWidget *path_panel_new(void)
13.65 {
13.66 - GtkWidget *table = gtk_table_new( 5, 3, FALSE );
13.67 - int i;
13.68 - for( i=0; i<5; i++ ) {
13.69 - GtkWidget *text = path_entry[i] = gtk_entry_new();
13.70 - GtkWidget *button = gtk_button_new();
13.71 - gtk_table_attach( GTK_TABLE(table), gtk_label_new(Q_(path_label[i])), 0, 1, i, i+1,
13.72 - GTK_SHRINK, GTK_SHRINK, 0, 0);
13.73 - gtk_entry_set_text( GTK_ENTRY(text), lxdream_get_config_value(path_id[i]) );
13.74 - gtk_entry_set_width_chars( GTK_ENTRY(text), 48 );
13.75 - gtk_table_attach_defaults( GTK_TABLE(table), text, 1, 2, i, i+1 );
13.76 - gtk_table_attach( GTK_TABLE(table), button, 2, 3, i, i+1, GTK_SHRINK, GTK_SHRINK, 0, 0 );
13.77 - if( path_action[i] == GTK_FILE_CHOOSER_ACTION_OPEN ) {
13.78 - GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON);
13.79 - gtk_button_set_image( GTK_BUTTON(button), image );
13.80 - g_signal_connect( button, "clicked", G_CALLBACK(path_file_button_clicked), text );
13.81 - } else {
13.82 - GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON);
13.83 - gtk_button_set_image( GTK_BUTTON(button), image );
13.84 - g_signal_connect( button, "clicked", G_CALLBACK(path_dir_button_clicked), text );
13.85 + int i, y=0;
13.86 + GtkWidget *table = gtk_table_new( CONFIG_KEY_MAX, 3, FALSE );
13.87 + for( i=0; i<CONFIG_KEY_MAX; i++ ) {
13.88 + const struct lxdream_config_entry *entry = lxdream_get_global_config_entry(i);
13.89 + if( entry->label != NULL ) {
13.90 + GtkWidget *text = path_entry[i] = gtk_entry_new();
13.91 + GtkWidget *button = gtk_button_new();
13.92 + gtk_table_attach( GTK_TABLE(table), gtk_label_new(Q_(entry->label)), 0, 1, y, y+1,
13.93 + GTK_SHRINK, GTK_SHRINK, 0, 0);
13.94 + gtk_entry_set_text( GTK_ENTRY(text), lxdream_get_global_config_value(i) );
13.95 + gtk_entry_set_width_chars( GTK_ENTRY(text), 48 );
13.96 + gtk_table_attach_defaults( GTK_TABLE(table), text, 1, 2, y, y+1 );
13.97 + gtk_table_attach( GTK_TABLE(table), button, 2, 3, y, y+1, GTK_SHRINK, GTK_SHRINK, 0, 0 );
13.98 + if( entry->type == CONFIG_TYPE_FILE ) {
13.99 + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
13.100 + gtk_button_set_image( GTK_BUTTON(button), image );
13.101 + g_signal_connect( button, "clicked", G_CALLBACK(path_file_button_clicked), text );
13.102 + } else {
13.103 + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU);
13.104 + gtk_button_set_image( GTK_BUTTON(button), image );
13.105 + g_signal_connect( button, "clicked", G_CALLBACK(path_dir_button_clicked), text );
13.106 + }
13.107 + y++;
13.108 }
13.109 }
13.110 + gtk_table_resize( GTK_TABLE(table), y, 3 );
13.111 return table;
13.112
13.113 }
13.114 @@ -112,13 +110,16 @@
13.115 {
13.116 if( isOK ) {
13.117 int i;
13.118 - for(i=0; i<5; i++ ) {
13.119 - const char *filename = gtk_entry_get_text( GTK_ENTRY(path_entry[i]) );
13.120 - lxdream_set_global_config_value( path_id[i], filename );
13.121 + for(i=0; i<CONFIG_KEY_MAX; i++ ) {
13.122 + if( path_entry[i] != NULL ) {
13.123 + const char *filename = gtk_entry_get_text( GTK_ENTRY(path_entry[i]) );
13.124 + lxdream_set_global_config_value( i, filename );
13.125 + }
13.126 }
13.127
13.128 lxdream_save_config();
13.129 dreamcast_config_changed();
13.130 + gui_config_paths_changed();
13.131 gtk_gui_update();
13.132 }
13.133 }
14.1 --- a/src/gtkui/gtkcb.c Wed Jun 24 05:10:25 2009 +0000
14.2 +++ b/src/gtkui/gtkcb.c Wed Jun 24 06:06:40 2009 +0000
14.3 @@ -40,58 +40,74 @@
14.4 }
14.5
14.6 gchar *open_file_dialog( const char *title, const char *pattern, const char *patname,
14.7 - const gchar *initial_dir )
14.8 + int initial_dir_key )
14.9 {
14.10 GtkWidget *file;
14.11 gchar *filename = NULL;
14.12 - gchar *initial_path = get_absolute_path(initial_dir);
14.13 +
14.14 file = gtk_file_chooser_dialog_new( title, NULL,
14.15 GTK_FILE_CHOOSER_ACTION_OPEN,
14.16 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
14.17 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
14.18 NULL );
14.19 add_file_pattern( GTK_FILE_CHOOSER(file), pattern, patname );
14.20 - gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(file), initial_path );
14.21 + if( initial_dir_key != -1 ) {
14.22 + gchar *initial_path = get_absolute_path(gui_get_configurable_path(initial_dir_key));
14.23 + gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(file), initial_path );
14.24 + g_free(initial_path);
14.25 + }
14.26 gtk_window_set_modal( GTK_WINDOW(file), TRUE );
14.27 gtk_dialog_set_default_response( GTK_DIALOG(file), GTK_RESPONSE_ACCEPT );
14.28 int result = gtk_dialog_run( GTK_DIALOG(file) );
14.29 if( result == GTK_RESPONSE_ACCEPT ) {
14.30 filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );
14.31 + if( initial_dir_key != -1 ) {
14.32 + gchar *end_path = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER(file) );
14.33 + gui_set_configurable_path(initial_dir_key,end_path);
14.34 + g_free(end_path);
14.35 + }
14.36 }
14.37 gtk_widget_destroy(file);
14.38 - g_free(initial_path);
14.39
14.40 return filename;
14.41 }
14.42
14.43 gchar *save_file_dialog( const char *title, const char *pattern, const char *patname,
14.44 - const gchar *initial_dir )
14.45 + int initial_dir_key )
14.46 {
14.47 GtkWidget *file;
14.48 gchar *filename;
14.49 - gchar *initial_path = get_absolute_path(initial_dir);
14.50 +
14.51 file = gtk_file_chooser_dialog_new( title, NULL,
14.52 GTK_FILE_CHOOSER_ACTION_SAVE,
14.53 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
14.54 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
14.55 NULL );
14.56 add_file_pattern( GTK_FILE_CHOOSER(file), pattern, patname );
14.57 - gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(file), initial_path );
14.58 + if( initial_dir_key != -1 ) {
14.59 + gchar *initial_path = get_absolute_path(gui_get_configurable_path(initial_dir_key));
14.60 + gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(file), initial_path );
14.61 + g_free(initial_path);
14.62 + }
14.63 gtk_window_set_modal( GTK_WINDOW(file), TRUE );
14.64 gtk_dialog_set_default_response( GTK_DIALOG(file), GTK_RESPONSE_ACCEPT );
14.65 int result = gtk_dialog_run( GTK_DIALOG(file) );
14.66 if( result == GTK_RESPONSE_ACCEPT ) {
14.67 filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );
14.68 + if( initial_dir_key != -1 ) {
14.69 + gchar *end_path = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER(file) );
14.70 + gui_set_configurable_path(initial_dir_key,end_path);
14.71 + g_free(end_path);
14.72 + }
14.73 }
14.74 gtk_widget_destroy(file);
14.75 - g_free(initial_path);
14.76 return filename;
14.77 }
14.78
14.79 void open_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,
14.80 - const gchar *initial_dir )
14.81 + int initial_dir_key )
14.82 {
14.83 - gchar *filename = open_file_dialog( title, pattern, patname, initial_dir );
14.84 + gchar *filename = open_file_dialog( title, pattern, patname, initial_dir_key );
14.85 if( filename != NULL ) {
14.86 action( filename );
14.87 g_free(filename);
14.88 @@ -99,9 +115,9 @@
14.89 }
14.90
14.91 void save_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,
14.92 - const gchar *initial_dir )
14.93 + int initial_dir_key )
14.94 {
14.95 - gchar *filename = save_file_dialog( title, pattern, patname, initial_dir );
14.96 + gchar *filename = save_file_dialog( title, pattern, patname, initial_dir_key );
14.97 if( filename != NULL ) {
14.98 action(filename);
14.99 g_free(filename);
14.100 @@ -110,8 +126,7 @@
14.101
14.102 void mount_action_callback( GtkAction *action, gpointer user_data)
14.103 {
14.104 - const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);
14.105 - open_file_dialog_cb( "Open...", gdrom_mount_image, NULL, NULL, dir );
14.106 + open_file_dialog_cb( "Open...", gdrom_mount_image, NULL, NULL, CONFIG_DEFAULT_PATH );
14.107 }
14.108 void reset_action_callback( GtkAction *action, gpointer user_data)
14.109 {
14.110 @@ -130,8 +145,7 @@
14.111
14.112 void load_binary_action_callback( GtkAction *action, gpointer user_data)
14.113 {
14.114 - const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);
14.115 - open_file_dialog_cb( "Open Binary...", file_load_magic, NULL, NULL, dir );
14.116 + open_file_dialog_cb( "Open Binary...", file_load_magic, NULL, NULL, CONFIG_DEFAULT_PATH );
14.117 }
14.118
14.119 void load_state_preview_callback( GtkFileChooser *chooser, gpointer user_data )
14.120 @@ -157,7 +171,7 @@
14.121 {
14.122 GtkWidget *file, *preview, *frame, *align;
14.123 GtkRequisition size;
14.124 - const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH);
14.125 + const gchar *dir = gui_get_configurable_path(CONFIG_SAVE_PATH);
14.126 gchar *path = get_absolute_path(dir);
14.127 file = gtk_file_chooser_dialog_new( _("Load state..."), NULL,
14.128 GTK_FILE_CHOOSER_ACTION_OPEN,
14.129 @@ -186,6 +200,9 @@
14.130 int result = gtk_dialog_run( GTK_DIALOG(file) );
14.131 if( result == GTK_RESPONSE_ACCEPT ) {
14.132 gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );
14.133 + gchar *end_path = gtk_file_chooser_get_current_folder( GTK_FILE_CHOOSER(file) );
14.134 + gui_set_configurable_path(CONFIG_SAVE_PATH,end_path);
14.135 + g_free(end_path);
14.136 dreamcast_load_state( filename );
14.137 }
14.138 gtk_widget_destroy(file);
14.139 @@ -194,8 +211,7 @@
14.140
14.141 void save_state_action_callback( GtkAction *action, gpointer user_data)
14.142 {
14.143 - const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH);
14.144 - save_file_dialog_cb( "Save state...", dreamcast_save_state, "*.dst", _("lxDream Save State (*.dst)"), dir );
14.145 + save_file_dialog_cb( "Save state...", dreamcast_save_state, "*.dst", _("lxDream Save State (*.dst)"), CONFIG_SAVE_PATH );
14.146 }
14.147 void about_action_callback( GtkAction *action, gpointer user_data)
14.148 {
14.149 @@ -269,8 +285,7 @@
14.150
14.151 void save_scene_action_callback( GtkAction *action, gpointer user_data)
14.152 {
14.153 - const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH);
14.154 - save_file_dialog_cb( _("Save next scene..."), pvr2_save_next_scene, "*.dsc", _("lxdream scene file (*.dsc)"), dir );
14.155 + save_file_dialog_cb( _("Save next scene..."), pvr2_save_next_scene, "*.dsc", _("lxdream scene file (*.dsc)"), CONFIG_SAVE_PATH );
14.156 }
14.157
14.158 int debug_window_get_selected_row( debug_window_t data );
15.1 --- a/src/gtkui/gtkui.c Wed Jun 24 05:10:25 2009 +0000
15.2 +++ b/src/gtkui/gtkui.c Wed Jun 24 06:06:40 2009 +0000
15.3 @@ -544,17 +544,4 @@
15.4 return keyval;
15.5 }
15.6
15.7 -gchar *get_absolute_path( const gchar *in_path )
15.8 -{
15.9 - char tmp[PATH_MAX];
15.10 - if( in_path == NULL ) {
15.11 - return NULL;
15.12 - }
15.13 - if( in_path[0] == '/' || in_path[0] == 0 ) {
15.14 - return g_strdup(in_path);
15.15 - } else {
15.16 - getcwd(tmp, sizeof(tmp));
15.17 - return g_strdup_printf("%s%c%s", tmp, G_DIR_SEPARATOR, in_path);
15.18 - }
15.19 -}
15.20
16.1 --- a/src/gtkui/gtkui.h Wed Jun 24 05:10:25 2009 +0000
16.2 +++ b/src/gtkui/gtkui.h Wed Jun 24 06:06:40 2009 +0000
16.3 @@ -89,13 +89,13 @@
16.4
16.5 typedef gboolean (*file_callback_t)( const gchar *filename );
16.6 gchar *open_file_dialog( const char *title, const char *pattern, const char *patname,
16.7 - const gchar *initial_dir );
16.8 + int initial_dir_key );
16.9 gchar *save_file_dialog( const char *title, const char *pattern, const char *patname,
16.10 - const gchar *initial_dir );
16.11 + int initial_dir_key );
16.12 void open_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,
16.13 - const gchar *initial_dir );
16.14 + int initial_dir_key );
16.15 void save_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,
16.16 - const gchar *initial_dir );
16.17 + int initial_dir_key );
16.18 /**
16.19 * Extract the keyval of the key event if no modifier keys were pressed -
16.20 * in other words get the keyval of the key by itself. The other way around
16.21 @@ -114,13 +114,6 @@
16.22 guint gdk_keycode_to_modifier( GdkDisplay *display, guint keycode );
16.23
16.24 /**
16.25 - * Return an absolute path for the given input path, as a newly allocated
16.26 - * string. If the input path is already absolute, the returned string will
16.27 - * be identical to the input string.
16.28 - */
16.29 -gchar *get_absolute_path( const gchar *path );
16.30 -
16.31 -/**
16.32 * Construct a new pixbuf that takes ownership of the frame buffer
16.33 */
16.34 GdkPixbuf *gdk_pixbuf_new_from_frame_buffer( frame_buffer_t buffer );
17.1 --- a/src/gui.h Wed Jun 24 05:10:25 2009 +0000
17.2 +++ b/src/gui.h Wed Jun 24 06:06:40 2009 +0000
17.3 @@ -84,6 +84,29 @@
17.4 */
17.5 void gui_do_later( do_later_callback_t func );
17.6
17.7 +
17.8 +/******************* GUI helper functions *****************/
17.9 +/* The following functions effectively track the current path for each of the
17.10 + * 3 main categories (save, vmu, and disc/binary loading) independently. They
17.11 + * default to the config values, but can be updated continuously without
17.12 + * writing back to the config.
17.13 + */
17.14 +const gchar *gui_get_configurable_path(int key);
17.15 +void gui_set_configurable_path( int key, const gchar *path );
17.16 +
17.17 +/**
17.18 + * Notify the helper functions that the config paths have changed, in which
17.19 + * event they will revert to the config-specified versions.
17.20 + */
17.21 +void gui_config_paths_changed();
17.22 +
17.23 +/**
17.24 + * Return an absolute path for the given input path, as a newly allocated
17.25 + * string. If the input path is already absolute, the returned string will
17.26 + * be identical to the input string.
17.27 + */
17.28 +gchar *get_absolute_path( const gchar *path );
17.29 +
17.30 #ifdef __cplusplus
17.31 }
17.32 #endif
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/src/guiutil.c Wed Jun 24 06:06:40 2009 +0000
18.3 @@ -0,0 +1,66 @@
18.4 +/**
18.5 + * $Id$
18.6 + *
18.7 + * GUI helper functions that aren't specific to any particular implementation.
18.8 + *
18.9 + * Copyright (c) 2009 Nathan Keynes.
18.10 + *
18.11 + * This program is free software; you can redistribute it and/or modify
18.12 + * it under the terms of the GNU General Public License as published by
18.13 + * the Free Software Foundation; either version 2 of the License, or
18.14 + * (at your option) any later version.
18.15 + *
18.16 + * This program is distributed in the hope that it will be useful,
18.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.19 + * GNU General Public License for more details.
18.20 + */
18.21 +
18.22 +#include <glib/gstrfuncs.h>
18.23 +#include <glib/gutils.h>
18.24 +
18.25 +#include "gui.h"
18.26 +#include "config.h"
18.27 +
18.28 +static gchar *gui_paths[CONFIG_KEY_MAX];
18.29 +
18.30 +gchar *get_absolute_path( const gchar *in_path )
18.31 +{
18.32 + char tmp[PATH_MAX];
18.33 + if( in_path == NULL ) {
18.34 + return NULL;
18.35 + }
18.36 + if( in_path[0] == '/' || in_path[0] == 0 ) {
18.37 + return g_strdup(in_path);
18.38 + } else {
18.39 + getcwd(tmp, sizeof(tmp));
18.40 + return g_strdup_printf("%s%c%s", tmp, G_DIR_SEPARATOR, in_path);
18.41 + }
18.42 +}
18.43 +
18.44 +const gchar *gui_get_configurable_path( int key )
18.45 +{
18.46 + if( gui_paths[key] == NULL ) {
18.47 + gui_paths[key] = lxdream_get_global_config_path_value(key);
18.48 + /* If no path defined, go with the current working directory */
18.49 + if( gui_paths[key] == NULL ) {
18.50 + gui_paths[key] = get_absolute_path(".");
18.51 + }
18.52 + }
18.53 + return gui_paths[key];
18.54 +}
18.55 +
18.56 +void gui_set_configurable_path( int key, const gchar *path )
18.57 +{
18.58 + g_free(gui_paths[key]);
18.59 + gui_paths[key] = g_strdup(path);
18.60 +}
18.61 +
18.62 +void gui_config_paths_changed()
18.63 +{
18.64 + int i;
18.65 + for( i=0; i < CONFIG_KEY_MAX; i++ ) {
18.66 + g_free(gui_paths[i]);
18.67 + gui_paths[i] = NULL;
18.68 + }
18.69 +}
19.1 --- a/src/loader.c Wed Jun 24 05:10:25 2009 +0000
19.2 +++ b/src/loader.c Wed Jun 24 06:06:40 2009 +0000
19.3 @@ -107,17 +107,19 @@
19.4
19.5 void file_load_postload( const gchar *filename, int pc )
19.6 {
19.7 - const gchar *bootstrap_file = lxdream_get_config_value(CONFIG_BOOTSTRAP);
19.8 + gchar *bootstrap_file = lxdream_get_global_config_path_value(CONFIG_BOOTSTRAP);
19.9 if( bootstrap_file != NULL && bootstrap_file[0] != '\0' ) {
19.10 /* Load in a bootstrap before the binary, to initialize everything
19.11 * correctly
19.12 */
19.13 if( mem_load_block( bootstrap_file, BOOTSTRAP_LOAD_ADDR, BOOTSTRAP_SIZE ) == 0 ) {
19.14 dreamcast_program_loaded( filename, BOOTSTRAP_LOAD_ADDR+0x300 );
19.15 + g_free(bootstrap_file);
19.16 return;
19.17 }
19.18 }
19.19 dreamcast_program_loaded( filename, pc );
19.20 + g_free(bootstrap_file);
19.21 }
19.22
19.23
20.1 --- a/src/main.c Wed Jun 24 05:10:25 2009 +0000
20.2 +++ b/src/main.c Wed Jun 24 06:06:40 2009 +0000
20.3 @@ -265,9 +265,10 @@
20.4 }
20.5
20.6 if( gdrom_get_current_disc() == NULL ) {
20.7 - const gchar *disc_file = lxdream_get_config_value( CONFIG_GDROM );
20.8 + gchar *disc_file = lxdream_get_global_config_path_value( CONFIG_GDROM );
20.9 if( disc_file != NULL ) {
20.10 gdrom_mount_image( disc_file );
20.11 + g_free(disc_file);
20.12 }
20.13 }
20.14
.