Search
lxdream.org :: lxdream :: r1072:d82e04e6d497
lxdream 0.9.1
released Jun 29
Download Now
changeset1072:d82e04e6d497
parent1071:182cfe43c09e
child1073:92dfe34665ed
authornkeynes
dateTue Jul 21 20:33:21 2009 +1000 (14 years ago)
Heavy configuration management refactor
- Configuration groups now take both an on_change event handler and a
default keybinding handler, making most keybinding tasks quite simple
- GUI configuration all merged into a unified model, drastically reducing
the amount of GUI config code.

Bonuses
- OSX now has a hotkey preference pane
- GTK keybinding editor is much more usable
po/POTFILES.in
src/Makefile.am
src/Makefile.in
src/cocoaui/cocoa_cfg.m
src/cocoaui/cocoa_ctrl.m
src/cocoaui/cocoa_path.m
src/cocoaui/cocoa_prefs.m
src/cocoaui/cocoaui.h
src/config.c
src/config.h
src/display.c
src/display.h
src/dreamcast.c
src/dreamcast.h
src/gtkui/gtk_cfg.c
src/gtkui/gtk_ctrl.c
src/gtkui/gtk_hotkeys.c
src/gtkui/gtk_path.c
src/gtkui/gtkcb.c
src/gtkui/gtkui.h
src/hotkeys.c
src/hotkeys.h
src/maple/controller.c
src/maple/kbd.c
src/maple/lightgun.c
src/maple/maple.c
src/maple/maple.h
src/maple/mouse.c
src/maple/vmu.c
1.1 --- a/po/POTFILES.in Tue Jul 21 20:21:52 2009 +1000
1.2 +++ b/po/POTFILES.in Tue Jul 21 20:33:21 2009 +1000
1.3 @@ -13,9 +13,9 @@
1.4 src/bootstrap.c
1.5 src/bootstrap.h
1.6 src/clock.h
1.7 +src/cocoaui/cocoa_cfg.m
1.8 src/cocoaui/cocoa_ctrl.m
1.9 src/cocoaui/cocoa_gd.m
1.10 -src/cocoaui/cocoa_path.m
1.11 src/cocoaui/cocoa_prefs.m
1.12 src/cocoaui/cocoaui.h
1.13 src/cocoaui/cocoaui.m
1.14 @@ -84,13 +84,12 @@
1.15 src/gdrom/packet.h
1.16 src/gettext.h
1.17 src/gtkui/gtkcb.c
1.18 +src/gtkui/gtk_cfg.c
1.19 src/gtkui/gtk_ctrl.c
1.20 src/gtkui/gtk_debug.c
1.21 src/gtkui/gtk_dump.c
1.22 src/gtkui/gtk_gd.c
1.23 -src/gtkui/gtk_hotkeys.c
1.24 src/gtkui/gtk_mmio.c
1.25 -src/gtkui/gtk_path.c
1.26 src/gtkui/gtkui.c
1.27 src/gtkui/gtkui.h
1.28 src/gtkui/gtk_win.c
2.1 --- a/src/Makefile.am Tue Jul 21 20:21:52 2009 +1000
2.2 +++ b/src/Makefile.am Tue Jul 21 20:33:21 2009 +1000
2.3 @@ -98,16 +98,16 @@
2.4
2.5 if GUI_GTK
2.6 lxdream_SOURCES += gtkui/gtkui.c gtkui/gtkui.h \
2.7 - gtkui/gtk_win.c gtkui/gtkcb.c \
2.8 + gtkui/gtk_win.c gtkui/gtkcb.c gtkui/gtk_cfg.c \
2.9 gtkui/gtk_mmio.c gtkui/gtk_debug.c gtkui/gtk_dump.c \
2.10 - gtkui/gtk_ctrl.c gtkui/gtk_path.c gtkui/gtk_gd.c \
2.11 - gtkui/gtk_hotkeys.c drivers/net_glib.c drivers/video_gtk.c
2.12 + gtkui/gtk_ctrl.c gtkui/gtk_gd.c \
2.13 + drivers/net_glib.c drivers/video_gtk.c
2.14 endif
2.15
2.16 if GUI_COCOA
2.17 -lxdream_SOURCES += cocoaui/cocoaui.m cocoaui/cocoaui.h \
2.18 +lxdream_SOURCES += cocoaui/cocoaui.m cocoaui/cocoaui.h cocoaui/cocoa_cfg.m \
2.19 cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \
2.20 - cocoaui/cocoa_path.m cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \
2.21 + cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \
2.22 drivers/net_osx.m drivers/video_osx.m \
2.23 drivers/mac_keymap.h drivers/mac_keymap.txt
2.24 else
3.1 --- a/src/Makefile.in Tue Jul 21 20:21:52 2009 +1000
3.2 +++ b/src/Makefile.in Tue Jul 21 20:33:21 2009 +1000
3.3 @@ -52,14 +52,14 @@
3.4
3.5 @BUILD_SH4X86_TRUE@am__append_3 = test/testsh4x86
3.6 @GUI_GTK_TRUE@am__append_4 = gtkui/gtkui.c gtkui/gtkui.h \
3.7 -@GUI_GTK_TRUE@ gtkui/gtk_win.c gtkui/gtkcb.c \
3.8 +@GUI_GTK_TRUE@ gtkui/gtk_win.c gtkui/gtkcb.c gtkui/gtk_cfg.c \
3.9 @GUI_GTK_TRUE@ gtkui/gtk_mmio.c gtkui/gtk_debug.c gtkui/gtk_dump.c \
3.10 -@GUI_GTK_TRUE@ gtkui/gtk_ctrl.c gtkui/gtk_path.c gtkui/gtk_gd.c \
3.11 -@GUI_GTK_TRUE@ gtkui/gtk_hotkeys.c drivers/net_glib.c drivers/video_gtk.c
3.12 +@GUI_GTK_TRUE@ gtkui/gtk_ctrl.c gtkui/gtk_gd.c \
3.13 +@GUI_GTK_TRUE@ drivers/net_glib.c drivers/video_gtk.c
3.14
3.15 -@GUI_COCOA_TRUE@am__append_5 = cocoaui/cocoaui.m cocoaui/cocoaui.h \
3.16 +@GUI_COCOA_TRUE@am__append_5 = cocoaui/cocoaui.m cocoaui/cocoaui.h cocoaui/cocoa_cfg.m \
3.17 @GUI_COCOA_TRUE@ cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \
3.18 -@GUI_COCOA_TRUE@ cocoaui/cocoa_path.m cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \
3.19 +@GUI_COCOA_TRUE@ cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \
3.20 @GUI_COCOA_TRUE@ drivers/net_osx.m drivers/video_osx.m \
3.21 @GUI_COCOA_TRUE@ drivers/mac_keymap.h drivers/mac_keymap.txt
3.22
3.23 @@ -174,13 +174,13 @@
3.24 x86dasm/dis-init.c x86dasm/dis-buf.c x86dasm/ansidecl.h \
3.25 x86dasm/bfd.h x86dasm/dis-asm.h x86dasm/symcat.h \
3.26 x86dasm/sysdep.h gtkui/gtkui.c gtkui/gtkui.h gtkui/gtk_win.c \
3.27 - gtkui/gtkcb.c gtkui/gtk_mmio.c gtkui/gtk_debug.c \
3.28 - gtkui/gtk_dump.c gtkui/gtk_ctrl.c gtkui/gtk_path.c \
3.29 - gtkui/gtk_gd.c gtkui/gtk_hotkeys.c drivers/net_glib.c \
3.30 - drivers/video_gtk.c cocoaui/cocoaui.m cocoaui/cocoaui.h \
3.31 + gtkui/gtkcb.c gtkui/gtk_cfg.c gtkui/gtk_mmio.c \
3.32 + gtkui/gtk_debug.c gtkui/gtk_dump.c gtkui/gtk_ctrl.c \
3.33 + gtkui/gtk_gd.c drivers/net_glib.c drivers/video_gtk.c \
3.34 + cocoaui/cocoaui.m cocoaui/cocoaui.h cocoaui/cocoa_cfg.m \
3.35 cocoaui/cocoa_win.m cocoaui/cocoa_gd.m cocoaui/cocoa_prefs.m \
3.36 - cocoaui/cocoa_path.m cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m \
3.37 - drivers/net_osx.m drivers/video_osx.m drivers/mac_keymap.h \
3.38 + cocoaui/cocoa_ctrl.m cocoaui/paths_osx.m drivers/net_osx.m \
3.39 + drivers/video_osx.m drivers/mac_keymap.h \
3.40 drivers/mac_keymap.txt paths_unix.c drivers/video_gdk.c \
3.41 drivers/video_glx.c drivers/video_glx.h drivers/video_nsgl.m \
3.42 drivers/video_nsgl.h drivers/audio_osx.m drivers/audio_sdl.c \
3.43 @@ -199,20 +199,19 @@
3.44 @GUI_GTK_TRUE@am__objects_3 = lxdream-gtkui.$(OBJEXT) \
3.45 @GUI_GTK_TRUE@ lxdream-gtk_win.$(OBJEXT) \
3.46 @GUI_GTK_TRUE@ lxdream-gtkcb.$(OBJEXT) \
3.47 +@GUI_GTK_TRUE@ lxdream-gtk_cfg.$(OBJEXT) \
3.48 @GUI_GTK_TRUE@ lxdream-gtk_mmio.$(OBJEXT) \
3.49 @GUI_GTK_TRUE@ lxdream-gtk_debug.$(OBJEXT) \
3.50 @GUI_GTK_TRUE@ lxdream-gtk_dump.$(OBJEXT) \
3.51 @GUI_GTK_TRUE@ lxdream-gtk_ctrl.$(OBJEXT) \
3.52 -@GUI_GTK_TRUE@ lxdream-gtk_path.$(OBJEXT) \
3.53 @GUI_GTK_TRUE@ lxdream-gtk_gd.$(OBJEXT) \
3.54 -@GUI_GTK_TRUE@ lxdream-gtk_hotkeys.$(OBJEXT) \
3.55 @GUI_GTK_TRUE@ lxdream-net_glib.$(OBJEXT) \
3.56 @GUI_GTK_TRUE@ lxdream-video_gtk.$(OBJEXT)
3.57 @GUI_COCOA_TRUE@am__objects_4 = lxdream-cocoaui.$(OBJEXT) \
3.58 +@GUI_COCOA_TRUE@ lxdream-cocoa_cfg.$(OBJEXT) \
3.59 @GUI_COCOA_TRUE@ lxdream-cocoa_win.$(OBJEXT) \
3.60 @GUI_COCOA_TRUE@ lxdream-cocoa_gd.$(OBJEXT) \
3.61 @GUI_COCOA_TRUE@ lxdream-cocoa_prefs.$(OBJEXT) \
3.62 -@GUI_COCOA_TRUE@ lxdream-cocoa_path.$(OBJEXT) \
3.63 @GUI_COCOA_TRUE@ lxdream-cocoa_ctrl.$(OBJEXT) \
3.64 @GUI_COCOA_TRUE@ lxdream-paths_osx.$(OBJEXT) \
3.65 @GUI_COCOA_TRUE@ lxdream-net_osx.$(OBJEXT) \
3.66 @@ -759,9 +758,9 @@
3.67 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cd_none.Po@am__quote@
3.68 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cd_osx.Po@am__quote@
3.69 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cdi.Po@am__quote@
3.70 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cocoa_cfg.Po@am__quote@
3.71 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cocoa_ctrl.Po@am__quote@
3.72 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cocoa_gd.Po@am__quote@
3.73 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cocoa_path.Po@am__quote@
3.74 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cocoa_prefs.Po@am__quote@
3.75 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cocoa_win.Po@am__quote@
3.76 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-cocoaui.Po@am__quote@
3.77 @@ -785,13 +784,12 @@
3.78 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gl_slsrc.Po@am__quote@
3.79 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-glrender.Po@am__quote@
3.80 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-glutil.Po@am__quote@
3.81 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_cfg.Po@am__quote@
3.82 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_ctrl.Po@am__quote@
3.83 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_debug.Po@am__quote@
3.84 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_dump.Po@am__quote@
3.85 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_gd.Po@am__quote@
3.86 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_hotkeys.Po@am__quote@
3.87 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_mmio.Po@am__quote@
3.88 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_path.Po@am__quote@
3.89 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtk_win.Po@am__quote@
3.90 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtkcb.Po@am__quote@
3.91 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-gtkui.Po@am__quote@
3.92 @@ -2100,6 +2098,20 @@
3.93 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.94 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtkcb.obj `if test -f 'gtkui/gtkcb.c'; then $(CYGPATH_W) 'gtkui/gtkcb.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtkcb.c'; fi`
3.95
3.96 +lxdream-gtk_cfg.o: gtkui/gtk_cfg.c
3.97 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_cfg.o -MD -MP -MF "$(DEPDIR)/lxdream-gtk_cfg.Tpo" -c -o lxdream-gtk_cfg.o `test -f 'gtkui/gtk_cfg.c' || echo '$(srcdir)/'`gtkui/gtk_cfg.c; \
3.98 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_cfg.Tpo" "$(DEPDIR)/lxdream-gtk_cfg.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_cfg.Tpo"; exit 1; fi
3.99 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtkui/gtk_cfg.c' object='lxdream-gtk_cfg.o' libtool=no @AMDEPBACKSLASH@
3.100 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.101 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_cfg.o `test -f 'gtkui/gtk_cfg.c' || echo '$(srcdir)/'`gtkui/gtk_cfg.c
3.102 +
3.103 +lxdream-gtk_cfg.obj: gtkui/gtk_cfg.c
3.104 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_cfg.obj -MD -MP -MF "$(DEPDIR)/lxdream-gtk_cfg.Tpo" -c -o lxdream-gtk_cfg.obj `if test -f 'gtkui/gtk_cfg.c'; then $(CYGPATH_W) 'gtkui/gtk_cfg.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_cfg.c'; fi`; \
3.105 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_cfg.Tpo" "$(DEPDIR)/lxdream-gtk_cfg.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_cfg.Tpo"; exit 1; fi
3.106 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtkui/gtk_cfg.c' object='lxdream-gtk_cfg.obj' libtool=no @AMDEPBACKSLASH@
3.107 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.108 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_cfg.obj `if test -f 'gtkui/gtk_cfg.c'; then $(CYGPATH_W) 'gtkui/gtk_cfg.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_cfg.c'; fi`
3.109 +
3.110 lxdream-gtk_mmio.o: gtkui/gtk_mmio.c
3.111 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_mmio.o -MD -MP -MF "$(DEPDIR)/lxdream-gtk_mmio.Tpo" -c -o lxdream-gtk_mmio.o `test -f 'gtkui/gtk_mmio.c' || echo '$(srcdir)/'`gtkui/gtk_mmio.c; \
3.112 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_mmio.Tpo" "$(DEPDIR)/lxdream-gtk_mmio.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_mmio.Tpo"; exit 1; fi
3.113 @@ -2156,20 +2168,6 @@
3.114 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.115 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_ctrl.obj `if test -f 'gtkui/gtk_ctrl.c'; then $(CYGPATH_W) 'gtkui/gtk_ctrl.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_ctrl.c'; fi`
3.116
3.117 -lxdream-gtk_path.o: gtkui/gtk_path.c
3.118 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_path.o -MD -MP -MF "$(DEPDIR)/lxdream-gtk_path.Tpo" -c -o lxdream-gtk_path.o `test -f 'gtkui/gtk_path.c' || echo '$(srcdir)/'`gtkui/gtk_path.c; \
3.119 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_path.Tpo" "$(DEPDIR)/lxdream-gtk_path.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_path.Tpo"; exit 1; fi
3.120 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtkui/gtk_path.c' object='lxdream-gtk_path.o' libtool=no @AMDEPBACKSLASH@
3.121 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.122 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_path.o `test -f 'gtkui/gtk_path.c' || echo '$(srcdir)/'`gtkui/gtk_path.c
3.123 -
3.124 -lxdream-gtk_path.obj: gtkui/gtk_path.c
3.125 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_path.obj -MD -MP -MF "$(DEPDIR)/lxdream-gtk_path.Tpo" -c -o lxdream-gtk_path.obj `if test -f 'gtkui/gtk_path.c'; then $(CYGPATH_W) 'gtkui/gtk_path.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_path.c'; fi`; \
3.126 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_path.Tpo" "$(DEPDIR)/lxdream-gtk_path.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_path.Tpo"; exit 1; fi
3.127 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtkui/gtk_path.c' object='lxdream-gtk_path.obj' libtool=no @AMDEPBACKSLASH@
3.128 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.129 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_path.obj `if test -f 'gtkui/gtk_path.c'; then $(CYGPATH_W) 'gtkui/gtk_path.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_path.c'; fi`
3.130 -
3.131 lxdream-gtk_gd.o: gtkui/gtk_gd.c
3.132 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_gd.o -MD -MP -MF "$(DEPDIR)/lxdream-gtk_gd.Tpo" -c -o lxdream-gtk_gd.o `test -f 'gtkui/gtk_gd.c' || echo '$(srcdir)/'`gtkui/gtk_gd.c; \
3.133 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_gd.Tpo" "$(DEPDIR)/lxdream-gtk_gd.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_gd.Tpo"; exit 1; fi
3.134 @@ -2184,20 +2182,6 @@
3.135 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.136 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_gd.obj `if test -f 'gtkui/gtk_gd.c'; then $(CYGPATH_W) 'gtkui/gtk_gd.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_gd.c'; fi`
3.137
3.138 -lxdream-gtk_hotkeys.o: gtkui/gtk_hotkeys.c
3.139 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_hotkeys.o -MD -MP -MF "$(DEPDIR)/lxdream-gtk_hotkeys.Tpo" -c -o lxdream-gtk_hotkeys.o `test -f 'gtkui/gtk_hotkeys.c' || echo '$(srcdir)/'`gtkui/gtk_hotkeys.c; \
3.140 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_hotkeys.Tpo" "$(DEPDIR)/lxdream-gtk_hotkeys.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_hotkeys.Tpo"; exit 1; fi
3.141 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtkui/gtk_hotkeys.c' object='lxdream-gtk_hotkeys.o' libtool=no @AMDEPBACKSLASH@
3.142 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.143 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_hotkeys.o `test -f 'gtkui/gtk_hotkeys.c' || echo '$(srcdir)/'`gtkui/gtk_hotkeys.c
3.144 -
3.145 -lxdream-gtk_hotkeys.obj: gtkui/gtk_hotkeys.c
3.146 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-gtk_hotkeys.obj -MD -MP -MF "$(DEPDIR)/lxdream-gtk_hotkeys.Tpo" -c -o lxdream-gtk_hotkeys.obj `if test -f 'gtkui/gtk_hotkeys.c'; then $(CYGPATH_W) 'gtkui/gtk_hotkeys.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_hotkeys.c'; fi`; \
3.147 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-gtk_hotkeys.Tpo" "$(DEPDIR)/lxdream-gtk_hotkeys.Po"; else rm -f "$(DEPDIR)/lxdream-gtk_hotkeys.Tpo"; exit 1; fi
3.148 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtkui/gtk_hotkeys.c' object='lxdream-gtk_hotkeys.obj' libtool=no @AMDEPBACKSLASH@
3.149 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.150 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gtk_hotkeys.obj `if test -f 'gtkui/gtk_hotkeys.c'; then $(CYGPATH_W) 'gtkui/gtk_hotkeys.c'; else $(CYGPATH_W) '$(srcdir)/gtkui/gtk_hotkeys.c'; fi`
3.151 -
3.152 lxdream-net_glib.o: drivers/net_glib.c
3.153 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-net_glib.o -MD -MP -MF "$(DEPDIR)/lxdream-net_glib.Tpo" -c -o lxdream-net_glib.o `test -f 'drivers/net_glib.c' || echo '$(srcdir)/'`drivers/net_glib.c; \
3.154 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-net_glib.Tpo" "$(DEPDIR)/lxdream-net_glib.Po"; else rm -f "$(DEPDIR)/lxdream-net_glib.Tpo"; exit 1; fi
3.155 @@ -2590,6 +2574,20 @@
3.156 @AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.157 @am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o lxdream-cocoaui.obj `if test -f 'cocoaui/cocoaui.m'; then $(CYGPATH_W) 'cocoaui/cocoaui.m'; else $(CYGPATH_W) '$(srcdir)/cocoaui/cocoaui.m'; fi`
3.158
3.159 +lxdream-cocoa_cfg.o: cocoaui/cocoa_cfg.m
3.160 +@am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT lxdream-cocoa_cfg.o -MD -MP -MF "$(DEPDIR)/lxdream-cocoa_cfg.Tpo" -c -o lxdream-cocoa_cfg.o `test -f 'cocoaui/cocoa_cfg.m' || echo '$(srcdir)/'`cocoaui/cocoa_cfg.m; \
3.161 +@am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/lxdream-cocoa_cfg.Tpo" "$(DEPDIR)/lxdream-cocoa_cfg.Po"; else rm -f "$(DEPDIR)/lxdream-cocoa_cfg.Tpo"; exit 1; fi
3.162 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='cocoaui/cocoa_cfg.m' object='lxdream-cocoa_cfg.o' libtool=no @AMDEPBACKSLASH@
3.163 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.164 +@am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o lxdream-cocoa_cfg.o `test -f 'cocoaui/cocoa_cfg.m' || echo '$(srcdir)/'`cocoaui/cocoa_cfg.m
3.165 +
3.166 +lxdream-cocoa_cfg.obj: cocoaui/cocoa_cfg.m
3.167 +@am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT lxdream-cocoa_cfg.obj -MD -MP -MF "$(DEPDIR)/lxdream-cocoa_cfg.Tpo" -c -o lxdream-cocoa_cfg.obj `if test -f 'cocoaui/cocoa_cfg.m'; then $(CYGPATH_W) 'cocoaui/cocoa_cfg.m'; else $(CYGPATH_W) '$(srcdir)/cocoaui/cocoa_cfg.m'; fi`; \
3.168 +@am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/lxdream-cocoa_cfg.Tpo" "$(DEPDIR)/lxdream-cocoa_cfg.Po"; else rm -f "$(DEPDIR)/lxdream-cocoa_cfg.Tpo"; exit 1; fi
3.169 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='cocoaui/cocoa_cfg.m' object='lxdream-cocoa_cfg.obj' libtool=no @AMDEPBACKSLASH@
3.170 +@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.171 +@am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o lxdream-cocoa_cfg.obj `if test -f 'cocoaui/cocoa_cfg.m'; then $(CYGPATH_W) 'cocoaui/cocoa_cfg.m'; else $(CYGPATH_W) '$(srcdir)/cocoaui/cocoa_cfg.m'; fi`
3.172 +
3.173 lxdream-cocoa_win.o: cocoaui/cocoa_win.m
3.174 @am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT lxdream-cocoa_win.o -MD -MP -MF "$(DEPDIR)/lxdream-cocoa_win.Tpo" -c -o lxdream-cocoa_win.o `test -f 'cocoaui/cocoa_win.m' || echo '$(srcdir)/'`cocoaui/cocoa_win.m; \
3.175 @am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/lxdream-cocoa_win.Tpo" "$(DEPDIR)/lxdream-cocoa_win.Po"; else rm -f "$(DEPDIR)/lxdream-cocoa_win.Tpo"; exit 1; fi
3.176 @@ -2632,20 +2630,6 @@
3.177 @AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.178 @am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o lxdream-cocoa_prefs.obj `if test -f 'cocoaui/cocoa_prefs.m'; then $(CYGPATH_W) 'cocoaui/cocoa_prefs.m'; else $(CYGPATH_W) '$(srcdir)/cocoaui/cocoa_prefs.m'; fi`
3.179
3.180 -lxdream-cocoa_path.o: cocoaui/cocoa_path.m
3.181 -@am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT lxdream-cocoa_path.o -MD -MP -MF "$(DEPDIR)/lxdream-cocoa_path.Tpo" -c -o lxdream-cocoa_path.o `test -f 'cocoaui/cocoa_path.m' || echo '$(srcdir)/'`cocoaui/cocoa_path.m; \
3.182 -@am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/lxdream-cocoa_path.Tpo" "$(DEPDIR)/lxdream-cocoa_path.Po"; else rm -f "$(DEPDIR)/lxdream-cocoa_path.Tpo"; exit 1; fi
3.183 -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='cocoaui/cocoa_path.m' object='lxdream-cocoa_path.o' libtool=no @AMDEPBACKSLASH@
3.184 -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.185 -@am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o lxdream-cocoa_path.o `test -f 'cocoaui/cocoa_path.m' || echo '$(srcdir)/'`cocoaui/cocoa_path.m
3.186 -
3.187 -lxdream-cocoa_path.obj: cocoaui/cocoa_path.m
3.188 -@am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT lxdream-cocoa_path.obj -MD -MP -MF "$(DEPDIR)/lxdream-cocoa_path.Tpo" -c -o lxdream-cocoa_path.obj `if test -f 'cocoaui/cocoa_path.m'; then $(CYGPATH_W) 'cocoaui/cocoa_path.m'; else $(CYGPATH_W) '$(srcdir)/cocoaui/cocoa_path.m'; fi`; \
3.189 -@am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/lxdream-cocoa_path.Tpo" "$(DEPDIR)/lxdream-cocoa_path.Po"; else rm -f "$(DEPDIR)/lxdream-cocoa_path.Tpo"; exit 1; fi
3.190 -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='cocoaui/cocoa_path.m' object='lxdream-cocoa_path.obj' libtool=no @AMDEPBACKSLASH@
3.191 -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3.192 -@am__fastdepOBJC_FALSE@ $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -c -o lxdream-cocoa_path.obj `if test -f 'cocoaui/cocoa_path.m'; then $(CYGPATH_W) 'cocoaui/cocoa_path.m'; else $(CYGPATH_W) '$(srcdir)/cocoaui/cocoa_path.m'; fi`
3.193 -
3.194 lxdream-cocoa_ctrl.o: cocoaui/cocoa_ctrl.m
3.195 @am__fastdepOBJC_TRUE@ if $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -MT lxdream-cocoa_ctrl.o -MD -MP -MF "$(DEPDIR)/lxdream-cocoa_ctrl.Tpo" -c -o lxdream-cocoa_ctrl.o `test -f 'cocoaui/cocoa_ctrl.m' || echo '$(srcdir)/'`cocoaui/cocoa_ctrl.m; \
3.196 @am__fastdepOBJC_TRUE@ then mv -f "$(DEPDIR)/lxdream-cocoa_ctrl.Tpo" "$(DEPDIR)/lxdream-cocoa_ctrl.Po"; else rm -f "$(DEPDIR)/lxdream-cocoa_ctrl.Tpo"; exit 1; fi
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/cocoaui/cocoa_cfg.m Tue Jul 21 20:33:21 2009 +1000
4.3 @@ -0,0 +1,383 @@
4.4 +/**
4.5 + * $Id$
4.6 + *
4.7 + * Construct and manage a configuration pane based on an underlying
4.8 + * configuration group.
4.9 + *
4.10 + * Copyright (c) 2009 Nathan Keynes.
4.11 + *
4.12 + * This program is free software; you can redistribute it and/or modify
4.13 + * it under the terms of the GNU General Public License as published by
4.14 + * the Free Software Foundation; either version 2 of the License, or
4.15 + * (at your option) any later version.
4.16 + *
4.17 + * This program is distributed in the hope that it will be useful,
4.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.20 + * GNU General Public License for more details.
4.21 + */
4.22 +
4.23 +#include "cocoaui.h"
4.24 +#include "display.h"
4.25 +#include "lxpaths.h"
4.26 +#include "maple/maple.h"
4.27 +
4.28 +static void cocoa_config_keysym_hook(void *data, const gchar *keysym);
4.29 +
4.30 +@interface KeyBindingEditor (Private)
4.31 +- (void)updateKeysym: (const gchar *)sym;
4.32 +@end
4.33 +
4.34 +@implementation KeyBindingEditor
4.35 +- (id)init
4.36 +{
4.37 + self = [super init];
4.38 + isPrimed = NO;
4.39 + lastValue = nil;
4.40 + [self setFieldEditor: YES];
4.41 + [self setEditable: FALSE];
4.42 + return self;
4.43 +}
4.44 +- (void)dealloc
4.45 +{
4.46 + if( lastValue != nil ) {
4.47 + [lastValue release];
4.48 + lastValue = nil;
4.49 + }
4.50 + [super dealloc];
4.51 +}
4.52 +- (void)setPrimed: (BOOL)primed
4.53 +{
4.54 + if( primed != isPrimed ) {
4.55 + isPrimed = primed;
4.56 + if( primed ) {
4.57 + lastValue = [[NSString stringWithString: [self string]] retain];
4.58 + [self setString: @"<press key>"];
4.59 + input_set_keysym_hook(cocoa_config_keysym_hook, self);
4.60 + } else {
4.61 + [lastValue release];
4.62 + lastValue = nil;
4.63 + input_set_keysym_hook(NULL,NULL);
4.64 + }
4.65 + }
4.66 +}
4.67 +- (BOOL)resignFirstResponder
4.68 +{
4.69 + if( isPrimed ) {
4.70 + [self setString: lastValue];
4.71 + [self setPrimed: NO];
4.72 + }
4.73 + return [super resignFirstResponder];
4.74 +}
4.75 +- (void)fireBindingChanged
4.76 +{
4.77 + id delegate = [self delegate];
4.78 + if( delegate != nil && [delegate respondsToSelector:@selector(textDidChange:)] ) {
4.79 + [delegate textDidChange: [NSNotification notificationWithName: NSTextDidChangeNotification object: self]];
4.80 + }
4.81 +}
4.82 +
4.83 +- (void)updateKeysym: (const gchar *)sym
4.84 +{
4.85 + if( sym != NULL ) {
4.86 + [self setString: [NSString stringWithCString: sym]];
4.87 + [self setPrimed: NO];
4.88 + [self fireBindingChanged];
4.89 + }
4.90 +}
4.91 +- (void)updateMousesym: (int)button
4.92 +{
4.93 + gchar *keysym = input_keycode_to_keysym( &system_mouse_driver, (button+1) );
4.94 + if( keysym != NULL ) {
4.95 + [self updateKeysym: keysym ];
4.96 + g_free(keysym);
4.97 + }
4.98 +}
4.99 +- (void)keyPressed: (int)keycode
4.100 +{
4.101 + gchar *keysym = input_keycode_to_keysym(NULL, keycode);
4.102 + if( keysym != NULL ) {
4.103 + [self updateKeysym: keysym];
4.104 + g_free(keysym);
4.105 + }
4.106 +}
4.107 +- (void)insertText:(id)string
4.108 +{
4.109 + // Do nothing
4.110 +}
4.111 +- (void)mouseDown: (NSEvent *)event
4.112 +{
4.113 + if( isPrimed ) {
4.114 + [self updateMousesym: 0];
4.115 + } else {
4.116 + [self setPrimed: YES];
4.117 + [super mouseDown: event];
4.118 + }
4.119 +}
4.120 +- (void)rightMouseDown: (NSEvent *)event
4.121 +{
4.122 + if( isPrimed ) {
4.123 + [self updateMousesym: 1];
4.124 + }
4.125 +}
4.126 +- (void)otherMouseDown: (NSEvent *)event
4.127 +{
4.128 + if( isPrimed ) {
4.129 + [self updateMousesym: [event buttonNumber]];
4.130 + }
4.131 +}
4.132 +- (void)keyDown: (NSEvent *) event
4.133 +{
4.134 + NSString *chars = [event characters];
4.135 + if( isPrimed ) {
4.136 + if( chars != NULL && [chars length] == 1 && [chars characterAtIndex: 0] == 27 ) {
4.137 + // Escape char = abort change
4.138 + [self setString: lastValue];
4.139 + [self setPrimed: NO];
4.140 + } else {
4.141 + [self keyPressed: ([event keyCode]+1)];
4.142 + }
4.143 + } else {
4.144 + if( chars != NULL && [chars length] == 1 ) {
4.145 + int ch = [chars characterAtIndex: 0];
4.146 + switch( ch ) {
4.147 + case 0x7F:
4.148 + [self setString: @""];
4.149 + [self fireBindingChanged];
4.150 + break;
4.151 + case '\r':
4.152 + [self setPrimed: YES];
4.153 + break;
4.154 + default:
4.155 + [super keyDown: event];
4.156 + break;
4.157 + }
4.158 + } else {
4.159 + [super keyDown: event];
4.160 + }
4.161 + }
4.162 +}
4.163 +- (void)flagsChanged: (NSEvent *) event
4.164 +{
4.165 + if( isPrimed ) {
4.166 + [self keyPressed: ([event keyCode]+1)];
4.167 + }
4.168 + [super flagsChanged: event];
4.169 +}
4.170 +@end
4.171 +
4.172 +static void cocoa_config_keysym_hook(void *data, const gchar *keysym)
4.173 +{
4.174 + KeyBindingEditor *editor = (KeyBindingEditor *)data;
4.175 + [editor updateKeysym: keysym];
4.176 +}
4.177 +
4.178 +@implementation KeyBindingField
4.179 +@end
4.180 +
4.181 +/*************************** Configuration sub-view ***********************/
4.182 +
4.183 +#define KEYBINDING_SIZE 110
4.184 +#define DEFAULT_LABEL_WIDTH 150
4.185 +#define RIGHT_MARGIN 40
4.186 +
4.187 +@implementation ConfigurationView
4.188 +- (id)initWithFrame: (NSRect)frameRect
4.189 +{
4.190 + return [self initWithFrame: frameRect configGroup: NULL];
4.191 +}
4.192 +- (id)initWithFrame: (NSRect)frameRect configGroup: (lxdream_config_group_t)config
4.193 +{
4.194 + if( [super initWithFrame: frameRect] == nil ) {
4.195 + return nil;
4.196 + } else {
4.197 + group = NULL;
4.198 + labelWidth = DEFAULT_LABEL_WIDTH;
4.199 + [self setConfigGroup: config];
4.200 + return self;
4.201 + }
4.202 +}
4.203 +- (BOOL)isFlipped
4.204 +{
4.205 + return YES;
4.206 +}
4.207 +- (void)setLabelWidth: (int)width
4.208 +{
4.209 + labelWidth = width;
4.210 +}
4.211 +- (void)removeSubviews
4.212 +{
4.213 + [[self subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
4.214 +}
4.215 +- (void)updateField: (int)binding
4.216 +{
4.217 + const gchar *p = NULL;
4.218 + NSString *val1 = [fields[binding][0] stringValue];
4.219 + if( fields[binding][1] == NULL ) {
4.220 + p = [val1 UTF8String];
4.221 + lxdream_set_config_value( group, binding, p );
4.222 + } else {
4.223 + NSString *val2 = [fields[binding][1] stringValue];
4.224 + char buf[ [val1 length] + [val2 length] + 2 ];
4.225 +
4.226 + if( [val1 length] == 0 ) {
4.227 + if( [val2 length] != 0 ) {
4.228 + p = [val2 UTF8String];
4.229 + }
4.230 + } else if( [val2 length] == 0 ) {
4.231 + p = [val1 UTF8String];
4.232 + } else {
4.233 + sprintf( buf, "%s,%s", [val1 UTF8String], [val2 UTF8String] );
4.234 + p = buf;
4.235 + }
4.236 + lxdream_set_config_value( group, binding, p );
4.237 + }
4.238 + lxdream_save_config();
4.239 +}
4.240 +
4.241 +- (void)controlTextDidChange: (NSNotification *)notify
4.242 +{
4.243 + if( [[notify object] isKindOfClass: [KeyBindingField class]] ) {
4.244 + [self updateField: [[notify object] tag]];
4.245 + }
4.246 +}
4.247 +- (void)controlTextDidEndEditing: (NSNotification *)notify
4.248 +{
4.249 + [self updateField: [[notify object] tag]];
4.250 +}
4.251 +
4.252 +- (void)openFileDialog: (id)sender
4.253 +{
4.254 + int tag = [sender tag];
4.255 + NSString *text = [fields[tag][0] stringValue];
4.256 + NSOpenPanel *panel = [NSOpenPanel openPanel];
4.257 + int result = [panel runModalForDirectory: nil file: nil types: nil];
4.258 + if( result == NSOKButton && [[panel filenames] count] > 0 ) {
4.259 + NSString *filename = [[panel filenames] objectAtIndex: 0];
4.260 + gchar *str = get_escaped_path( [filename UTF8String] );
4.261 + [fields[tag][0] setStringValue: [NSString stringWithUTF8String: str]];
4.262 + lxdream_set_global_config_value(tag,str);
4.263 + lxdream_save_config();
4.264 + }
4.265 +}
4.266 +- (void)openDirDialog: (id)sender
4.267 +{
4.268 + int tag = [sender tag];
4.269 + NSString *text = [fields[tag][0] stringValue];
4.270 + NSOpenPanel *panel = [NSOpenPanel openPanel];
4.271 + [panel setCanChooseDirectories: YES];
4.272 + [panel setCanCreateDirectories: YES];
4.273 + int result = [panel runModalForDirectory: nil file: nil types: nil];
4.274 + if( result == NSOKButton && [[panel filenames] count] > 0 ) {
4.275 + NSString *filename = [[panel filenames] objectAtIndex: 0];
4.276 + gchar *str = get_escaped_path( [filename UTF8String] );
4.277 + [fields[tag][0] setStringValue: [NSString stringWithUTF8String: str]];
4.278 + lxdream_set_global_config_value(tag,str);
4.279 + lxdream_save_config();
4.280 + }
4.281 +}
4.282 +
4.283 +- (void)setConfigGroup: (lxdream_config_group_t) config
4.284 +{
4.285 + if( group == config ) {
4.286 + return;
4.287 + }
4.288 + int width = [self frame].size.width;
4.289 + int fieldWidth;
4.290 +
4.291 + group = config;
4.292 + [self removeSubviews];
4.293 + if( config != NULL && config->params[0].key != NULL ) {
4.294 + int count, i, y, x;
4.295 +
4.296 + for( count=0; config->params[count].label != NULL; count++ );
4.297 + int minWidth = labelWidth+KEYBINDING_SIZE*2+TEXT_GAP*4;
4.298 + if( minWidth > width ) {
4.299 + width = minWidth;
4.300 + }
4.301 + NSSize size = NSMakeSize( width, count*(TEXT_HEIGHT+TEXT_GAP)+TEXT_GAP);
4.302 + [self setFrameSize: size];
4.303 + [self scrollRectToVisible: NSMakeRect(0,0,1,1)];
4.304 +
4.305 + x = TEXT_GAP;
4.306 + y = TEXT_GAP;
4.307 + for( i=0; config->params[i].label != NULL; i++ ) {
4.308 + /* Add label */
4.309 + NSRect frame = NSMakeRect(x, y + 2, labelWidth, LABEL_HEIGHT);
4.310 + NSTextField *label = cocoa_gui_add_label(self, NS_(config->params[i].label), frame);
4.311 + [label setAlignment: NSRightTextAlignment];
4.312 +
4.313 + switch(config->params[i].type) {
4.314 + case CONFIG_TYPE_KEY:
4.315 + frame = NSMakeRect( x + labelWidth + TEXT_GAP, y, KEYBINDING_SIZE, TEXT_HEIGHT);
4.316 + fields[i][0] = [[KeyBindingField alloc] initWithFrame: frame];
4.317 + [fields[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
4.318 + [fields[i][0] setTag: i];
4.319 + [fields[i][0] setDelegate: self];
4.320 + [self addSubview: fields[i][0]];
4.321 +
4.322 + frame = NSMakeRect( x + labelWidth + KEYBINDING_SIZE + (TEXT_GAP*2), y, KEYBINDING_SIZE, TEXT_HEIGHT);
4.323 + fields[i][1] = [[KeyBindingField alloc] initWithFrame: frame];
4.324 + [fields[i][1] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
4.325 + [fields[i][1] setTag: i];
4.326 + [fields[i][1] setDelegate: self];
4.327 + [self addSubview: fields[i][1]];
4.328 +
4.329 + if( config->params[i].value != NULL ) {
4.330 + gchar **parts = g_strsplit(config->params[i].value,",",3);
4.331 + if( parts[0] != NULL ) {
4.332 + [fields[i][0] setStringValue: [NSString stringWithCString: parts[0]]];
4.333 + if( parts[1] != NULL ) {
4.334 + [fields[i][1] setStringValue: [NSString stringWithCString: parts[1]]];
4.335 + }
4.336 + }
4.337 + g_strfreev(parts);
4.338 + }
4.339 + break;
4.340 + case CONFIG_TYPE_FILE:
4.341 + case CONFIG_TYPE_PATH:
4.342 + fieldWidth = width - labelWidth - x - TEXT_HEIGHT - RIGHT_MARGIN - (TEXT_GAP*2);
4.343 + frame = NSMakeRect( x + labelWidth + TEXT_GAP, y, fieldWidth, TEXT_HEIGHT );
4.344 + NSTextField *field = [[NSTextField alloc] initWithFrame: frame];
4.345 + [field setTag: i];
4.346 + [field setStringValue: [NSString stringWithCString: config->params[i].value]];
4.347 + [field setDelegate: self];
4.348 + [field setAutoresizingMask: (NSViewMinYMargin|NSViewWidthSizable)];
4.349 +
4.350 + frame = NSMakeRect( x+ labelWidth + fieldWidth + (TEXT_GAP*2), y, TEXT_HEIGHT, TEXT_HEIGHT );
4.351 + NSButton *button = [[NSButton alloc] initWithFrame: frame];
4.352 + [button setTag: i];
4.353 + [button setTitle: @""];
4.354 + [button setButtonType: NSMomentaryPushInButton];
4.355 + [button setBezelStyle: NSRoundedDisclosureBezelStyle];
4.356 + [button setAutoresizingMask: (NSViewMinYMargin|NSViewMinXMargin)];
4.357 + [button setTarget: self];
4.358 + if( config->params[i].type == CONFIG_TYPE_FILE ) {
4.359 + [button setAction: @selector(openFileDialog:)];
4.360 + } else {
4.361 + [button setAction: @selector(openDirDialog:)];
4.362 + }
4.363 +
4.364 + [self addSubview: label];
4.365 + [self addSubview: field];
4.366 + [self addSubview: button];
4.367 + fields[i][0] = field;
4.368 + fields[i][1] = NULL;
4.369 + }
4.370 + y += (TEXT_HEIGHT + TEXT_GAP);
4.371 + }
4.372 + } else {
4.373 + [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];
4.374 + }
4.375 +}
4.376 +
4.377 +- (void)setDevice: (maple_device_t)newDevice
4.378 +{
4.379 + if( newDevice != NULL && !MAPLE_IS_VMU(newDevice) ) {
4.380 + [self setConfigGroup: maple_get_device_config(newDevice)];
4.381 + } else {
4.382 + [self setConfigGroup: NULL];
4.383 + }
4.384 +}
4.385 +@end
4.386 +
5.1 --- a/src/cocoaui/cocoa_ctrl.m Tue Jul 21 20:21:52 2009 +1000
5.2 +++ b/src/cocoaui/cocoa_ctrl.m Tue Jul 21 20:33:21 2009 +1000
5.3 @@ -31,291 +31,10 @@
5.4 #define LOAD_VMU_TAG -1
5.5 #define CREATE_VMU_TAG -2
5.6
5.7 -#define KEYBINDING_SIZE 110
5.8 +#define LABEL_WIDTH 85
5.9
5.10 -static void cocoa_config_keysym_hook(void *data, const gchar *keysym);
5.11 +
5.12 static gboolean cocoa_config_vmulist_hook(vmulist_change_type_t type, int idx, void *data);
5.13 -
5.14 -@interface KeyBindingEditor (Private)
5.15 -- (void)updateKeysym: (const gchar *)sym;
5.16 -@end
5.17 -
5.18 -@implementation KeyBindingEditor
5.19 -- (id)init
5.20 -{
5.21 - self = [super init];
5.22 - isPrimed = NO;
5.23 - lastValue = nil;
5.24 - [self setFieldEditor: YES];
5.25 - [self setEditable: FALSE];
5.26 - return self;
5.27 -}
5.28 -- (void)dealloc
5.29 -{
5.30 - if( lastValue != nil ) {
5.31 - [lastValue release];
5.32 - lastValue = nil;
5.33 - }
5.34 - [super dealloc];
5.35 -}
5.36 -- (void)setPrimed: (BOOL)primed
5.37 -{
5.38 - if( primed != isPrimed ) {
5.39 - isPrimed = primed;
5.40 - if( primed ) {
5.41 - lastValue = [[NSString stringWithString: [self string]] retain];
5.42 - [self setString: @"<press key>"];
5.43 - input_set_keysym_hook(cocoa_config_keysym_hook, self);
5.44 - } else {
5.45 - [lastValue release];
5.46 - lastValue = nil;
5.47 - input_set_keysym_hook(NULL,NULL);
5.48 - }
5.49 - }
5.50 -}
5.51 -- (BOOL)resignFirstResponder
5.52 -{
5.53 - if( isPrimed ) {
5.54 - [self setString: lastValue];
5.55 - [self setPrimed: NO];
5.56 - }
5.57 - return [super resignFirstResponder];
5.58 -}
5.59 -- (void)fireBindingChanged
5.60 -{
5.61 - id delegate = [self delegate];
5.62 - if( delegate != nil && [delegate respondsToSelector:@selector(textDidChange:)] ) {
5.63 - [delegate textDidChange: [NSNotification notificationWithName: NSTextDidChangeNotification object: self]];
5.64 - }
5.65 -}
5.66 -
5.67 -- (void)updateKeysym: (const gchar *)sym
5.68 -{
5.69 - if( sym != NULL ) {
5.70 - [self setString: [NSString stringWithCString: sym]];
5.71 - [self setPrimed: NO];
5.72 - [self fireBindingChanged];
5.73 - }
5.74 -}
5.75 -- (void)updateMousesym: (int)button
5.76 -{
5.77 - gchar *keysym = input_keycode_to_keysym( &system_mouse_driver, (button+1) );
5.78 - if( keysym != NULL ) {
5.79 - [self updateKeysym: keysym ];
5.80 - g_free(keysym);
5.81 - }
5.82 -}
5.83 -- (void)keyPressed: (int)keycode
5.84 -{
5.85 - gchar *keysym = input_keycode_to_keysym(NULL, keycode);
5.86 - if( keysym != NULL ) {
5.87 - [self updateKeysym: keysym];
5.88 - g_free(keysym);
5.89 - }
5.90 -}
5.91 -- (void)insertText:(id)string
5.92 -{
5.93 - // Do nothing
5.94 -}
5.95 -- (void)mouseDown: (NSEvent *)event
5.96 -{
5.97 - if( isPrimed ) {
5.98 - [self updateMousesym: 0];
5.99 - } else {
5.100 - [self setPrimed: YES];
5.101 - [super mouseDown: event];
5.102 - }
5.103 -}
5.104 -- (void)rightMouseDown: (NSEvent *)event
5.105 -{
5.106 - if( isPrimed ) {
5.107 - [self updateMousesym: 1];
5.108 - }
5.109 -}
5.110 -- (void)otherMouseDown: (NSEvent *)event
5.111 -{
5.112 - if( isPrimed ) {
5.113 - [self updateMousesym: [event buttonNumber]];
5.114 - }
5.115 -}
5.116 -- (void)keyDown: (NSEvent *) event
5.117 -{
5.118 - NSString *chars = [event characters];
5.119 - if( isPrimed ) {
5.120 - if( chars != NULL && [chars length] == 1 && [chars characterAtIndex: 0] == 27 ) {
5.121 - // Escape char = abort change
5.122 - [self setString: lastValue];
5.123 - [self setPrimed: NO];
5.124 - } else {
5.125 - [self keyPressed: ([event keyCode]+1)];
5.126 - }
5.127 - } else {
5.128 - if( chars != NULL && [chars length] == 1 ) {
5.129 - int ch = [chars characterAtIndex: 0];
5.130 - switch( ch ) {
5.131 - case 0x7F:
5.132 - [self setString: @""];
5.133 - [self fireBindingChanged];
5.134 - break;
5.135 - case '\r':
5.136 - [self setPrimed: YES];
5.137 - break;
5.138 - default:
5.139 - [super keyDown: event];
5.140 - break;
5.141 - }
5.142 - } else {
5.143 - [super keyDown: event];
5.144 - }
5.145 - }
5.146 -}
5.147 -- (void)flagsChanged: (NSEvent *) event
5.148 -{
5.149 - if( isPrimed ) {
5.150 - [self keyPressed: ([event keyCode]+1)];
5.151 - }
5.152 - [super flagsChanged: event];
5.153 -}
5.154 -@end
5.155 -
5.156 -static void cocoa_config_keysym_hook(void *data, const gchar *keysym)
5.157 -{
5.158 - KeyBindingEditor *editor = (KeyBindingEditor *)data;
5.159 - [editor updateKeysym: keysym];
5.160 -}
5.161 -
5.162 -
5.163 -@implementation KeyBindingField
5.164 -@end
5.165 -
5.166 -/*************************** Key-binding sub-view ***********************/
5.167 -
5.168 -#define MAX_KEY_BINDINGS 32
5.169 -
5.170 -@interface ControllerKeyBindingView : NSView
5.171 -{
5.172 - maple_device_t device;
5.173 - NSTextField *field[MAX_KEY_BINDINGS][2];
5.174 -}
5.175 -- (id)initWithFrame: (NSRect)frameRect;
5.176 -- (void)setDevice: (maple_device_t)device;
5.177 -@end
5.178 -
5.179 -@implementation ControllerKeyBindingView
5.180 -- (id)initWithFrame: (NSRect)frameRect
5.181 -{
5.182 - if( [super initWithFrame: frameRect] == nil ) {
5.183 - return nil;
5.184 - } else {
5.185 - device = NULL;
5.186 - return self;
5.187 - }
5.188 -}
5.189 -- (BOOL)isFlipped
5.190 -{
5.191 - return YES;
5.192 -}
5.193 -- (void)removeSubviews
5.194 -{
5.195 - [[self subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
5.196 -}
5.197 -- (void)controlTextDidChange: (NSNotification *)notify
5.198 -{
5.199 - const gchar *p = NULL;
5.200 - int binding = [[notify object] tag];
5.201 - NSString *val1 = [field[binding][0] stringValue];
5.202 - if( field[binding][1] == NULL ) {
5.203 - p = [val1 UTF8String];
5.204 - } else {
5.205 - NSString *val2 = [field[binding][1] stringValue];
5.206 - char buf[ [val1 length] + [val2 length] + 2 ];
5.207 -
5.208 - if( [val1 length] == 0 ) {
5.209 - if( [val2 length] != 0 ) {
5.210 - p = [val2 UTF8String];
5.211 - }
5.212 - } else if( [val2 length] == 0 ) {
5.213 - p = [val1 UTF8String];
5.214 - } else {
5.215 - sprintf( buf, "%s,%s", [val1 UTF8String], [val2 UTF8String] );
5.216 - p = buf;
5.217 - }
5.218 - }
5.219 - maple_set_device_config_value( device, binding, p );
5.220 - lxdream_save_config();
5.221 -}
5.222 -- (void)setDevice: (maple_device_t)newDevice
5.223 -{
5.224 - device = newDevice;
5.225 - [self removeSubviews];
5.226 - if( device != NULL && !MAPLE_IS_VMU(device) ) {
5.227 - lxdream_config_entry_t config = maple_get_device_config(device);
5.228 - if( config != NULL ) {
5.229 - int count, i, y, x;
5.230 -
5.231 - for( count=0; config[count].key != NULL; count++ );
5.232 - x = TEXT_GAP;
5.233 - NSSize size = NSMakeSize(85+KEYBINDING_SIZE*2+TEXT_GAP*4, count*(TEXT_HEIGHT+TEXT_GAP)+TEXT_GAP);
5.234 - [self setFrameSize: size];
5.235 - [self scrollRectToVisible: NSMakeRect(0,0,1,1)];
5.236 - y = TEXT_GAP;
5.237 - for( i=0; config[i].key != NULL; i++ ) {
5.238 - /* Add label */
5.239 - NSRect frame = NSMakeRect(x, y + 2, 85, LABEL_HEIGHT);
5.240 - NSTextField *label = cocoa_gui_add_label(self, NS_(config[i].label), frame);
5.241 - [label setAlignment: NSRightTextAlignment];
5.242 -
5.243 - switch(config[i].type) {
5.244 - case CONFIG_TYPE_KEY:
5.245 - frame = NSMakeRect( x + 85 + TEXT_GAP, y, KEYBINDING_SIZE, TEXT_HEIGHT);
5.246 - field[i][0] = [[KeyBindingField alloc] initWithFrame: frame];
5.247 - [field[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
5.248 - [field[i][0] setTag: i];
5.249 - [field[i][0] setDelegate: self];
5.250 - [self addSubview: field[i][0]];
5.251 -
5.252 - frame = NSMakeRect( x + 85 + KEYBINDING_SIZE + (TEXT_GAP*2), y, KEYBINDING_SIZE, TEXT_HEIGHT);
5.253 - field[i][1] = [[KeyBindingField alloc] initWithFrame: frame];
5.254 - [field[i][1] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
5.255 - [field[i][1] setTag: i];
5.256 - [field[i][1] setDelegate: self];
5.257 - [self addSubview: field[i][1]];
5.258 -
5.259 - if( config[i].value != NULL ) {
5.260 - gchar **parts = g_strsplit(config[i].value,",",3);
5.261 - if( parts[0] != NULL ) {
5.262 - [field[i][0] setStringValue: [NSString stringWithCString: parts[0]]];
5.263 - if( parts[1] != NULL ) {
5.264 - [field[i][1] setStringValue: [NSString stringWithCString: parts[1]]];
5.265 - }
5.266 - }
5.267 - g_strfreev(parts);
5.268 - }
5.269 - break;
5.270 - case CONFIG_TYPE_FILE:
5.271 - case CONFIG_TYPE_PATH:
5.272 - frame = NSMakeRect( x + 85 + TEXT_GAP, y, KEYBINDING_SIZE*2+TEXT_GAP, TEXT_HEIGHT);
5.273 - field[i][0] = [[NSTextField alloc] initWithFrame: frame];
5.274 - [field[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];
5.275 - [field[i][0] setTag: i];
5.276 - [field[i][0] setDelegate: self];
5.277 - [self addSubview: field[i][0]];
5.278 - if( config[i].value != NULL ) {
5.279 - [field[i][0] setStringValue: [NSString stringWithCString: config[i].value]];
5.280 - }
5.281 - field[i][1] = NULL;
5.282 - }
5.283 - y += (TEXT_HEIGHT + TEXT_GAP);
5.284 - }
5.285 - } else {
5.286 - [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];
5.287 - }
5.288 - } else {
5.289 - [self setFrameSize: NSMakeSize(100,TEXT_HEIGHT+TEXT_GAP) ];
5.290 - }
5.291 -}
5.292 -@end
5.293 -
5.294 /*************************** Top-level controller pane ***********************/
5.295 static NSButton *addRadioButton( int port, int sub, int x, int y, id parent )
5.296 {
5.297 @@ -385,10 +104,14 @@
5.298
5.299 if( !primary ) {
5.300 BOOL vmu_selected = NO;
5.301 - const char *vmu_name;
5.302 + const char *vmu_name = NULL;
5.303 if( device != NULL && MAPLE_IS_VMU(device) ) {
5.304 - vmu_selected = YES;
5.305 vmu_name = MAPLE_VMU_NAME(device);
5.306 + if( vmu_name == NULL ) {
5.307 + device = NULL;
5.308 + } else {
5.309 + vmu_selected = YES;
5.310 + }
5.311 }
5.312 if( [popup numberOfItems] > 0 ) {
5.313 [[popup menu] addItem: [NSMenuItem separatorItem]];
5.314 @@ -474,7 +197,7 @@
5.315 struct maple_device *save_controller[MAPLE_MAX_DEVICES];
5.316 NSButton *radio[MAPLE_MAX_DEVICES];
5.317 NSPopUpButton *popup[MAPLE_MAX_DEVICES];
5.318 - ControllerKeyBindingView *key_bindings;
5.319 + ConfigurationView *key_bindings;
5.320 }
5.321 + (LxdreamPrefsControllerPane *)new;
5.322 - (void)vmulistChanged: (id)sender;
5.323 @@ -511,7 +234,8 @@
5.324 NSRect bindingFrame = NSMakeRect(210+(TEXT_GAP*4), 0,
5.325 frameRect.size.width - (210+(TEXT_GAP*4)), [self contentHeight] + TEXT_GAP );
5.326 NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame: bindingFrame];
5.327 - key_bindings = [[ControllerKeyBindingView alloc] initWithFrame: bindingFrame ];
5.328 + key_bindings = [[ConfigurationView alloc] initWithFrame: bindingFrame ];
5.329 + [key_bindings setLabelWidth: LABEL_WIDTH];
5.330 [scrollView setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
5.331 [scrollView setDocumentView: key_bindings];
5.332 [scrollView setDrawsBackground: NO];
6.1 --- a/src/cocoaui/cocoa_path.m Tue Jul 21 20:21:52 2009 +1000
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,135 +0,0 @@
6.4 -/**
6.5 - * $Id$
6.6 - *
6.7 - * Construct and manage the paths configuration pane
6.8 - *
6.9 - * Copyright (c) 2008 Nathan Keynes.
6.10 - *
6.11 - * This program is free software; you can redistribute it and/or modify
6.12 - * it under the terms of the GNU General Public License as published by
6.13 - * the Free Software Foundation; either version 2 of the License, or
6.14 - * (at your option) any later version.
6.15 - *
6.16 - * This program is distributed in the hope that it will be useful,
6.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.19 - * GNU General Public License for more details.
6.20 - */
6.21 -
6.22 -#include "cocoaui.h"
6.23 -#include "config.h"
6.24 -#include "lxpaths.h"
6.25 -#include "dreamcast.h"
6.26 -
6.27 -@interface LxdreamPrefsPathPane: LxdreamPrefsPane
6.28 -{
6.29 - NSTextField *fields[CONFIG_KEY_MAX];
6.30 -}
6.31 -+ (LxdreamPrefsPathPane *)new;
6.32 -@end
6.33 -
6.34 -@implementation LxdreamPrefsPathPane
6.35 -+ (LxdreamPrefsPathPane *)new
6.36 -{
6.37 - return [[LxdreamPrefsPathPane alloc] initWithFrame: NSMakeRect(0,0,600,400)];
6.38 -}
6.39 -- (id)initWithFrame: (NSRect)frameRect
6.40 -{
6.41 - if( [super initWithFrame: frameRect title: NS_("Paths")] == nil ) {
6.42 - return nil;
6.43 - } else {
6.44 - int i;
6.45 - int height = [self contentHeight] - TEXT_HEIGHT - TEXT_GAP;
6.46 - int y = height;
6.47 -
6.48 - for( i=0; i<=CONFIG_KEY_MAX; i++ ) {
6.49 - const struct lxdream_config_entry *entry = lxdream_get_global_config_entry(i);
6.50 - if( entry->label != NULL ) {
6.51 - NSRect frame = NSMakeRect( TEXT_GAP, y+2, 150, LABEL_HEIGHT );
6.52 - NSTextField *label = cocoa_gui_add_label(self, NS_(entry->label), frame);
6.53 - [label setAlignment: NSRightTextAlignment];
6.54 -
6.55 - frame = NSMakeRect( 150 + (TEXT_GAP*2), y, 360, TEXT_HEIGHT );
6.56 - NSTextField *field = [[NSTextField alloc] initWithFrame: frame];
6.57 - [field setTag: i];
6.58 - [field setStringValue: [NSString stringWithCString: entry->value]];
6.59 - [field setDelegate: self];
6.60 - [field setAutoresizingMask: (NSViewMinYMargin|NSViewWidthSizable)];
6.61 -
6.62 - frame = NSMakeRect( 510 + (TEXT_GAP*3), y, TEXT_HEIGHT, TEXT_HEIGHT );
6.63 - NSButton *button = [[NSButton alloc] initWithFrame: frame];
6.64 - [button setTag: i];
6.65 - [button setTitle: @""];
6.66 - [button setButtonType: NSMomentaryPushInButton];
6.67 - [button setBezelStyle: NSRoundedDisclosureBezelStyle];
6.68 - [button setAutoresizingMask: (NSViewMinYMargin|NSViewMinXMargin)];
6.69 - [button setTarget: self];
6.70 - if( entry->type == CONFIG_TYPE_FILE ) {
6.71 - [button setAction: @selector(openFileDialog:)];
6.72 - } else {
6.73 - [button setAction: @selector(openDirDialog:)];
6.74 - }
6.75 -
6.76 - [self addSubview: label];
6.77 - [self addSubview: field];
6.78 - [self addSubview: button];
6.79 - fields[i] = field;
6.80 - y -= (TEXT_HEIGHT + TEXT_GAP);
6.81 - }
6.82 - }
6.83 - }
6.84 - return self;
6.85 -}
6.86 -- (void)controlTextDidEndEditing:(NSNotification *)notify
6.87 -{
6.88 - int tag = [[notify object] tag];
6.89 - const char *str = [[[notify object] stringValue] UTF8String];
6.90 - const char *oldval = lxdream_get_global_config_value(tag);
6.91 - if( str[0] == '\0' )
6.92 - str = NULL;
6.93 - if( oldval == NULL ? str != NULL : (str == NULL || strcmp(oldval,str) != 0 ) ) {
6.94 - lxdream_set_global_config_value(tag, str);
6.95 - lxdream_save_config();
6.96 - dreamcast_config_changed();
6.97 - }
6.98 -}
6.99 -- (void)openFileDialog: (id)sender
6.100 -{
6.101 - int tag = [sender tag];
6.102 - NSString *text = [fields[tag] stringValue];
6.103 - NSOpenPanel *panel = [NSOpenPanel openPanel];
6.104 - int result = [panel runModalForDirectory: nil file: nil types: nil];
6.105 - if( result == NSOKButton && [[panel filenames] count] > 0 ) {
6.106 - NSString *filename = [[panel filenames] objectAtIndex: 0];
6.107 - gchar *str = get_escaped_path( [filename UTF8String] );
6.108 - [fields[tag] setStringValue: [NSString stringWithUTF8String: str]];
6.109 - lxdream_set_global_config_value(tag,str);
6.110 - lxdream_save_config();
6.111 - dreamcast_config_changed();
6.112 - }
6.113 -}
6.114 -- (void)openDirDialog: (id)sender
6.115 -{
6.116 - int tag = [sender tag];
6.117 - NSString *text = [fields[tag] stringValue];
6.118 - NSOpenPanel *panel = [NSOpenPanel openPanel];
6.119 - [panel setCanChooseDirectories: YES];
6.120 - [panel setCanCreateDirectories: YES];
6.121 - int result = [panel runModalForDirectory: nil file: nil types: nil];
6.122 - if( result == NSOKButton && [[panel filenames] count] > 0 ) {
6.123 - NSString *filename = [[panel filenames] objectAtIndex: 0];
6.124 - gchar *str = get_escaped_path( [filename UTF8String] );
6.125 - [fields[tag] setStringValue: [NSString stringWithUTF8String: str]];
6.126 - lxdream_set_global_config_value(tag,str);
6.127 - lxdream_save_config();
6.128 - dreamcast_config_changed();
6.129 - }
6.130 -}
6.131 -
6.132 -@end
6.133 -
6.134 -
6.135 -NSView *cocoa_gui_create_prefs_path_pane()
6.136 -{
6.137 - return [LxdreamPrefsPathPane new];
6.138 -}
7.1 --- a/src/cocoaui/cocoa_prefs.m Tue Jul 21 20:21:52 2009 +1000
7.2 +++ b/src/cocoaui/cocoa_prefs.m Tue Jul 21 20:33:21 2009 +1000
7.3 @@ -54,6 +54,29 @@
7.4 return self;
7.5 }
7.6 }
7.7 +
7.8 +- (id)initWithFrame: (NSRect)frameRect title:(NSString *)title configGroup: (lxdream_config_group_t)group scrollable: (BOOL)scroll
7.9 +{
7.10 + if( [self initWithFrame: frameRect title: title] == nil ) {
7.11 + return nil;
7.12 + }
7.13 + ConfigurationView *view = [[ConfigurationView alloc] initWithFrame: frameRect
7.14 + configGroup: group ];
7.15 + [view setAutoresizingMask: (NSViewWidthSizable|NSViewMinYMargin)];
7.16 + if( scroll ) {
7.17 + NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame: NSMakeRect(0,0,frameRect.size.width,[self contentHeight]+TEXT_GAP)];
7.18 + [scrollView setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
7.19 + [scrollView setDocumentView: view];
7.20 + [scrollView setDrawsBackground: NO];
7.21 + [scrollView setHasVerticalScroller: YES];
7.22 + [scrollView setAutohidesScrollers: YES];
7.23 + [self addSubview: scrollView];
7.24 +// [view scrollRectToVisible: NSMakeRect(0,0,1,1)];
7.25 + } else {
7.26 + [self addSubview: view];
7.27 + }
7.28 + return self;
7.29 +}
7.30 @end
7.31
7.32 /**************************** Main preferences window ************************/
7.33 @@ -85,10 +108,18 @@
7.34 [self setDelegate: self];
7.35 [self setMinSize: NSMakeSize(400,300)];
7.36 [self initToolbar];
7.37 - path_pane = cocoa_gui_create_prefs_path_pane();
7.38 - ctrl_pane = cocoa_gui_create_prefs_controller_pane();
7.39 + config_panes[0] = [[LxdreamPrefsPane alloc] initWithFrame: NSMakeRect(0,0,600,400)
7.40 + title: NS_("Paths")
7.41 + configGroup: lxdream_get_config_group(CONFIG_GROUP_GLOBAL)
7.42 + scrollable: YES];
7.43 + config_panes[1] = cocoa_gui_create_prefs_controller_pane();
7.44 + config_panes[2] = [[LxdreamPrefsPane alloc] initWithFrame: NSMakeRect(0,0,600,400)
7.45 + title: NS_("Hotkeys")
7.46 + configGroup: lxdream_get_config_group(CONFIG_GROUP_HOTKEYS)
7.47 + scrollable: YES];
7.48 +
7.49 binding_editor = nil;
7.50 - [self setContentView: path_pane];
7.51 + [self setContentView: config_panes[0]];
7.52 return self;
7.53 }
7.54 }
7.55 @@ -124,9 +155,12 @@
7.56 NSToolbarItem *ctrls = [self createToolbarItem: @"Controllers" label: @"Controllers"
7.57 tooltip: @"Configure controllers" icon: @"tb-ctrls"
7.58 action: @selector(controllers_action:)];
7.59 - toolbar_ids = [NSArray arrayWithObjects: @"Paths", @"Controllers", nil ];
7.60 - toolbar_defaults = [NSArray arrayWithObjects: @"Paths", @"Controllers", nil ];
7.61 - NSArray *values = [NSArray arrayWithObjects: paths, ctrls, nil ];
7.62 + NSToolbarItem *hotkeys=[self createToolbarItem: @"Hotkeys" label: @"Hotkeys"
7.63 + tooltip: @"Configure hotkeys" icon: @"tb-ctrls"
7.64 + action: @selector(hotkeys_action:)];
7.65 + toolbar_ids = [NSArray arrayWithObjects: @"Paths", @"Controllers", @"Hotkeys", nil ];
7.66 + toolbar_defaults = [NSArray arrayWithObjects: @"Paths", @"Controllers", @"Hotkeys", nil ];
7.67 + NSArray *values = [NSArray arrayWithObjects: paths, ctrls, hotkeys, nil ];
7.68 toolbar_items = [NSDictionary dictionaryWithObjects: values forKeys: toolbar_ids];
7.69
7.70 [toolbar setDelegate: self];
7.71 @@ -138,11 +172,15 @@
7.72
7.73 - (void)paths_action: (id)sender
7.74 {
7.75 - [self setContentView: path_pane];
7.76 + [self setContentView: config_panes[0]];
7.77 }
7.78 - (void)controllers_action: (id)sender
7.79 {
7.80 - [self setContentView: ctrl_pane];
7.81 + [self setContentView: config_panes[1]];
7.82 +}
7.83 +- (void)hotkeys_action: (id)sender
7.84 +{
7.85 + [self setContentView: config_panes[2]];
7.86 }
7.87
7.88 /***************************** Toolbar methods ***************************/
7.89 @@ -171,7 +209,7 @@
7.90
7.91 - (NSArray *)toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar
7.92 {
7.93 - return [NSArray arrayWithObjects: @"Paths", @"Controllers", nil ];
7.94 + return [NSArray arrayWithObjects: @"Paths", @"Controllers", @"Hotkeys", nil ];
7.95 }
7.96
7.97 - (NSToolbarItem *) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier
7.98 @@ -187,4 +225,7 @@
7.99 prefs_panel = [[LxdreamPrefsPanel alloc] initWithContentRect: NSMakeRect(0,0,640,540)];
7.100 }
7.101 [prefs_panel makeKeyAndOrderFront: prefs_panel];
7.102 -}
7.103 \ No newline at end of file
7.104 +}
7.105 +
7.106 +/**************************** Simple config panels ***************************/
7.107 +
8.1 --- a/src/cocoaui/cocoaui.h Tue Jul 21 20:21:52 2009 +1000
8.2 +++ b/src/cocoaui/cocoaui.h Tue Jul 21 20:33:21 2009 +1000
8.3 @@ -21,6 +21,7 @@
8.4
8.5 #import <AppKit/AppKit.h>
8.6 #include "lxdream.h"
8.7 +#include "config.h"
8.8 #include "gui.h"
8.9 #include "gettext.h"
8.10
8.11 @@ -75,6 +76,7 @@
8.12 int headerHeight;
8.13 }
8.14 - (id)initWithFrame: (NSRect)frameRect title:(NSString *)title;
8.15 +- (id)initWithFrame: (NSRect)frameRect title:(NSString *)title configGroup: (lxdream_config_group_t)group scrollable: (BOOL)scroll;
8.16 - (int)contentHeight;
8.17 @end
8.18
8.19 @@ -90,12 +92,27 @@
8.20 }
8.21 @end
8.22
8.23 +
8.24 +@interface ConfigurationView : NSView
8.25 +{
8.26 + lxdream_config_group_t group;
8.27 + int labelWidth;
8.28 + NSTextField *fields[CONFIG_MAX_KEYS][2];
8.29 +}
8.30 +- (id)initWithFrame: (NSRect)frameRect;
8.31 +- (id)initWithFrame: (NSRect)frameRect configGroup: (lxdream_config_group_t)group;
8.32 +- (void)setLabelWidth: (int)width;
8.33 +- (void)setConfigGroup: (lxdream_config_group_t)group;
8.34 +- (void)setDevice: (struct maple_device *)device;
8.35 +@end
8.36 +
8.37 +
8.38 @interface LxdreamPrefsPanel : NSPanel
8.39 {
8.40 NSArray *toolbar_ids;
8.41 NSArray *toolbar_defaults;
8.42 + NSView *config_panes[3];
8.43 NSDictionary *toolbar_items;
8.44 - NSView *path_pane, *ctrl_pane;
8.45 KeyBindingEditor *binding_editor;
8.46 }
8.47 - (id)initWithContentRect:(NSRect)contentRect;
8.48 @@ -107,11 +124,10 @@
8.49 NSView *video_osx_create_drawable();
8.50 void cocoa_gui_show_preferences();
8.51 NSView *cocoa_gui_create_prefs_controller_pane();
8.52 -NSView *cocoa_gui_create_prefs_path_pane();
8.53
8.54
8.55 #ifdef __cplusplus
8.56 }
8.57 #endif
8.58
8.59 -#endif /* lxdream_cocoaui_H */
8.60 \ No newline at end of file
8.61 +#endif /* lxdream_cocoaui_H */
9.1 --- a/src/config.c Tue Jul 21 20:21:52 2009 +1000
9.2 +++ b/src/config.c Tue Jul 21 20:33:21 2009 +1000
9.3 @@ -25,22 +25,22 @@
9.4 #include <glib/gstrfuncs.h>
9.5 #include <sys/types.h>
9.6 #include <sys/stat.h>
9.7 -#include "dream.h"
9.8 +#include "dreamcast.h"
9.9 #include "config.h"
9.10 #include "lxpaths.h"
9.11 #include "maple/maple.h"
9.12
9.13 #define MAX_ROOT_GROUPS 16
9.14
9.15 -extern struct lxdream_config_entry alsa_config[];
9.16 -extern struct lxdream_config_entry hotkeys_config[];
9.17 +extern struct lxdream_config_group hotkeys_group;
9.18
9.19 gboolean lxdream_load_config_file( const gchar *filename );
9.20 gboolean lxdream_save_config_file( const gchar *filename );
9.21 gboolean lxdream_load_config_stream( FILE *f );
9.22 gboolean lxdream_save_config_stream( FILE *f );
9.23
9.24 -static struct lxdream_config_entry global_config[] =
9.25 +static struct lxdream_config_group global_group =
9.26 + { "global", dreamcast_config_changed, NULL, NULL,
9.27 {{ "bios", N_("Bios ROM"), CONFIG_TYPE_FILE, NULL },
9.28 { "flash", N_("Flash ROM"), CONFIG_TYPE_FILE, NULL },
9.29 { "default path", N_("Default disc path"), CONFIG_TYPE_PATH, "." },
9.30 @@ -51,31 +51,32 @@
9.31 { "recent", NULL, CONFIG_TYPE_FILELIST, NULL },
9.32 { "vmu", NULL, CONFIG_TYPE_FILELIST, NULL },
9.33 { "quick state", NULL, CONFIG_TYPE_INTEGER, "0" },
9.34 - { NULL, CONFIG_TYPE_NONE }};
9.35 + { NULL, CONFIG_TYPE_NONE }} };
9.36
9.37 -static struct lxdream_config_entry serial_config[] =
9.38 +static struct lxdream_config_group serial_group =
9.39 + { "serial", NULL, NULL, NULL,
9.40 {{ "device", N_("Serial device"), CONFIG_TYPE_FILE, "/dev/ttyS1" },
9.41 - { NULL, CONFIG_TYPE_NONE }};
9.42 + { NULL, CONFIG_TYPE_NONE }} };
9.43
9.44 -struct lxdream_config_group lxdream_config_root[MAX_ROOT_GROUPS+1] =
9.45 - {{ "global", global_config },
9.46 - { "controllers", NULL },
9.47 - { "hotkeys", hotkeys_config },
9.48 - { "serial", serial_config },
9.49 - { NULL, CONFIG_TYPE_NONE }};
9.50 +/**
9.51 + * Dummy group for controllers (handled specially)
9.52 + */
9.53 +static struct lxdream_config_group controllers_group =
9.54 + { "controllers", NULL, NULL, NULL, {{NULL, CONFIG_TYPE_NONE}} };
9.55 +
9.56 +struct lxdream_config_group *lxdream_config_root[MAX_ROOT_GROUPS+1] =
9.57 + { &global_group, &controllers_group, &hotkeys_group, &serial_group, NULL };
9.58
9.59 static gchar *lxdream_config_load_filename = NULL;
9.60 static gchar *lxdream_config_save_filename = NULL;
9.61
9.62 -void lxdream_register_config_group( const gchar *key, lxdream_config_entry_t group )
9.63 +void lxdream_register_config_group( const gchar *key, lxdream_config_group_t group )
9.64 {
9.65 int i;
9.66 for( i=0; i<MAX_ROOT_GROUPS; i++ ) {
9.67 - if( lxdream_config_root[i].key == NULL ) {
9.68 - lxdream_config_root[i].key = key;
9.69 - lxdream_config_root[i].params = group;
9.70 - lxdream_config_root[i+1].key = NULL;
9.71 - lxdream_config_root[i+1].params = CONFIG_TYPE_NONE;
9.72 + if( lxdream_config_root[i] == NULL ) {
9.73 + lxdream_config_root[i] = group;
9.74 + lxdream_config_root[i+1] = NULL;
9.75 return;
9.76 }
9.77 }
9.78 @@ -129,16 +130,15 @@
9.79 {
9.80 /* Construct platform dependent defaults */
9.81 const gchar *user_path = get_user_data_path();
9.82 - global_config[CONFIG_BIOS_PATH].default_value = g_strdup_printf( "%s/dcboot.rom", user_path );
9.83 - global_config[CONFIG_FLASH_PATH].default_value = g_strdup_printf( "%s/dcflash.rom", user_path );
9.84 - global_config[CONFIG_SAVE_PATH].default_value = g_strdup_printf( "%s/save", user_path );
9.85 - global_config[CONFIG_VMU_PATH].default_value = g_strdup_printf( "%s/vmu", user_path );
9.86 - global_config[CONFIG_BOOTSTRAP].default_value = g_strdup_printf( "%s/IP.BIN", user_path );
9.87 + global_group.params[CONFIG_BIOS_PATH].default_value = g_strdup_printf( "%s/dcboot.rom", user_path );
9.88 + global_group.params[CONFIG_FLASH_PATH].default_value = g_strdup_printf( "%s/dcflash.rom", user_path );
9.89 + global_group.params[CONFIG_SAVE_PATH].default_value = g_strdup_printf( "%s/save", user_path );
9.90 + global_group.params[CONFIG_VMU_PATH].default_value = g_strdup_printf( "%s/vmu", user_path );
9.91 + global_group.params[CONFIG_BOOTSTRAP].default_value = g_strdup_printf( "%s/IP.BIN", user_path );
9.92
9.93 /* Copy defaults into main values */
9.94 - struct lxdream_config_group *group = lxdream_config_root;
9.95 - while( group->key != NULL ) {
9.96 - struct lxdream_config_entry *param = group->params;
9.97 + for( int i=0; lxdream_config_root[i] != NULL; i++ ) {
9.98 + struct lxdream_config_entry *param = lxdream_config_root[i]->params;
9.99 if( param != NULL ) {
9.100 while( param->key != NULL ) {
9.101 if( param->value != param->default_value ) {
9.102 @@ -149,14 +149,53 @@
9.103 param++;
9.104 }
9.105 }
9.106 - group++;
9.107 }
9.108 maple_detach_all();
9.109 }
9.110
9.111 +const gchar *lxdream_get_config_value( lxdream_config_group_t group, int key )
9.112 +{
9.113 + return group->params[key].value;
9.114 +}
9.115 +
9.116 +
9.117 +gboolean lxdream_set_config_value( lxdream_config_group_t group, int key, const gchar *value )
9.118 +{
9.119 + lxdream_config_entry_t param = &group->params[key];
9.120 + if( param->value != value &&
9.121 + (param->value == NULL || value == NULL || strcmp(param->value,value) != 0) ) {
9.122 +
9.123 + gchar *new_value = g_strdup(value);
9.124 +
9.125 + /* If the group defines an on_change handler, it can block the change
9.126 + * (ie due to an invalid setting).
9.127 + */
9.128 + if( group->on_change == NULL ||
9.129 + group->on_change(group->data, group,key, param->value, new_value) ) {
9.130 +
9.131 + /* Don't free the default value, but otherwise need to release the
9.132 + * old value.
9.133 + */
9.134 + if( param->value != param->default_value && param->value != NULL ) {
9.135 + free( param->value );
9.136 + }
9.137 + param->value = new_value;
9.138 + } else { /* on_change handler said no. */
9.139 + g_free(new_value);
9.140 + return FALSE;
9.141 + }
9.142 + }
9.143 + return TRUE;
9.144 +}
9.145 +
9.146 const gchar *lxdream_get_global_config_value( int key )
9.147 {
9.148 - return global_config[key].value;
9.149 + return global_group.params[key].value;
9.150 +}
9.151 +
9.152 +void lxdream_set_global_config_value( int key, const gchar *value )
9.153 +{
9.154 + lxdream_set_config_value(&global_group, key, value);
9.155 }
9.156
9.157 GList *lxdream_get_global_config_list_value( int key )
9.158 @@ -213,44 +252,38 @@
9.159 return lxdream_get_global_config_value(key);
9.160 }
9.161
9.162 -void lxdream_set_config_value( lxdream_config_entry_t param, const gchar *value )
9.163 +struct lxdream_config_group * lxdream_get_config_group( int group )
9.164 {
9.165 - if( param->value != value ) {
9.166 - if( param->value != param->default_value && param->value != NULL ) {
9.167 - free( param->value );
9.168 - }
9.169 - param->value = g_strdup(value);
9.170 + return lxdream_config_root[group];
9.171 +}
9.172 +
9.173 +void lxdream_copy_config_group( lxdream_config_group_t dest, lxdream_config_group_t src )
9.174 +{
9.175 + int i;
9.176 + for( i=0; src->params[i].key != NULL; i++ ) {
9.177 + lxdream_set_config_value( dest, i, src->params[i].value );
9.178 }
9.179 }
9.180
9.181 -void lxdream_set_global_config_value( int key, const gchar *value )
9.182 -{
9.183 - lxdream_set_config_value(&global_config[key], value);
9.184 -}
9.185 -
9.186 -const struct lxdream_config_entry * lxdream_get_global_config_entry( int key )
9.187 -{
9.188 - return &global_config[key];
9.189 -}
9.190 -
9.191 -gboolean lxdream_set_group_value( lxdream_config_group_t group, const gchar *key, const gchar *value )
9.192 +void lxdream_clone_config_group( lxdream_config_group_t dest, lxdream_config_group_t src )
9.193 {
9.194 int i;
9.195 - for( i=0; group->params[i].key != NULL; i++ ) {
9.196 - if( strcasecmp( group->params[i].key, key ) == 0 ) {
9.197 - lxdream_set_config_value( &group->params[i], value );
9.198 - return TRUE;
9.199 - }
9.200 +
9.201 + dest->key = src->key;
9.202 + dest->on_change = NULL;
9.203 + dest->key_binding = NULL;
9.204 + dest->data = NULL;
9.205 + for( i=0; src->params[i].key != NULL; i++ ) {
9.206 + dest->params[i].key = src->params[i].key;
9.207 + dest->params[i].label = src->params[i].label;
9.208 + dest->params[i].type = src->params[i].type;
9.209 + dest->params[i].tag = src->params[i].tag;
9.210 + dest->params[i].default_value = src->params[i].default_value;
9.211 + dest->params[i].value = NULL;
9.212 + lxdream_set_config_value( dest, i, src->params[i].value );
9.213 }
9.214 - return FALSE;
9.215 -}
9.216 -
9.217 -void lxdream_copy_config_list( lxdream_config_entry_t dest, lxdream_config_entry_t src )
9.218 -{
9.219 - int i;
9.220 - for( i=0; src[i].key != NULL; i++ ) {
9.221 - lxdream_set_config_value( &dest[i], src[i].value );
9.222 - }
9.223 + dest->params[i].key = NULL;
9.224 + dest->params[i].label = NULL;
9.225 }
9.226
9.227 gboolean lxdream_load_config( )
9.228 @@ -296,9 +329,9 @@
9.229 {
9.230
9.231 char buf[512];
9.232 - int maple_device = -1, maple_subdevice = -1;
9.233 - struct lxdream_config_group devgroup;
9.234 + int maple_device = -1, maple_subdevice = -1, i;
9.235 struct lxdream_config_group *group = NULL;
9.236 + struct lxdream_config_group *top_group = NULL;
9.237 maple_device_t device = NULL;
9.238 lxdream_set_default_config();
9.239
9.240 @@ -309,17 +342,14 @@
9.241 if( *buf == '[' ) {
9.242 char *p = strchr(buf, ']');
9.243 if( p != NULL ) {
9.244 - struct lxdream_config_group *tmp_group;
9.245 maple_device = maple_subdevice = -1;
9.246 *p = '\0';
9.247 g_strstrip(buf+1);
9.248 - tmp_group = &lxdream_config_root[0];
9.249 - while( tmp_group->key != NULL ) {
9.250 - if( strcasecmp(tmp_group->key, buf+1) == 0 ) {
9.251 - group = tmp_group;
9.252 + for( i=0; lxdream_config_root[i] != NULL; i++ ) {
9.253 + if( strcasecmp(lxdream_config_root[i]->key, buf+1) == 0 ) {
9.254 + top_group = group = lxdream_config_root[i];
9.255 break;
9.256 }
9.257 - tmp_group++;
9.258 }
9.259 }
9.260 } else if( group != NULL ) {
9.261 @@ -330,7 +360,7 @@
9.262 value++;
9.263 g_strstrip(buf);
9.264 g_strstrip(value);
9.265 - if( strcmp(group->key,"controllers") == 0 ) {
9.266 + if( top_group == &controllers_group ) {
9.267 if( g_strncasecmp( buf, "device ", 7 ) == 0 ) {
9.268 maple_device = strtoul( buf+7, NULL, 0 );
9.269 if( maple_device < 0 || maple_device > 3 ) {
9.270 @@ -342,10 +372,8 @@
9.271 if( device == NULL ) {
9.272 ERROR( "Unrecognized device '%s'", value );
9.273 } else {
9.274 - devgroup.key = "controllers";
9.275 - devgroup.params = maple_get_device_config(device);
9.276 + group = maple_get_device_config(device);
9.277 maple_attach_device( device, maple_device, maple_subdevice );
9.278 - group = &devgroup;
9.279 }
9.280 continue;
9.281 } else if( g_strncasecmp( buf, "subdevice ", 10 ) == 0 ) {
9.282 @@ -357,10 +385,8 @@
9.283 } else if( (device = maple_new_device(value)) == NULL ) {
9.284 ERROR( "Unrecognized subdevice '%s'", value );
9.285 } else {
9.286 - devgroup.key = "controllers";
9.287 - devgroup.params = maple_get_device_config(device);
9.288 + group = maple_get_device_config(device);
9.289 maple_attach_device( device, maple_device, maple_subdevice );
9.290 - group = &devgroup;
9.291 }
9.292 continue;
9.293 }
9.294 @@ -393,20 +419,11 @@
9.295
9.296 gboolean lxdream_save_config_stream( FILE *f )
9.297 {
9.298 - struct lxdream_config_group *group = &lxdream_config_root[0];
9.299 + int i;
9.300 + for( i=0; lxdream_config_root[i] != NULL; i++ ) {
9.301 + fprintf( f, "[%s]\n", lxdream_config_root[i]->key );
9.302
9.303 - while( group->key != NULL ) {
9.304 - struct lxdream_config_entry *entry = group->params;
9.305 - fprintf( f, "[%s]\n", group->key );
9.306 -
9.307 - if( entry != NULL ) {
9.308 - while( entry->key != NULL ) {
9.309 - if( entry->value != NULL ) {
9.310 - fprintf( f, "%s = %s\n", entry->key, entry->value );
9.311 - }
9.312 - entry++;
9.313 - }
9.314 - } else if( strcmp(group->key, "controllers") == 0 ) {
9.315 + if( lxdream_config_root[i] == &controllers_group ) {
9.316 int i,j;
9.317 for( i=0; i<4; i++ ) {
9.318 for( j=0; j<6; j++ ) {
9.319 @@ -416,7 +433,9 @@
9.320 fprintf( f, "Device %d = %s\n", i, dev->device_class->name );
9.321 else
9.322 fprintf( f, "Subdevice %d = %s\n", j, dev->device_class->name );
9.323 - if( dev->get_config != NULL && ((entry = dev->get_config(dev)) != NULL) ) {
9.324 + lxdream_config_group_t group = maple_get_device_config(dev);
9.325 + if( group != NULL ) {
9.326 + lxdream_config_entry_t entry = group->params;
9.327 while( entry->key != NULL ) {
9.328 if( entry->value != NULL ) {
9.329 fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value );
9.330 @@ -427,9 +446,16 @@
9.331 }
9.332 }
9.333 }
9.334 + } else {
9.335 + struct lxdream_config_entry *entry = lxdream_config_root[i]->params;
9.336 + while( entry->key != NULL ) {
9.337 + if( entry->value != NULL ) {
9.338 + fprintf( f, "%s = %s\n", entry->key, entry->value );
9.339 + }
9.340 + entry++;
9.341 + }
9.342 }
9.343 fprintf( f, "\n" );
9.344 - group++;
9.345 }
9.346 return TRUE;
9.347 }
10.1 --- a/src/config.h Tue Jul 21 20:21:52 2009 +1000
10.2 +++ b/src/config.h Tue Jul 21 20:33:21 2009 +1000
10.3 @@ -21,12 +21,15 @@
10.4
10.5 #include <glib/gtypes.h>
10.6 #include <glib/glist.h>
10.7 +#include "lxdream.h"
10.8 #include "gettext.h"
10.9
10.10 #ifdef __cplusplus
10.11 extern "C" {
10.12 #endif
10.13
10.14 +#define CONFIG_MAX_KEYS 24
10.15 +
10.16 #define CONFIG_TYPE_NONE 0
10.17 #define CONFIG_TYPE_FILE 1
10.18 #define CONFIG_TYPE_PATH 2
10.19 @@ -39,14 +42,32 @@
10.20 typedef struct lxdream_config_entry {
10.21 const gchar *key;
10.22 const gchar *label; // i18n
10.23 - const int type;
10.24 + int type;
10.25 const gchar *default_value;
10.26 + uint32_t tag;
10.27 gchar *value;
10.28 } *lxdream_config_entry_t;
10.29
10.30 +struct lxdream_config_group;
10.31 +
10.32 +/**
10.33 + * Callback invoked for key presses (key-up/key-down).
10.34 + */
10.35 +typedef void (*key_binding_t)( void *data, uint32_t value, uint32_t pressure, gboolean isKeyDown );
10.36 +
10.37 +/**
10.38 + * Callback invoked immediately before updating a configuration item.
10.39 + * @return FALSE to abort the change (ie invalid value), or TRUE to proceed normally.
10.40 + */
10.41 +typedef gboolean (*config_change_callback_t)( void *data, struct lxdream_config_group *group, unsigned item,
10.42 + const gchar *oldval, const gchar *newval );
10.43 +
10.44 typedef struct lxdream_config_group {
10.45 const gchar *key;
10.46 - struct lxdream_config_entry *params;
10.47 + config_change_callback_t on_change;
10.48 + key_binding_t key_binding;
10.49 + void *data;
10.50 + struct lxdream_config_entry params[CONFIG_MAX_KEYS];
10.51 } *lxdream_config_group_t;
10.52
10.53 #define CONFIG_BIOS_PATH 0
10.54 @@ -61,17 +82,20 @@
10.55 #define CONFIG_QUICK_STATE 9
10.56 #define CONFIG_KEY_MAX CONFIG_QUICK_STATE
10.57
10.58 -extern struct lxdream_config_group lxdream_config_root[];
10.59 +#define CONFIG_GROUP_GLOBAL 0
10.60 +#define CONFIG_GROUP_HOTKEYS 2
10.61 +#define CONFIG_GROUP_SERIAL 3
10.62 +
10.63
10.64 /* Global config values */
10.65 const gchar *lxdream_get_global_config_value( int key );
10.66 -const struct lxdream_config_entry * lxdream_get_global_config_entry( int key );
10.67 +struct lxdream_config_group * lxdream_get_config_group( int group );
10.68 void lxdream_set_global_config_value( int key, const gchar *value );
10.69
10.70 -void lxdream_register_config_group( const gchar *key, lxdream_config_entry_t group );
10.71 -void lxdream_set_config_value( lxdream_config_entry_t entry, const gchar *value );
10.72 -gboolean lxdream_set_group_value( lxdream_config_group_t group, const gchar *key, const gchar *value );
10.73 -void lxdream_copy_config_list( lxdream_config_entry_t dest, lxdream_config_entry_t src );
10.74 +void lxdream_register_config_group( const gchar *key, lxdream_config_group_t group );
10.75 +gboolean lxdream_set_config_value( lxdream_config_group_t group, int key, const gchar *value );
10.76 +void lxdream_copy_config_group( lxdream_config_group_t dest, lxdream_config_group_t src );
10.77 +void lxdream_clone_config_group( lxdream_config_group_t dest, lxdream_config_group_t src );
10.78
10.79 /**
10.80 * Return a fully expanded path value for a key - this performs substitutions
11.1 --- a/src/display.c Tue Jul 21 20:21:52 2009 +1000
11.2 +++ b/src/display.c Tue Jul 21 20:33:21 2009 +1000
11.3 @@ -56,6 +56,7 @@
11.4 input_key_callback_t callback;
11.5 void *data;
11.6 uint32_t value;
11.7 + lxdream_config_group_t group;
11.8 struct keymap_entry *next; // allow chaining
11.9 } *keymap_entry_t;
11.10
11.11 @@ -63,6 +64,7 @@
11.12 gboolean relative;
11.13 input_mouse_callback_t callback;
11.14 void *data;
11.15 + const lxdream_config_group_t group;
11.16 struct mouse_entry *next;
11.17 } *mouse_entry_t;
11.18
11.19 @@ -293,6 +295,38 @@
11.20 g_strfreev(strv);
11.21 }
11.22
11.23 +int input_register_keygroup( lxdream_config_group_t group)
11.24 +{
11.25 + int i;
11.26 + int result = 0;
11.27 + for( i=0; group->params[i].key != NULL; i++ ) {
11.28 + if( group->params[i].type == CONFIG_TYPE_KEY ) {
11.29 + if( input_register_key( group->params[i].value, group->key_binding, group->data, group->params[i].tag ) ) {
11.30 + result++;
11.31 + }
11.32 + }
11.33 + }
11.34 + return result;
11.35 +}
11.36 +
11.37 +void input_unregister_keygroup( lxdream_config_group_t group )
11.38 +{
11.39 + int i;
11.40 + for( i=0; group->params[i].key != NULL; i++ ) {
11.41 + if( group->params[i].type == CONFIG_TYPE_KEY ) {
11.42 + input_unregister_key( group->params[i].value, group->key_binding, group->data, group->params[i].tag );
11.43 + }
11.44 + }
11.45 +}
11.46 +
11.47 +gboolean input_keygroup_changed( void *data, lxdream_config_group_t group, unsigned key,
11.48 + const gchar *oldval, const gchar *newval )
11.49 +{
11.50 + input_unregister_key( oldval, group->key_binding, group->data, group->params[key].tag );
11.51 + input_register_key( newval, group->key_binding, group->data, group->params[key].tag );
11.52 + return TRUE;
11.53 +}
11.54 +
11.55 gboolean input_register_keyboard_hook( input_key_callback_t callback,
11.56 void *data )
11.57 {
12.1 --- a/src/display.h Tue Jul 21 20:21:52 2009 +1000
12.2 +++ b/src/display.h Tue Jul 21 20:33:21 2009 +1000
12.3 @@ -27,6 +27,7 @@
12.4 #include <glib.h>
12.5 #include "lxdream.h"
12.6 #include "gettext.h"
12.7 +#include "config.h"
12.8 #ifdef APPLE_BUILD
12.9 #include <OpenGL/gl.h>
12.10 #include <OpenGL/glext.h>
12.11 @@ -230,7 +231,7 @@
12.12 /* Pressure is 0..127 (allowing a joystick to be defined as two half-axes of 7- bits each) */
12.13 #define MAX_PRESSURE 0x7F
12.14
12.15 -typedef void (*input_key_callback_t)( void *data, uint32_t value, uint32_t pressure, gboolean isKeyDown );
12.16 +typedef key_binding_t input_key_callback_t;
12.17
12.18 /**
12.19 * Callback to receive mouse input events
12.20 @@ -252,6 +253,11 @@
12.21 void input_unregister_key( const gchar *keysym, input_key_callback_t callback,
12.22 void *data, uint32_t value );
12.23
12.24 +gboolean input_register_keygroup( lxdream_config_group_t group );
12.25 +void input_unregister_keygroup( lxdream_config_group_t group );
12.26 +gboolean input_keygroup_changed( void *data, lxdream_config_group_t group, unsigned key,
12.27 + const gchar *oldval, const gchar *newval );
12.28 +
12.29 /**
12.30 * Register a hook to receive all keyboard input events
12.31 */
13.1 --- a/src/dreamcast.c Tue Jul 21 20:21:52 2009 +1000
13.2 +++ b/src/dreamcast.c Tue Jul 21 20:33:21 2009 +1000
13.3 @@ -126,17 +126,39 @@
13.4 g_free(flash_path);
13.5 }
13.6
13.7 -void dreamcast_config_changed(void)
13.8 +gboolean dreamcast_load_bios( const gchar *filename )
13.9 {
13.10 - char *bios_path = lxdream_get_global_config_path_value(CONFIG_BIOS_PATH);
13.11 - char *flash_path = lxdream_get_global_config_path_value(CONFIG_FLASH_PATH);
13.12 - dreamcast_has_bios = mem_load_rom( dc_boot_rom, bios_path, 2 MB, 0x89f2b1a1 );
13.13 - if( flash_path != NULL && flash_path[0] != '\0' ) {
13.14 - mem_load_block( flash_path, 0x00200000, 0x00020000 );
13.15 + dreamcast_has_bios = mem_load_rom( dc_boot_rom, filename, 2 MB, 0x89f2b1a1 );
13.16 + return dreamcast_has_bios;
13.17 +}
13.18 +
13.19 +gboolean dreamcast_load_flash( const gchar *filename )
13.20 +{
13.21 + if( filename != NULL && filename[0] != '\0' ) {
13.22 + return mem_load_block( filename, 0x00200000, 0x00020000 ) == 0;
13.23 }
13.24 - g_free(bios_path);
13.25 - g_free(flash_path);
13.26 + return FALSE;
13.27 +}
13.28 +
13.29 +
13.30 +gboolean dreamcast_config_changed(void *data, struct lxdream_config_group *group, unsigned item,
13.31 + const gchar *oldval, const gchar *newval)
13.32 +{
13.33 + gchar *tmp;
13.34 + switch(item) {
13.35 + case CONFIG_BIOS_PATH:
13.36 + tmp = get_expanded_path(newval);
13.37 + dreamcast_load_bios(tmp);
13.38 + g_free(tmp);
13.39 + break;
13.40 + case CONFIG_FLASH_PATH:
13.41 + tmp = get_expanded_path(newval);
13.42 + dreamcast_load_flash(tmp);
13.43 + g_free(tmp);
13.44 + break;
13.45 + }
13.46 reset_gui_paths();
13.47 + return TRUE;
13.48 }
13.49
13.50 void dreamcast_save_flash()
14.1 --- a/src/dreamcast.h Tue Jul 21 20:21:52 2009 +1000
14.2 +++ b/src/dreamcast.h Tue Jul 21 20:33:21 2009 +1000
14.3 @@ -35,6 +35,8 @@
14.4 #define XLAT_TEMP_CACHE_SIZE 2 MB
14.5 #define XLAT_OLD_CACHE_SIZE 8 MB
14.6
14.7 +struct lxdream_config_group; // Forward declaration
14.8 +
14.9 void dreamcast_configure(void);
14.10 void dreamcast_configure_aica_only(void);
14.11 void dreamcast_init(void);
14.12 @@ -44,9 +46,9 @@
14.13 void dreamcast_set_exit_on_stop( gboolean flag );
14.14 void dreamcast_stop(void);
14.15 void dreamcast_shutdown(void);
14.16 -void dreamcast_config_changed(void);
14.17 gboolean dreamcast_is_running(void);
14.18 -
14.19 +gboolean dreamcast_config_changed(void *data, struct lxdream_config_group *group, unsigned item,
14.20 + const gchar *oldval, const gchar *newval);
14.21 /**
14.22 * Return if it's possible to start the VM - currently this requires
14.23 * a) A configured system
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/src/gtkui/gtk_cfg.c Tue Jul 21 20:33:21 2009 +1000
15.3 @@ -0,0 +1,330 @@
15.4 +/**
15.5 + * $Id$
15.6 + *
15.7 + * Configuration pane to display a configuration group
15.8 + * TODO:
15.9 + *
15.10 + * Copyright (c) 2009 Nathan Keynes.
15.11 + *
15.12 + * This program is free software; you can redistribute it and/or modify
15.13 + * it under the terms of the GNU General Public License as published by
15.14 + * the Free Software Foundation; either version 2 of the License, or
15.15 + * (at your option) any later version.
15.16 + *
15.17 + * This program is distributed in the hope that it will be useful,
15.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.20 + * GNU General Public License for more details.
15.21 + */
15.22 +
15.23 +#include <assert.h>
15.24 +#include <string.h>
15.25 +#include <errno.h>
15.26 +#include <gtk/gtk.h>
15.27 +#include <gdk/gdkkeysyms.h>
15.28 +
15.29 +#include "lxdream.h"
15.30 +#include "config.h"
15.31 +#include "lxpaths.h"
15.32 +#include "display.h"
15.33 +#include "gtkui/gtkui.h"
15.34 +
15.35 +struct config_data {
15.36 + lxdream_config_group_t config;
15.37 + GtkWidget *fields[CONFIG_MAX_KEYS][2];
15.38 +};
15.39 +
15.40 +/**
15.41 + * Update the configuration data for the current value of the given field.
15.42 + */
15.43 +static gboolean config_text_changed( GtkWidget *field, gpointer p )
15.44 +{
15.45 + GtkWidget *panel = field->parent;
15.46 + struct config_data *data= (struct config_data *)gtk_object_get_data( GTK_OBJECT(panel), "config_data" );
15.47 + int tag = GPOINTER_TO_INT( g_object_get_data( G_OBJECT(field), "tag" ) );
15.48 +
15.49 + char buf[64];
15.50 + GtkWidget *entry1, *entry2;
15.51 + const gchar *key1 = NULL, *key2 = NULL;
15.52 +
15.53 + if( data->fields[tag][0] != NULL ) {
15.54 + key1 = gtk_entry_get_text(GTK_ENTRY(data->fields[tag][0]));
15.55 + }
15.56 + if( data->fields[tag][1] != NULL ) {
15.57 + key2 = gtk_entry_get_text(GTK_ENTRY(data->fields[tag][1]));
15.58 + }
15.59 +
15.60 + if( key1 == NULL || key1[0] == '\0') {
15.61 + lxdream_set_config_value( data->config, tag, key2 );
15.62 + } else if( key2 == NULL || key2[0] == '\0') {
15.63 + lxdream_set_config_value( data->config, tag, key1 );
15.64 + } else {
15.65 + char buf[strlen(key1) + strlen(key2) + 3];
15.66 + snprintf( buf, sizeof(buf), "%s, %s", key1, key2 );
15.67 + lxdream_set_config_value( data->config, tag, buf );
15.68 + }
15.69 + return TRUE;
15.70 +}
15.71 +
15.72 +/**
15.73 + * Reset the fields (identified by one of the widgets in the field) back to it's
15.74 + * value in the config group.
15.75 + */
15.76 +static void config_text_reset( GtkWidget *field )
15.77 +{
15.78 + GtkWidget *panel = field->parent;
15.79 + struct config_data *data= (struct config_data *)gtk_object_get_data( GTK_OBJECT(panel), "config_data" );
15.80 + int tag = GPOINTER_TO_INT( g_object_get_data( G_OBJECT(field), "tag" ) );
15.81 +
15.82 + const gchar *value = data->config->params[tag].value;
15.83 + if( value == NULL ) {
15.84 + value = "";
15.85 + }
15.86 +
15.87 + if( data->fields[tag][0] == NULL ) {
15.88 + if( data->fields[tag][1] != NULL ) {
15.89 + gtk_entry_set_text( GTK_ENTRY(data->fields[tag][1]), value );
15.90 + }
15.91 + } else if( data->fields[tag][1] == NULL ) {
15.92 + gtk_entry_set_text( GTK_ENTRY(data->fields[tag][0]), value );
15.93 + } else { /* Split between two fields */
15.94 + gchar *v1 = "", *v2 = "";
15.95 + gchar **parts = g_strsplit(value,",",3);
15.96 + if( parts[0] != NULL ) {
15.97 + v1 = parts[0];
15.98 + if( parts[1] != NULL ) {
15.99 + v2 = parts[1];
15.100 + }
15.101 +
15.102 + }
15.103 + gtk_entry_set_text( GTK_ENTRY(data->fields[tag][0]), v1 );
15.104 + gtk_entry_set_text( GTK_ENTRY(data->fields[tag][1]), v2 );
15.105 + g_strfreev(parts);
15.106 + }
15.107 +}
15.108 +
15.109 +static void config_set_field( void *p, const gchar *keysym )
15.110 +{
15.111 + GtkWidget *field = GTK_WIDGET(p);
15.112 + GtkWidget *panel = field->parent;
15.113 +
15.114 + gtk_entry_set_text( GTK_ENTRY(field), keysym );
15.115 + g_object_set_data( G_OBJECT(field), "keypress_mode", GINT_TO_POINTER(FALSE) );
15.116 + input_set_keysym_hook(NULL, NULL);
15.117 + config_text_changed( field, NULL );
15.118 +}
15.119 +
15.120 +static gboolean config_key_buttonpress( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
15.121 +{
15.122 + gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
15.123 + if( keypress_mode ) {
15.124 + gchar *keysym = input_keycode_to_keysym( &system_mouse_driver, event->button);
15.125 + if( keysym != NULL ) {
15.126 + config_set_field( widget, keysym );
15.127 + g_free(keysym);
15.128 + }
15.129 + return TRUE;
15.130 + } else {
15.131 + gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
15.132 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
15.133 + input_set_keysym_hook( (display_keysym_callback_t)config_set_field, widget);
15.134 + gtk_widget_grab_focus( widget );
15.135 + }
15.136 + return FALSE;
15.137 +}
15.138 +
15.139 +static gboolean config_key_keypress( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
15.140 +{
15.141 + gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
15.142 + if( keypress_mode ) {
15.143 + if( event->keyval == GDK_Escape ) {
15.144 + config_text_reset( widget );
15.145 + return TRUE;
15.146 + }
15.147 + GdkKeymap *keymap = gdk_keymap_get_default();
15.148 + guint keyval;
15.149 +
15.150 + gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
15.151 + NULL, NULL, NULL );
15.152 + config_set_field( widget, gdk_keyval_name(keyval) );
15.153 + return TRUE;
15.154 + } else {
15.155 + switch( event->keyval ) {
15.156 + case GDK_Return:
15.157 + case GDK_KP_Enter:
15.158 + gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
15.159 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
15.160 + input_set_keysym_hook((display_keysym_callback_t)config_set_field, widget);
15.161 + return TRUE;
15.162 + case GDK_BackSpace:
15.163 + case GDK_Delete:
15.164 + config_set_field( widget, "" );
15.165 + return TRUE;
15.166 + }
15.167 + return FALSE;
15.168 + }
15.169 +}
15.170 +
15.171 +static gboolean config_key_unfocus( GtkWidget *widget, gpointer user_data )
15.172 +{
15.173 + gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
15.174 + if( keypress_mode ) {
15.175 + /* We've lost focus while waiting for a key binding - restore the old value */
15.176 + config_text_reset(widget);
15.177 + g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
15.178 + input_set_keysym_hook(NULL,NULL);
15.179 + }
15.180 + return TRUE;
15.181 +}
15.182 +
15.183 +static gboolean path_file_button_clicked( GtkWidget *button, gpointer user_data )
15.184 +{
15.185 + GtkWidget *entry = GTK_WIDGET(user_data);
15.186 + GtkWidget *file = gtk_file_chooser_dialog_new( _("Select file"), NULL,
15.187 + GTK_FILE_CHOOSER_ACTION_OPEN,
15.188 + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
15.189 + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
15.190 + NULL );
15.191 + gchar *filename = get_expanded_path(gtk_entry_get_text(GTK_ENTRY(entry)));
15.192 + gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename );
15.193 + gtk_window_set_modal( GTK_WINDOW(file), TRUE );
15.194 + gtk_widget_show_all( file );
15.195 + gint result = gtk_dialog_run(GTK_DIALOG(file));
15.196 + g_free(filename);
15.197 + if( result == GTK_RESPONSE_ACCEPT ) {
15.198 + filename = get_escaped_path(gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ));
15.199 + config_set_field( entry, filename );
15.200 + g_free(filename);
15.201 + }
15.202 + gtk_widget_destroy(file);
15.203 + return TRUE;
15.204 +}
15.205 +
15.206 +static gboolean path_dir_button_clicked( GtkWidget *button, gpointer user_data )
15.207 +{
15.208 + GtkWidget *entry = GTK_WIDGET(user_data);
15.209 + GtkWidget *file = gtk_file_chooser_dialog_new( _("Select file"), NULL,
15.210 + GTK_FILE_CHOOSER_ACTION_OPEN,
15.211 + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
15.212 + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
15.213 + NULL );
15.214 + gchar *filename = get_expanded_path(gtk_entry_get_text(GTK_ENTRY(entry)));
15.215 + gtk_file_chooser_set_action( GTK_FILE_CHOOSER(file), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER );
15.216 + gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename );
15.217 + gtk_window_set_modal( GTK_WINDOW(file), TRUE );
15.218 + gtk_widget_show_all( file );
15.219 + gint result = gtk_dialog_run(GTK_DIALOG(file));
15.220 + g_free(filename);
15.221 + if( result == GTK_RESPONSE_ACCEPT ) {
15.222 + filename = get_escaped_path(gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ));
15.223 + config_set_field( entry, filename );
15.224 + g_free(filename);
15.225 + }
15.226 + gtk_widget_destroy(file);
15.227 + return TRUE;
15.228 +}
15.229 +
15.230 +
15.231 +static void lxdream_configuration_panel_destroy( GtkWidget *panel, gpointer data )
15.232 +{
15.233 + input_set_keysym_hook(NULL, NULL);
15.234 +}
15.235 +
15.236 +static GtkWidget *gtk_configuration_panel_new( lxdream_config_group_t conf )
15.237 +{
15.238 + int count, i;
15.239 + for( count=0; conf->params[count].label != NULL; count++ );
15.240 +
15.241 + GtkWidget *table = gtk_table_new( count, 5, FALSE );
15.242 + struct config_data *data = g_malloc0( sizeof(struct config_data) );
15.243 + data->config = conf;
15.244 + GList *focus_chain = NULL;
15.245 + gtk_object_set_data_full( GTK_OBJECT(table), "config_data", data, g_free );
15.246 + g_signal_connect( table, "destroy_event", G_CALLBACK(lxdream_configuration_panel_destroy), NULL );
15.247 + for( i=0; conf->params[i].label != NULL; i++ ) {
15.248 + GtkWidget *text, *text2, *button;
15.249 + int x=0;
15.250 + int y=i;
15.251 + gtk_table_attach( GTK_TABLE(table), gtk_label_new(Q_(conf->params[i].label)), x, x+1, y, y+1,
15.252 + GTK_SHRINK, GTK_SHRINK, 0, 0 );
15.253 + switch( conf->params[i].type ) {
15.254 + case CONFIG_TYPE_KEY:
15.255 + data->fields[i][0] = text = gtk_entry_new();
15.256 + gtk_entry_set_width_chars( GTK_ENTRY(text), 11 );
15.257 + gtk_entry_set_editable( GTK_ENTRY(text), FALSE );
15.258 + g_signal_connect( text, "key_press_event",
15.259 + G_CALLBACK(config_key_keypress), NULL );
15.260 + g_signal_connect( text, "button_press_event",
15.261 + G_CALLBACK(config_key_buttonpress), NULL );
15.262 + g_signal_connect( text, "focus_out_event",
15.263 + G_CALLBACK(config_key_unfocus), NULL);
15.264 + g_object_set_data( G_OBJECT(text), "keypress_mode", GINT_TO_POINTER(FALSE) );
15.265 + g_object_set_data( G_OBJECT(text), "tag", GINT_TO_POINTER(i) );
15.266 + gtk_table_attach_defaults( GTK_TABLE(table), text, x+1, x+2, y, y+1);
15.267 + focus_chain = g_list_append( focus_chain, text );
15.268 +
15.269 + data->fields[i][1] = text2 = gtk_entry_new();
15.270 + gtk_entry_set_width_chars( GTK_ENTRY(text2), 11 );
15.271 + gtk_entry_set_editable( GTK_ENTRY(text2), FALSE );
15.272 + g_signal_connect( text2, "key_press_event",
15.273 + G_CALLBACK(config_key_keypress), NULL );
15.274 + g_signal_connect( text2, "button_press_event",
15.275 + G_CALLBACK(config_key_buttonpress), NULL );
15.276 + g_signal_connect( text2, "focus_out_event",
15.277 + G_CALLBACK(config_key_unfocus), NULL);
15.278 + g_object_set_data( G_OBJECT(text2), "keypress_mode", GINT_TO_POINTER(FALSE) );
15.279 + g_object_set_data( G_OBJECT(text2), "tag", GINT_TO_POINTER(i) );
15.280 + gtk_table_attach_defaults( GTK_TABLE(table), text2, x+2, x+3, y, y+1);
15.281 + focus_chain = g_list_append( focus_chain, text2 );
15.282 +
15.283 + if( conf->params[i].value != NULL ) {
15.284 + gchar **parts = g_strsplit(conf->params[i].value,",",3);
15.285 + if( parts[0] != NULL ) {
15.286 + gtk_entry_set_text( GTK_ENTRY(text), g_strstrip(parts[0]) );
15.287 + if( parts[1] != NULL ) {
15.288 + gtk_entry_set_text( GTK_ENTRY(text2), g_strstrip(parts[1]) );
15.289 + }
15.290 + }
15.291 + g_strfreev(parts);
15.292 + }
15.293 + break;
15.294 + case CONFIG_TYPE_FILE:
15.295 + case CONFIG_TYPE_PATH:
15.296 + data->fields[i][0] = text = gtk_entry_new();
15.297 + data->fields[i][1] = NULL;
15.298 + button = gtk_button_new();
15.299 + gtk_entry_set_text( GTK_ENTRY(text), conf->params[i].value );
15.300 + gtk_entry_set_width_chars( GTK_ENTRY(text), 48 );
15.301 + g_object_set_data( G_OBJECT(text), "tag", GINT_TO_POINTER(i) );
15.302 + gtk_table_attach_defaults( GTK_TABLE(table), text, 1, 2, y, y+1 );
15.303 + gtk_table_attach( GTK_TABLE(table), button, 2, 3, y, y+1, GTK_SHRINK, GTK_SHRINK, 0, 0 );
15.304 + g_signal_connect( text, "changed", G_CALLBACK(config_text_changed), NULL );
15.305 + if( conf->params[i].type == CONFIG_TYPE_FILE ) {
15.306 + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
15.307 + gtk_button_set_image( GTK_BUTTON(button), image );
15.308 + g_signal_connect( button, "clicked", G_CALLBACK(path_file_button_clicked), text );
15.309 + } else {
15.310 + GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU);
15.311 + gtk_button_set_image( GTK_BUTTON(button), image );
15.312 + g_signal_connect( button, "clicked", G_CALLBACK(path_dir_button_clicked), text );
15.313 + }
15.314 + break;
15.315 + }
15.316 + }
15.317 + gtk_container_set_focus_chain( GTK_CONTAINER(table), focus_chain );
15.318 +// gtk_gui_run_property_dialog( _("Controller Configuration"), table, controller_config_done );
15.319 + return table;
15.320 +}
15.321 +
15.322 +int gtk_configuration_panel_run( const gchar *title, lxdream_config_group_t group )
15.323 +{
15.324 + struct lxdream_config_group tmp;
15.325 + lxdream_clone_config_group( &tmp, group );
15.326 + GtkWidget *panel = gtk_configuration_panel_new( &tmp );
15.327 + int result = gtk_gui_run_property_dialog( title, panel, NULL );
15.328 + if( result == GTK_RESPONSE_ACCEPT ) {
15.329 + lxdream_copy_config_group( group, &tmp );
15.330 + lxdream_save_config();
15.331 + }
15.332 + return result;
15.333 +}
16.1 --- a/src/gtkui/gtk_ctrl.c Tue Jul 21 20:21:52 2009 +1000
16.2 +++ b/src/gtkui/gtk_ctrl.c Tue Jul 21 20:33:21 2009 +1000
16.3 @@ -34,7 +34,6 @@
16.4 #define LOAD_VMU_TAG ((void *)-1)
16.5 #define CREATE_VMU_TAG ((void *)-2)
16.6
16.7 -static void controller_device_configure(maple_device_t device);
16.8 static void maple_set_device_selection( GtkWidget *combo, maple_device_t device );
16.9
16.10 struct maple_config_class {
16.11 @@ -51,11 +50,6 @@
16.12 } *maple_slot_data_t;
16.13
16.14
16.15 -static struct maple_config_class maple_device_config[] = {
16.16 - { "Sega Controller", controller_device_configure },
16.17 - { "Sega Lightgun", controller_device_configure },
16.18 - { NULL, NULL } };
16.19 -
16.20 static struct maple_slot_data maple_data[MAPLE_MAX_DEVICES];
16.21
16.22 /**
16.23 @@ -64,174 +58,20 @@
16.24 */
16.25 static gboolean maple_device_adjusting = FALSE;
16.26
16.27 -static void config_keysym_hook( void *data, const gchar *keysym )
16.28 -{
16.29 - GtkWidget *widget = (GtkWidget *)data;
16.30 - gtk_entry_set_text( GTK_ENTRY(widget), keysym );
16.31 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
16.32 - input_set_keysym_hook(NULL, NULL);
16.33 -}
16.34 -
16.35 -static gboolean config_key_buttonpress( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
16.36 -{
16.37 - gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
16.38 - if( keypress_mode ) {
16.39 - gchar *keysym = input_keycode_to_keysym( &system_mouse_driver, event->button);
16.40 - if( keysym != NULL ) {
16.41 - config_keysym_hook( widget, keysym );
16.42 - g_free(keysym);
16.43 - }
16.44 - return TRUE;
16.45 - } else {
16.46 - gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
16.47 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
16.48 - input_set_keysym_hook(config_keysym_hook, widget);
16.49 - }
16.50 - return FALSE;
16.51 -}
16.52 -
16.53 -static gboolean config_key_keypress( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
16.54 -{
16.55 - gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
16.56 - if( keypress_mode ) {
16.57 - if( event->keyval == GDK_Escape ) {
16.58 - gtk_entry_set_text( GTK_ENTRY(widget), "" );
16.59 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
16.60 - return TRUE;
16.61 - }
16.62 - GdkKeymap *keymap = gdk_keymap_get_default();
16.63 - guint keyval;
16.64 -
16.65 - gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
16.66 - NULL, NULL, NULL );
16.67 - gtk_entry_set_text( GTK_ENTRY(widget), gdk_keyval_name(keyval) );
16.68 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
16.69 - input_set_keysym_hook(NULL, NULL);
16.70 - return TRUE;
16.71 - } else {
16.72 - switch( event->keyval ) {
16.73 - case GDK_Return:
16.74 - case GDK_KP_Enter:
16.75 - gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
16.76 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
16.77 - input_set_keysym_hook(config_keysym_hook, widget);
16.78 - return TRUE;
16.79 - case GDK_BackSpace:
16.80 - case GDK_Delete:
16.81 - gtk_entry_set_text( GTK_ENTRY(widget), "" );
16.82 - return TRUE;
16.83 - }
16.84 - return FALSE;
16.85 - }
16.86 -
16.87 -}
16.88 -
16.89 -static void controller_config_done( GtkWidget *panel, gboolean isOK )
16.90 -{
16.91 - if( isOK ) {
16.92 - maple_device_t device = (maple_device_t)gtk_object_get_data( GTK_OBJECT(panel), "maple_device" );
16.93 - lxdream_config_entry_t conf = device->get_config(device);
16.94 - int i;
16.95 - for( i=0; conf[i].key != NULL; i++ ) {
16.96 - char buf[64];
16.97 - GtkWidget *entry1, *entry2;
16.98 - const gchar *key1, *key2;
16.99 - snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
16.100 - entry1 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
16.101 - key1 = gtk_entry_get_text(GTK_ENTRY(entry1));
16.102 - snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
16.103 - entry2 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
16.104 - key2 = gtk_entry_get_text(GTK_ENTRY(entry2));
16.105 - if( key1 == NULL || key1[0] == '\0') {
16.106 - lxdream_set_config_value( &conf[i], key2 );
16.107 - } else if( key2 == NULL || key2[0] == '\0') {
16.108 - lxdream_set_config_value( &conf[i], key1 );
16.109 - } else {
16.110 - char buf[64];
16.111 - snprintf( buf, sizeof(buf), "%s, %s", key1, key2 );
16.112 - lxdream_set_config_value( &conf[i], buf );
16.113 - }
16.114 - }
16.115 - }
16.116 - input_set_keysym_hook(NULL, NULL);
16.117 -}
16.118 -
16.119 -static void controller_device_configure( maple_device_t device )
16.120 -{
16.121 - lxdream_config_entry_t conf = maple_get_device_config(device);
16.122 - int count, i;
16.123 - for( count=0; conf[count].key != NULL; count++ );
16.124 -
16.125 - GtkWidget *table = gtk_table_new( (count+1)>>1, 6, FALSE );
16.126 - GList *focus_chain = NULL;
16.127 - gtk_object_set_data( GTK_OBJECT(table), "maple_device", device );
16.128 - for( i=0; i<count; i++ ) {
16.129 - GtkWidget *text, *text2;
16.130 - char buf[64];
16.131 - int x=0;
16.132 - int y=i;
16.133 - if( i >= (count+1)>>1 ) {
16.134 - x = 3;
16.135 - y -= (count+1)>>1;
16.136 - }
16.137 - gtk_table_attach( GTK_TABLE(table), gtk_label_new(gettext(conf[i].label)), x, x+1, y, y+1,
16.138 - GTK_SHRINK, GTK_SHRINK, 0, 0 );
16.139 - text = gtk_entry_new();
16.140 - gtk_entry_set_width_chars( GTK_ENTRY(text), 11 );
16.141 - gtk_entry_set_editable( GTK_ENTRY(text), FALSE );
16.142 - g_signal_connect( text, "key_press_event",
16.143 - G_CALLBACK(config_key_keypress), NULL );
16.144 - g_signal_connect( text, "button_press_event",
16.145 - G_CALLBACK(config_key_buttonpress), NULL );
16.146 - snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
16.147 - g_object_set_data( G_OBJECT(text), "keypress_mode", GINT_TO_POINTER(FALSE) );
16.148 - g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text );
16.149 - gtk_table_attach_defaults( GTK_TABLE(table), text, x+1, x+2, y, y+1);
16.150 - focus_chain = g_list_append( focus_chain, text );
16.151 - text2 = gtk_entry_new();
16.152 - gtk_entry_set_width_chars( GTK_ENTRY(text2), 11 );
16.153 - gtk_entry_set_editable( GTK_ENTRY(text2), FALSE );
16.154 - g_signal_connect( text2, "key_press_event",
16.155 - G_CALLBACK(config_key_keypress), NULL );
16.156 - g_signal_connect( text2, "button_press_event",
16.157 - G_CALLBACK(config_key_buttonpress), NULL );
16.158 - snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
16.159 - g_object_set_data( G_OBJECT(text2), "keypress_mode", GINT_TO_POINTER(FALSE) );
16.160 - g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text2 );
16.161 - gtk_table_attach_defaults( GTK_TABLE(table), text2, x+2, x+3, y, y+1);
16.162 - focus_chain = g_list_append( focus_chain, text2 );
16.163 - if( conf[i].value != NULL ) {
16.164 - gchar **parts = g_strsplit(conf[i].value,",",3);
16.165 - if( parts[0] != NULL ) {
16.166 - gtk_entry_set_text( GTK_ENTRY(text), g_strstrip(parts[0]) );
16.167 - if( parts[1] != NULL ) {
16.168 - gtk_entry_set_text( GTK_ENTRY(text2), g_strstrip(parts[1]) );
16.169 - }
16.170 - }
16.171 - g_strfreev(parts);
16.172 - }
16.173 - }
16.174 - gtk_container_set_focus_chain( GTK_CONTAINER(table), focus_chain );
16.175 - gtk_gui_run_property_dialog( _("Controller Configuration"), table, controller_config_done );
16.176 -}
16.177 -
16.178 static gboolean maple_properties_activated( GtkButton *button, gpointer user_data )
16.179 {
16.180 maple_slot_data_t data = (maple_slot_data_t)user_data;
16.181 if( data->new_device != NULL ) {
16.182 int i;
16.183 - for( i=0; maple_device_config[i].name != NULL; i++ ) {
16.184 - if( strcmp(data->new_device->device_class->name, maple_device_config[i].name) == 0 ) {
16.185 - if( data->new_device == data->old_device ) {
16.186 - // Make a copy at this point if we haven't already
16.187 - data->new_device = data->old_device->clone(data->old_device);
16.188 - }
16.189 - maple_device_config[i].config_func(data->new_device);
16.190 - break;
16.191 + lxdream_config_group_t config = data->new_device->get_config(data->new_device);
16.192 + if( config != NULL ) {
16.193 +
16.194 + if( data->new_device == data->old_device ) {
16.195 + // Make a copy at this point if we haven't already
16.196 + data->new_device = data->old_device->clone(data->old_device);
16.197 }
16.198 - }
16.199 - if( maple_device_config[i].name == NULL ) {
16.200 - gui_error_dialog( _("No configuration page available for device type") );
16.201 +
16.202 + gtk_configuration_panel_run(_("Controller Configuration"), config);
16.203 }
16.204 }
16.205 return TRUE;
16.206 @@ -310,7 +150,7 @@
16.207 MAPLE_VMU_HAS_NAME(maple_data[i].new_device, vmu_filename) ) {
16.208 maple_data[i].new_device->destroy(maple_data[i].new_device);
16.209 maple_data[i].new_device = NULL;
16.210 - gtk_combo_box_set_active(maple_data[i].combo,0);
16.211 + gtk_combo_box_set_active(GTK_COMBO_BOX(maple_data[i].combo),0);
16.212 }
16.213 }
16.214 MAPLE_SET_VMU_NAME(data->new_device,vmu_filename);
17.1 --- a/src/gtkui/gtk_hotkeys.c Tue Jul 21 20:21:52 2009 +1000
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,187 +0,0 @@
17.4 -/**
17.5 - * $Id: $
17.6 - *
17.7 - * GTK dialog for defining hotkeys
17.8 - *
17.9 - * Copyright (c) 2009 wahrhaft.
17.10 - *
17.11 - * This program is free software; you can redistribute it and/or modify
17.12 - * it under the terms of the GNU General Public License as published by
17.13 - * the Free Software Foundation; either version 2 of the License, or
17.14 - * (at your option) any later version.
17.15 - *
17.16 - * This program is distributed in the hope that it will be useful,
17.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
17.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17.19 - * GNU General Public License for more details.
17.20 - */
17.21 -
17.22 -#include <assert.h>
17.23 -#include <string.h>
17.24 -#include <gtk/gtk.h>
17.25 -#include <gdk/gdkkeysyms.h>
17.26 -
17.27 -#include "lxdream.h"
17.28 -#include "display.h"
17.29 -#include "gtkui/gtkui.h"
17.30 -#include "hotkeys.h"
17.31 -
17.32 -
17.33 -
17.34 -static void config_keysym_hook( void *data, const gchar *keysym )
17.35 -{
17.36 - GtkWidget *widget = (GtkWidget *)data;
17.37 - gtk_entry_set_text( GTK_ENTRY(widget), keysym );
17.38 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
17.39 - input_set_keysym_hook(NULL, NULL);
17.40 -}
17.41 -
17.42 -static gboolean config_key_buttonpress( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
17.43 -{
17.44 - gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
17.45 - if( keypress_mode ) {
17.46 - gchar *keysym = input_keycode_to_keysym( &system_mouse_driver, event->button);
17.47 - if( keysym != NULL ) {
17.48 - config_keysym_hook( widget, keysym );
17.49 - g_free(keysym);
17.50 - }
17.51 - return TRUE;
17.52 - } else {
17.53 - gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
17.54 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
17.55 - input_set_keysym_hook(config_keysym_hook, widget);
17.56 - }
17.57 - return FALSE;
17.58 -}
17.59 -
17.60 -static gboolean config_key_keypress( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
17.61 -{
17.62 - gboolean keypress_mode = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(widget), "keypress_mode"));
17.63 - if( keypress_mode ) {
17.64 - if( event->keyval == GDK_Escape ) {
17.65 - gtk_entry_set_text( GTK_ENTRY(widget), "" );
17.66 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
17.67 - return TRUE;
17.68 - }
17.69 - GdkKeymap *keymap = gdk_keymap_get_default();
17.70 - guint keyval;
17.71 -
17.72 - gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
17.73 - NULL, NULL, NULL );
17.74 - gtk_entry_set_text( GTK_ENTRY(widget), gdk_keyval_name(keyval) );
17.75 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(FALSE) );
17.76 - input_set_keysym_hook(NULL, NULL);
17.77 - return TRUE;
17.78 - } else {
17.79 - switch( event->keyval ) {
17.80 - case GDK_Return:
17.81 - case GDK_KP_Enter:
17.82 - gtk_entry_set_text( GTK_ENTRY(widget), _("<press key>") );
17.83 - g_object_set_data( G_OBJECT(widget), "keypress_mode", GINT_TO_POINTER(TRUE) );
17.84 - input_set_keysym_hook(config_keysym_hook, widget);
17.85 - return TRUE;
17.86 - case GDK_BackSpace:
17.87 - case GDK_Delete:
17.88 - gtk_entry_set_text( GTK_ENTRY(widget), "" );
17.89 - return TRUE;
17.90 - }
17.91 - return FALSE;
17.92 - }
17.93 -
17.94 -}
17.95 -
17.96 -void hotkeys_dialog_done( GtkWidget *panel, gboolean isOK )
17.97 -{
17.98 - if( isOK ) {
17.99 - hotkeys_unregister_keys();
17.100 - lxdream_config_entry_t conf = hotkeys_get_config();
17.101 - int i;
17.102 - for( i=0; conf[i].key != NULL; i++ ) {
17.103 - char buf[64];
17.104 - GtkWidget *entry1, *entry2;
17.105 - const gchar *key1, *key2;
17.106 - snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
17.107 - entry1 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
17.108 - key1 = gtk_entry_get_text(GTK_ENTRY(entry1));
17.109 - snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
17.110 - entry2 = GTK_WIDGET(g_object_get_qdata( G_OBJECT(panel), g_quark_from_string(buf)));
17.111 - key2 = gtk_entry_get_text(GTK_ENTRY(entry2));
17.112 - if( key1 == NULL || key1[0] == '\0') {
17.113 - lxdream_set_config_value( &conf[i], key2 );
17.114 - } else if( key2 == NULL || key2[0] == '\0') {
17.115 - lxdream_set_config_value( &conf[i], key1 );
17.116 - } else {
17.117 - char buf[64];
17.118 - snprintf( buf, sizeof(buf), "%s, %s", key1, key2 );
17.119 - lxdream_set_config_value( &conf[i], buf );
17.120 - }
17.121 - }
17.122 - lxdream_save_config();
17.123 - hotkeys_register_keys();
17.124 - }
17.125 -}
17.126 -
17.127 -GtkWidget *hotkeys_panel_new()
17.128 -{
17.129 - lxdream_config_entry_t conf = hotkeys_get_config();
17.130 - int count, i;
17.131 - for( count=0; conf[count].key != NULL; count++ );
17.132 -
17.133 - GtkWidget *table = gtk_table_new( (count+1)>>1, 6, FALSE );
17.134 - GList *focus_chain = NULL;
17.135 - //gtk_object_set_data( GTK_OBJECT(table), "maple_device", device );
17.136 - for( i=0; i<count; i++ ) {
17.137 - GtkWidget *text, *text2;
17.138 - char buf[64];
17.139 - int x=0;
17.140 - int y=i;
17.141 - if( i >= (count+1)>>1 ) {
17.142 - x = 3;
17.143 - y -= (count+1)>>1;
17.144 - }
17.145 - gtk_table_attach( GTK_TABLE(table), gtk_label_new(gettext(conf[i].label)), x, x+1, y, y+1,
17.146 - GTK_SHRINK, GTK_SHRINK, 0, 0 );
17.147 - text = gtk_entry_new();
17.148 - gtk_entry_set_width_chars( GTK_ENTRY(text), 11 );
17.149 - gtk_entry_set_editable( GTK_ENTRY(text), FALSE );
17.150 - g_signal_connect( text, "key_press_event",
17.151 - G_CALLBACK(config_key_keypress), NULL );
17.152 - g_signal_connect( text, "button_press_event",
17.153 - G_CALLBACK(config_key_buttonpress), NULL );
17.154 - snprintf( buf, sizeof(buf), "%s.1", conf[i].key );
17.155 - g_object_set_data( G_OBJECT(text), "keypress_mode", GINT_TO_POINTER(FALSE) );
17.156 - g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text );
17.157 - gtk_table_attach_defaults( GTK_TABLE(table), text, x+1, x+2, y, y+1);
17.158 - focus_chain = g_list_append( focus_chain, text );
17.159 - text2 = gtk_entry_new();
17.160 - gtk_entry_set_width_chars( GTK_ENTRY(text2), 11 );
17.161 - gtk_entry_set_editable( GTK_ENTRY(text2), FALSE );
17.162 - g_signal_connect( text2, "key_press_event",
17.163 - G_CALLBACK(config_key_keypress), NULL );
17.164 - g_signal_connect( text2, "button_press_event",
17.165 - G_CALLBACK(config_key_buttonpress), NULL );
17.166 - snprintf( buf, sizeof(buf), "%s.2", conf[i].key );
17.167 - g_object_set_data( G_OBJECT(text2), "keypress_mode", GINT_TO_POINTER(FALSE) );
17.168 - g_object_set_qdata( G_OBJECT(table), g_quark_from_string(buf), text2 );
17.169 - gtk_table_attach_defaults( GTK_TABLE(table), text2, x+2, x+3, y, y+1);
17.170 - focus_chain = g_list_append( focus_chain, text2 );
17.171 - if( conf[i].value != NULL ) {
17.172 - gchar **parts = g_strsplit(conf[i].value,",",3);
17.173 - if( parts[0] != NULL ) {
17.174 - gtk_entry_set_text( GTK_ENTRY(text), g_strstrip(parts[0]) );
17.175 - if( parts[1] != NULL ) {
17.176 - gtk_entry_set_text( GTK_ENTRY(text2), g_strstrip(parts[1]) );
17.177 - }
17.178 - }
17.179 - g_strfreev(parts);
17.180 - }
17.181 - }
17.182 - gtk_container_set_focus_chain( GTK_CONTAINER(table), focus_chain );
17.183 -
17.184 - return table;
17.185 -}
17.186 -
17.187 -void hotkeys_dialog_run( )
17.188 -{
17.189 - gtk_gui_run_property_dialog( _("Hotkey Settings"), hotkeys_panel_new(), hotkeys_dialog_done );
17.190 -}
18.1 --- a/src/gtkui/gtk_path.c Tue Jul 21 20:21:52 2009 +1000
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,130 +0,0 @@
18.4 -/**
18.5 - * $Id$
18.6 - *
18.7 - * Define the main (emu) GTK window, along with its menubars,
18.8 - * toolbars, etc.
18.9 - *
18.10 - * Copyright (c) 2005 Nathan Keynes.
18.11 - *
18.12 - * This program is free software; you can redistribute it and/or modify
18.13 - * it under the terms of the GNU General Public License as published by
18.14 - * the Free Software Foundation; either version 2 of the License, or
18.15 - * (at your option) any later version.
18.16 - *
18.17 - * This program is distributed in the hope that it will be useful,
18.18 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
18.19 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.20 - * GNU General Public License for more details.
18.21 - */
18.22 -
18.23 -#include <assert.h>
18.24 -#include <gtk/gtk.h>
18.25 -
18.26 -#include "lxdream.h"
18.27 -#include "dreamcast.h"
18.28 -#include "config.h"
18.29 -#include "lxpaths.h"
18.30 -#include "gtkui/gtkui.h"
18.31 -
18.32 -static GtkWidget *path_entry[CONFIG_KEY_MAX];
18.33 -
18.34 -static gboolean path_file_button_clicked( GtkWidget *button, gpointer user_data )
18.35 -{
18.36 - GtkWidget *entry = GTK_WIDGET(user_data);
18.37 - GtkWidget *file = gtk_file_chooser_dialog_new( _("Select file"), NULL,
18.38 - GTK_FILE_CHOOSER_ACTION_OPEN,
18.39 - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
18.40 - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
18.41 - NULL );
18.42 - gchar *filename = get_expanded_path(gtk_entry_get_text(GTK_ENTRY(entry)));
18.43 - gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename );
18.44 - gtk_window_set_modal( GTK_WINDOW(file), TRUE );
18.45 - gtk_widget_show_all( file );
18.46 - gint result = gtk_dialog_run(GTK_DIALOG(file));
18.47 - g_free(filename);
18.48 - if( result == GTK_RESPONSE_ACCEPT ) {
18.49 - filename = get_escaped_path(gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ));
18.50 - gtk_entry_set_text(GTK_ENTRY(entry), filename);
18.51 - g_free(filename);
18.52 - }
18.53 - gtk_widget_destroy(file);
18.54 - return TRUE;
18.55 -}
18.56 -
18.57 -static gboolean path_dir_button_clicked( GtkWidget *button, gpointer user_data )
18.58 -{
18.59 - GtkWidget *entry = GTK_WIDGET(user_data);
18.60 - GtkWidget *file = gtk_file_chooser_dialog_new( _("Select file"), NULL,
18.61 - GTK_FILE_CHOOSER_ACTION_OPEN,
18.62 - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
18.63 - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
18.64 - NULL );
18.65 - gchar *filename = get_expanded_path(gtk_entry_get_text(GTK_ENTRY(entry)));
18.66 - gtk_file_chooser_set_action( GTK_FILE_CHOOSER(file), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER );
18.67 - gtk_file_chooser_set_filename( GTK_FILE_CHOOSER(file), filename );
18.68 - gtk_window_set_modal( GTK_WINDOW(file), TRUE );
18.69 - gtk_widget_show_all( file );
18.70 - gint result = gtk_dialog_run(GTK_DIALOG(file));
18.71 - g_free(filename);
18.72 - if( result == GTK_RESPONSE_ACCEPT ) {
18.73 - filename = get_escaped_path(gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) ));
18.74 - gtk_entry_set_text(GTK_ENTRY(entry), filename);
18.75 - g_free(filename);
18.76 - }
18.77 - gtk_widget_destroy(file);
18.78 - return TRUE;
18.79 -}
18.80 -
18.81 -GtkWidget *path_panel_new(void)
18.82 -{
18.83 - int i, y=0;
18.84 - GtkWidget *table = gtk_table_new( CONFIG_KEY_MAX, 3, FALSE );
18.85 - for( i=0; i<CONFIG_KEY_MAX; i++ ) {
18.86 - const struct lxdream_config_entry *entry = lxdream_get_global_config_entry(i);
18.87 - if( entry->label != NULL ) {
18.88 - GtkWidget *text = path_entry[i] = gtk_entry_new();
18.89 - GtkWidget *button = gtk_button_new();
18.90 - gtk_table_attach( GTK_TABLE(table), gtk_label_new(Q_(entry->label)), 0, 1, y, y+1,
18.91 - GTK_SHRINK, GTK_SHRINK, 0, 0);
18.92 - gtk_entry_set_text( GTK_ENTRY(text), lxdream_get_global_config_value(i) );
18.93 - gtk_entry_set_width_chars( GTK_ENTRY(text), 48 );
18.94 - gtk_table_attach_defaults( GTK_TABLE(table), text, 1, 2, y, y+1 );
18.95 - gtk_table_attach( GTK_TABLE(table), button, 2, 3, y, y+1, GTK_SHRINK, GTK_SHRINK, 0, 0 );
18.96 - if( entry->type == CONFIG_TYPE_FILE ) {
18.97 - GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
18.98 - gtk_button_set_image( GTK_BUTTON(button), image );
18.99 - g_signal_connect( button, "clicked", G_CALLBACK(path_file_button_clicked), text );
18.100 - } else {
18.101 - GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU);
18.102 - gtk_button_set_image( GTK_BUTTON(button), image );
18.103 - g_signal_connect( button, "clicked", G_CALLBACK(path_dir_button_clicked), text );
18.104 - }
18.105 - y++;
18.106 - }
18.107 - }
18.108 - gtk_table_resize( GTK_TABLE(table), y, 3 );
18.109 - return table;
18.110 -
18.111 -}
18.112 -
18.113 -void path_panel_done( GtkWidget *panel, gboolean isOK )
18.114 -{
18.115 - if( isOK ) {
18.116 - int i;
18.117 - for(i=0; i<CONFIG_KEY_MAX; i++ ) {
18.118 - if( path_entry[i] != NULL ) {
18.119 - const char *filename = gtk_entry_get_text( GTK_ENTRY(path_entry[i]) );
18.120 - lxdream_set_global_config_value( i, filename );
18.121 - }
18.122 - }
18.123 -
18.124 - lxdream_save_config();
18.125 - dreamcast_config_changed();
18.126 - gtk_gui_update();
18.127 - }
18.128 -}
18.129 -
18.130 -void path_dialog_run( void )
18.131 -{
18.132 - gtk_gui_run_property_dialog( _("Path Settings"), path_panel_new(), path_panel_done );
18.133 -}
19.1 --- a/src/gtkui/gtkcb.c Tue Jul 21 20:21:52 2009 +1000
19.2 +++ b/src/gtkui/gtkcb.c Tue Jul 21 20:33:21 2009 +1000
19.3 @@ -79,7 +79,7 @@
19.4 int initial_dir_key )
19.5 {
19.6 GtkWidget *file;
19.7 - gchar *filename;
19.8 + gchar *filename = NULL;
19.9
19.10 file = gtk_file_chooser_dialog_new( title, NULL,
19.11 GTK_FILE_CHOOSER_ACTION_SAVE,
19.12 @@ -257,7 +257,7 @@
19.13
19.14 void path_settings_callback( GtkAction *action, gpointer user_data)
19.15 {
19.16 - path_dialog_run();
19.17 + gtk_configuration_panel_run( _("Path Settings"), lxdream_get_config_group(CONFIG_GROUP_GLOBAL) );
19.18 }
19.19
19.20 void audio_settings_callback( GtkAction *action, gpointer user_data)
19.21 @@ -279,7 +279,7 @@
19.22
19.23 void hotkey_settings_callback( GtkAction *action, gpointer user_data)
19.24 {
19.25 - hotkeys_dialog_run();
19.26 + gtk_configuration_panel_run( _("Hotkey Settings"), lxdream_get_config_group(CONFIG_GROUP_HOTKEYS) );
19.27 }
19.28
19.29 void fullscreen_toggle_callback( GtkToggleAction *action, gpointer user_data)
20.1 --- a/src/gtkui/gtkui.h Tue Jul 21 20:21:52 2009 +1000
20.2 +++ b/src/gtkui/gtkui.h Tue Jul 21 20:33:21 2009 +1000
20.3 @@ -36,6 +36,8 @@
20.4 typedef struct mmio_window_info *mmio_window_t;
20.5 typedef struct dump_window_info *dump_window_t;
20.6
20.7 +struct lxdream_config_group; /* Forward declaration */
20.8 +
20.9 /**
20.10 * Construct and show the main window, returning an
20.11 * opaque pointer to the window.
20.12 @@ -85,7 +87,7 @@
20.13 typedef void (*gtk_dialog_done_fn)(GtkWidget *panel, gboolean isOK);
20.14 void gtk_gui_enable_action( const gchar *action, gboolean enabled );
20.15 gint gtk_gui_run_property_dialog( const gchar *title, GtkWidget *panel, gtk_dialog_done_fn fn );
20.16 -
20.17 +int gtk_configuration_panel_run( const gchar *title, struct lxdream_config_group *group );
20.18
20.19 typedef gboolean (*file_callback_t)( const gchar *filename );
20.20 gchar *open_file_dialog( const char *title, const char *pattern, const char *patname,
21.1 --- a/src/hotkeys.c Tue Jul 21 20:21:52 2009 +1000
21.2 +++ b/src/hotkeys.c Tue Jul 21 20:33:21 2009 +1000
21.3 @@ -1,5 +1,5 @@
21.4 /**
21.5 - * $Id: $
21.6 + * $Id$
21.7 *
21.8 * Handles hotkeys for pause/continue, save states, quit, etc
21.9 *
21.10 @@ -27,34 +27,37 @@
21.11 #include "gui.h"
21.12 #include "config.h"
21.13
21.14 -static void hotkey_resume_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.15 -static void hotkey_stop_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.16 -static void hotkey_reset_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.17 -static void hotkey_exit_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.18 -static void hotkey_state_select_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.19 -static void hotkey_state_save_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.20 -static void hotkey_state_load_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.21 +static void hotkey_key_callback( void *data, uint32_t value, uint32_t pressure, gboolean isKeyDown );
21.22 +static gboolean hotkey_config_changed( void *data, lxdream_config_group_t group, unsigned key,
21.23 + const gchar *oldval, const gchar *newval );
21.24
21.25 +#define TAG_RESUME 0
21.26 +#define TAG_STOP 1
21.27 +#define TAG_RESET 2
21.28 +#define TAG_EXIT 3
21.29 +#define TAG_SAVE 4
21.30 +#define TAG_LOAD 5
21.31 +#define TAG_SELECT(i) (6+(i))
21.32
21.33 -struct lxdream_config_entry hotkeys_config[] = {
21.34 - {"resume", N_("Resume emulation"), CONFIG_TYPE_KEY},
21.35 - {"stop", N_("Stop emulation"), CONFIG_TYPE_KEY},
21.36 - {"reset", N_("Reset emulator"), CONFIG_TYPE_KEY},
21.37 - {"exit", N_("Exit emulator"), CONFIG_TYPE_KEY},
21.38 - {"save", N_("Save current quick save"), CONFIG_TYPE_KEY},
21.39 - {"load", N_("Load current quick save"), CONFIG_TYPE_KEY},
21.40 - {"state0", N_("Select quick save state 0"), CONFIG_TYPE_KEY},
21.41 - {"state1", N_("Select quick save state 1"), CONFIG_TYPE_KEY},
21.42 - {"state2", N_("Select quick save state 2"), CONFIG_TYPE_KEY},
21.43 - {"state3", N_("Select quick save state 3"), CONFIG_TYPE_KEY},
21.44 - {"state4", N_("Select quick save state 4"), CONFIG_TYPE_KEY},
21.45 - {"state5", N_("Select quick save state 5"), CONFIG_TYPE_KEY},
21.46 - {"state6", N_("Select quick save state 6"), CONFIG_TYPE_KEY},
21.47 - {"state7", N_("Select quick save state 7"), CONFIG_TYPE_KEY},
21.48 - {"state8", N_("Select quick save state 8"), CONFIG_TYPE_KEY},
21.49 - {"state9", N_("Select quick save state 9"), CONFIG_TYPE_KEY},
21.50 - {NULL, CONFIG_TYPE_NONE}
21.51 -};
21.52 +struct lxdream_config_group hotkeys_group = {
21.53 + "hotkeys", input_keygroup_changed, hotkey_key_callback, NULL, {
21.54 + {"resume", N_("Resume emulation"), CONFIG_TYPE_KEY, NULL, TAG_RESUME },
21.55 + {"stop", N_("Stop emulation"), CONFIG_TYPE_KEY, NULL, TAG_STOP },
21.56 + {"reset", N_("Reset emulator"), CONFIG_TYPE_KEY, NULL, TAG_RESET },
21.57 + {"exit", N_("Exit emulator"), CONFIG_TYPE_KEY, NULL, TAG_EXIT },
21.58 + {"save", N_("Save current quick save"), CONFIG_TYPE_KEY, NULL, TAG_SAVE },
21.59 + {"load", N_("Load current quick save"), CONFIG_TYPE_KEY, NULL, TAG_LOAD },
21.60 + {"state0", N_("Select quick save state 0"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(0) },
21.61 + {"state1", N_("Select quick save state 1"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(1) },
21.62 + {"state2", N_("Select quick save state 2"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(2) },
21.63 + {"state3", N_("Select quick save state 3"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(3) },
21.64 + {"state4", N_("Select quick save state 4"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(4) },
21.65 + {"state5", N_("Select quick save state 5"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(5) },
21.66 + {"state6", N_("Select quick save state 6"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(6) },
21.67 + {"state7", N_("Select quick save state 7"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(7) },
21.68 + {"state8", N_("Select quick save state 8"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(8) },
21.69 + {"state9", N_("Select quick save state 9"), CONFIG_TYPE_KEY, NULL, TAG_SELECT(9) },
21.70 + {NULL, CONFIG_TYPE_NONE}} };
21.71
21.72 void hotkeys_init()
21.73 {
21.74 @@ -63,86 +66,47 @@
21.75
21.76 void hotkeys_register_keys()
21.77 {
21.78 - input_register_key(hotkeys_config[0].value, &hotkey_resume_callback, NULL, 0);
21.79 - input_register_key(hotkeys_config[1].value, &hotkey_stop_callback, NULL, 0);
21.80 - input_register_key(hotkeys_config[2].value, &hotkey_reset_callback, NULL, 0);
21.81 - input_register_key(hotkeys_config[3].value, &hotkey_exit_callback, NULL, 0);
21.82 - input_register_key(hotkeys_config[4].value, &hotkey_state_save_callback, NULL, 0);
21.83 - input_register_key(hotkeys_config[5].value, &hotkey_state_load_callback, NULL, 0);
21.84 - for (int i = 0; i < 10; i++)
21.85 - {
21.86 - input_register_key(hotkeys_config[6 + i].value, &hotkey_state_select_callback, NULL, i);
21.87 - }
21.88 + input_register_keygroup( &hotkeys_group );
21.89 }
21.90
21.91 void hotkeys_unregister_keys()
21.92 {
21.93 - input_unregister_key(hotkeys_config[0].value, &hotkey_resume_callback, NULL, 0);
21.94 - input_unregister_key(hotkeys_config[1].value, &hotkey_stop_callback, NULL, 0);
21.95 - input_unregister_key(hotkeys_config[2].value, &hotkey_reset_callback, NULL, 0);
21.96 - input_unregister_key(hotkeys_config[3].value, &hotkey_exit_callback, NULL, 0);
21.97 - input_unregister_key(hotkeys_config[4].value, &hotkey_state_save_callback, NULL, 0);
21.98 - input_unregister_key(hotkeys_config[5].value, &hotkey_state_load_callback, NULL, 0);
21.99 - for (int i = 0; i < 10; i++)
21.100 - {
21.101 - input_unregister_key(hotkeys_config[6 + i].value, &hotkey_state_select_callback, NULL, i);
21.102 + input_unregister_keygroup( &hotkeys_group );
21.103 +}
21.104 +
21.105 +lxdream_config_group_t hotkeys_get_config()
21.106 +{
21.107 + return &hotkeys_group;
21.108 +}
21.109 +
21.110 +static void hotkey_key_callback( void *data, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.111 +{
21.112 + if( isKeyDown ) {
21.113 + switch(value) {
21.114 + case TAG_RESUME:
21.115 + if( !dreamcast_is_running() )
21.116 + gui_do_later(dreamcast_run);
21.117 + break;
21.118 + case TAG_STOP:
21.119 + if( dreamcast_is_running() )
21.120 + gui_do_later(dreamcast_stop);
21.121 + break;
21.122 + case TAG_RESET:
21.123 + dreamcast_reset();
21.124 + break;
21.125 + case TAG_EXIT:
21.126 + dreamcast_shutdown();
21.127 + exit(0);
21.128 + break;
21.129 + case TAG_SAVE:
21.130 + dreamcast_quick_save();
21.131 + break;
21.132 + case TAG_LOAD:
21.133 + dreamcast_quick_load();
21.134 + break;
21.135 + default:
21.136 + dreamcast_set_quick_state(value- TAG_SELECT(0) );
21.137 + break;
21.138 + }
21.139 }
21.140 }
21.141 -
21.142 -lxdream_config_entry_t hotkeys_get_config()
21.143 -{
21.144 - return hotkeys_config;
21.145 -}
21.146 -
21.147 -
21.148 -static void hotkey_resume_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.149 -{
21.150 - if (isKeyDown && !dreamcast_is_running() ) {
21.151 - gui_do_later(dreamcast_run);
21.152 - }
21.153 -}
21.154 -
21.155 -static void hotkey_stop_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.156 -{
21.157 - if (isKeyDown && dreamcast_is_running() ) {
21.158 - gui_do_later(dreamcast_stop);
21.159 - }
21.160 -}
21.161 -
21.162 -static void hotkey_reset_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.163 -{
21.164 - if (isKeyDown) {
21.165 - dreamcast_reset();
21.166 - }
21.167 -}
21.168 -
21.169 -static void hotkey_exit_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.170 -{
21.171 - if (isKeyDown) {
21.172 - dreamcast_shutdown();
21.173 - }
21.174 - exit(0);
21.175 -}
21.176 -
21.177 -static void hotkey_state_select_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.178 -{
21.179 - if (isKeyDown) {
21.180 - dreamcast_set_quick_state(value);
21.181 - }
21.182 -}
21.183 -
21.184 -static void hotkey_state_save_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.185 -{
21.186 - if (isKeyDown) {
21.187 - dreamcast_quick_save();
21.188 - }
21.189 -}
21.190 -
21.191 -static void hotkey_state_load_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown )
21.192 -{
21.193 - if (isKeyDown) {
21.194 - dreamcast_quick_load();
21.195 - }
21.196 -}
21.197 -
21.198 -
22.1 --- a/src/hotkeys.h Tue Jul 21 20:21:52 2009 +1000
22.2 +++ b/src/hotkeys.h Tue Jul 21 20:33:21 2009 +1000
22.3 @@ -1,5 +1,5 @@
22.4 /**
22.5 - * $Id: $
22.6 + * $Id$
22.7 *
22.8 * Handles hotkeys for pause/continue, save states, quit, etc
22.9 *
22.10 @@ -26,7 +26,7 @@
22.11 #endif
22.12
22.13 void hotkeys_init();
22.14 - lxdream_config_entry_t hotkeys_get_config();
22.15 + lxdream_config_group_t hotkeys_get_config();
22.16 void hotkeys_register_keys();
22.17 void hotkeys_unregister_keys();
22.18
23.1 --- a/src/maple/controller.c Tue Jul 21 20:21:52 2009 +1000
23.2 +++ b/src/maple/controller.c Tue Jul 21 20:33:21 2009 +1000
23.3 @@ -79,18 +79,17 @@
23.4
23.5 static void controller_attach( maple_device_t dev );
23.6 static void controller_detach( maple_device_t dev );
23.7 -static void controller_destroy( maple_device_t dev );
23.8 +static void controller_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
23.9 static maple_device_t controller_clone( maple_device_t dev );
23.10 static maple_device_t controller_new();
23.11 -static lxdream_config_entry_t controller_get_config( maple_device_t dev );
23.12 -static void controller_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );
23.13 +static lxdream_config_group_t controller_get_config( maple_device_t dev );
23.14 static int controller_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
23.15 unsigned int *outlen );
23.16
23.17 typedef struct controller_device {
23.18 struct maple_device dev;
23.19 uint32_t condition[2];
23.20 - struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES+1];
23.21 + struct lxdream_config_group config;
23.22 } *controller_device_t;
23.23
23.24 struct maple_device_class controller_class = { "Sega Controller",
23.25 @@ -99,26 +98,30 @@
23.26 static struct controller_device base_controller = {
23.27 { MAPLE_DEVICE_TAG, &controller_class,
23.28 CONTROLLER_IDENT, CONTROLLER_VERSION,
23.29 - controller_get_config, controller_set_config_value,
23.30 - controller_attach, controller_detach, controller_destroy,
23.31 + controller_get_config,
23.32 + controller_attach, controller_detach, maple_default_destroy,
23.33 controller_clone, NULL, NULL, controller_get_cond, NULL, NULL, NULL, NULL, NULL, NULL },
23.34 - {0x0000FFFF, 0x80808080},
23.35 - {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },
23.36 - { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY },
23.37 - { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY },
23.38 - { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY },
23.39 - { "analog left", N_("Analog left"), CONFIG_TYPE_KEY },
23.40 - { "analog right", N_("Analog right"), CONFIG_TYPE_KEY },
23.41 - { "analog up", N_("Analog up"), CONFIG_TYPE_KEY },
23.42 - { "analog down", N_("Analog down"), CONFIG_TYPE_KEY },
23.43 - { "button X", N_("Button X"), CONFIG_TYPE_KEY },
23.44 - { "button Y", N_("Button Y"), CONFIG_TYPE_KEY },
23.45 - { "button A", N_("Button A"), CONFIG_TYPE_KEY },
23.46 - { "button B", N_("Button B"), CONFIG_TYPE_KEY },
23.47 - { "trigger left", N_("Trigger left"), CONFIG_TYPE_KEY },
23.48 - { "trigger right", N_("Trigger right"), CONFIG_TYPE_KEY },
23.49 - { "start", N_("Start button"), CONFIG_TYPE_KEY },
23.50 - { NULL, CONFIG_TYPE_NONE }} };
23.51 + {0x0000FFFF, 0x80808080},
23.52 + {"Sega Controller", NULL, controller_key_callback, NULL,
23.53 + {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_LEFT },
23.54 + { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_RIGHT },
23.55 + { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_UP },
23.56 + { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_DOWN },
23.57 + { "analog left", N_("Analog left"), CONFIG_TYPE_KEY, NULL, JOY_LEFT },
23.58 + { "analog right", N_("Analog right"), CONFIG_TYPE_KEY, NULL, JOY_RIGHT },
23.59 + { "analog up", N_("Analog up"), CONFIG_TYPE_KEY, NULL, JOY_UP },
23.60 + { "analog down", N_("Analog down"), CONFIG_TYPE_KEY, NULL, JOY_DOWN },
23.61 + { "button X", N_("Button X"), CONFIG_TYPE_KEY, NULL, BUTTON_X },
23.62 + { "button Y", N_("Button Y"), CONFIG_TYPE_KEY, NULL, BUTTON_Y },
23.63 + { "button A", N_("Button A"), CONFIG_TYPE_KEY, NULL, BUTTON_A },
23.64 + { "button B", N_("Button B"), CONFIG_TYPE_KEY, NULL, BUTTON_B },
23.65 + { "trigger left", N_("Trigger left"), CONFIG_TYPE_KEY, NULL, BUTTON_LEFT_TRIGGER },
23.66 + { "trigger right", N_("Trigger right"), CONFIG_TYPE_KEY, NULL, BUTTON_RIGHT_TRIGGER },
23.67 + { "start", N_("Start button"), CONFIG_TYPE_KEY, NULL, BUTTON_START },
23.68 + { NULL, CONFIG_TYPE_NONE }}} };
23.69 +
23.70 +/* Get the controller_device * from a lxdream_config_group_t */
23.71 +#define DEV_FROM_CONFIG_GROUP(grp) ((controller_device_t)(((char *)grp) - offsetof( struct controller_device, config )))
23.72
23.73 static int config_button_map[] = {
23.74 BUTTON_DPAD_LEFT, BUTTON_DPAD_RIGHT, BUTTON_DPAD_UP, BUTTON_DPAD_DOWN,
23.75 @@ -129,8 +132,9 @@
23.76
23.77 static maple_device_t controller_new( )
23.78 {
23.79 - controller_device_t dev = malloc( sizeof(struct controller_device) );
23.80 + controller_device_t dev = malloc( sizeof(base_controller) );
23.81 memcpy( dev, &base_controller, sizeof(base_controller) );
23.82 + dev->config.data = dev;
23.83 return MAPLE_DEVICE(dev);
23.84 }
23.85
23.86 @@ -138,7 +142,7 @@
23.87 {
23.88 controller_device_t src = (controller_device_t)srcdevice;
23.89 controller_device_t dev = (controller_device_t)controller_new();
23.90 - lxdream_copy_config_list( dev->config, src->config );
23.91 + lxdream_copy_config_group( &dev->config, &src->config );
23.92 memcpy( dev->condition, src->condition, sizeof(src->condition) );
23.93 return MAPLE_DEVICE(dev);
23.94 }
23.95 @@ -194,25 +198,10 @@
23.96 }
23.97 }
23.98
23.99 -static lxdream_config_entry_t controller_get_config( maple_device_t mdev )
23.100 +static lxdream_config_group_t controller_get_config( maple_device_t mdev )
23.101 {
23.102 controller_device_t dev = (controller_device_t)mdev;
23.103 - return dev->config;
23.104 -}
23.105 -
23.106 -static void controller_set_config_value( maple_device_t mdev, unsigned int key, const gchar *value )
23.107 -{
23.108 - controller_device_t dev = (controller_device_t)mdev;
23.109 - assert( key < CONTROLLER_CONFIG_ENTRIES );
23.110 -
23.111 - input_unregister_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
23.112 - lxdream_set_config_value( &dev->config[key], value );
23.113 - input_register_key( dev->config[key].value, controller_key_callback, dev, config_button_map[key] );
23.114 -}
23.115 -
23.116 -static void controller_destroy( maple_device_t mdev )
23.117 -{
23.118 - free( mdev );
23.119 + return &dev->config;
23.120 }
23.121
23.122 /**
23.123 @@ -222,20 +211,15 @@
23.124 static void controller_attach( maple_device_t mdev )
23.125 {
23.126 controller_device_t dev = (controller_device_t)mdev;
23.127 - int i;
23.128 - for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
23.129 - input_register_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
23.130 - }
23.131 + dev->config.on_change = input_keygroup_changed;
23.132 + input_register_keygroup( &dev->config );
23.133 }
23.134
23.135 static void controller_detach( maple_device_t mdev )
23.136 {
23.137 controller_device_t dev = (controller_device_t)mdev;
23.138 - int i;
23.139 - for( i=0; i<CONTROLLER_CONFIG_ENTRIES; i++ ) {
23.140 - input_unregister_key( dev->config[i].value, controller_key_callback, dev, config_button_map[i] );
23.141 - }
23.142 -
23.143 + input_unregister_keygroup( &dev->config );
23.144 + dev->config.on_change = NULL;
23.145 }
23.146
23.147
24.1 --- a/src/maple/kbd.c Tue Jul 21 20:21:52 2009 +1000
24.2 +++ b/src/maple/kbd.c Tue Jul 21 20:33:21 2009 +1000
24.3 @@ -57,7 +57,7 @@
24.4 static struct keyboard_device base_keyboard = {
24.5 { MAPLE_DEVICE_TAG, &keyboard_class,
24.6 KEYBOARD_IDENT, KEYBOARD_VERSION,
24.7 - NULL, NULL, keyboard_attach, keyboard_detach, maple_default_destroy,
24.8 + NULL, keyboard_attach, keyboard_detach, maple_default_destroy,
24.9 keyboard_clone, NULL, NULL, keyboard_get_cond, NULL, NULL, NULL,
24.10 NULL, NULL, NULL},
24.11 {0,0,0,0,0,0,0,0},
25.1 --- a/src/maple/lightgun.c Tue Jul 21 20:21:52 2009 +1000
25.2 +++ b/src/maple/lightgun.c Tue Jul 21 20:33:21 2009 +1000
25.3 @@ -57,19 +57,22 @@
25.4 static void lightgun_destroy( maple_device_t dev );
25.5 static maple_device_t lightgun_clone( maple_device_t dev );
25.6 static maple_device_t lightgun_new();
25.7 -static lxdream_config_entry_t lightgun_get_config( maple_device_t dev );
25.8 -static void lightgun_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );
25.9 +static void lightgun_key_callback( void *mdev, uint32_t value, uint32_t pressure, gboolean isKeyDown );
25.10 +static lxdream_config_group_t lightgun_get_config( maple_device_t dev );
25.11 static int lightgun_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
25.12 unsigned int *outlen );
25.13 static void lightgun_start_gun( maple_device_t dev );
25.14 static void lightgun_stop_gun( maple_device_t dev );
25.15
25.16 +static gboolean lightgun_set_config_value( lxdream_config_group_t group, unsigned int key,
25.17 + const gchar *oldvalue, const gchar *value );
25.18 +
25.19 typedef struct lightgun_device {
25.20 struct maple_device dev;
25.21 uint32_t condition[2];
25.22 int gun_active;
25.23 int mouse_x, mouse_y;
25.24 - struct lxdream_config_entry config[LIGHTGUN_CONFIG_ENTRIES+1];
25.25 + struct lxdream_config_group config;
25.26 } *lightgun_device_t;
25.27
25.28 struct maple_device_class lightgun_class = { "Sega Lightgun",
25.29 @@ -78,30 +81,29 @@
25.30 static struct lightgun_device base_lightgun = {
25.31 { MAPLE_DEVICE_TAG, &lightgun_class,
25.32 LIGHTGUN_IDENT, LIGHTGUN_VERSION,
25.33 - lightgun_get_config, lightgun_set_config_value,
25.34 + lightgun_get_config,
25.35 lightgun_attach, lightgun_detach, lightgun_destroy,
25.36 lightgun_clone, NULL, NULL, lightgun_get_cond, NULL, NULL, NULL, NULL,
25.37 lightgun_start_gun, lightgun_stop_gun},
25.38 - {0x0000FFFF, 0x80808080}, 0, -1, -1,
25.39 - {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },
25.40 - { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY },
25.41 - { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY },
25.42 - { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY },
25.43 - { "button A", N_("Button A"), CONFIG_TYPE_KEY },
25.44 - { "button B", N_("Button B"), CONFIG_TYPE_KEY },
25.45 - { "start", N_("Start button"), CONFIG_TYPE_KEY },
25.46 - { NULL, CONFIG_TYPE_NONE }} };
25.47 + {0x0000FFFF, 0x80808080}, 0, -1, -1,
25.48 + {"Sega Lightgun", NULL, lightgun_key_callback, NULL,
25.49 + {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_LEFT },
25.50 + { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_RIGHT },
25.51 + { "dpad up", N_("Dpad up"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_UP },
25.52 + { "dpad down", N_("Dpad down"), CONFIG_TYPE_KEY, NULL, BUTTON_DPAD_DOWN },
25.53 + { "button A", N_("Button A"), CONFIG_TYPE_KEY, NULL, BUTTON_A },
25.54 + { "button B", N_("Button B"), CONFIG_TYPE_KEY, NULL, BUTTON_B },
25.55 + { "start", N_("Start button"), CONFIG_TYPE_KEY, NULL, BUTTON_START },
25.56 + { NULL, CONFIG_TYPE_NONE }}} };
25.57
25.58 -static int config_button_map[] = {
25.59 - BUTTON_DPAD_LEFT, BUTTON_DPAD_RIGHT, BUTTON_DPAD_UP, BUTTON_DPAD_DOWN,
25.60 - BUTTON_A, BUTTON_B, BUTTON_START };
25.61 -
25.62 +
25.63 #define lightgun(x) ((lightgun_device_t)(x))
25.64
25.65 static maple_device_t lightgun_new( )
25.66 {
25.67 lightgun_device_t dev = malloc( sizeof(struct lightgun_device) );
25.68 memcpy( dev, &base_lightgun, sizeof(base_lightgun) );
25.69 + dev->config.data = dev;
25.70 return MAPLE_DEVICE(dev);
25.71 }
25.72
25.73 @@ -109,11 +111,22 @@
25.74 {
25.75 lightgun_device_t src = (lightgun_device_t)srcdevice;
25.76 lightgun_device_t dev = (lightgun_device_t)lightgun_new();
25.77 - lxdream_copy_config_list( dev->config, src->config );
25.78 + lxdream_copy_config_group( &dev->config, &src->config );
25.79 memcpy( dev->condition, src->condition, sizeof(src->condition) );
25.80 return MAPLE_DEVICE(dev);
25.81 }
25.82
25.83 +static lxdream_config_group_t lightgun_get_config( maple_device_t mdev )
25.84 +{
25.85 + lightgun_device_t dev = (lightgun_device_t)mdev;
25.86 + return &dev->config;
25.87 +}
25.88 +
25.89 +static void lightgun_destroy( maple_device_t mdev )
25.90 +{
25.91 + free( mdev );
25.92 +}
25.93 +
25.94 /**
25.95 * Input callback
25.96 */
25.97 @@ -127,28 +140,6 @@
25.98 }
25.99 }
25.100
25.101 -static lxdream_config_entry_t lightgun_get_config( maple_device_t mdev )
25.102 -{
25.103 - lightgun_device_t dev = (lightgun_device_t)mdev;
25.104 - return dev->config;
25.105 -}
25.106 -
25.107 -static void lightgun_set_config_value( maple_device_t mdev, unsigned int key, const gchar *value )
25.108 -{
25.109 - lightgun_device_t dev = (lightgun_device_t)mdev;
25.110 - assert( key < LIGHTGUN_CONFIG_ENTRIES );
25.111 -
25.112 - input_unregister_key( dev->config[key].value, lightgun_key_callback, dev, config_button_map[key] );
25.113 - lxdream_set_config_value( &dev->config[key], value );
25.114 - input_register_key( dev->config[key].value, lightgun_key_callback, dev, config_button_map[key] );
25.115 -}
25.116 -
25.117 -static void lightgun_destroy( maple_device_t mdev )
25.118 -{
25.119 - free( mdev );
25.120 -}
25.121 -
25.122 -
25.123 static void lightgun_mouse_callback( void *mdev, uint32_t buttons, int32_t x, int32_t y, gboolean absolute )
25.124 {
25.125 lightgun_device_t dev = (lightgun_device_t)mdev;
25.126 @@ -169,21 +160,16 @@
25.127 static void lightgun_attach( maple_device_t mdev )
25.128 {
25.129 lightgun_device_t dev = (lightgun_device_t)mdev;
25.130 - int i;
25.131 - for( i=0; i<LIGHTGUN_CONFIG_ENTRIES; i++ ) {
25.132 - input_register_key( dev->config[i].value, lightgun_key_callback, dev, config_button_map[i] );
25.133 - }
25.134 + dev->config.on_change = input_keygroup_changed;
25.135 + input_register_keygroup( &dev->config );
25.136 input_register_mouse_hook( TRUE, lightgun_mouse_callback, dev );
25.137 -
25.138 }
25.139
25.140 static void lightgun_detach( maple_device_t mdev )
25.141 {
25.142 lightgun_device_t dev = (lightgun_device_t)mdev;
25.143 - int i;
25.144 - for( i=0; i<LIGHTGUN_CONFIG_ENTRIES; i++ ) {
25.145 - input_unregister_key( dev->config[i].value, lightgun_key_callback, dev, config_button_map[i] );
25.146 - }
25.147 + input_unregister_keygroup( &dev->config );
25.148 + dev->config.on_change = NULL;
25.149 input_unregister_mouse_hook( lightgun_mouse_callback, dev );
25.150
25.151 }
26.1 --- a/src/maple/maple.c Tue Jul 21 20:21:52 2009 +1000
26.2 +++ b/src/maple/maple.c Tue Jul 21 20:33:21 2009 +1000
26.3 @@ -61,7 +61,7 @@
26.4 return (const struct maple_device_class **)maple_device_classes;
26.5 }
26.6
26.7 -lxdream_config_entry_t maple_get_device_config( maple_device_t dev )
26.8 +lxdream_config_group_t maple_get_device_config( maple_device_t dev )
26.9 {
26.10 if( dev->get_config == NULL )
26.11 return NULL;
26.12 @@ -397,13 +397,6 @@
26.13 return mode == MAPLE_GRAB_YES;
26.14 }
26.15
26.16 -void maple_set_device_config_value( maple_device_t dev, unsigned int key, const gchar *value )
26.17 -{
26.18 - if( dev != NULL && dev->set_config_value != NULL ) {
26.19 - dev->set_config_value( dev, key, value );
26.20 - }
26.21 -}
26.22 -
26.23 void maple_default_destroy( maple_device_t mdev )
26.24 {
26.25 free(mdev);
27.1 --- a/src/maple/maple.h Tue Jul 21 20:21:52 2009 +1000
27.2 +++ b/src/maple/maple.h Tue Jul 21 20:33:21 2009 +1000
27.3 @@ -86,8 +86,8 @@
27.4 /* Some convenience methods for VMU handling */
27.5 #define MAPLE_IS_VMU(dev) ((dev)->device_class == &vmu_class)
27.6 #define MAPLE_IS_VMU_CLASS(clz) ((clz) == &vmu_class)
27.7 -#define MAPLE_VMU_NAME(dev) (((dev)->get_config(dev))[0].value)
27.8 -#define MAPLE_SET_VMU_NAME(dev,name) ((dev)->set_config_value((dev),0,(name)))
27.9 +#define MAPLE_VMU_NAME(dev) (((dev)->get_config(dev))->params[0].value)
27.10 +#define MAPLE_SET_VMU_NAME(dev,name) lxdream_set_config_value( (dev)->get_config(dev), 0 ,(name) )
27.11 #define MAPLE_VMU_HAS_NAME(d1,name) (MAPLE_VMU_NAME(d1) == NULL ? name == NULL : \
27.12 name != NULL && strcmp(MAPLE_VMU_NAME(d1),name) == 0)
27.13 #define MAPLE_IS_SAME_VMU(d1,d2) (MAPLE_VMU_NAME(d1) == NULL ? MAPLE_VMU_NAME(d2) == NULL : \
27.14 @@ -99,6 +99,7 @@
27.15 struct maple_device_class {
27.16 const char *name;
27.17 int flags;
27.18 +
27.19 maple_device_t (*new_device)();
27.20 };
27.21
27.22 @@ -110,8 +111,7 @@
27.23 maple_device_class_t device_class;
27.24 unsigned char ident[112];
27.25 unsigned char version[80];
27.26 - lxdream_config_entry_t (*get_config)(struct maple_device *dev);
27.27 - void (*set_config_value)(struct maple_device *dev, unsigned int key, const gchar *value);
27.28 + lxdream_config_group_t (*get_config)(struct maple_device *dev);
27.29 void (*attach)(struct maple_device *dev);
27.30 void (*detach)(struct maple_device *dev);
27.31 void (*destroy)(struct maple_device *dev);
27.32 @@ -142,8 +142,7 @@
27.33 maple_device_t maple_get_device( unsigned int port, unsigned int periph );
27.34 const struct maple_device_class *maple_get_device_class( const gchar *name );
27.35 const struct maple_device_class **maple_get_device_classes();
27.36 -lxdream_config_entry_t maple_get_device_config( maple_device_t dev );
27.37 -void maple_set_device_config_value( maple_device_t dev, unsigned int key, const gchar *value );
27.38 +lxdream_config_group_t maple_get_device_config( maple_device_t dev );
27.39
27.40 void maple_handle_buffer( uint32_t buffer );
27.41 void maple_attach_device( maple_device_t dev, unsigned int port, unsigned int periph );
27.42 @@ -152,6 +151,7 @@
27.43 void maple_reattach_all( );
27.44 gboolean maple_should_grab();
27.45
27.46 +
27.47 /**
27.48 * Default destroy implementation that just frees the dev memory.
27.49 */
28.1 --- a/src/maple/mouse.c Tue Jul 21 20:21:52 2009 +1000
28.2 +++ b/src/maple/mouse.c Tue Jul 21 20:33:21 2009 +1000
28.3 @@ -60,7 +60,7 @@
28.4 static struct mouse_device base_mouse = {
28.5 { MAPLE_DEVICE_TAG, &mouse_class,
28.6 MOUSE_IDENT, MOUSE_VERSION,
28.7 - NULL, NULL, mouse_attach, mouse_detach, maple_default_destroy,
28.8 + NULL, mouse_attach, mouse_detach, maple_default_destroy,
28.9 mouse_clone, NULL, NULL, mouse_get_cond, NULL, NULL, NULL, NULL, NULL, NULL },
28.10 0, {0,0,0,0,0,0,0,0},
28.11 };
29.1 --- a/src/maple/vmu.c Tue Jul 21 20:21:52 2009 +1000
29.2 +++ b/src/maple/vmu.c Tue Jul 21 20:33:21 2009 +1000
29.3 @@ -57,8 +57,9 @@
29.4 static void vmu_destroy( maple_device_t dev );
29.5 static maple_device_t vmu_clone( maple_device_t dev );
29.6 static maple_device_t vmu_new();
29.7 -static lxdream_config_entry_t vmu_get_config( maple_device_t dev );
29.8 -static void vmu_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );
29.9 +static lxdream_config_group_t vmu_get_config( maple_device_t dev );
29.10 +static gboolean vmu_set_config_value( void *data, lxdream_config_group_t group, unsigned int key,
29.11 + const gchar *oldvalue, const gchar *value );
29.12 static int vmu_get_condition( maple_device_t dev, int function, unsigned char *outbuf,
29.13 unsigned int *outlen );
29.14 static int vmu_get_meminfo( maple_device_t dev, int function, unsigned int pt,
29.15 @@ -76,25 +77,31 @@
29.16 struct maple_device dev;
29.17 vmu_volume_t vol;
29.18 char lcd_bitmap[VMU_LCD_SIZE]; /* 48x32 bitmap */
29.19 - struct lxdream_config_entry config[VMU_CONFIG_ENTRIES+1];
29.20 + struct lxdream_config_group config;
29.21 } *vmu_device_t;
29.22
29.23 +#define DEV_FROM_CONFIG_GROUP(grp) ((vmu_device_t)(((char *)grp) - offsetof( struct vmu_device, config )))
29.24 +
29.25 struct maple_device_class vmu_class = { "Sega VMU", MAPLE_GRAB_DONTCARE, vmu_new };
29.26
29.27 static struct vmu_device base_vmu = {
29.28 { MAPLE_DEVICE_TAG, &vmu_class,
29.29 VMU_IDENT, VMU_VERSION,
29.30 - vmu_get_config, vmu_set_config_value,
29.31 + vmu_get_config,
29.32 vmu_attach, vmu_detach, vmu_destroy,
29.33 vmu_clone, NULL, NULL, vmu_get_condition, NULL,
29.34 vmu_get_meminfo, vmu_read_block, vmu_write_block, NULL, NULL },
29.35 - NULL, {0},
29.36 + NULL, {0},
29.37 + {"Sega VMU", vmu_set_config_value, NULL, NULL,
29.38 {{ "volume", N_("Volume"), CONFIG_TYPE_FILE },
29.39 - { NULL, CONFIG_TYPE_NONE }} };
29.40 + { NULL, CONFIG_TYPE_NONE }}} };
29.41 +
29.42 +
29.43
29.44 static maple_device_t vmu_new( )
29.45 {
29.46 vmu_device_t dev = malloc( sizeof(struct vmu_device) );
29.47 + dev->config.data = dev;
29.48 memcpy( dev, &base_vmu, sizeof(base_vmu) );
29.49 return MAPLE_DEVICE(dev);
29.50 }
29.51 @@ -103,41 +110,38 @@
29.52 {
29.53 vmu_device_t src = (vmu_device_t)srcdevice;
29.54 vmu_device_t dev = (vmu_device_t)vmu_new();
29.55 - lxdream_copy_config_list( dev->config, src->config );
29.56 + lxdream_copy_config_group( &dev->config, &src->config );
29.57 + dev->config.data = dev;
29.58 return MAPLE_DEVICE(dev);
29.59 }
29.60
29.61 -static lxdream_config_entry_t vmu_get_config( maple_device_t mdev )
29.62 +static lxdream_config_group_t vmu_get_config( maple_device_t mdev )
29.63 {
29.64 vmu_device_t dev = (vmu_device_t)mdev;
29.65 - return dev->config;
29.66 + return &dev->config;
29.67 }
29.68
29.69 -static void vmu_set_config_value( maple_device_t dev, unsigned int key, const gchar *value )
29.70 +static gboolean vmu_set_config_value( void *data, lxdream_config_group_t group, unsigned int key,
29.71 + const gchar *oldvalue, const gchar *value )
29.72 {
29.73 - vmu_device_t vmu = (vmu_device_t)dev;
29.74 + vmu_device_t vmu = (vmu_device_t)data;
29.75 assert( key < VMU_CONFIG_ENTRIES );
29.76
29.77 - if( value == vmu->config[key].value ||
29.78 - value != NULL && vmu->config[key].value != NULL && strcmp(vmu->config[key].value, value) == 0 ) {
29.79 - return; /* Unchanged */
29.80 - }
29.81 -
29.82 if( vmu->vol != NULL ) {
29.83 vmulist_detach_vmu(vmu->vol);
29.84 }
29.85 - lxdream_set_config_value( &vmu->config[key], value );
29.86 vmu->vol = vmulist_get_vmu_by_filename( value );
29.87 if( vmu->vol != NULL ) {
29.88 vmulist_attach_vmu(vmu->vol, "MAPLE");
29.89 }
29.90 + return TRUE;
29.91 }
29.92
29.93 void vmu_attach(struct maple_device *dev)
29.94 {
29.95 vmu_device_t vmu = (vmu_device_t)dev;
29.96 - if( vmu->config[0].value != NULL ) {
29.97 - vmu->vol = vmulist_get_vmu_by_filename(vmu->config[0].value);
29.98 + if( vmu->config.params[0].value != NULL ) {
29.99 + vmu->vol = vmulist_get_vmu_by_filename(vmu->config.params[0].value);
29.100 if( vmu->vol != NULL ) {
29.101 vmulist_attach_vmu(vmu->vol, "MAPLE");
29.102 }
29.103 @@ -162,6 +166,7 @@
29.104 static int vmu_get_condition(struct maple_device *dev, int function,
29.105 unsigned char *outbuf, unsigned int *buflen)
29.106 {
29.107 + return 0;
29.108 }
29.109 static int vmu_set_condition(struct maple_device *dev, int function,
29.110 unsigned char *inbuf, unsigned int buflen)
.