Search
lxdream.org :: lxdream :: r608:4f588e52bce0
lxdream 0.9.1
released Jun 29
Download Now
changeset608:4f588e52bce0
parent607:268c85ddc01f
child609:41b61a0d5f1a
authornkeynes
dateSat Jan 26 02:45:27 2008 +0000 (11 years ago)
Bug #50: Implement mouse and keyboard
src/Makefile.am
src/Makefile.in
src/config.c
src/dckeysyms.h
src/display.c
src/display.h
src/drivers/video_gtk.c
src/drivers/video_null.c
src/gtkui/ctrl_dlg.c
src/gtkui/gtkui.c
src/gtkui/gtkui.h
src/gtkui/main_win.c
src/maple/kbd.c
src/maple/maple.c
src/maple/maple.h
src/maple/mouse.c
1.1 --- a/src/Makefile.am Sat Jan 26 02:43:30 2008 +0000
1.2 +++ b/src/Makefile.am Sat Jan 26 02:45:27 2008 +0000
1.3 @@ -36,9 +36,9 @@
1.4 pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \
1.5 pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c \
1.6 maple/maple.c maple/maple.h \
1.7 - maple/controller.c maple/controller.h \
1.8 + maple/controller.c maple/controller.h maple/kbd.c maple/mouse.c \
1.9 loader.c bootstrap.c util.c \
1.10 - display.c display.h \
1.11 + display.c display.h dckeysyms.h \
1.12 drivers/audio_null.c drivers/video_null.c \
1.13 drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c \
1.14 drivers/gl_sl.c drivers/gl_slsrc.c
2.1 --- a/src/Makefile.in Sat Jan 26 02:43:30 2008 +0000
2.2 +++ b/src/Makefile.in Sat Jan 26 02:45:27 2008 +0000
2.3 @@ -225,9 +225,9 @@
2.4 pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \
2.5 pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c \
2.6 maple/maple.c maple/maple.h \
2.7 - maple/controller.c maple/controller.h \
2.8 + maple/controller.c maple/controller.h maple/kbd.c maple/mouse.c \
2.9 loader.c bootstrap.c util.c \
2.10 - display.c display.h \
2.11 + display.c display.h dckeysyms.h \
2.12 drivers/audio_null.c drivers/video_null.c \
2.13 drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c \
2.14 drivers/gl_sl.c drivers/gl_slsrc.c\
2.15 @@ -282,19 +282,19 @@
2.16 pvr2/pvr2.h pvr2/pvr2mem.c pvr2/tacore.c pvr2/render.c \
2.17 pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c pvr2/texcache.c \
2.18 pvr2/yuv.c pvr2/rendsave.c maple/maple.c maple/maple.h \
2.19 - maple/controller.c maple/controller.h loader.c bootstrap.c \
2.20 - util.c display.c display.h drivers/audio_null.c \
2.21 - drivers/video_null.c drivers/gl_common.c drivers/gl_common.h \
2.22 - drivers/gl_fbo.c drivers/gl_sl.c drivers/gl_slsrc.c \
2.23 - sh4/sh4x86.c sh4/x86op.h sh4/ia32abi.h sh4/ia32mac.h \
2.24 - sh4/ia64abi.h sh4/sh4trans.c sh4/sh4trans.h x86dasm/x86dasm.c \
2.25 - x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \
2.26 - x86dasm/dis-buf.c gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c \
2.27 - gtkui/gtkcb.c gtkui/mmio_win.c gtkui/debug_win.c \
2.28 - gtkui/dump_win.c gtkui/ctrl_dlg.c gtkui/path_dlg.c \
2.29 - gtkui/gdrom_menu.c drivers/video_gtk.c drivers/video_gtk.h \
2.30 - drivers/video_glx.c drivers/video_glx.h drivers/cd_linux.c \
2.31 - drivers/cd_none.c drivers/audio_esd.c
2.32 + maple/controller.c maple/controller.h maple/kbd.c maple/mouse.c \
2.33 + loader.c bootstrap.c util.c display.c display.h dckeysyms.h \
2.34 + drivers/audio_null.c drivers/video_null.c drivers/gl_common.c \
2.35 + drivers/gl_common.h drivers/gl_fbo.c drivers/gl_sl.c \
2.36 + drivers/gl_slsrc.c sh4/sh4x86.c sh4/x86op.h sh4/ia32abi.h \
2.37 + sh4/ia32mac.h sh4/ia64abi.h sh4/sh4trans.c sh4/sh4trans.h \
2.38 + x86dasm/x86dasm.c x86dasm/x86dasm.h x86dasm/i386-dis.c \
2.39 + x86dasm/dis-init.c x86dasm/dis-buf.c gtkui/gtkui.c \
2.40 + gtkui/gtkui.h gtkui/main_win.c gtkui/gtkcb.c gtkui/mmio_win.c \
2.41 + gtkui/debug_win.c gtkui/dump_win.c gtkui/ctrl_dlg.c \
2.42 + gtkui/path_dlg.c gtkui/gdrom_menu.c drivers/video_gtk.c \
2.43 + drivers/video_gtk.h drivers/video_glx.c drivers/video_glx.h \
2.44 + drivers/cd_linux.c drivers/cd_none.c drivers/audio_esd.c
2.45 @BUILD_SH4X86_TRUE@am__objects_1 = sh4x86.$(OBJEXT) sh4trans.$(OBJEXT) \
2.46 @BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \
2.47 @BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT)
2.48 @@ -320,12 +320,13 @@
2.49 pvr2mem.$(OBJEXT) tacore.$(OBJEXT) render.$(OBJEXT) \
2.50 rendcore.$(OBJEXT) rendbkg.$(OBJEXT) rendsort.$(OBJEXT) \
2.51 texcache.$(OBJEXT) yuv.$(OBJEXT) rendsave.$(OBJEXT) \
2.52 - maple.$(OBJEXT) controller.$(OBJEXT) loader.$(OBJEXT) \
2.53 - bootstrap.$(OBJEXT) util.$(OBJEXT) display.$(OBJEXT) \
2.54 - audio_null.$(OBJEXT) video_null.$(OBJEXT) gl_common.$(OBJEXT) \
2.55 - gl_fbo.$(OBJEXT) gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) \
2.56 - $(am__objects_1) $(am__objects_2) $(am__objects_3) \
2.57 - $(am__objects_4) $(am__objects_5)
2.58 + maple.$(OBJEXT) controller.$(OBJEXT) kbd.$(OBJEXT) \
2.59 + mouse.$(OBJEXT) loader.$(OBJEXT) bootstrap.$(OBJEXT) \
2.60 + util.$(OBJEXT) display.$(OBJEXT) audio_null.$(OBJEXT) \
2.61 + video_null.$(OBJEXT) gl_common.$(OBJEXT) gl_fbo.$(OBJEXT) \
2.62 + gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) $(am__objects_1) \
2.63 + $(am__objects_2) $(am__objects_3) $(am__objects_4) \
2.64 + $(am__objects_5)
2.65 lxdream_OBJECTS = $(am_lxdream_OBJECTS)
2.66 lxdream_DEPENDENCIES =
2.67 lxdream_LDFLAGS =
2.68 @@ -374,10 +375,11 @@
2.69 @AMDEP_TRUE@ ./$(DEPDIR)/gtkcb.Po ./$(DEPDIR)/gtkui.Po \
2.70 @AMDEP_TRUE@ ./$(DEPDIR)/i386-dis.Po ./$(DEPDIR)/ide.Po \
2.71 @AMDEP_TRUE@ ./$(DEPDIR)/insparse.Po ./$(DEPDIR)/intc.Po \
2.72 -@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \
2.73 -@AMDEP_TRUE@ ./$(DEPDIR)/main_win.Po ./$(DEPDIR)/maple.Po \
2.74 -@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmio_win.Po \
2.75 -@AMDEP_TRUE@ ./$(DEPDIR)/mmu.Po ./$(DEPDIR)/nrg.Po \
2.76 +@AMDEP_TRUE@ ./$(DEPDIR)/kbd.Po ./$(DEPDIR)/loader.Po \
2.77 +@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/main_win.Po \
2.78 +@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \
2.79 +@AMDEP_TRUE@ ./$(DEPDIR)/mmio_win.Po ./$(DEPDIR)/mmu.Po \
2.80 +@AMDEP_TRUE@ ./$(DEPDIR)/mouse.Po ./$(DEPDIR)/nrg.Po \
2.81 @AMDEP_TRUE@ ./$(DEPDIR)/path_dlg.Po ./$(DEPDIR)/pvr2.Po \
2.82 @AMDEP_TRUE@ ./$(DEPDIR)/pvr2mem.Po ./$(DEPDIR)/rendbkg.Po \
2.83 @AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \
2.84 @@ -511,6 +513,7 @@
2.85 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@
2.86 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insparse.Po@am__quote@
2.87 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intc.Po@am__quote@
2.88 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kbd.Po@am__quote@
2.89 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loader.Po@am__quote@
2.90 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
2.91 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main_win.Po@am__quote@
2.92 @@ -518,6 +521,7 @@
2.93 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@
2.94 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmio_win.Po@am__quote@
2.95 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmu.Po@am__quote@
2.96 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouse.Po@am__quote@
2.97 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrg.Po@am__quote@
2.98 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path_dlg.Po@am__quote@
2.99 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2.Po@am__quote@
2.100 @@ -1431,6 +1435,50 @@
2.101 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.102 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o controller.obj `if test -f 'maple/controller.c'; then $(CYGPATH_W) 'maple/controller.c'; else $(CYGPATH_W) '$(srcdir)/maple/controller.c'; fi`
2.103
2.104 +kbd.o: maple/kbd.c
2.105 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kbd.o -MD -MP -MF "$(DEPDIR)/kbd.Tpo" \
2.106 +@am__fastdepCC_TRUE@ -c -o kbd.o `test -f 'maple/kbd.c' || echo '$(srcdir)/'`maple/kbd.c; \
2.107 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/kbd.Tpo" "$(DEPDIR)/kbd.Po"; \
2.108 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/kbd.Tpo"; exit 1; \
2.109 +@am__fastdepCC_TRUE@ fi
2.110 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/kbd.c' object='kbd.o' libtool=no @AMDEPBACKSLASH@
2.111 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/kbd.Po' tmpdepfile='$(DEPDIR)/kbd.TPo' @AMDEPBACKSLASH@
2.112 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.113 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kbd.o `test -f 'maple/kbd.c' || echo '$(srcdir)/'`maple/kbd.c
2.114 +
2.115 +kbd.obj: maple/kbd.c
2.116 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kbd.obj -MD -MP -MF "$(DEPDIR)/kbd.Tpo" \
2.117 +@am__fastdepCC_TRUE@ -c -o kbd.obj `if test -f 'maple/kbd.c'; then $(CYGPATH_W) 'maple/kbd.c'; else $(CYGPATH_W) '$(srcdir)/maple/kbd.c'; fi`; \
2.118 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/kbd.Tpo" "$(DEPDIR)/kbd.Po"; \
2.119 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/kbd.Tpo"; exit 1; \
2.120 +@am__fastdepCC_TRUE@ fi
2.121 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/kbd.c' object='kbd.obj' libtool=no @AMDEPBACKSLASH@
2.122 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/kbd.Po' tmpdepfile='$(DEPDIR)/kbd.TPo' @AMDEPBACKSLASH@
2.123 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.124 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kbd.obj `if test -f 'maple/kbd.c'; then $(CYGPATH_W) 'maple/kbd.c'; else $(CYGPATH_W) '$(srcdir)/maple/kbd.c'; fi`
2.125 +
2.126 +mouse.o: maple/mouse.c
2.127 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mouse.o -MD -MP -MF "$(DEPDIR)/mouse.Tpo" \
2.128 +@am__fastdepCC_TRUE@ -c -o mouse.o `test -f 'maple/mouse.c' || echo '$(srcdir)/'`maple/mouse.c; \
2.129 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/mouse.Tpo" "$(DEPDIR)/mouse.Po"; \
2.130 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/mouse.Tpo"; exit 1; \
2.131 +@am__fastdepCC_TRUE@ fi
2.132 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/mouse.c' object='mouse.o' libtool=no @AMDEPBACKSLASH@
2.133 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/mouse.Po' tmpdepfile='$(DEPDIR)/mouse.TPo' @AMDEPBACKSLASH@
2.134 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.135 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mouse.o `test -f 'maple/mouse.c' || echo '$(srcdir)/'`maple/mouse.c
2.136 +
2.137 +mouse.obj: maple/mouse.c
2.138 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mouse.obj -MD -MP -MF "$(DEPDIR)/mouse.Tpo" \
2.139 +@am__fastdepCC_TRUE@ -c -o mouse.obj `if test -f 'maple/mouse.c'; then $(CYGPATH_W) 'maple/mouse.c'; else $(CYGPATH_W) '$(srcdir)/maple/mouse.c'; fi`; \
2.140 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/mouse.Tpo" "$(DEPDIR)/mouse.Po"; \
2.141 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/mouse.Tpo"; exit 1; \
2.142 +@am__fastdepCC_TRUE@ fi
2.143 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/mouse.c' object='mouse.obj' libtool=no @AMDEPBACKSLASH@
2.144 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/mouse.Po' tmpdepfile='$(DEPDIR)/mouse.TPo' @AMDEPBACKSLASH@
2.145 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.146 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mouse.obj `if test -f 'maple/mouse.c'; then $(CYGPATH_W) 'maple/mouse.c'; else $(CYGPATH_W) '$(srcdir)/maple/mouse.c'; fi`
2.147 +
2.148 audio_null.o: drivers/audio_null.c
2.149 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT audio_null.o -MD -MP -MF "$(DEPDIR)/audio_null.Tpo" \
2.150 @am__fastdepCC_TRUE@ -c -o audio_null.o `test -f 'drivers/audio_null.c' || echo '$(srcdir)/'`drivers/audio_null.c; \
3.1 --- a/src/config.c Sat Jan 26 02:43:30 2008 +0000
3.2 +++ b/src/config.c Sat Jan 26 02:45:27 2008 +0000
3.3 @@ -312,12 +312,13 @@
3.4 fprintf( f, "Device %d = %s\n", i, dev->device_class->name );
3.5 else
3.6 fprintf( f, "Subdevice %d = %s\n", j, dev->device_class->name );
3.7 - entry = dev->get_config(dev);
3.8 - while( entry->key != NULL ) {
3.9 - if( entry->value != NULL ) {
3.10 - fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value );
3.11 + if( dev->get_config != NULL && ((entry = dev->get_config(dev)) != NULL) ) {
3.12 + while( entry->key != NULL ) {
3.13 + if( entry->value != NULL ) {
3.14 + fprintf( f, "%*c%s = %s\n", j==0?4:8, ' ',entry->key, entry->value );
3.15 + }
3.16 + entry++;
3.17 }
3.18 - entry++;
3.19 }
3.20 }
3.21 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/dckeysyms.h Sat Jan 26 02:45:27 2008 +0000
4.3 @@ -0,0 +1,133 @@
4.4 +/**
4.5 + * $Id: dckeysyms.h 602 2008-01-15 20:50:23Z nkeynes $
4.6 + *
4.7 + * Keysym definitions for the dreamcast keyboard.
4.8 + *
4.9 + * Copyright (c) 2005 Nathan Keynes.
4.10 + *
4.11 + * This program is free software; you can redistribute it and/or modify
4.12 + * it under the terms of the GNU General Public License as published by
4.13 + * the Free Software Foundation; either version 2 of the License, or
4.14 + * (at your option) any later version.
4.15 + *
4.16 + * This program is distributed in the hope that it will be useful,
4.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.19 + * GNU General Public License for more details.
4.20 + */
4.21 +
4.22 +#ifndef lxdream_dckeysyms_H
4.23 +#define lxdream_dckeysyms_H 1
4.24 +
4.25 +
4.26 +#define DCKB_NONE 0x00
4.27 +#define DCKB_ERROR 0x01
4.28 +#define DCKB_A 0x04
4.29 +#define DCKB_B 0x05
4.30 +#define DCKB_C 0x06
4.31 +#define DCKB_D 0x07
4.32 +#define DCKB_E 0x08
4.33 +#define DCKB_F 0x09
4.34 +#define DCKB_G 0x0A
4.35 +#define DCKB_H 0x0B
4.36 +#define DCKB_I 0x0C
4.37 +#define DCKB_J 0x0D
4.38 +#define DCKB_K 0x0E
4.39 +#define DCKB_L 0x0F
4.40 +#define DCKB_M 0x10
4.41 +#define DCKB_N 0x11
4.42 +#define DCKB_O 0x12
4.43 +#define DCKB_P 0x13
4.44 +#define DCKB_Q 0x14
4.45 +#define DCKB_R 0x15
4.46 +#define DCKB_S 0x16
4.47 +#define DCKB_T 0x17
4.48 +#define DCKB_U 0x18
4.49 +#define DCKB_V 0x19
4.50 +#define DCKB_W 0x1A
4.51 +#define DCKB_X 0x1B
4.52 +#define DCKB_Y 0x1C
4.53 +#define DCKB_Z 0x1D
4.54 +#define DCKB_1 0x1E
4.55 +#define DCKB_2 0x1F
4.56 +#define DCKB_3 0x20
4.57 +#define DCKB_4 0x21
4.58 +#define DCKB_5 0x22
4.59 +#define DCKB_6 0x23
4.60 +#define DCKB_7 0x24
4.61 +#define DCKB_8 0x25
4.62 +#define DCKB_9 0x26
4.63 +#define DCKB_0 0x27
4.64 +#define DCKB_ENTER 0x28
4.65 +#define DCKB_ESCAPE 0x29
4.66 +#define DCKB_BACKSPACE 0x2A
4.67 +#define DCKB_TAB 0x2B
4.68 +#define DCKB_SPACE 0x2C
4.69 +#define DCKB_MINUS 0x2D
4.70 +#define DCKB_EQUAL 0x2E
4.71 +#define DCKB_LBRACKET 0x2F
4.72 +#define DCKB_RBRACKET 0x30
4.73 +#define DCKB_BACKSLASH 0x31
4.74 +#define DCKB_SEMICOLON 0x33
4.75 +#define DCKB_QUOTE 0x34
4.76 +#define DCKB_BACKQUOTE 0x35
4.77 +#define DCKB_COMMA 0x36
4.78 +#define DCKB_PERIOD 0x37
4.79 +#define DCKB_SLASH 0x38
4.80 +#define DCKB_CAPSLOCK 0x39
4.81 +#define DCKB_F1 0x3A
4.82 +#define DCKB_F2 0x3B
4.83 +#define DCKB_F3 0x3C
4.84 +#define DCKB_F4 0x3D
4.85 +#define DCKB_F5 0x3E
4.86 +#define DCKB_F6 0x3F
4.87 +#define DCKB_F7 0x40
4.88 +#define DCKB_F8 0x41
4.89 +#define DCKB_F9 0x42
4.90 +#define DCKB_F10 0x43
4.91 +#define DCKB_F11 0x44
4.92 +#define DCKB_F12 0x45
4.93 +#define DCKB_PRINTSCR 0x46
4.94 +#define DCKB_SCROLLLOCK 0x47
4.95 +#define DCKB_PAUSE 0x48
4.96 +#define DCKB_INSERT 0x49
4.97 +#define DCKB_HOME 0x4A
4.98 +#define DCKB_PAGEUP 0x4B
4.99 +#define DCKB_DELETE 0x4C
4.100 +#define DCKB_END 0x4D
4.101 +#define DCKB_PAGEDOWN 0x4E
4.102 +#define DCKB_RIGHT 0x4F
4.103 +#define DCKB_LEFT 0x50
4.104 +#define DCKB_DOWN 0x51
4.105 +#define DCKB_UP 0x52
4.106 +#define DCKB_NUMLOCK 0x53
4.107 +#define DCKB_KP_SLASH 0x54
4.108 +#define DCKB_KP_STAR 0x55
4.109 +#define DCKB_KP_MINUS 0x56
4.110 +#define DCKB_KP_PLUS 0x57
4.111 +#define DCKB_KP_ENTER 0x58
4.112 +#define DCKB_KP_1 0x59
4.113 +#define DCKB_KP_2 0x5A
4.114 +#define DCKB_KP_3 0x5B
4.115 +#define DCKB_KP_4 0x5C
4.116 +#define DCKB_KP_5 0x5D
4.117 +#define DCKB_KP_6 0x5E
4.118 +#define DCKB_KP_7 0x5F
4.119 +#define DCKB_KP_8 0x60
4.120 +#define DCKB_KP_9 0x61
4.121 +#define DCKB_KP_0 0x62
4.122 +#define DCKB_KP_PERIOD 0x63
4.123 +#define DCKB_S3 0x65
4.124 +
4.125 +/* Modifier keys */
4.126 +
4.127 +#define DCKB_CONTROL_L 0xFF01
4.128 +#define DCKB_SHIFT_L 0xFF02
4.129 +#define DCKB_ALT_L 0xFF04
4.130 +#define DCKB_S1 0xFF08
4.131 +#define DCKB_CONTROL_R 0xFF10
4.132 +#define DCKB_SHIFT_R 0xFF20
4.133 +#define DCKB_ALT_R 0xFF40
4.134 +#define DCKB_S2 0xFF80
4.135 +
4.136 +#endif /* !lxdream_dckeysyms_H */
5.1 --- a/src/display.c Sat Jan 26 02:43:30 2008 +0000
5.2 +++ b/src/display.c Sat Jan 26 02:45:27 2008 +0000
5.3 @@ -36,8 +36,16 @@
5.4 input_key_callback_t callback;
5.5 void *data;
5.6 uint32_t value;
5.7 + struct keymap_entry *next; // allow chaining
5.8 } *keymap_entry_t;
5.9
5.10 +typedef struct mouse_entry {
5.11 + gboolean relative;
5.12 + input_mouse_callback_t callback;
5.13 + void *data;
5.14 + struct mouse_entry *next;
5.15 +} *mouse_entry_t;
5.16 +
5.17 /**
5.18 * Colour format information
5.19 */
5.20 @@ -59,7 +67,8 @@
5.21 * FIXME: make this more memory efficient
5.22 */
5.23 struct keymap_entry *keymap[65536];
5.24 -
5.25 +struct keymap_entry *keyhooks = NULL;
5.26 +struct mouse_entry *mousehooks = NULL;
5.27
5.28 static struct keymap_entry *input_create_key( uint16_t keycode )
5.29 {
5.30 @@ -113,14 +122,85 @@
5.31 void input_unregister_key( const gchar *keysym, input_key_callback_t callback,
5.32 void *data, uint32_t value )
5.33 {
5.34 - if( display_driver == NULL || keysym == NULL )
5.35 + if( display_driver == NULL || keysym == NULL || display_driver->resolve_keysym == NULL )
5.36 return;
5.37 uint16_t keycode = display_driver->resolve_keysym(keysym);
5.38 if( keycode == 0 )
5.39 return;
5.40 input_delete_key( keycode, callback, data, value );
5.41 }
5.42 -
5.43 +
5.44 +gboolean input_register_hook( input_key_callback_t callback,
5.45 + void *data )
5.46 +{
5.47 + keymap_entry_t key = malloc( sizeof( struct keymap_entry ) );
5.48 + assert( key != NULL );
5.49 + key->callback = callback;
5.50 + key->data = data;
5.51 + key->next = keyhooks;
5.52 + keyhooks = key;
5.53 + return TRUE;
5.54 +}
5.55 +
5.56 +void input_unregister_hook( input_key_callback_t callback,
5.57 + void *data )
5.58 +{
5.59 + keymap_entry_t key = keyhooks;
5.60 + if( key != NULL ) {
5.61 + keymap_entry_t next = key->next;
5.62 + if( key->callback == callback && key->data == data ) {
5.63 + free(key);
5.64 + keyhooks = next;
5.65 + return;
5.66 + }
5.67 + while( next != NULL ) {
5.68 + if( next->callback == callback && next->data == data ) {
5.69 + key->next = next->next;
5.70 + free(next);
5.71 + }
5.72 + }
5.73 + }
5.74 +}
5.75 +
5.76 +gboolean input_register_mouse_hook( gboolean relative, input_mouse_callback_t callback,
5.77 + void *data )
5.78 +{
5.79 + mouse_entry_t ent = malloc( sizeof( struct mouse_entry ) );
5.80 + assert( ent != NULL );
5.81 + ent->callback = callback;
5.82 + ent->data = data;
5.83 + ent->next = mousehooks;
5.84 + mousehooks = ent;
5.85 + return TRUE;
5.86 +}
5.87 +
5.88 +void input_unregister_mouse_hook( input_mouse_callback_t callback, void *data )
5.89 +{
5.90 + mouse_entry_t ent = mousehooks;
5.91 + if( ent != NULL ) {
5.92 + mouse_entry_t next = ent->next;
5.93 + if( ent->callback == callback && ent->data == data ) {
5.94 + free(ent);
5.95 + mousehooks = next;
5.96 + return;
5.97 + }
5.98 + while( next != NULL ) {
5.99 + if( next->callback == callback && next->data == data ) {
5.100 + ent->next = next->next;
5.101 + free(next);
5.102 + }
5.103 + }
5.104 + }
5.105 +}
5.106 +
5.107 +void input_event_mouse( uint32_t buttons, int32_t x, int32_t y )
5.108 +{
5.109 + mouse_entry_t ent = mousehooks;
5.110 + while( ent != NULL ) {
5.111 + ent->callback(ent->data, buttons, x, y);
5.112 + ent = ent->next;
5.113 + }
5.114 +}
5.115
5.116 gboolean input_is_key_valid( const gchar *keysym )
5.117 {
5.118 @@ -144,7 +224,12 @@
5.119 struct keymap_entry *key = input_get_key(keycode);
5.120 if( key != NULL ) {
5.121 key->callback( key->data, key->value, TRUE );
5.122 - }
5.123 + }
5.124 + key = keyhooks;
5.125 + while( key != NULL ) {
5.126 + key->callback( key->data, keycode, TRUE );
5.127 + key = key->next;
5.128 + }
5.129 }
5.130
5.131 void input_event_keyup( uint16_t keycode )
5.132 @@ -153,6 +238,16 @@
5.133 if( key != NULL ) {
5.134 key->callback( key->data, key->value, FALSE );
5.135 }
5.136 + key = keyhooks;
5.137 + while( key != NULL ) {
5.138 + key->callback( key->data, keycode, FALSE );
5.139 + key = key->next;
5.140 + }
5.141 +}
5.142 +
5.143 +uint16_t input_keycode_to_dckeysym( uint16_t keycode )
5.144 +{
5.145 + return display_driver->convert_to_dckeysym(keycode);
5.146 }
5.147
5.148 display_driver_t get_display_driver_by_name( const char *name )
6.1 --- a/src/display.h Sat Jan 26 02:43:30 2008 +0000
6.2 +++ b/src/display.h Sat Jan 26 02:45:27 2008 +0000
6.3 @@ -118,6 +118,11 @@
6.4 uint16_t (*resolve_keysym)( const gchar *keysym );
6.5
6.6 /**
6.7 + * Given a native system keycode, convert it to a dreamcast keyboard code.
6.8 + */
6.9 + uint16_t (*convert_to_dckeysym)( uint16_t keycode );
6.10 +
6.11 + /**
6.12 * Create a render target with the given width and height.
6.13 */
6.14 render_buffer_t (*create_render_buffer)( uint32_t width, uint32_t height );
6.15 @@ -180,12 +185,38 @@
6.16
6.17 typedef void (*input_key_callback_t)( void *data, uint32_t value, gboolean isKeyDown );
6.18
6.19 +/**
6.20 + * Callback to receive mouse input events
6.21 + * @param data pointer passed in at the time the hook was registered
6.22 + * @param buttons bitmask of button states, where bit 0 is button 0 (left), bit 1 is button
6.23 + * 1 (middle), bit 2 is button 2 (right) and so forth.
6.24 + * @param x Horizontal movement since the last invocation (in relative mode) or window position
6.25 + * (in absolute mode).
6.26 + * @param y Vertical movement since the last invocation (in relative mode) or window position
6.27 + * (in absolute mode).
6.28 + */
6.29 +typedef void (*input_mouse_callback_t)( void *data, uint32_t buttons, int32_t x, int32_t y );
6.30 +
6.31 gboolean input_register_key( const gchar *keysym, input_key_callback_t callback,
6.32 void *data, uint32_t value );
6.33
6.34 void input_unregister_key( const gchar *keysym, input_key_callback_t callback,
6.35 void *data, uint32_t value );
6.36
6.37 +/**
6.38 + * Register a hook to receive all input events
6.39 + */
6.40 +gboolean input_register_hook( input_key_callback_t callback, void *data );
6.41 +void input_unregister_hook( input_key_callback_t callback, void *data );
6.42 +
6.43 +/**
6.44 + * Register a mouse event hook.
6.45 + * @param relative TRUE if the caller wants relative mouse movement, FALSE for
6.46 + * absolute mouse positioning. It's not generally possible to receive both at the same time.
6.47 + */
6.48 +gboolean input_register_mouse_hook( gboolean relative, input_mouse_callback_t callback, void *data );
6.49 +void input_unregister_mouse_hook( input_mouse_callback_t callback, void *data );
6.50 +
6.51 gboolean input_is_key_valid( const gchar *keysym );
6.52
6.53 gboolean input_is_key_registered( const gchar *keysym );
6.54 @@ -194,7 +225,9 @@
6.55
6.56 void input_event_keyup( uint16_t keycode );
6.57
6.58 +void input_event_mouse( uint32_t buttons, int32_t x_axis, int32_t y_axis );
6.59
6.60 +uint16_t input_keycode_to_dckeysym( uint16_t keycode );
6.61
6.62 #ifdef __cplusplus
6.63 }
7.1 --- a/src/drivers/video_gtk.c Sat Jan 26 02:43:30 2008 +0000
7.2 +++ b/src/drivers/video_gtk.c Sat Jan 26 02:45:27 2008 +0000
7.3 @@ -22,6 +22,7 @@
7.4 #include <stdint.h>
7.5 #include "dream.h"
7.6 #include "display.h"
7.7 +#include "dckeysyms.h"
7.8 #include "drivers/video_glx.h"
7.9 #include "drivers/gl_common.h"
7.10 #include "pvr2/pvr2.h"
7.11 @@ -35,44 +36,14 @@
7.12 void video_gtk_shutdown();
7.13 gboolean video_gtk_display_blank( uint32_t colour );
7.14 uint16_t video_gtk_resolve_keysym( const gchar *keysym );
7.15 +uint16_t video_gtk_keycode_to_dckeysym(uint32_t keycode);
7.16
7.17 struct display_driver display_gtk_driver = { "gtk", video_gtk_init, video_gtk_shutdown,
7.18 video_gtk_resolve_keysym,
7.19 + video_gtk_keycode_to_dckeysym,
7.20 NULL, NULL, NULL, NULL, NULL,
7.21 video_gtk_display_blank, NULL };
7.22
7.23 -/**
7.24 - * Extract the keyval of the key event if no modifier keys were pressed -
7.25 - * in other words get the keyval of the key by itself. The other way around
7.26 - * would be to use the hardware keysyms directly rather than the keyvals,
7.27 - * but the mapping looks to be messier.
7.28 - */
7.29 -uint16_t video_gtk_unmodified_keyval( GdkEventKey *event )
7.30 -{
7.31 - GdkKeymap *keymap = gdk_keymap_get_default();
7.32 - guint keyval;
7.33 -
7.34 - gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
7.35 - NULL, NULL, NULL );
7.36 - return keyval;
7.37 -}
7.38 -
7.39 -gboolean video_gtk_keydown_callback(GtkWidget *widget,
7.40 - GdkEventKey *event,
7.41 - gpointer user_data)
7.42 -{
7.43 - input_event_keydown( video_gtk_unmodified_keyval(event) );
7.44 - return TRUE;
7.45 -}
7.46 -
7.47 -gboolean video_gtk_keyup_callback(GtkWidget *widget,
7.48 - GdkEventKey *event,
7.49 - gpointer user_data)
7.50 -{
7.51 - input_event_keyup( video_gtk_unmodified_keyval(event) );
7.52 - return TRUE;
7.53 -}
7.54 -
7.55 uint16_t video_gtk_resolve_keysym( const gchar *keysym )
7.56 {
7.57 int val = gdk_keyval_from_name( keysym );
7.58 @@ -100,6 +71,85 @@
7.59 return TRUE;
7.60 }
7.61
7.62 +uint16_t video_gtk_keycode_to_dckeysym(uint32_t keycode)
7.63 +{
7.64 + if( keycode >= 'a' && keycode <= 'z' ) {
7.65 + return (keycode - 'a') + DCKB_A;
7.66 + } else if( keycode >= '1' && keycode <= '9' ) {
7.67 + return (keycode - '1') + DCKB_1;
7.68 + }
7.69 + switch(keycode) {
7.70 + case XK_0: return DCKB_0;
7.71 + case XK_Return: return DCKB_ENTER;
7.72 + case XK_Escape: return DCKB_ESCAPE;
7.73 + case XK_BackSpace: return DCKB_BACKSPACE;
7.74 + case XK_Tab: return DCKB_TAB;
7.75 + case XK_space: return DCKB_SPACE;
7.76 + case XK_minus: return DCKB_MINUS;
7.77 + case XK_equal: return DCKB_EQUAL;
7.78 + case XK_bracketleft: return DCKB_LBRACKET;
7.79 + case XK_bracketright: return DCKB_RBRACKET;
7.80 + case XK_semicolon: return DCKB_SEMICOLON;
7.81 + case XK_apostrophe:return DCKB_QUOTE;
7.82 + case XK_grave : return DCKB_BACKQUOTE;
7.83 + case XK_comma: return DCKB_COMMA;
7.84 + case XK_period: return DCKB_PERIOD;
7.85 + case XK_slash: return DCKB_SLASH;
7.86 + case XK_Caps_Lock: return DCKB_CAPSLOCK;
7.87 + case XK_F1: return DCKB_F1;
7.88 + case XK_F2: return DCKB_F2;
7.89 + case XK_F3: return DCKB_F3;
7.90 + case XK_F4: return DCKB_F4;
7.91 + case XK_F5: return DCKB_F5;
7.92 + case XK_F6: return DCKB_F6;
7.93 + case XK_F7: return DCKB_F7;
7.94 + case XK_F8: return DCKB_F8;
7.95 + case XK_F9: return DCKB_F9;
7.96 + case XK_F10: return DCKB_F10;
7.97 + case XK_F11: return DCKB_F11;
7.98 + case XK_F12: return DCKB_F12;
7.99 + case XK_Scroll_Lock: return DCKB_SCROLLLOCK;
7.100 + case XK_Pause: return DCKB_PAUSE;
7.101 + case XK_Insert: return DCKB_INSERT;
7.102 + case XK_Home: return DCKB_HOME;
7.103 + case XK_Page_Up: return DCKB_PAGEUP;
7.104 + case XK_Delete: return DCKB_DELETE;
7.105 + case XK_End: return DCKB_END;
7.106 + case XK_Page_Down: return DCKB_PAGEDOWN;
7.107 + case XK_Right: return DCKB_RIGHT;
7.108 + case XK_Left: return DCKB_LEFT;
7.109 + case XK_Down: return DCKB_DOWN;
7.110 + case XK_Up: return DCKB_UP;
7.111 + case XK_Num_Lock: return DCKB_NUMLOCK;
7.112 + case XK_KP_Divide: return DCKB_KP_SLASH;
7.113 + case XK_KP_Multiply: return DCKB_KP_STAR;
7.114 + case XK_KP_Subtract: return DCKB_KP_MINUS;
7.115 + case XK_KP_Add: return DCKB_KP_PLUS;
7.116 + case XK_KP_Enter: return DCKB_KP_ENTER;
7.117 + case XK_KP_1: return DCKB_KP_1;
7.118 + case XK_KP_2: return DCKB_KP_2;
7.119 + case XK_KP_3: return DCKB_KP_3;
7.120 + case XK_KP_4: return DCKB_KP_4;
7.121 + case XK_KP_5: return DCKB_KP_5;
7.122 + case XK_KP_6: return DCKB_KP_6;
7.123 + case XK_KP_7: return DCKB_KP_7;
7.124 + case XK_KP_8: return DCKB_KP_8;
7.125 + case XK_KP_9: return DCKB_KP_9;
7.126 + case XK_KP_0: return DCKB_KP_0;
7.127 + case XK_KP_Decimal:return DCKB_KP_PERIOD;
7.128 + case XK_backslash: return DCKB_BACKSLASH;
7.129 + case XK_Control_L: return DCKB_CONTROL_L;
7.130 + case XK_Shift_L: return DCKB_SHIFT_L;
7.131 + case XK_Alt_L: return DCKB_ALT_L;
7.132 + case XK_Meta_L: return DCKB_S1;
7.133 + case XK_Control_R: return DCKB_CONTROL_R;
7.134 + case XK_Shift_R: return DCKB_SHIFT_R;
7.135 + case XK_Alt_R: return DCKB_ALT_R;
7.136 + case XK_Meta_R: return DCKB_S2;
7.137 + }
7.138 + return DCKB_NONE;
7.139 +}
7.140 +
7.141 gboolean video_gtk_init()
7.142 {
7.143
7.144 @@ -108,18 +158,10 @@
7.145 return FALSE;
7.146 }
7.147
7.148 - g_signal_connect( video_win, "key_press_event",
7.149 - G_CALLBACK(video_gtk_keydown_callback), NULL );
7.150 - g_signal_connect( video_win, "key_release_event",
7.151 - G_CALLBACK(video_gtk_keyup_callback), NULL );
7.152 g_signal_connect( video_win, "expose_event",
7.153 G_CALLBACK(video_gtk_expose_callback), NULL );
7.154 g_signal_connect( video_win, "configure_event",
7.155 G_CALLBACK(video_gtk_resize_callback), NULL );
7.156 - gtk_widget_add_events( video_win,
7.157 - GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
7.158 - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK );
7.159 - gtk_widget_set_double_buffered( video_win, FALSE );
7.160 video_width = video_win->allocation.width;
7.161 video_height = video_win->allocation.height;
7.162 Display *display = gdk_x11_display_get_xdisplay( gtk_widget_get_display(GTK_WIDGET(video_win)));
8.1 --- a/src/drivers/video_null.c Sat Jan 26 02:43:30 2008 +0000
8.2 +++ b/src/drivers/video_null.c Sat Jan 26 02:45:27 2008 +0000
8.3 @@ -60,6 +60,7 @@
8.4 NULL,
8.5 NULL,
8.6 NULL,
8.7 + NULL,
8.8 video_null_create_render_buffer,
8.9 video_null_destroy_render_buffer,
8.10 video_null_set_render_target,
9.1 --- a/src/gtkui/ctrl_dlg.c Sat Jan 26 02:43:30 2008 +0000
9.2 +++ b/src/gtkui/ctrl_dlg.c Sat Jan 26 02:45:27 2008 +0000
9.3 @@ -180,7 +180,6 @@
9.4 gtk_gui_run_property_dialog( _("Controller Configuration"), table, controller_config_done );
9.5 }
9.6
9.7 -
9.8 gboolean maple_properties_activated( GtkButton *button, gpointer user_data )
9.9 {
9.10 maple_slot_data_t data = (maple_slot_data_t)user_data;
9.11 @@ -207,7 +206,7 @@
9.12 {
9.13 maple_slot_data_t data = (maple_slot_data_t)user_data;
9.14 int active = gtk_combo_box_get_active(combo);
9.15 - gtk_widget_set_sensitive(data->button, active != 0);
9.16 + gboolean has_config = FALSE;
9.17 if( active != 0 ) {
9.18 gchar *devname = gtk_combo_box_get_active_text(combo);
9.19 const maple_device_class_t devclz = maple_get_device_class(devname);
9.20 @@ -220,12 +219,14 @@
9.21 } else {
9.22 data->new_device = maple_new_device(devname);
9.23 }
9.24 + has_config = data->new_device != NULL && data->new_device->get_config != NULL;
9.25 } else {
9.26 if( data->new_device != NULL && data->new_device != data->old_device ) {
9.27 data->new_device->destroy(data->new_device);
9.28 }
9.29 data->new_device = NULL;
9.30 }
9.31 + gtk_widget_set_sensitive(data->button, has_config);
9.32 return TRUE;
9.33 }
9.34
9.35 @@ -280,7 +281,7 @@
9.36 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), active);
9.37 gtk_table_attach_defaults( GTK_TABLE(table), combo, 1, 2, i, i+1 );
9.38 button = gtk_button_new_from_stock( GTK_STOCK_PROPERTIES );
9.39 - gtk_widget_set_sensitive(button, active != 0);
9.40 + gtk_widget_set_sensitive(button, active != 0 && device->get_config != NULL);
9.41 gtk_table_attach_defaults( GTK_TABLE(table), button, 2, 3, i, i+1 );
9.42
9.43 maple_data[i].old_device = device;
10.1 --- a/src/gtkui/gtkui.c Sat Jan 26 02:43:30 2008 +0000
10.2 +++ b/src/gtkui/gtkui.c Sat Jan 26 02:45:27 2008 +0000
10.3 @@ -225,6 +225,7 @@
10.4 GtkWidget *gdrommenu = gdrom_menu_new();
10.5 gtk_menu_item_set_submenu( GTK_MENU_ITEM(gdrommenuitem), gdrommenu );
10.6 main_win = main_window_new( APP_NAME " " APP_VERSION, menubar, toolbar, accel_group );
10.7 + main_window_set_use_grab(main_win, TRUE);
10.8 if( withDebug ) {
10.9 gtk_gui_show_debugger();
10.10 }
10.11 @@ -473,3 +474,20 @@
10.12 delete_frame_buffer,
10.13 buffer );
10.14 }
10.15 +
10.16 +/**
10.17 + * Extract the keyval of the key event if no modifier keys were pressed -
10.18 + * in other words get the keyval of the key by itself. The other way around
10.19 + * would be to use the hardware keysyms directly rather than the keyvals,
10.20 + * but the mapping looks to be messier.
10.21 + */
10.22 +uint16_t gtk_get_unmodified_keyval( GdkEventKey *event )
10.23 +{
10.24 + GdkKeymap *keymap = gdk_keymap_get_default();
10.25 + guint keyval;
10.26 +
10.27 + gdk_keymap_translate_keyboard_state( keymap, event->hardware_keycode, 0, 0, &keyval,
10.28 + NULL, NULL, NULL );
10.29 + return keyval;
10.30 +}
10.31 +
11.1 --- a/src/gtkui/gtkui.h Sat Jan 26 02:43:30 2008 +0000
11.2 +++ b/src/gtkui/gtkui.h Sat Jan 26 02:45:27 2008 +0000
11.3 @@ -44,6 +44,7 @@
11.4 void main_window_set_framerate( main_window_t win, float rate );
11.5 void main_window_set_speed( main_window_t win, double speed );
11.6 void main_window_set_fullscreen( main_window_t win, gboolean fullscreen );
11.7 +void main_window_set_use_grab( main_window_t win, gboolean grab );
11.8
11.9 debug_window_t debug_window_new( const gchar *title, GtkWidget *menubar,
11.10 GtkWidget *toolbar, GtkAccelGroup *accel );
11.11 @@ -82,6 +83,13 @@
11.12 typedef gboolean (*file_callback_t)( const gchar *filename );
11.13 void open_file_dialog( char *title, file_callback_t action, char *pattern, char *patname,
11.14 gchar const *initial_dir );
11.15 +/**
11.16 + * Extract the keyval of the key event if no modifier keys were pressed -
11.17 + * in other words get the keyval of the key by itself. The other way around
11.18 + * would be to use the hardware keysyms directly rather than the keyvals,
11.19 + * but the mapping looks to be messier.
11.20 + */
11.21 +uint16_t gtk_get_unmodified_keyval( GdkEventKey *event );
11.22
11.23 /**
11.24 * Construct a new pixbuf that takes ownership of the frame buffer
12.1 --- a/src/gtkui/main_win.c Sat Jan 26 02:43:30 2008 +0000
12.2 +++ b/src/gtkui/main_win.c Sat Jan 26 02:45:27 2008 +0000
12.3 @@ -26,7 +26,9 @@
12.4 #include <stdlib.h>
12.5
12.6 #include <gtk/gtk.h>
12.7 +#include <gdk/gdk.h>
12.8 #include <gdk/gdkx.h>
12.9 +#include <gdk/gdkkeysyms.h>
12.10 #include <X11/Xutil.h>
12.11
12.12 #include "dream.h"
12.13 @@ -41,8 +43,159 @@
12.14 GtkWidget *toolbar;
12.15 GtkWidget *statusbar;
12.16 GtkActionGroup *actions;
12.17 + gboolean use_grab;
12.18 + gboolean is_grabbed;
12.19 + int32_t mouse_x, mouse_y;
12.20 };
12.21
12.22 +
12.23 +/******************** Video window **************************/
12.24 +
12.25 +/**
12.26 + * Adjust the mouse pointer so that it appears in the center of the video
12.27 + * window. Mainly used for when we have the mouse grab
12.28 + */
12.29 +void video_window_center_pointer( main_window_t win )
12.30 +{
12.31 + GdkDisplay *display = gtk_widget_get_display(win->video);
12.32 + GdkScreen *screen = gtk_widget_get_screen(win->video);
12.33 + int x,y;
12.34 + int width, height;
12.35 +
12.36 + gdk_window_get_origin(win->video->window, &x, &y);
12.37 + gdk_drawable_get_size(GDK_DRAWABLE(win->video->window), &width, &height);
12.38 + x += width / 2;
12.39 + y += height / 2;
12.40 +
12.41 + gdk_display_warp_pointer( display, screen, x, y );
12.42 + win->mouse_x = width/2;
12.43 + win->mouse_y = height/2;
12.44 +}
12.45 +
12.46 +/**
12.47 + * Grab the keyboard and mouse for the display. The mouse cursor is hidden and
12.48 + * moved to the centre of the window.
12.49 + *
12.50 + * @param win The window receiving the grab
12.51 + * @return TRUE if the grab was successful, FALSE on failure.
12.52 + */
12.53 +gboolean video_window_grab_display( main_window_t win )
12.54 +{
12.55 + GdkWindow *gdkwin = win->video->window;
12.56 + GdkColor color = { 0,0,0,0 };
12.57 + char bytes[32]; /* 16 * 16 / 8 */
12.58 + memset(bytes, 0, 32);
12.59 + GdkPixmap *pixmap = gdk_bitmap_create_from_data(NULL, bytes, 16, 16);
12.60 + GdkCursor *cursor = gdk_cursor_new_from_pixmap(pixmap, pixmap, &color, &color, 16, 16);
12.61 + gdk_pixmap_unref(pixmap);
12.62 +
12.63 + gboolean success =
12.64 + gdk_pointer_grab( gdkwin, FALSE,
12.65 + GDK_POINTER_MOTION_MASK|GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK,
12.66 + gdkwin, cursor, GDK_CURRENT_TIME ) == GDK_GRAB_SUCCESS;
12.67 + gdk_cursor_unref(cursor);
12.68 + if( success ) {
12.69 + success = gdk_keyboard_grab( gdkwin, FALSE, GDK_CURRENT_TIME ) == GDK_GRAB_SUCCESS;
12.70 + if( !success ) {
12.71 + gdk_pointer_ungrab(GDK_CURRENT_TIME);
12.72 + }
12.73 + }
12.74 + win->is_grabbed = success;
12.75 + main_window_set_running(win, dreamcast_is_running());
12.76 + return success;
12.77 +}
12.78 +
12.79 +/**
12.80 + * Release the display grab.
12.81 + */
12.82 +void video_window_ungrab_display( main_window_t win )
12.83 +{
12.84 + gdk_pointer_ungrab(GDK_CURRENT_TIME);
12.85 + gdk_keyboard_ungrab(GDK_CURRENT_TIME);
12.86 + win->is_grabbed = FALSE;
12.87 + main_window_set_running(win, dreamcast_is_running());
12.88 +}
12.89 +
12.90 +static gboolean on_video_window_mouse_motion( GtkWidget *widget, GdkEventMotion *event,
12.91 + gpointer user_data )
12.92 +{
12.93 + main_window_t win = (main_window_t)user_data;
12.94 + int32_t x = (int32_t)event->x;
12.95 + int32_t y = (int32_t)event->y;
12.96 + if( win->is_grabbed &&
12.97 + (x != win->mouse_x || y != win->mouse_y) ) {
12.98 + uint32_t buttons = (event->state >> 8)&0x1F;
12.99 + input_event_mouse( buttons, x - win->mouse_x, y - win->mouse_y );
12.100 + video_window_center_pointer(win);
12.101 + }
12.102 + return TRUE;
12.103 +}
12.104 +
12.105 +static gboolean on_video_window_mouse_pressed( GtkWidget *widget, GdkEventButton *event,
12.106 + gpointer user_data )
12.107 +{
12.108 + main_window_t win = (main_window_t)user_data;
12.109 + if( win->is_grabbed ) {
12.110 + // Get the buttons from the event state, and remove the released button
12.111 + uint32_t buttons = ((event->state >> 8) & 0x1F) | (1<<(event->button-1));
12.112 + input_event_mouse( buttons, 0, 0 );
12.113 + }
12.114 + return TRUE;
12.115 +}
12.116 +
12.117 +static gboolean on_video_window_mouse_released( GtkWidget *widget, GdkEventButton *event,
12.118 + gpointer user_data )
12.119 +{
12.120 + main_window_t win = (main_window_t)user_data;
12.121 + if( win->is_grabbed ) {
12.122 + // Get the buttons from the event state, and remove the released button
12.123 + uint32_t buttons = ((event->state >> 8) & 0x1F) & (~(1<<(event->button-1)));
12.124 + input_event_mouse( buttons, 0, 0 );
12.125 + } else if( win->use_grab) {
12.126 + video_window_grab_display(win);
12.127 + }
12.128 + return TRUE;
12.129 +}
12.130 +
12.131 +static gboolean on_video_window_key_pressed( GtkWidget *widget, GdkEventKey *event,
12.132 + gpointer user_data )
12.133 +{
12.134 + main_window_t win = (main_window_t)user_data;
12.135 + if( win->is_grabbed ) {
12.136 + /* Check for ungrab key combo (ctrl-alt). Unfortunately GDK sends it as
12.137 + * a singly-modified keypress rather than a double-modified 'null' press,
12.138 + * so we have to do a little more work.
12.139 + */
12.140 + if( (event->state == GDK_CONTROL_MASK &&
12.141 + (event->keyval == GDK_Alt_L || event->keyval == GDK_Alt_R)) ||
12.142 + (event->state == GDK_MOD1_MASK &&
12.143 + (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R)) ) {
12.144 + video_window_ungrab_display(win);
12.145 + // Consume the keypress, DC doesn't get it.
12.146 + return TRUE;
12.147 + }
12.148 + }
12.149 + input_event_keydown( gtk_get_unmodified_keyval(event) );
12.150 + return TRUE;
12.151 +}
12.152 +
12.153 +static gboolean on_video_window_key_released( GtkWidget *widget, GdkEventKey *event,
12.154 + gpointer user_data )
12.155 +{
12.156 + main_window_t win = (main_window_t)user_data;
12.157 + input_event_keyup( gtk_get_unmodified_keyval(event) );
12.158 + return TRUE;
12.159 +}
12.160 +
12.161 +static gboolean on_video_window_grab_broken( GtkWidget *widget, GdkEventGrabBroken *event,
12.162 + gpointer user_data )
12.163 +{
12.164 + main_window_t win = (main_window_t)user_data;
12.165 + fprintf( stderr, "Grab broken\n" );
12.166 +}
12.167 +
12.168 +/*************************** Main window (frame) ******************************/
12.169 +
12.170 static gboolean on_main_window_deleted( GtkWidget *widget, GdkEvent event, gpointer user_data )
12.171 {
12.172 exit(0);
12.173 @@ -86,6 +239,8 @@
12.174 win->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
12.175 win->menubar = menubar;
12.176 win->toolbar = toolbar;
12.177 + win->use_grab = FALSE;
12.178 + win->is_grabbed = FALSE;
12.179 gtk_window_set_title( GTK_WINDOW(win->window), title );
12.180 gtk_window_add_accel_group (GTK_WINDOW (win->window), accel_group);
12.181
12.182 @@ -106,6 +261,7 @@
12.183 gtk_widget_set_colormap( win->video, colormap );
12.184 GTK_WIDGET_SET_FLAGS(win->video, GTK_CAN_FOCUS|GTK_CAN_DEFAULT);
12.185 gtk_widget_set_size_request( win->video, 640, 480 );
12.186 + gtk_widget_set_double_buffered( win->video, FALSE );
12.187 frame = gtk_frame_new(NULL);
12.188 gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_IN );
12.189 gtk_container_add( GTK_CONTAINER(frame), win->video );
12.190 @@ -122,19 +278,51 @@
12.191 gtk_widget_grab_focus( win->video );
12.192
12.193 gtk_statusbar_push( GTK_STATUSBAR(win->statusbar), 1, "Stopped" );
12.194 +
12.195 g_signal_connect( win->window, "delete_event",
12.196 G_CALLBACK(on_main_window_deleted), win );
12.197 g_signal_connect( win->window, "window-state-event",
12.198 G_CALLBACK(on_main_window_state_changed), win );
12.199 +
12.200 + g_signal_connect( win->video, "grab-broken-event",
12.201 + G_CALLBACK(on_video_window_grab_broken), win );
12.202 + g_signal_connect( win->video, "key-press-event",
12.203 + G_CALLBACK(on_video_window_key_pressed), win );
12.204 + g_signal_connect( win->video, "key-release-event",
12.205 + G_CALLBACK(on_video_window_key_released), win );
12.206 + g_signal_connect( win->video, "motion-notify-event",
12.207 + G_CALLBACK(on_video_window_mouse_motion), win );
12.208 + g_signal_connect( win->video, "button-press-event",
12.209 + G_CALLBACK(on_video_window_mouse_pressed), win );
12.210 + g_signal_connect( win->video, "button-release-event",
12.211 + G_CALLBACK(on_video_window_mouse_released), win );
12.212 +
12.213 + gtk_widget_add_events( win->video,
12.214 + GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
12.215 + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
12.216 + GDK_POINTER_MOTION_MASK );
12.217 +
12.218 return win;
12.219 }
12.220
12.221 +void main_window_set_status_text( main_window_t win, char *text )
12.222 +{
12.223 + gtk_statusbar_pop( GTK_STATUSBAR(win->statusbar), 1 );
12.224 + if( win->is_grabbed ) {
12.225 + char buf[128];
12.226 + snprintf( buf, sizeof(buf), "%s %s", text, _("(Press <ctrl><alt> to release grab)") );
12.227 + gtk_statusbar_push( GTK_STATUSBAR(win->statusbar), 1, buf );
12.228 + } else {
12.229 + gtk_statusbar_push( GTK_STATUSBAR(win->statusbar), 1, text );
12.230 + }
12.231 +}
12.232 +
12.233 void main_window_set_running( main_window_t win, gboolean running )
12.234 {
12.235 + char *text = running ? _("Running") : _("Stopped");
12.236 gtk_gui_enable_action( "Pause", running );
12.237 gtk_gui_enable_action( "Run", !running && dreamcast_can_run() );
12.238 - gtk_statusbar_pop( GTK_STATUSBAR(win->statusbar), 1 );
12.239 - gtk_statusbar_push( GTK_STATUSBAR(win->statusbar), 1, running ? "Running" : "Stopped" );
12.240 + main_window_set_status_text( win, text );
12.241 }
12.242
12.243 void main_window_set_framerate( main_window_t win, float rate )
12.244 @@ -148,10 +336,7 @@
12.245 char buf[32];
12.246
12.247 snprintf( buf, 32, "Running (%2.4f%%)", speed );
12.248 - gtk_statusbar_pop( GTK_STATUSBAR(win->statusbar), 1 );
12.249 - gtk_statusbar_push( GTK_STATUSBAR(win->statusbar), 1, buf );
12.250 -
12.251 -
12.252 + main_window_set_status_text( win, buf );
12.253 }
12.254
12.255 GtkWidget *main_window_get_renderarea( main_window_t win )
12.256 @@ -172,3 +357,20 @@
12.257 gtk_window_unfullscreen( GTK_WINDOW(win->window) );
12.258 }
12.259 }
12.260 +
12.261 +void main_window_set_use_grab( main_window_t win, gboolean use_grab )
12.262 +{
12.263 + if( use_grab != win->use_grab ) {
12.264 + if( use_grab ) {
12.265 + GdkCursor *cursor = gdk_cursor_new( GDK_HAND2 );
12.266 + gdk_window_set_cursor( win->video->window, cursor );
12.267 + gdk_cursor_unref( cursor );
12.268 + } else {
12.269 + gdk_window_set_cursor( win->video->window, NULL );
12.270 + if( gdk_pointer_is_grabbed() ) {
12.271 + video_window_ungrab_display(win);
12.272 + }
12.273 + }
12.274 + win->use_grab = use_grab;
12.275 + }
12.276 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/src/maple/kbd.c Sat Jan 26 02:45:27 2008 +0000
13.3 @@ -0,0 +1,162 @@
13.4 +/**
13.5 + * $Id: kbd.c 602 2008-01-15 20:50:23Z nkeynes $
13.6 + *
13.7 + * Implements the standard dreamcast keyboard
13.8 + *
13.9 + * Copyright (c) 2005 Nathan Keynes.
13.10 + *
13.11 + * This program is free software; you can redistribute it and/or modify
13.12 + * it under the terms of the GNU General Public License as published by
13.13 + * the Free Software Foundation; either version 2 of the License, or
13.14 + * (at your option) any later version.
13.15 + *
13.16 + * This program is distributed in the hope that it will be useful,
13.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.19 + * GNU General Public License for more details.
13.20 + */
13.21 +
13.22 +#include <stdlib.h>
13.23 +#include <X11/keysym.h>
13.24 +#include "dream.h"
13.25 +#include "dreamcast.h"
13.26 +#include "display.h"
13.27 +#include "maple.h"
13.28 +
13.29 +#define KEYBOARD_IDENT { 0x00, 0x00, 0x00, 0x40, 0x02, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, \
13.30 + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x20, 0x20, \
13.31 + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
13.32 + 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x42, 0x79, 0x20, \
13.33 + 0x6f, 0x72, 0x20, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, \
13.34 + 0x20, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x45, 0x4e, 0x54, 0x45, 0x52, \
13.35 + 0x50, 0x52, 0x49, 0x53, 0x45, 0x53, 0x2c, 0x4c, 0x54, 0x44, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, \
13.36 + 0x2c, 0x01, 0x90, 0x01 }
13.37 +
13.38 +#define KEYBOARD_VERSION {0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x31, \
13.39 + 0x30, 0x2c, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x34, 0x2f, 0x32, 0x37, 0x2c, 0x33, 0x31, 0x35, \
13.40 + 0x2d, 0x36, 0x32, 0x31, 0x31, 0x2d, 0x41, 0x4d, 0x20, 0x20, 0x20, 0x2c, 0x4b, 0x65, 0x79, 0x20, \
13.41 + 0x53, 0x63, 0x61, 0x6e, 0x20, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x3a, 0x20, 0x54, 0x68, \
13.42 + 0x65, 0x20, 0x32, 0x6e, 0x64, 0x20, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, 0x30, \
13.43 + 0x34, 0x2f, 0x32, 0x35 }
13.44 +
13.45 +void keyboard_attach( maple_device_t dev );
13.46 +void keyboard_detach( maple_device_t dev );
13.47 +maple_device_t keyboard_clone( maple_device_t dev );
13.48 +maple_device_t keyboard_new();
13.49 +int keyboard_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
13.50 + unsigned int *outlen );
13.51 +
13.52 +typedef struct keyboard_device {
13.53 + struct maple_device dev;
13.54 + uint8_t condition[8];
13.55 +} *keyboard_device_t;
13.56 +
13.57 +struct maple_device_class keyboard_class = { "Sega Keyboard", keyboard_new };
13.58 +
13.59 +static struct keyboard_device base_keyboard = {
13.60 + { MAPLE_DEVICE_TAG, &keyboard_class, KEYBOARD_IDENT, KEYBOARD_VERSION,
13.61 + NULL, keyboard_attach, keyboard_detach, maple_default_destroy,
13.62 + keyboard_clone, NULL, NULL, keyboard_get_cond, NULL, NULL, NULL },
13.63 + {0,0,0,0,0,0,0,0},
13.64 +};
13.65 +
13.66 +#define KEYBOARD(x) ((keyboard_device_t)(x))
13.67 +
13.68 +maple_device_t keyboard_new( )
13.69 +{
13.70 + keyboard_device_t dev = malloc( sizeof(struct keyboard_device) );
13.71 + memcpy( dev, &base_keyboard, sizeof(base_keyboard) );
13.72 + return MAPLE_DEVICE(dev);
13.73 +}
13.74 +
13.75 +maple_device_t keyboard_clone( maple_device_t srcdevice )
13.76 +{
13.77 + keyboard_device_t src = (keyboard_device_t)srcdevice;
13.78 + keyboard_device_t dev = (keyboard_device_t)keyboard_new();
13.79 + memcpy( dev->condition, src->condition, sizeof(src->condition) );
13.80 + return MAPLE_DEVICE(dev);
13.81 +}
13.82 +
13.83 +void keyboard_key_down( keyboard_device_t dev, uint8_t key )
13.84 +{
13.85 + int i;
13.86 + for( i=2; i<8; i++ ) {
13.87 + if( dev->condition[i] == key ) {
13.88 + return; // key already down, missed event or repeat
13.89 + } else if( dev->condition[i] == 0 ) {
13.90 + dev->condition[i] = key;
13.91 + return;
13.92 + }
13.93 + }
13.94 + /* Key array is full - skip for the moment */
13.95 +}
13.96 +
13.97 +void keyboard_key_up( keyboard_device_t dev, uint8_t key )
13.98 +{
13.99 + int i;
13.100 + for( i=2; i<8; i++ ) {
13.101 + if( dev->condition[i] == key ) {
13.102 + for( ; i<7; i++ ) {
13.103 + dev->condition[i] = dev->condition[i+1];
13.104 + }
13.105 + dev->condition[7] = 0;
13.106 + break;
13.107 + }
13.108 + }
13.109 +}
13.110 +
13.111 +void keyboard_input_hook( void *mdev, uint32_t keycode, gboolean isKeyDown )
13.112 +{
13.113 + keyboard_device_t dev = (keyboard_device_t)mdev;
13.114 + uint16_t key = input_keycode_to_dckeysym( keycode );
13.115 + if( key != 0 ) {
13.116 + if( key >> 8 == 0xFF ) { // shift
13.117 + if( isKeyDown ) {
13.118 + dev->condition[0] |= (key&0xFF);
13.119 + } else {
13.120 + dev->condition[0] &= ~(key&0xFF);
13.121 + }
13.122 + } else {
13.123 + if( isKeyDown ) {
13.124 + keyboard_key_down( dev, (uint8_t)key );
13.125 + } else {
13.126 + keyboard_key_up( dev, (uint8_t)key );
13.127 + }
13.128 + }
13.129 + }
13.130 + /*
13.131 + fprintf( stderr, "Key cond: %02X %02X %02X %02X %02X %02X %02X %02X\n",
13.132 + dev->condition[0], dev->condition[1], dev->condition[2],
13.133 + dev->condition[3], dev->condition[4], dev->condition[5],
13.134 + dev->condition[6], dev->condition[7] );
13.135 + */
13.136 +}
13.137 +
13.138 +/**
13.139 + * Device is being attached to the bus. Go through the config and reserve the
13.140 + * keys we need.
13.141 + */
13.142 +void keyboard_attach( maple_device_t mdev )
13.143 +{
13.144 + input_register_hook( keyboard_input_hook, mdev );
13.145 +}
13.146 +
13.147 +void keyboard_detach( maple_device_t mdev )
13.148 +{
13.149 + input_unregister_hook( keyboard_input_hook, mdev );
13.150 +}
13.151 +
13.152 +
13.153 +int keyboard_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,
13.154 + unsigned int *outlen )
13.155 +{
13.156 + keyboard_device_t dev = (keyboard_device_t)mdev;
13.157 + if( function == MAPLE_FUNC_KEYBOARD ) {
13.158 + *outlen = 2;
13.159 + memcpy( outbuf, dev->condition, 8 );
13.160 + return 0;
13.161 + } else {
13.162 + return MAPLE_ERR_FUNC_UNSUP;
13.163 + }
13.164 +}
13.165 +
14.1 --- a/src/maple/maple.c Sat Jan 26 02:43:30 2008 +0000
14.2 +++ b/src/maple/maple.c Sat Jan 26 02:45:27 2008 +0000
14.3 @@ -29,7 +29,8 @@
14.4 struct dreamcast_module maple_module = { "Maple", maple_init, NULL, NULL, NULL,
14.5 NULL, NULL, NULL };
14.6
14.7 -struct maple_device_class *maple_device_classes[] = { &controller_class, NULL };
14.8 +struct maple_device_class *maple_device_classes[] = {
14.9 + &controller_class, &keyboard_class, &mouse_class, NULL };
14.10
14.11 void maple_init( void )
14.12 {
14.13 @@ -322,9 +323,16 @@
14.14 for( j=0; j<6; j++ ) {
14.15 if( maple_devices[i][j] != NULL ) {
14.16 maple_device_t dev = maple_devices[i][j];
14.17 + if( dev->detach != NULL )
14.18 + dev->detach(dev);
14.19 if( dev->attach != NULL )
14.20 dev->attach(dev);
14.21 }
14.22 }
14.23 }
14.24 }
14.25 +
14.26 +void maple_default_destroy( maple_device_t mdev )
14.27 +{
14.28 + free(mdev);
14.29 +}
15.1 --- a/src/maple/maple.h Sat Jan 26 02:43:30 2008 +0000
15.2 +++ b/src/maple/maple.h Sat Jan 26 02:45:27 2008 +0000
15.3 @@ -89,6 +89,8 @@
15.4 };
15.5
15.6 extern struct maple_device_class controller_class;
15.7 +extern struct maple_device_class keyboard_class;
15.8 +extern struct maple_device_class mouse_class;
15.9
15.10 maple_device_t maple_new_device( const gchar *name );
15.11 maple_device_t maple_get_device( unsigned int port, unsigned int periph );
15.12 @@ -102,4 +104,9 @@
15.13 void maple_detach_all( );
15.14 void maple_reattach_all( );
15.15
15.16 +/**
15.17 + * Default destroy implementation that just frees the dev memory.
15.18 + */
15.19 +void maple_default_destroy( maple_device_t dev );
15.20 +
15.21 #endif /* !lxdream_maple_H */
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/src/maple/mouse.c Sat Jan 26 02:45:27 2008 +0000
16.3 @@ -0,0 +1,141 @@
16.4 +/**
16.5 + * $Id: mouse.c 602 2008-01-15 20:50:23Z nkeynes $
16.6 + *
16.7 + * Implementation of the standard mouse device
16.8 + *
16.9 + * Copyright (c) 2005 Nathan Keynes.
16.10 + *
16.11 + * This program is free software; you can redistribute it and/or modify
16.12 + * it under the terms of the GNU General Public License as published by
16.13 + * the Free Software Foundation; either version 2 of the License, or
16.14 + * (at your option) any later version.
16.15 + *
16.16 + * This program is distributed in the hope that it will be useful,
16.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
16.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.19 + * GNU General Public License for more details.
16.20 + */
16.21 +#include <stdlib.h>
16.22 +#include <stdio.h>
16.23 +#include <string.h>
16.24 +#include "maple/maple.h"
16.25 +
16.26 +#define MOUSE_IDENT { 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,\
16.27 + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x72, 0x65, 0x61, 0x6d, 0x63, 0x61, 0x73, 0x74, 0x20,\
16.28 + 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\
16.29 + 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x42, 0x79, 0x20,\
16.30 + 0x6f, 0x72, 0x20, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65,\
16.31 + 0x20, 0x46, 0x72, 0x6f, 0x6d, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x45, 0x4e, 0x54, 0x45, 0x52,\
16.32 + 0x50, 0x52, 0x49, 0x53, 0x45, 0x53, 0x2c, 0x4c, 0x54, 0x44, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20,\
16.33 + 0x90, 0x01, 0xf4, 0x01 }
16.34 +#define MOUSE_VERSION { 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x30,\
16.35 + 0x30, 0x2c, 0x32, 0x30, 0x30, 0x30, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x35, 0x2c, 0x33, 0x31, 0x35,\
16.36 + 0x2d, 0x36, 0x32, 0x31, 0x31, 0x2d, 0x41, 0x54, 0x20, 0x20, 0x20, 0x2c, 0x33, 0x20, 0x42, 0x75,\
16.37 + 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x26, 0x20, 0x58, 0x2d, 0x59, 0x20, 0x42, 0x61, 0x6c, 0x6c, 0x20,\
16.38 + 0x26, 0x20, 0x5a, 0x20, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x20, 0x2c, 0x34, 0x30, 0x30, 0x64, 0x70,\
16.39 + 0x69, 0x20, 0x20, 0x20 }
16.40 +
16.41 +#define BUTTON_MIDDLE 0x01
16.42 +#define BUTTON_RIGHT 0x02
16.43 +#define BUTTON_LEFT 0x04
16.44 +#define BUTTON_THUMB 0x08
16.45 +
16.46 +void mouse_attach( maple_device_t dev );
16.47 +void mouse_detach( maple_device_t dev );
16.48 +maple_device_t mouse_clone( maple_device_t dev );
16.49 +maple_device_t mouse_new();
16.50 +int mouse_get_cond( maple_device_t dev, int function, unsigned char *outbuf,
16.51 + unsigned int *outlen );
16.52 +
16.53 +typedef struct mouse_device {
16.54 + struct maple_device dev;
16.55 + uint32_t buttons;
16.56 + int32_t axis[8];
16.57 +} *mouse_device_t;
16.58 +
16.59 +struct maple_device_class mouse_class = { "Sega Mouse", mouse_new };
16.60 +
16.61 +static struct mouse_device base_mouse = {
16.62 + { MAPLE_DEVICE_TAG, &mouse_class, MOUSE_IDENT, MOUSE_VERSION,
16.63 + NULL, mouse_attach, mouse_detach, maple_default_destroy,
16.64 + mouse_clone, NULL, NULL, mouse_get_cond, NULL, NULL, NULL },
16.65 + 0, {0,0,0,0,0,0,0,0},
16.66 +};
16.67 +
16.68 +static int32_t mouse_axis_scale_factors[8] = { 10, 10, 1, 1, 1, 1, 1, 1 };
16.69 +
16.70 +#define MOUSE(x) ((mouse_device_t)(x))
16.71 +
16.72 +maple_device_t mouse_new( )
16.73 +{
16.74 + mouse_device_t dev = malloc( sizeof(struct mouse_device) );
16.75 + memcpy( dev, &base_mouse, sizeof(base_mouse) );
16.76 + return MAPLE_DEVICE(dev);
16.77 +}
16.78 +
16.79 +maple_device_t mouse_clone( maple_device_t srcdevice )
16.80 +{
16.81 + mouse_device_t src = (mouse_device_t)srcdevice;
16.82 + mouse_device_t dev = (mouse_device_t)mouse_new();
16.83 + dev->buttons = src->buttons;
16.84 + memcpy( dev->axis, src->axis, sizeof(src->axis) );
16.85 + return MAPLE_DEVICE(dev);
16.86 +}
16.87 +
16.88 +void mouse_input_callback( void *mdev, uint32_t buttons, int32_t x, int32_t y )
16.89 +{
16.90 + mouse_device_t dev = (mouse_device_t)mdev;
16.91 + dev->buttons = 0;
16.92 + if( buttons & 0x01 ) {
16.93 + dev->buttons |= BUTTON_LEFT;
16.94 + }
16.95 + if( buttons & 0x02 ) {
16.96 + dev->buttons |= BUTTON_MIDDLE;
16.97 + }
16.98 + if( buttons & 0x04 ) {
16.99 + dev->buttons |= BUTTON_RIGHT;
16.100 + }
16.101 + if( buttons & 0x08 ) {
16.102 + dev->buttons |= BUTTON_THUMB;
16.103 + }
16.104 + dev->axis[0] += x;
16.105 + dev->axis[1] += y;
16.106 +}
16.107 +
16.108 +void mouse_attach( maple_device_t dev )
16.109 +{
16.110 + input_register_mouse_hook( TRUE, mouse_input_callback, dev );
16.111 +}
16.112 +
16.113 +void mouse_detach( maple_device_t dev )
16.114 +{
16.115 + input_unregister_mouse_hook( mouse_input_callback, dev );
16.116 +}
16.117 +
16.118 +int mouse_get_cond( maple_device_t mdev, int function, unsigned char *outbuf,
16.119 + unsigned int *outlen )
16.120 +{
16.121 + mouse_device_t dev = (mouse_device_t)mdev;
16.122 + if( function == MAPLE_FUNC_MOUSE ) {
16.123 + *outlen = 5;
16.124 + *(uint32_t *)outbuf = dev->buttons;
16.125 + uint16_t *p = (uint16_t *)(outbuf+4);
16.126 + int i;
16.127 + // Axis values are in the range 0..0x3FF, where 0x200 is zero movement
16.128 + for( i=0; i<8; i++ ) {
16.129 + int32_t value = dev->axis[i] / mouse_axis_scale_factors[i];
16.130 + if( value < -0x200 ) {
16.131 + p[i] = 0;
16.132 + } else if( value > 0x1FF ) {
16.133 + p[i] = 0x3FF;
16.134 + } else {
16.135 + p[i] = 0x200 + value;
16.136 + }
16.137 + dev->axis[i] = 0; // clear after returning.
16.138 + }
16.139 + return 0;
16.140 + } else {
16.141 + return MAPLE_ERR_FUNC_UNSUP;
16.142 + }
16.143 +}
16.144 +
.