revision 608:4f588e52bce0
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 608:4f588e52bce0 |
parent | 607:268c85ddc01f |
child | 609:41b61a0d5f1a |
author | nkeynes |
date | Sat Jan 26 02:45:27 2008 +0000 (16 years ago) |
Bug #50: Implement mouse and keyboard
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/config.c | view | annotate | diff | log | ||
src/dckeysyms.h | view | annotate | diff | log | ||
src/display.c | view | annotate | diff | log | ||
src/display.h | view | annotate | diff | log | ||
src/drivers/video_gtk.c | view | annotate | diff | log | ||
src/drivers/video_null.c | view | annotate | diff | log | ||
src/gtkui/ctrl_dlg.c | view | annotate | diff | log | ||
src/gtkui/gtkui.c | view | annotate | diff | log | ||
src/gtkui/gtkui.h | view | annotate | diff | log | ||
src/gtkui/main_win.c | view | annotate | diff | log | ||
src/maple/kbd.c | view | annotate | diff | log | ||
src/maple/maple.c | view | annotate | diff | log | ||
src/maple/maple.h | view | annotate | diff | log | ||
src/maple/mouse.c | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Sat Jan 26 02:43:30 2008 +00001.2 +++ b/src/Makefile.am Sat Jan 26 02:45:27 2008 +00001.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 +00002.2 +++ b/src/Makefile.in Sat Jan 26 02:45:27 2008 +00002.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.c2.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.c2.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.104 +kbd.o: maple/kbd.c2.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@ fi2.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.c2.114 +2.115 +kbd.obj: maple/kbd.c2.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@ fi2.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.c2.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@ fi2.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.c2.136 +2.137 +mouse.obj: maple/mouse.c2.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@ fi2.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.c2.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 +00003.2 +++ b/src/config.c Sat Jan 26 02:45:27 2008 +00003.3 @@ -312,12 +312,13 @@3.4 fprintf( f, "Device %d = %s\n", i, dev->device_class->name );3.5 else3.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 +00004.2 +++ b/src/dckeysyms.h Sat Jan 26 02:45:27 2008 +00004.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 modify4.12 + * it under the terms of the GNU General Public License as published by4.13 + * the Free Software Foundation; either version 2 of the License, or4.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 of4.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the4.19 + * GNU General Public License for more details.4.20 + */4.21 +4.22 +#ifndef lxdream_dckeysyms_H4.23 +#define lxdream_dckeysyms_H 14.24 +4.25 +4.26 +#define DCKB_NONE 0x004.27 +#define DCKB_ERROR 0x014.28 +#define DCKB_A 0x044.29 +#define DCKB_B 0x054.30 +#define DCKB_C 0x064.31 +#define DCKB_D 0x074.32 +#define DCKB_E 0x084.33 +#define DCKB_F 0x094.34 +#define DCKB_G 0x0A4.35 +#define DCKB_H 0x0B4.36 +#define DCKB_I 0x0C4.37 +#define DCKB_J 0x0D4.38 +#define DCKB_K 0x0E4.39 +#define DCKB_L 0x0F4.40 +#define DCKB_M 0x104.41 +#define DCKB_N 0x114.42 +#define DCKB_O 0x124.43 +#define DCKB_P 0x134.44 +#define DCKB_Q 0x144.45 +#define DCKB_R 0x154.46 +#define DCKB_S 0x164.47 +#define DCKB_T 0x174.48 +#define DCKB_U 0x184.49 +#define DCKB_V 0x194.50 +#define DCKB_W 0x1A4.51 +#define DCKB_X 0x1B4.52 +#define DCKB_Y 0x1C4.53 +#define DCKB_Z 0x1D4.54 +#define DCKB_1 0x1E4.55 +#define DCKB_2 0x1F4.56 +#define DCKB_3 0x204.57 +#define DCKB_4 0x214.58 +#define DCKB_5 0x224.59 +#define DCKB_6 0x234.60 +#define DCKB_7 0x244.61 +#define DCKB_8 0x254.62 +#define DCKB_9 0x264.63 +#define DCKB_0 0x274.64 +#define DCKB_ENTER 0x284.65 +#define DCKB_ESCAPE 0x294.66 +#define DCKB_BACKSPACE 0x2A4.67 +#define DCKB_TAB 0x2B4.68 +#define DCKB_SPACE 0x2C4.69 +#define DCKB_MINUS 0x2D4.70 +#define DCKB_EQUAL 0x2E4.71 +#define DCKB_LBRACKET 0x2F4.72 +#define DCKB_RBRACKET 0x304.73 +#define DCKB_BACKSLASH 0x314.74 +#define DCKB_SEMICOLON 0x334.75 +#define DCKB_QUOTE 0x344.76 +#define DCKB_BACKQUOTE 0x354.77 +#define DCKB_COMMA 0x364.78 +#define DCKB_PERIOD 0x374.79 +#define DCKB_SLASH 0x384.80 +#define DCKB_CAPSLOCK 0x394.81 +#define DCKB_F1 0x3A4.82 +#define DCKB_F2 0x3B4.83 +#define DCKB_F3 0x3C4.84 +#define DCKB_F4 0x3D4.85 +#define DCKB_F5 0x3E4.86 +#define DCKB_F6 0x3F4.87 +#define DCKB_F7 0x404.88 +#define DCKB_F8 0x414.89 +#define DCKB_F9 0x424.90 +#define DCKB_F10 0x434.91 +#define DCKB_F11 0x444.92 +#define DCKB_F12 0x454.93 +#define DCKB_PRINTSCR 0x464.94 +#define DCKB_SCROLLLOCK 0x474.95 +#define DCKB_PAUSE 0x484.96 +#define DCKB_INSERT 0x494.97 +#define DCKB_HOME 0x4A4.98 +#define DCKB_PAGEUP 0x4B4.99 +#define DCKB_DELETE 0x4C4.100 +#define DCKB_END 0x4D4.101 +#define DCKB_PAGEDOWN 0x4E4.102 +#define DCKB_RIGHT 0x4F4.103 +#define DCKB_LEFT 0x504.104 +#define DCKB_DOWN 0x514.105 +#define DCKB_UP 0x524.106 +#define DCKB_NUMLOCK 0x534.107 +#define DCKB_KP_SLASH 0x544.108 +#define DCKB_KP_STAR 0x554.109 +#define DCKB_KP_MINUS 0x564.110 +#define DCKB_KP_PLUS 0x574.111 +#define DCKB_KP_ENTER 0x584.112 +#define DCKB_KP_1 0x594.113 +#define DCKB_KP_2 0x5A4.114 +#define DCKB_KP_3 0x5B4.115 +#define DCKB_KP_4 0x5C4.116 +#define DCKB_KP_5 0x5D4.117 +#define DCKB_KP_6 0x5E4.118 +#define DCKB_KP_7 0x5F4.119 +#define DCKB_KP_8 0x604.120 +#define DCKB_KP_9 0x614.121 +#define DCKB_KP_0 0x624.122 +#define DCKB_KP_PERIOD 0x634.123 +#define DCKB_S3 0x654.124 +4.125 +/* Modifier keys */4.126 +4.127 +#define DCKB_CONTROL_L 0xFF014.128 +#define DCKB_SHIFT_L 0xFF024.129 +#define DCKB_ALT_L 0xFF044.130 +#define DCKB_S1 0xFF084.131 +#define DCKB_CONTROL_R 0xFF104.132 +#define DCKB_SHIFT_R 0xFF204.133 +#define DCKB_ALT_R 0xFF404.134 +#define DCKB_S2 0xFF804.135 +4.136 +#endif /* !lxdream_dckeysyms_H */
5.1 --- a/src/display.c Sat Jan 26 02:43:30 2008 +00005.2 +++ b/src/display.c Sat Jan 26 02:45:27 2008 +00005.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 chaining5.8 } *keymap_entry_t;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 information5.19 */5.20 @@ -59,7 +67,8 @@5.21 * FIXME: make this more memory efficient5.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.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.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.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.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 +00006.2 +++ b/src/display.h Sat Jan 26 02:45:27 2008 +00006.3 @@ -118,6 +118,11 @@6.4 uint16_t (*resolve_keysym)( const gchar *keysym );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.17 typedef void (*input_key_callback_t)( void *data, uint32_t value, gboolean isKeyDown );6.19 +/**6.20 + * Callback to receive mouse input events6.21 + * @param data pointer passed in at the time the hook was registered6.22 + * @param buttons bitmask of button states, where bit 0 is button 0 (left), bit 1 is button6.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 position6.25 + * (in absolute mode).6.26 + * @param y Vertical movement since the last invocation (in relative mode) or window position6.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.34 void input_unregister_key( const gchar *keysym, input_key_callback_t callback,6.35 void *data, uint32_t value );6.37 +/**6.38 + * Register a hook to receive all input events6.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 for6.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.53 gboolean input_is_key_registered( const gchar *keysym );6.54 @@ -194,7 +225,9 @@6.56 void input_event_keyup( uint16_t keycode );6.58 +void input_event_mouse( uint32_t buttons, int32_t x_axis, int32_t y_axis );6.60 +uint16_t input_keycode_to_dckeysym( uint16_t keycode );6.62 #ifdef __cplusplus6.63 }
7.1 --- a/src/drivers/video_gtk.c Sat Jan 26 02:43:30 2008 +00007.2 +++ b/src/drivers/video_gtk.c Sat Jan 26 02:45:27 2008 +00007.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.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.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 around7.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.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.144 @@ -108,18 +158,10 @@7.145 return FALSE;7.146 }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 +00008.2 +++ b/src/drivers/video_null.c Sat Jan 26 02:45:27 2008 +00008.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 +00009.2 +++ b/src/gtkui/ctrl_dlg.c Sat Jan 26 02:45:27 2008 +00009.3 @@ -180,7 +180,6 @@9.4 gtk_gui_run_property_dialog( _("Controller Configuration"), table, controller_config_done );9.5 }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.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.43 maple_data[i].old_device = device;
10.1 --- a/src/gtkui/gtkui.c Sat Jan 26 02:43:30 2008 +000010.2 +++ b/src/gtkui/gtkui.c Sat Jan 26 02:45:27 2008 +000010.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 around10.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 +000011.2 +++ b/src/gtkui/gtkui.h Sat Jan 26 02:45:27 2008 +000011.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.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 around11.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.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 +000012.2 +++ b/src/gtkui/main_win.c Sat Jan 26 02:45:27 2008 +000012.3 @@ -26,7 +26,9 @@12.4 #include <stdlib.h>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.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.22 +12.23 +/******************** Video window **************************/12.24 +12.25 +/**12.26 + * Adjust the mouse pointer so that it appears in the center of the video12.27 + * window. Mainly used for when we have the mouse grab12.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 and12.48 + * moved to the centre of the window.12.49 + *12.50 + * @param win The window receiving the grab12.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 button12.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 button12.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 as12.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.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.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.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.243 void main_window_set_framerate( main_window_t win, float rate )12.244 @@ -148,10 +336,7 @@12.245 char buf[32];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.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 +000013.2 +++ b/src/maple/kbd.c Sat Jan 26 02:45:27 2008 +000013.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 keyboard13.8 + *13.9 + * Copyright (c) 2005 Nathan Keynes.13.10 + *13.11 + * This program is free software; you can redistribute it and/or modify13.12 + * it under the terms of the GNU General Public License as published by13.13 + * the Free Software Foundation; either version 2 of the License, or13.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 of13.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13.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 repeat13.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 ) { // shift13.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 the13.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 +000014.2 +++ b/src/maple/maple.c Sat Jan 26 02:45:27 2008 +000014.3 @@ -29,7 +29,8 @@14.4 struct dreamcast_module maple_module = { "Maple", maple_init, NULL, NULL, NULL,14.5 NULL, NULL, NULL };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.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 +000015.2 +++ b/src/maple/maple.h Sat Jan 26 02:45:27 2008 +000015.3 @@ -89,6 +89,8 @@15.4 };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.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.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 +000016.2 +++ b/src/maple/mouse.c Sat Jan 26 02:45:27 2008 +000016.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 device16.8 + *16.9 + * Copyright (c) 2005 Nathan Keynes.16.10 + *16.11 + * This program is free software; you can redistribute it and/or modify16.12 + * it under the terms of the GNU General Public License as published by16.13 + * the Free Software Foundation; either version 2 of the License, or16.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 of16.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16.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 0x0116.42 +#define BUTTON_RIGHT 0x0216.43 +#define BUTTON_LEFT 0x0416.44 +#define BUTTON_THUMB 0x0816.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 movement16.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 +
.