summaryrefslogtreecommitdiff
path: root/plugins/dfinput
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-04-16 06:22:51 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-04-16 06:22:51 +0000
commit8139fbf8204882663446bcb06f68789353597820 (patch)
tree6ea1f39932b33faee84d603e956470e37f135804 /plugins/dfinput
downloadpcsxr-8139fbf8204882663446bcb06f68789353597820.tar.gz
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@23061 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins/dfinput')
-rw-r--r--plugins/dfinput/Makefile.am22
-rw-r--r--plugins/dfinput/Makefile.in583
-rw-r--r--plugins/dfinput/cfg.c1289
-rw-r--r--plugins/dfinput/dfinput.glade2226
-rw-r--r--plugins/dfinput/pad.c989
-rw-r--r--plugins/dfinput/padjoy.h82
6 files changed, 3191 insertions, 0 deletions
diff --git a/plugins/dfinput/Makefile.am b/plugins/dfinput/Makefile.am
new file mode 100644
index 00000000..cb6d2648
--- /dev/null
+++ b/plugins/dfinput/Makefile.am
@@ -0,0 +1,22 @@
+bindir = @libdir@/games/psemu/
+libdir = @libdir@/games/psemu/
+
+lib_LTLIBRARIES = libDFInput.la
+
+libDFInput_la_SOURCES = pad.c padjoy.h
+libDFInput_la_LDFLAGS = -module -avoid-version -lpthread -lX11 \
+ -L/usr/X11R6/lib64 -L/usr/X11R6/lib
+
+INCLUDES = -DPIXMAPDIR=\"${datadir}/pixmaps/\" \
+ -DLOCALE_DIR=\"${datadir}/locale/\" \
+ -DDATADIR=\"${datadir}/psemu/\" \
+ $(GTK2_CFLAGS) $(GLADE2_CFLAGS) -I/usr/X11R6/include \
+ -DVERSION=0 -DREVISION=1 -DBUILD=0
+
+bin_PROGRAMS = cfgDFInput
+cfgDFInput_SOURCES = cfg.c padjoy.h
+cfgDFInput_LDADD = $(GTK2_LIBS) $(GLADE2_LIBS)
+
+glade_DATA = dfinput.glade2
+gladedir = $(datadir)/psemu/
+EXTRA_DIST = $(glade_DATA)
diff --git a/plugins/dfinput/Makefile.in b/plugins/dfinput/Makefile.in
new file mode 100644
index 00000000..6210f4cb
--- /dev/null
+++ b/plugins/dfinput/Makefile.in
@@ -0,0 +1,583 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = cfgDFInput$(EXEEXT)
+subdir = plugins/dfinput
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(gladedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libDFInput_la_LIBADD =
+am_libDFInput_la_OBJECTS = pad.lo
+libDFInput_la_OBJECTS = $(am_libDFInput_la_OBJECTS)
+libDFInput_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libDFInput_la_LDFLAGS) $(LDFLAGS) -o $@
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_cfgDFInput_OBJECTS = cfg.$(OBJEXT)
+cfgDFInput_OBJECTS = $(am_cfgDFInput_OBJECTS)
+am__DEPENDENCIES_1 =
+cfgDFInput_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libDFInput_la_SOURCES) $(cfgDFInput_SOURCES)
+DIST_SOURCES = $(libDFInput_la_SOURCES) $(cfgDFInput_SOURCES)
+gladeDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(glade_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALSA_LIBS = @ALSA_LIBS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFOPENGL = @DFOPENGL@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLADE2_CFLAGS = @GLADE2_CFLAGS@
+GLADE2_LIBS = @GLADE2_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+GTK2_CFLAGS = @GTK2_CFLAGS@
+GTK2_LIBS = @GTK2_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NASM = @NASM@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @libdir@/games/psemu/
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@/games/psemu/
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+lib_LTLIBRARIES = libDFInput.la
+libDFInput_la_SOURCES = pad.c padjoy.h
+libDFInput_la_LDFLAGS = -module -avoid-version -lpthread -lX11 \
+ -L/usr/X11R6/lib64 -L/usr/X11R6/lib
+
+INCLUDES = -DPIXMAPDIR=\"${datadir}/pixmaps/\" \
+ -DLOCALE_DIR=\"${datadir}/locale/\" \
+ -DDATADIR=\"${datadir}/psemu/\" \
+ $(GTK2_CFLAGS) $(GLADE2_CFLAGS) -I/usr/X11R6/include \
+ -DVERSION=0 -DREVISION=1 -DBUILD=0
+
+cfgDFInput_SOURCES = cfg.c padjoy.h
+cfgDFInput_LDADD = $(GTK2_LIBS) $(GLADE2_LIBS)
+glade_DATA = dfinput.glade2
+gladedir = $(datadir)/psemu/
+EXTRA_DIST = $(glade_DATA)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plugins/dfinput/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu plugins/dfinput/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libDFInput.la: $(libDFInput_la_OBJECTS) $(libDFInput_la_DEPENDENCIES)
+ $(libDFInput_la_LINK) -rpath $(libdir) $(libDFInput_la_OBJECTS) $(libDFInput_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+cfgDFInput$(EXEEXT): $(cfgDFInput_OBJECTS) $(cfgDFInput_DEPENDENCIES)
+ @rm -f cfgDFInput$(EXEEXT)
+ $(LINK) $(cfgDFInput_OBJECTS) $(cfgDFInput_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pad.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-gladeDATA: $(glade_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(gladedir)" || $(MKDIR_P) "$(DESTDIR)$(gladedir)"
+ @list='$(glade_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(gladeDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(gladedir)/$$f'"; \
+ $(gladeDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(gladedir)/$$f"; \
+ done
+
+uninstall-gladeDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(glade_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(gladedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(gladedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(gladedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-gladeDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-gladeDATA \
+ uninstall-libLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-gladeDATA install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-gladeDATA uninstall-libLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/plugins/dfinput/cfg.c b/plugins/dfinput/cfg.c
new file mode 100644
index 00000000..3f6d0184
--- /dev/null
+++ b/plugins/dfinput/cfg.c
@@ -0,0 +1,1289 @@
+/*
+ * Pad for Psemu Pro like Emulators
+ * This is the config program, taken out from the pad
+ * It's also responsible for the about-dialog box
+ *
+ * Written by Erich Kitzmuller <ammoq@ammoq.com>
+ * Based on padXwin by linuzappz <linuzappz@hotmail.com>
+ *
+ * Copyright 2002,2003 by Erich Kitzmuller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#ifdef __linux__
+#include <linux/joystick.h>
+#endif
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <errno.h>
+#include "padjoy.h"
+
+#ifdef __linux__
+char *LibName = "Gamepad/Keyboard Input";
+#else
+char *LibName = "Keyboard Input";
+#endif
+
+#define CONFIG_FILENAME "dfinput.cfg"
+
+const unsigned char version = VERSION;
+const unsigned char revision = REVISION;
+const unsigned char build = BUILD;
+
+// Prototypes
+static void loadConfig();
+static void saveConfig();
+static char *eventDescription(EventCode);
+static void initPadtime();
+
+// Filenames for device files, e.g. "/dev/input/js0"
+static char devicefilename[MAXDEVICES][FILENAME_MAX+1] = {"/dev/input/js0", "/dev/input/js1"};
+
+// File desciptors for device files
+static int devicefile[MAXDEVICES] = { -1, -1 };
+
+// Use Threading for joy device input?
+static int use_threads = 1;
+
+// Emulate Dualshock(TM) analog pad?
+static int use_analog = 0;
+
+// calibration data
+int minzero[MAXAXES];
+int maxzero[MAXAXES];
+
+// axes status - so only changing status are reported
+int axestatus[MAXDEVICES][MAXAXES];
+
+// Assignment of PSX buttons to Events
+static EventCode PadButtons[MAXDEVICES][MAXPSXBUTTONS] =
+{
+ {
+ KEY_EVENT(XK_e), // L2
+ KEY_EVENT(XK_t), // R2
+ KEY_EVENT(XK_w), // L1
+ KEY_EVENT(XK_r), // R1
+ KEY_EVENT(XK_d), // Triangle
+ KEY_EVENT(XK_x), // Circle
+ KEY_EVENT(XK_z), // Cross
+ KEY_EVENT(XK_s), // Square
+ KEY_EVENT(XK_c), // Select
+ NO_EVENT, // Left Analog
+ NO_EVENT, // Right Analog
+ KEY_EVENT(XK_v), // Start
+ KEY_EVENT(XK_Up), // Up
+ KEY_EVENT(XK_Right), // Right
+ KEY_EVENT(XK_Down), // Down
+ KEY_EVENT(XK_Left), // Left
+ NO_EVENT, // Left Anlaog X
+ NO_EVENT, // Left Analog Y
+ NO_EVENT, // Right Analog X
+ NO_EVENT // Right Analog Y
+ },
+ {
+ NO_EVENT, // L2
+ NO_EVENT, // R2
+ NO_EVENT, // L1
+ NO_EVENT, // R1
+ NO_EVENT, // Triangle
+ NO_EVENT, // Circle
+ NO_EVENT, // Cross
+ NO_EVENT, // Square
+ NO_EVENT, // Select
+ NO_EVENT, // Left Analog
+ NO_EVENT, // Right Analog
+ NO_EVENT, // Start
+ NO_EVENT, // Up
+ NO_EVENT, // Right
+ NO_EVENT, // Down
+ NO_EVENT, // Left
+ NO_EVENT, // Left Anlaog X
+ NO_EVENT, // Left Analog Y
+ NO_EVENT, // Right Analog X
+ NO_EVENT // Right Analog Y
+ }
+};
+
+static Display *Dsp;
+
+static EventCode macroLaunch[MAXDEVICES][MAXMACROS];
+static EventCode macroEvents[MAXDEVICES][MAXMACROS][MAXMACROLENGTH];
+static long macroInterval[MAXDEVICES][MAXMACROS][MAXMACROLENGTH];
+static int macroActive[MAXDEVICES];
+static int macroIndex[MAXDEVICES];
+static long macroNext[MAXDEVICES];
+
+void init_macros() {
+ int i,j;
+
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXMACROS; j++) {
+ macroLaunch[i][j]=NO_EVENT;
+ macroEvents[i][j][0]=NO_EVENT;
+ macroInterval[i][j][0]=0;
+ }
+ macroActive[i]=-1;
+ macroIndex[i]=0;
+ macroNext[i]=0;
+ }
+}
+
+long PADinit(long flags) {
+ int i,j;
+
+ init_macros();
+ initPadtime();
+ for (i=0; i<MAXDEVICES; i++) {
+ maxzero[i] = 250;
+ minzero[i] = -250;
+
+ for (j=0; j<MAXAXES; j++) {
+ axestatus[i][j] = AXESTS_UNKNOWN;
+ }
+ }
+ loadConfig();
+
+ return 0;
+}
+
+static long firstsecond = 0;
+
+static void initPadtime() {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ firstsecond = tv.tv_sec;
+}
+
+// construct a time on our own
+long getPadtime() {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (tv.tv_sec-firstsecond)*10000+tv.tv_usec/100;
+}
+
+unsigned short PadStat[2] = {0xffff, 0xffff};
+
+// get pending events
+static int getPendingEvents(int millisecondstowait, EventCode *events, int maxevents, int useGDK, int checkJoydevice, int checkXKeyboard, long *timing) {
+ fd_set rfds;
+ int retval;
+ int i;
+ int md;
+ int eventsread=0;
+ XEvent xe;
+ GdkEvent *ge;
+ int cntopen;
+ struct timeval tv;
+ int oldstatus;
+
+#ifdef __linux__
+ struct js_event je;
+
+ if (checkJoydevice) {
+ FD_ZERO(&rfds);
+ md = -1;
+ cntopen=0;
+ for (i=0; i<MAXDEVICES; i++) {
+ if (devicefile[i] > -1) {
+ FD_SET(devicefile[i], &rfds);
+ cntopen++;
+ }
+ if (devicefile[i] > md) md = devicefile[i];
+ }
+ tv.tv_sec = millisecondstowait / 1000;
+ tv.tv_usec = 1000 * (millisecondstowait % 1000);
+
+ retval = select(md+1, &rfds, NULL, NULL, &tv);
+
+ while (retval && eventsread<maxevents-2*checkXKeyboard) {
+ for (i=0; i<MAXDEVICES; i++) {
+ if (devicefile[i]>-1 && FD_ISSET(devicefile[i], &rfds)) {
+ read (devicefile[i], &je, 8);
+
+ if (je.type == JS_EVENT_AXIS && je.number<MAXAXES) {
+ if (axestatus[i][je.number] == AXESTS_ANALOG) {
+ /* this axe should be reported analog */
+ events[eventsread++] = ANALOGAXIS_EVENT(i,je.number, (je.value+32768)>>8);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ }
+ else if (je.value > maxzero[i]) {
+ if (axestatus[i][je.number] != AXESTS_PLUS &&
+ axestatus[i][je.number] != AXESTS_UNUSED) {
+
+ oldstatus = axestatus[i][je.number];
+
+ axestatus[i][je.number] = AXESTS_PLUS;
+
+ events[eventsread++] = AXISPLUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+
+ if (oldstatus == AXESTS_MINUS) {
+ events[eventsread++] = RELEASE_EVENT+AXISMINUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ }
+
+ }
+ }
+ else if (je.value < minzero[i]) {
+ if (axestatus[i][je.number] != AXESTS_MINUS &&
+ axestatus[i][je.number] != AXESTS_UNUSED) {
+
+ oldstatus = axestatus[i][je.number];
+
+ axestatus[i][je.number] = AXESTS_MINUS;
+
+ events[eventsread++] = AXISMINUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+
+ if (oldstatus == AXESTS_PLUS) {
+ events[eventsread++] = RELEASE_EVENT+AXISPLUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ }
+ }
+ }
+ else {
+ if (axestatus[i][je.number] != AXESTS_CENTER &&
+ axestatus[i][je.number] != AXESTS_UNUSED) {
+
+ oldstatus = axestatus[i][je.number];
+
+ axestatus[i][je.number] = AXESTS_CENTER;
+
+ if (oldstatus == AXESTS_PLUS) {
+ events[eventsread++] = RELEASE_EVENT+AXISPLUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ }
+ else if (oldstatus == AXESTS_MINUS) {
+ events[eventsread++] = RELEASE_EVENT+AXISMINUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ }
+ }
+ }
+ }
+ else if (je.type == JS_EVENT_BUTTON && je.number<MAXBUTTONS) {
+ events[eventsread++] = (je.value?0:RELEASE_EVENT) + BUTTON_EVENT(i,je.number);
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ }
+ }
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ retval = select(md+1, &rfds, NULL, NULL, &tv);
+ }
+
+ }
+#endif
+
+ if (checkXKeyboard) {
+ if (useGDK) {
+ while ((ge = gdk_event_get() ) != NULL ) {
+ if (ge->type == GDK_KEY_PRESS) {
+ events[eventsread++] = KEY_EVENT(ge->key.keyval);
+ if (timing) {
+ (*timing)=((GdkEventKey *)ge)->time*10;
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ }
+ else if (ge->type == GDK_KEY_RELEASE) {
+ events[eventsread++] = RELEASE_EVENT+KEY_EVENT(ge->key.keyval);
+ if (timing) {
+ (*timing)=((GdkEventKey *)ge)->time*10;
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ }
+ gdk_event_free(ge);
+ }
+ }
+ else {
+ while ((i=XPending(Dsp))) {
+ while (i--) {
+ XNextEvent(Dsp, &xe);
+ switch (xe.type) {
+ case KeyPress:
+ events[eventsread++] = KEY_EVENT(XLookupKeysym((XKeyEvent *)&xe, 0));
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ break;
+ case KeyRelease:
+ events[eventsread++] = RELEASE_EVENT+KEY_EVENT(XLookupKeysym((XKeyEvent *)&xe, 0));
+ if (timing) {
+ (*timing)=getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+ break;
+/*
+ case FocusIn:
+ XAutoRepeatOff(Dsp);
+ break;
+ case FocusOut:
+ XAutoRepeatOn(Dsp);
+ break;
+*/
+ }
+ }
+ }
+ }
+ }
+
+ return eventsread;
+}
+
+
+/*---------------------------------------------------------------------*/
+/* Config Dialogue stuff */
+/*---------------------------------------------------------------------*/
+
+// analyse Eventcode
+static PadJoyEvent *EventCode2PadJoyEvent(EventCode p_e) {
+ static PadJoyEvent event;
+ EventCode e;
+ int i,p;
+
+ event.event_type = EVENTTYPE_NONE;
+ event.pad = 0;
+ event.no = 0;
+ event.value = 0;
+
+ if (!p_e) {
+ return &event;
+ }
+
+ e = p_e;
+
+ if (e>RELEASE_EVENT) {
+ event.value = 0;
+ e -= RELEASE_EVENT;
+ }
+ else {
+ event.value = 1;
+ }
+
+ if (e && e<FIRST_JOY_EVENT) {
+ event.event_type = EVENTTYPE_KEY;
+ event.no = e;
+ return &event;
+ }
+
+ if (e >= FIRST_ANALOG_EVENT) {
+ event.event_type = EVENTTYPE_ANALOG;
+ event.pad = (e-FIRST_ANALOG_EVENT)/(256*MAXAXES);
+ event.no = (e-ANALOGAXIS_EVENT(event.pad,0,0))/256;
+ event.value = e & 0xff;
+ return &event;
+ }
+
+
+ for (p=0; p<MAXDEVICES; p++) {
+ for (i=0; i<MAXAXES; i++) {
+ if (e == AXISPLUS_EVENT(p,i)) {
+ event.event_type = EVENTTYPE_AXISPLUS;
+ event.pad = p;
+ event.no = i;
+ return &event;
+ }
+ if (e == AXISMINUS_EVENT(p,i)) {
+ event.event_type = EVENTTYPE_AXISMINUS;
+ event.pad = p;
+ event.no = i;
+ return &event;
+ }
+ }
+
+ for (i=0; i<MAXBUTTONS; i++) {
+ if (e == BUTTON_EVENT(p,i)) {
+ event.event_type = EVENTTYPE_BUTTON;
+ event.pad = p;
+ event.no = i;
+ return &event;
+ }
+ }
+ }
+
+ return &event;
+}
+
+
+
+// get the description of an Eventcode
+// this implementation is not optimized,
+// but I only need it for the configuration part so speed doesn't matter
+// should be changed to use EventCode2PadJoyEvent
+static char *eventDescription(EventCode e) {
+ static char buffer[256];
+ int i,p;
+
+ if (e && e<FIRST_JOY_EVENT) {
+ sprintf(buffer, "\"%s\"", XKeysymToString(e-FIRST_KEY_EVENT));
+ return buffer;
+ }
+
+ if (e >= FIRST_ANALOG_EVENT) {
+ p = (e-FIRST_ANALOG_EVENT)/(256*MAXAXES);
+ i = (e-ANALOGAXIS_EVENT(p,0,0))/256;
+ sprintf(buffer, "X%d", i);
+ return buffer;
+ }
+
+ for (p=0; p<MAXDEVICES; p++) {
+ for (i=0; i<MAXAXES; i++) {
+ if (e == AXISPLUS_EVENT(p,i)) {
+ sprintf(buffer, "A%d+", i);
+ return buffer;
+ }
+ if (e == AXISMINUS_EVENT(p,i)) {
+ sprintf(buffer, "A%d-", i);
+ return buffer;
+ }
+ }
+
+ for (i=0; i<MAXBUTTONS; i++) {
+ if (e == BUTTON_EVENT(p,i)) {
+ sprintf(buffer, "B%d", i);
+ return buffer;
+ }
+ }
+ }
+
+ sprintf(buffer, "???");
+ return buffer;
+}
+
+
+// get a String for each EventCode
+// more accurate than eventDescription()
+// should be changed to use EventCode2PadJoyEvent
+static char *EventCode2String(EventCode p_e) {
+ static char buffer[256];
+ int i,p,v;
+ char push_release;
+ EventCode e;
+
+ if (!p_e) {
+ sprintf(buffer, "???");
+ return buffer;
+ }
+
+ e = p_e;
+
+ if (e>RELEASE_EVENT) {
+ push_release = 'R';
+ e -= RELEASE_EVENT;
+ }
+ else {
+ push_release = 'P';
+ }
+
+ if (e && e<FIRST_JOY_EVENT) {
+ sprintf(buffer, "K%c\"%s\"", push_release, XKeysymToString(e-FIRST_KEY_EVENT));
+ return buffer;
+ }
+
+ if (e >= FIRST_ANALOG_EVENT) {
+ p = (e-FIRST_ANALOG_EVENT)/(256*MAXAXES);
+ i = (e-ANALOGAXIS_EVENT(p,0,0))/256;
+ v = e & 0xff;;
+ sprintf(buffer, "X%dP%dv%d",p, i, v);
+ return buffer;
+ }
+
+
+ for (p=0; p<MAXDEVICES; p++) {
+ for (i=0; i<MAXAXES; i++) {
+ if (e == AXISPLUS_EVENT(p,i)) {
+ sprintf(buffer, "A%d%c%d+", p, push_release, i);
+ return buffer;
+ }
+ if (e == AXISMINUS_EVENT(p,i)) {
+ sprintf(buffer, "A%d%c%d-", p, push_release, i);
+ return buffer;
+ }
+ }
+
+ for (i=0; i<MAXBUTTONS; i++) {
+ if (e == BUTTON_EVENT(p,i)) {
+ sprintf(buffer, "B%d%c%d", p, push_release, i);
+ return buffer;
+ }
+ }
+ }
+
+ sprintf(buffer, "???");
+ return buffer;
+}
+
+// reversal of EventCode2String
+static EventCode String2EventCode(char *s) {
+ static char buffer[256];
+ int i,p;
+ char *q;
+ char push_release;
+ EventCode e;
+
+ if (s[0]>='0' && s[0]<='9') return atoi(s); // allow numeric input
+
+ e=0;
+ push_release = 'P';
+
+ switch(s[0]) {
+ case 'K':
+ push_release = s[1];
+ strncpy(buffer, s+3, 255);
+ q=buffer;
+ i=1;
+ while (*q) {
+ if (*q=='"') i=!i;
+ if (*q==' ' && !i)
+ *q='\0';
+ else
+ q++;
+ }
+ if (s[2]=='"' && buffer[0] && buffer[strlen(buffer)-1]=='"') {
+ buffer[strlen(buffer)-1] = '\0';
+ e = KEY_EVENT(XStringToKeysym(buffer));
+ }
+ break;
+ case 'A':
+ if (s[1]>='0' && s[1]<='1' && strlen(s)>=5) {
+ p = s[1]-'0';
+ push_release = s[2];
+ i = atoi(s+3);
+ q=s+3;
+ while (*q && *q!='+' && *q!='-') q++;
+ if (*q=='+')
+ e = AXISPLUS_EVENT(p,i);
+ else if (*q=='-')
+ e = AXISMINUS_EVENT(p,i);
+ }
+ break;
+ case 'B':
+ if (s[1]>='0' && s[1]<='1' && strlen(s)>=4) {
+ p = s[1]-'0';
+ push_release = s[2];
+ i = atoi(s+3);
+ e = BUTTON_EVENT(p,i);
+ }
+ break;
+ case 'X':
+ if (s[1]>='0' && s[1]<='1' && strlen(s)>=5) {
+ p = s[1]-'0';
+ i = atoi(s+3);
+ q=s+3;
+ while (*q && *q!='v') q++;
+ if (*q=='v')
+ e = ANALOGAXIS_EVENT(p,i,atoi(q+1));
+ }
+ break;
+ }
+
+ if (push_release=='R')
+ return e+RELEASE_EVENT;
+ else
+ return e;
+}
+
+static void saveConfig() {
+ FILE *f;
+ int i,j,k;
+
+ f = fopen(CONFIG_FILENAME, "w");
+ if (!f) {
+ fprintf(stderr, "DFInput error: couldn't write config file!\n");
+ return;
+ }
+
+ fprintf(f,"[general]\n");
+ fprintf(f,"use_threads = %d\n", use_threads);
+ fprintf(f,"use_analog = %d\n", use_analog);
+ for (i=0;i<MAXDEVICES;i++) {
+ fprintf(f,"[pad %d]\n", i+1);
+ fprintf(f,"devicefilename = %s\n", devicefilename[i]);
+ fprintf(f,"minzero = %d\n", minzero[i]);
+ fprintf(f,"maxzero = %d\n", maxzero[i]);
+ fprintf(f,"event_l2 = %s\n", EventCode2String(PadButtons[i][0]));
+ fprintf(f,"event_r2 = %s\n", EventCode2String(PadButtons[i][1]));
+ fprintf(f,"event_l1 = %s\n", EventCode2String(PadButtons[i][2]));
+ fprintf(f,"event_r1 = %s\n", EventCode2String(PadButtons[i][3]));
+ fprintf(f,"event_triangle = %s\n", EventCode2String(PadButtons[i][4]));
+ fprintf(f,"event_circle = %s\n", EventCode2String(PadButtons[i][5]));
+ fprintf(f,"event_cross = %s\n", EventCode2String(PadButtons[i][6]));
+ fprintf(f,"event_square = %s\n", EventCode2String(PadButtons[i][7]));
+ fprintf(f,"event_select = %s\n", EventCode2String(PadButtons[i][8]));
+ fprintf(f,"event_lanalog = %s\n", EventCode2String(PadButtons[i][9]));
+ fprintf(f,"event_ranalog = %s\n", EventCode2String(PadButtons[i][10]));
+ fprintf(f,"event_start = %s\n", EventCode2String(PadButtons[i][11]));
+ fprintf(f,"event_up = %s\n", EventCode2String(PadButtons[i][12]));
+ fprintf(f,"event_right = %s\n", EventCode2String(PadButtons[i][13]));
+ fprintf(f,"event_down = %s\n", EventCode2String(PadButtons[i][14]));
+ fprintf(f,"event_left = %s\n", EventCode2String(PadButtons[i][15]));
+ fprintf(f,"event_lanax = %s\n", EventCode2String(PadButtons[i][16]));
+ fprintf(f,"event_lanay = %s\n", EventCode2String(PadButtons[i][17]));
+ fprintf(f,"event_ranax = %s\n", EventCode2String(PadButtons[i][18]));
+ fprintf(f,"event_ranay = %s\n", EventCode2String(PadButtons[i][19]));
+ for (j=0; j<MAXMACROS; j++) {
+ fprintf(f, "[macro %d]\n", j+1);
+ fprintf(f, "event_launch = %s\n", EventCode2String(macroLaunch[i][j]));
+ fprintf(f, "events =");
+ for (k=0; k<MAXMACROLENGTH && macroEvents[i][j][k]; k++) {
+ fprintf(f, " %s", EventCode2String(macroEvents[i][j][k]));
+ }
+ fprintf(f,"\n");
+ fprintf(f, "interval =");
+ for (k=0; k<MAXMACROLENGTH && macroEvents[i][j][k]; k++) {
+ fprintf(f, " %ld", macroInterval[i][j][k]);
+ }
+ fprintf(f,"\n");
+ }
+ }
+
+ fclose(f);
+}
+
+static void loadConfig() {
+ FILE *f;
+ int i;
+ char line[FILENAME_MAX+30];
+ int pad=0;
+ int macronr=0;
+ char *val;
+
+ f = fopen(CONFIG_FILENAME, "r");
+ if (!f) {
+// fprintf(stderr, "DFInput warning: config file not found.");
+ return;
+ }
+
+ while(!feof(f)) {
+ fgets(line, FILENAME_MAX+29, f);
+ i=strlen(line)-1;
+ while (i>0 && line[i]<32) line[i--]='\0';
+
+ val=NULL;
+ while(i>0) {
+ if (line[i]=='=') val = line+(i+1);
+ i--;
+ }
+ if (val) {
+ while (*val==' ') val++;
+ }
+
+ if (!strcmp(line, "[general]")) {
+ // nothing to do
+ }
+ else if (!strncmp(line, "use_threads", 11)) {
+ use_threads = atoi(val);
+ }
+ else if (!strncmp(line, "use_analog", 10)) {
+ use_analog = atoi(val);
+ }
+ else if (!strcmp(line, "[pad 1]")) {
+ pad = 0;
+ }
+ else if (!strcmp(line, "[pad 2]")) {
+ pad = 1;
+ }
+ else if (!strncmp(line, "[macro ", 7)) {
+ macronr = atoi(line+7)-1;
+ if (macronr<0 || macronr>=MAXMACROS) macronr=0;
+ }
+ else if (!strncmp(line, "devicefilename", 14)) {
+ strcpy(devicefilename[pad], val);
+ }
+ else if (!strncmp(line, "minzero", 7)) {
+ minzero[pad] = atoi(val);
+ }
+ else if (!strncmp(line, "maxzero", 7)) {
+ maxzero[pad] = atoi(val);
+ }
+ else if (!strncmp(line, "event_l2", 8)) PadButtons[pad][0] = String2EventCode(val);
+ else if (!strncmp(line, "event_r2", 8)) PadButtons[pad][1] = String2EventCode(val);
+ else if (!strncmp(line, "event_l1", 8)) PadButtons[pad][2] = String2EventCode(val);
+ else if (!strncmp(line, "event_r1", 8)) PadButtons[pad][3] = String2EventCode(val);
+ else if (!strncmp(line, "event_triangle", 14)) PadButtons[pad][4] = String2EventCode(val);
+ else if (!strncmp(line, "event_circle", 12)) PadButtons[pad][5] = String2EventCode(val);
+ else if (!strncmp(line, "event_cross", 11)) PadButtons[pad][6] = String2EventCode(val);
+ else if (!strncmp(line, "event_square", 12)) PadButtons[pad][7] = String2EventCode(val);
+ else if (!strncmp(line, "event_select", 12)) PadButtons[pad][8] = String2EventCode(val);
+ else if (!strncmp(line, "event_lanalog", 13)) PadButtons[pad][9] = String2EventCode(val);
+ else if (!strncmp(line, "event_ranalog", 13)) PadButtons[pad][10] = String2EventCode(val);
+ else if (!strncmp(line, "event_start", 11)) PadButtons[pad][11] = String2EventCode(val);
+ else if (!strncmp(line, "event_up", 8)) PadButtons[pad][12] = String2EventCode(val);
+ else if (!strncmp(line, "event_right", 11)) PadButtons[pad][13] = String2EventCode(val);
+ else if (!strncmp(line, "event_down", 10)) PadButtons[pad][14] = String2EventCode(val);
+ else if (!strncmp(line, "event_left", 10)) PadButtons[pad][15] = String2EventCode(val);
+ else if (!strncmp(line, "event_lanax", 11)) PadButtons[pad][16] = String2EventCode(val);
+ else if (!strncmp(line, "event_lanay", 11)) PadButtons[pad][17] = String2EventCode(val);
+ else if (!strncmp(line, "event_ranax", 11)) PadButtons[pad][18] = String2EventCode(val);
+ else if (!strncmp(line, "event_ranay", 11)) PadButtons[pad][19] = String2EventCode(val);
+ else if (!strncmp(line, "event_launch", 12)) macroLaunch[pad][macronr] = String2EventCode(val);
+ else if (!strncmp(line, "events", 6)) {
+ i=0;
+ while (*val) {
+ macroEvents[pad][macronr][i++]=String2EventCode(val);
+ while (*val && *val!=' ') val++;
+ if (*val==' ') val++;
+ }
+ macroEvents[pad][macronr][i]=NO_EVENT;
+ }
+ else if (!strncmp(line, "interval", 8)) {
+ i=0;
+ while (*val) {
+ macroInterval[pad][macronr][i++]=atol(val);
+ while (*val && *val!=' ') val++;
+ if (*val==' ') val++;
+ }
+ }
+// else fprintf(stderr, "DFInput error: can't interpret %s\n", line);
+ }
+}
+
+static int currentPad=0;
+
+static struct {
+ GtkWidget *config_window;
+
+/* ADB
+ GSList *padnogroup;
+ GtkWidget *padno_radio[2];*/
+ GtkWidget *filename_entry; // TODO
+ GtkWidget *button[CONFIGBUTTONCOUNT];
+ GtkWidget *label[CONFIGBUTTONCOUNT];
+/* ADB
+ GSList *pcsxgroup;
+ GtkWidget *epsxe_radio;
+ GtkWidget *pcsx_radio;
+ GtkWidget *thread_check;
+ GtkWidget *analog_check;*/
+ GtkWidget *macro_button[MAXMACROS];
+ GtkWidget *macro_label[MAXMACROS];
+ GtkWidget *macro_def_button[MAXMACROS];
+
+ GtkWidget *ok_button;
+ GtkWidget *cancel_button;
+} ConfWidgets;
+
+static struct { int nr;
+ char *label;
+ int x;
+ int y; }
+ buttonInfo[CONFIGBUTTONCOUNT] =
+{
+{0, " L2 ", 20, 30},
+{2, " L1 ", 20, 70},
+{1, " R2 ", 350, 30},
+{3, " R1 ", 350, 70},
+{12, " ^ ", 70, 110},
+{15, " < ", 20, 140},
+{13, " > ", 120, 140},
+{14, " v ", 70, 170},
+{4, " /\\ ", 300, 110},
+{7, " [_] ", 250, 140},
+{5, " (_) ", 350, 140},
+{6, " >< ", 300, 170},
+{8, " Select ", 100, 200},
+{11, " Start ", 250, 200},
+{9, " + ", 90, 280},
+{10," + ", 320, 280},
+{16," -- ", 20, 280},
+{17," | ", 70, 250},
+{18," -- ",250, 280},
+{19," | ",300, 250}
+};
+
+static void showPadConfiguration() {
+ int i;
+
+ // gtk_toggle_button_set_active(ConfWidgets.padno_radio[currentPad], TRUE);
+ // gtk_toggle_button_set_active(ConfWidgets.padno_radio[1-currentPad], FALSE);
+
+ gtk_entry_set_text ( GTK_ENTRY(ConfWidgets.filename_entry), devicefilename[currentPad] );
+
+ for (i=0; i<CONFIGBUTTONCOUNT; i++) {
+ gtk_label_set(GTK_LABEL(ConfWidgets.label[i]), eventDescription(PadButtons[currentPad][buttonInfo[i].nr]));
+ }
+
+ for (i=0; i<MAXMACROS; i++) {
+ gtk_label_set(GTK_LABEL(ConfWidgets.macro_label[i]), eventDescription(macroLaunch[currentPad][i]));
+ }
+}
+
+static void OnConfCancel(GtkWidget *widget, gpointer user_data) {
+ loadConfig();
+ gtk_widget_hide(ConfWidgets.config_window);
+ gtk_widget_destroy(ConfWidgets.config_window);
+ gtk_main_quit();
+}
+
+static void OnConfOk(GtkWidget *widget, gpointer user_data) {
+ saveConfig();
+ gtk_widget_hide(ConfWidgets.config_window);
+ gtk_widget_destroy(ConfWidgets.config_window);
+ gtk_main_quit();
+}
+
+static void OnConfBtn(GtkWidget *But, gpointer data) {
+ EventCode events[MAXCNT];
+ EventCode e=NO_EVENT;
+ int i,j,cnt;
+ KeySym ksym;
+ PadJoyEvent *pje;
+ int ok=0;
+ int labelnr = (int) gtk_object_get_user_data(GTK_OBJECT(But));
+ int btnnr = buttonInfo[labelnr].nr;
+ int e_rem1 =NO_EVENT;
+ int e_rem2 =NO_EVENT;
+
+ devicefile[currentPad] = open(devicefilename[currentPad], O_RDONLY);
+
+ if (devicefilename[currentPad][0] && devicefile[currentPad] == -1) {
+ fprintf(stderr, "DFInput: could not open device %s, errno=%d\n", devicefilename[currentPad], errno);
+ }
+
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXAXES; j++) {
+ axestatus[i][j] = AXESTS_UNKNOWN;
+ }
+ }
+
+ for (i=0; i<100 && !ok; i++) {
+ cnt = getPendingEvents(30, events, MAXCNT, 1, 1, 1, NULL);
+
+ for (j=0; j<cnt && !ok; j++) {
+ e = events[j];
+ if (e<RELEASE_EVENT) {
+ pje = EventCode2PadJoyEvent(e);
+ if (btnnr>15) {
+ if (pje->event_type == EVENTTYPE_AXISPLUS || pje->event_type == EVENTTYPE_AXISMINUS) {
+ e = ANALOGAXIS_EVENT(pje->pad, pje->no, 0);
+ PadButtons[currentPad][btnnr] = e;
+ ok = 1;
+ e_rem1 = AXISPLUS_EVENT(pje->pad, pje->no);
+ e_rem2 = AXISMINUS_EVENT(pje->pad, pje->no);
+ }
+ }
+ else if (e<FIRST_JOY_EVENT) {
+ ksym = e-FIRST_KEY_EVENT;
+ if (ksym != XK_Escape) {
+ PadButtons[currentPad][btnnr] = e;
+ ok=1;
+ }
+ }
+ else {
+ PadButtons[currentPad][btnnr] = e;
+ if (pje->event_type == EVENTTYPE_AXISPLUS || pje->event_type == EVENTTYPE_AXISMINUS) {
+ e_rem1 = ANALOGAXIS_EVENT(pje->pad, pje->no, 0);
+ }
+ ok=1;
+ }
+ }
+
+ if (!ok) {
+ fprintf(stderr, "DFInput: event %ld (%s) is not usable.\n", (long) e, EventCode2String(e));
+ }
+ }
+ }
+
+ if (!ok) {
+ fprintf(stderr, "DFInput: no usable input received.\n");
+ }
+
+ while (getPendingEvents(0, events, MAXCNT, 1, 1, 1, NULL)){} // read pending events to clear buffers
+
+ close(devicefile[currentPad]);
+ devicefile[currentPad] = -1;
+
+ if (ok) {
+ // If this event is assigned to another button, remove this assignment
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXPSXBUTTONS; j++) {
+ if ((PadButtons[i][j] == e || PadButtons[i][j] == e_rem1 || PadButtons[i][j] == e_rem2) &&
+ (i!=currentPad || j!=btnnr)) {
+ PadButtons[i][j] = NO_EVENT;
+ }
+ }
+ for (j=0; j<MAXMACROS; j++) {
+ if (macroLaunch[i][j] == e || macroLaunch[i][j] == e_rem1 || macroLaunch[i][j] == e_rem2) {
+ macroLaunch[i][j] = NO_EVENT;
+ }
+ }
+ }
+
+ showPadConfiguration();
+ }
+}
+
+static void OnMacroBtn(GtkWidget *But, gpointer data) {
+ EventCode events[MAXCNT];
+ EventCode e=NO_EVENT;
+ PadJoyEvent *pje;
+ int i,j,cnt;
+ KeySym ksym;
+ int ok=0;
+ int e_rem1 =NO_EVENT;
+
+ int macronr = (int) gtk_object_get_user_data(GTK_OBJECT(But));
+
+ devicefile[currentPad] = open(devicefilename[currentPad], O_RDONLY);
+
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXAXES; j++) {
+ axestatus[i][j] = AXESTS_UNKNOWN;
+ }
+ }
+
+ for (i=0; i<100 && !ok; i++) {
+ cnt = getPendingEvents(30, events, MAXCNT, 1, 1, 1, NULL);
+
+ for (j=0; j<cnt && !ok; j++) {
+ e = events[j];
+ if (e<RELEASE_EVENT) {
+ pje = EventCode2PadJoyEvent(e);
+ if (e<FIRST_JOY_EVENT) {
+ ksym = e-FIRST_KEY_EVENT;
+ if (ksym != XK_Escape) {
+ macroLaunch[currentPad][macronr] = e;
+ ok=1;
+ }
+ }
+ else {
+ macroLaunch[currentPad][macronr] = e;
+ ok=1;
+ if (pje->event_type == EVENTTYPE_AXISPLUS || pje->event_type == EVENTTYPE_AXISMINUS) {
+ e_rem1 = ANALOGAXIS_EVENT(pje->pad, pje->no, 0);
+ }
+ }
+ }
+ }
+ }
+ while (getPendingEvents(0, events, MAXCNT, 1, 1, 1, NULL)){} // read pending events to clear buffers
+
+ close(devicefile[currentPad]);
+ devicefile[currentPad] = -1;
+
+ if (ok) {
+ // If this event is assigned to another button, remove this assignment
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXPSXBUTTONS; j++) {
+ if (PadButtons[i][j] == e || PadButtons[i][j] == e_rem1) {
+ PadButtons[i][j] = NO_EVENT;
+ }
+ }
+ for (j=0; j<MAXMACROS; j++) {
+ if (macroLaunch[i][j] == e && (i!=currentPad || j!=macronr)) {
+ macroLaunch[i][j] = NO_EVENT;
+ }
+ }
+ }
+
+ showPadConfiguration();
+ }
+}
+
+static void OnMacroDefineBtn(GtkWidget *But, gpointer data) {
+ EventCode events[MAXCNT];
+ EventCode e=NO_EVENT;
+ PadJoyEvent *pje;
+ int i,j,cnt;
+ int ok=0;
+ long now;
+ long timing[MAXCNT];
+
+ int macronr = (int) gtk_object_get_user_data(GTK_OBJECT(But));
+
+ devicefile[currentPad] = open(devicefilename[currentPad], O_RDONLY);
+
+ now = -1;
+
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXAXES; j++) {
+ axestatus[i][j] = AXESTS_UNUSED;
+ }
+ }
+
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXPSXBUTTONS; j++) {
+ pje = EventCode2PadJoyEvent(PadButtons[i][j]);
+
+ if (pje->event_type == EVENTTYPE_AXISPLUS || pje->event_type == EVENTTYPE_AXISMINUS) {
+ axestatus[pje->pad][pje->no] = AXESTS_UNKNOWN;
+ }
+ else if (pje->event_type == EVENTTYPE_ANALOG && use_analog) {
+ axestatus[pje->pad][pje->no] = AXESTS_ANALOG;
+ }
+ }
+ }
+
+ i=0;
+
+ gtk_widget_add_events(ConfWidgets.config_window,GDK_KEY_RELEASE_MASK);
+
+ /* Listen for input events until finished (Escape is pressed) or timeout */
+ while (!ok && i<MAXMACROLENGTH-1) {
+ cnt = getPendingEvents(2000, events, MAXCNT, 1, 1, 1, timing);
+
+ if (cnt && now<0) {
+ now=timing[0];
+ }
+ else if (!cnt && i) {
+ // inactivity for 2 seconds, finish definition
+ ok=1;
+ }
+
+ for (j=0; j<cnt && !ok && i<MAXMACROLENGTH-1; j++) {
+ e = events[j];
+ if ((e-FIRST_KEY_EVENT) != XK_Escape && (e-FIRST_KEY_EVENT) != (XK_Escape+RELEASE_EVENT)) {
+ macroEvents[currentPad][macronr][i] = e;
+ macroInterval[currentPad][macronr][i] = timing[j]-now;
+ now = timing[j];
+ i++;
+ }
+ else {
+ ok=1;
+ }
+ }
+ }
+
+ if (i>0) {
+ macroEvents[currentPad][macronr][i] = NO_EVENT;
+ }
+
+ close(devicefile[currentPad]);
+ devicefile[currentPad] = -1;
+
+}
+
+static void OnThreadCheck(GtkWidget *But, gpointer data) {
+ use_threads = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(But));
+}
+
+static void OnAnalogCheck(GtkWidget *But, gpointer data) {
+ use_analog = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(But));
+}
+
+static void OnPadnoRadio(GtkWidget *But, gpointer data) {
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (But)))
+ currentPad = (int) data;
+ showPadConfiguration();
+}
+
+static void OnFilenameEntry(GtkWidget *Ent, gpointer data) {
+ strcpy(devicefilename[currentPad], gtk_entry_get_text(GTK_ENTRY(Ent)));
+}
+
+/* Closed by clicking on the top-right hand corner */
+void on_config_win_clicked (GtkWidget *widget, gpointer user_data) {
+ gtk_widget_destroy (widget);
+ gtk_main_quit();
+ exit (0);
+}
+
+static void CreateConfigWindow(void) {
+ char buffer[100];
+ int i;
+ GtkWidget *hbox;
+
+ GladeXML *xml;
+ xml = glade_xml_new (DATADIR "dfinput.glade2", "CfgWin", NULL);
+ /* ADB TODO Error checking */
+
+ GtkWidget *widget = glade_xml_get_widget (xml, "CfgWin");
+ ConfWidgets.config_window = widget;
+ GtkWidget *fixedbox = glade_xml_get_widget (xml, "fixed1");
+
+ g_signal_connect_data(GTK_OBJECT(widget), "delete_event",
+ GTK_SIGNAL_FUNC(on_config_win_clicked), NULL, NULL, G_CONNECT_AFTER);
+
+/* DELETE hbox = gtk_hbox_new(FALSE, 0);
+ gtk_fixed_put(GTK_FIXED(fixedbox), hbox, 10, 10);
+ gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Pad number:"), FALSE, TRUE, 2);*/
+
+// ConfWidgets.padnogroup = NULL;
+
+ widget = glade_xml_get_widget (xml, "radiobutton1");
+ g_signal_connect_data (GTK_OBJECT (widget), "toggled",
+ GTK_SIGNAL_FUNC (OnPadnoRadio), (gpointer) 0, NULL, G_CONNECT_AFTER);
+ widget = glade_xml_get_widget (xml, "radiobutton2");
+ g_signal_connect_data (GTK_OBJECT (widget), "toggled",
+ GTK_SIGNAL_FUNC (OnPadnoRadio), (gpointer) 1, NULL, G_CONNECT_AFTER);
+
+// hbox = gtk_hbox_new(FALSE, 0);
+// gtk_fixed_put (GTK_FIXED (fixedbox), hbox, 10, 40);
+
+// gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Device file:"), FALSE, TRUE, 2);
+ /*ConfWidgets.filename_entry = gtk_entry_new();*/
+
+ widget = glade_xml_get_widget (xml, "filename_entry");
+ gtk_entry_set_text ( GTK_ENTRY(widget), (gchar *) devicefilename[0] );
+ gtk_entry_set_max_length ( GTK_ENTRY(widget), FILENAME_MAX);
+ //gtk_box_pack_start(GTK_BOX(hbox), ConfWidgets.filename_entry, FALSE, TRUE, 2);
+ gtk_signal_connect(GTK_OBJECT(widget), "changed", GTK_SIGNAL_FUNC(OnFilenameEntry), NULL);
+ ConfWidgets.filename_entry = widget;
+
+/* TODO
+ ConfWidgets.thread_check = gtk_check_button_new_with_label("multithreaded");*/
+ widget = glade_xml_get_widget (xml, "chkMultithreaded");
+ g_signal_connect_data (GTK_OBJECT (widget), "toggled",
+ GTK_SIGNAL_FUNC (OnThreadCheck), NULL, NULL, G_CONNECT_AFTER);
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widget), use_threads);
+
+ /* TODO
+ ConfWidgets.analog_check = gtk_check_button_new_with_label("analog");*/
+ widget = glade_xml_get_widget (xml, "chkAnalog");
+ g_signal_connect_data (GTK_OBJECT (widget), "toggled",
+ GTK_SIGNAL_FUNC (OnAnalogCheck), NULL, NULL, G_CONNECT_AFTER);
+ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widget), use_analog);
+
+ // Pad Buttons
+ for (i=0; i<CONFIGBUTTONCOUNT; i++) {
+ hbox = gtk_hbox_new(FALSE, 0);
+ ConfWidgets.button[i] = gtk_button_new_with_label(buttonInfo[i].label);
+ gtk_box_pack_start(GTK_BOX(hbox), ConfWidgets.button[i], FALSE, TRUE, 2);
+ gtk_fixed_put(GTK_FIXED(fixedbox), hbox, buttonInfo[i].x, buttonInfo[i].y);
+ gtk_object_set_user_data(GTK_OBJECT(ConfWidgets.button[i]), (char *)i);
+ gtk_signal_connect(GTK_OBJECT(ConfWidgets.button[i]), "clicked", GTK_SIGNAL_FUNC(OnConfBtn), NULL);
+ ConfWidgets.label[i] = gtk_label_new(eventDescription(PadButtons[0][buttonInfo[i].nr]));
+ gtk_box_pack_start(GTK_BOX(hbox), ConfWidgets.label[i], FALSE, TRUE, 2);
+ }
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_fixed_put(GTK_FIXED(fixedbox), hbox, 20, 390);
+ // Macro Buttons
+ for (i=0; i<MAXMACROS; i++) {
+ sprintf(buffer, "M%d", i+1);
+ ConfWidgets.macro_button[i] = gtk_button_new_with_label(buffer);
+ gtk_box_pack_start(GTK_BOX(hbox), ConfWidgets.macro_button[i], FALSE, TRUE, 2);
+ gtk_object_set_user_data(GTK_OBJECT(ConfWidgets.macro_button[i]), (char *)i);
+ gtk_signal_connect(GTK_OBJECT(ConfWidgets.macro_button[i]), "clicked", GTK_SIGNAL_FUNC(OnMacroBtn), NULL);
+ ConfWidgets.macro_label[i] = gtk_label_new(eventDescription(macroLaunch[0][i]));
+ gtk_box_pack_start(GTK_BOX(hbox), ConfWidgets.macro_label[i], FALSE, TRUE, 2);
+ ConfWidgets.macro_def_button[i] = gtk_button_new_with_label("Def");
+ gtk_box_pack_start(GTK_BOX(hbox), ConfWidgets.macro_def_button[i], FALSE, TRUE, 2);
+ gtk_object_set_user_data(GTK_OBJECT(ConfWidgets.macro_def_button[i]), (char *)i);
+ gtk_signal_connect(GTK_OBJECT(ConfWidgets.macro_def_button[i]), "clicked", GTK_SIGNAL_FUNC(OnMacroDefineBtn), NULL);
+ if (i<MAXMACROS-1) {
+ gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(" "), FALSE, TRUE, 2);
+ }
+ }
+
+ gtk_widget_show_all (GTK_WIDGET (fixedbox));
+
+ widget = glade_xml_get_widget (xml, "btnOK");
+ g_signal_connect_data (GTK_OBJECT (widget), "clicked", GTK_SIGNAL_FUNC (OnConfOk), NULL, NULL, G_CONNECT_AFTER);
+
+ widget = glade_xml_get_widget (xml, "btnCancel");
+ g_signal_connect_data (GTK_OBJECT (widget), "clicked", GTK_SIGNAL_FUNC (OnConfCancel), NULL, NULL, G_CONNECT_AFTER);
+}
+
+long PADconfigure(void) {
+ currentPad = 0;
+ initPadtime();
+ PADinit(0);
+ CreateConfigWindow();
+ gtk_widget_show_all(ConfWidgets.config_window);
+
+ gtk_main();
+
+ return 0;
+}
+
+
+/*---------------------------------------------------------------------*/
+/* About dialogue stuff */
+/*---------------------------------------------------------------------*/
+
+void PADabout(void) {
+ GladeXML *xml;
+ xml = glade_xml_new (DATADIR "dfinput.glade2", "AboutWin", NULL);
+
+ GtkWidget *widget = glade_xml_get_widget (xml, "AboutWin");
+
+ /* TODO Authors, about, version */
+
+ gtk_dialog_run (GTK_DIALOG (widget));
+ gtk_widget_destroy (widget);
+// gtk_main_quit();
+}
+
+/*---------------------------------------------------------------------*/
+/* Main program */
+/*---------------------------------------------------------------------*/
+
+int main(int argc, char **argv) {
+ gtk_set_locale();
+ gtk_init (&argc, &argv);
+
+ if (argc>1 && !strcmp(argv[1], "-about")) {
+ PADabout();
+ }
+ else {
+ PADconfigure();
+ }
+
+ gtk_exit (0);
+
+ return 0;
+}
diff --git a/plugins/dfinput/dfinput.glade2 b/plugins/dfinput/dfinput.glade2
new file mode 100644
index 00000000..b6905f2e
--- /dev/null
+++ b/plugins/dfinput/dfinput.glade2
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
+<glade-interface>
+ <widget class="GtkWindow" id="CfgWin">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Configure Gamepad/Keyboard</property>
+ <property name="modal">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">50</property>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Pad number:</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="radiobutton1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">1</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="radiobutton2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">2</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton1</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Device file:</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="filename_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">*</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkMultithreaded">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Multi-threaded</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkAnalog">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Analog</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="frame1">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="bottom_padding">5</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">12</property>
+ <child>
+ <widget class="GtkFixed" id="fixed1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Button Configuration&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="btnCancel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="btnOK">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkAboutDialog" id="AboutWin">
+ <property name="visible">True</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="comments" translatable="yes">Based on PadJoy by Erich Kitzmüller (ammoq@ammoq.com)</property>
+ <property name="authors">Erich Kitzmüller (ammoq@ammoq.com)
+Andrew Burton (adb@iinet.net.au)</property>
+ <property name="translator_credits" translatable="yes" comments="TRANSLATORS: Replace this string with your names, one name per line.">translator-credits</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/plugins/dfinput/pad.c b/plugins/dfinput/pad.c
new file mode 100644
index 00000000..dd564479
--- /dev/null
+++ b/plugins/dfinput/pad.c
@@ -0,0 +1,989 @@
+/*
+ * Pad for Psemu Pro like Emulators
+ * This is the plugin
+ *
+ * Modified for PCSX-df by Ryan Schultz
+ *
+ * Written by Erich Kitzmuller <ammoq@ammoq.com>
+ * Based on padXwin by linuzappz <linuzappz@hotmail.com>
+ *
+ * Copyright 2002,2003 by Erich Kitzmuller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#ifdef __linux__
+#include <linux/joystick.h>
+#endif
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/XKBlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include "padjoy.h"
+
+#ifdef __linux__
+char *LibName = "Gamepad/Keyboard Input";
+#else
+char *LibName = "Keyboard Input";
+#endif
+
+const unsigned char version = VERSION;
+const unsigned char revision = REVISION;
+const unsigned char build = BUILD;
+
+// Prototypes
+static void loadConfig();
+static void *thread_check_joydevice(void *arg);
+static void initPadtime();
+static PadJoyEvent *EventCode2PadJoyEvent(EventCode p_e);
+
+// Filenames for device files, e.g. "/dev/input/js0"
+static char devicefilename[MAXDEVICES][FILENAME_MAX+1] = {"/dev/input/js0", "/dev/input/js1"};
+
+// File desciptors for device files
+static int devicefile[MAXDEVICES] = { -1, -1 };
+
+// Use Threading for joy device input?
+static int use_threads = 1;
+static pthread_t joy_thread;
+static int die_thread_die = 0;
+
+// Emulate Dualshock(TM) analog pad?
+static int use_analog = 0;
+
+// any joydevice open?
+static int joydevice_open = 0;
+
+// initialisation already done?
+static int init_done = 0;
+
+// calibration data
+int minzero[MAXAXES];
+int maxzero[MAXAXES];
+
+// axes status - so only changing status are reported
+int axestatus[MAXDEVICES][MAXAXES];
+
+// Assignment of PSX buttons to Events
+static EventCode PadButtons[MAXDEVICES][MAXPSXBUTTONS] =
+{
+ {
+ KEY_EVENT(XK_e), // L2
+ KEY_EVENT(XK_t), // R2
+ KEY_EVENT(XK_w), // L1
+ KEY_EVENT(XK_r), // R1
+ KEY_EVENT(XK_d), // Triangle
+ KEY_EVENT(XK_x), // Circle
+ KEY_EVENT(XK_z), // Cross
+ KEY_EVENT(XK_s), // Square
+ KEY_EVENT(XK_c), // Select
+ NO_EVENT, // Left Analog
+ NO_EVENT, // Right Analog
+ KEY_EVENT(XK_v), // Start
+ KEY_EVENT(XK_Up), // Up
+ KEY_EVENT(XK_Right), // Right
+ KEY_EVENT(XK_Down), // Down
+ KEY_EVENT(XK_Left), // Left
+ NO_EVENT, // Left Analog X
+ NO_EVENT, // Left Analog Y
+ NO_EVENT, // Right Analog X
+ NO_EVENT // Right Analog Y
+ },
+ {
+ NO_EVENT, // L2
+ NO_EVENT, // R2
+ NO_EVENT, // L1
+ NO_EVENT, // R1
+ NO_EVENT, // Triangle
+ NO_EVENT, // Circle
+ NO_EVENT, // Cross
+ NO_EVENT, // Square
+ NO_EVENT, // Select
+ NO_EVENT, // Left Analog
+ NO_EVENT, // Right Analog
+ NO_EVENT, // Start
+ NO_EVENT, // Up
+ NO_EVENT, // Right
+ NO_EVENT, // Down
+ NO_EVENT, // Left
+ NO_EVENT, // Left Analog X
+ NO_EVENT, // Left Analog Y
+ NO_EVENT, // Right Analog X
+ NO_EVENT // Right Analog Y
+ }
+};
+
+static Display *Dsp;
+static Atom wmprotocols, wmdelwindow;
+
+static EventCode macroLaunch[MAXDEVICES][MAXMACROS];
+static EventCode macroEvents[MAXDEVICES][MAXMACROS][MAXMACROLENGTH];
+static long macroInterval[MAXDEVICES][MAXMACROS][MAXMACROLENGTH];
+static int macroActive[MAXDEVICES];
+static int macroIndex[MAXDEVICES];
+static long macroNext[MAXDEVICES];
+
+unsigned short PadStat[MAXDEVICES] = {0xffff, 0xffff};
+
+int AnalogValue[MAXDEVICES][MAXPSXBUTTONS-4] = {{127,127,127,127}, {127,127,127,127}};
+
+char *PSEgetLibName(void) {
+ return LibName;
+}
+
+uint32_t PSEgetLibType(void) {
+ return 8; // PSE_LT_PAD
+}
+
+uint32_t PSEgetLibVersion(void) {
+ return version<<16|revision<<8|build;
+}
+
+void init_macros() {
+ int i,j;
+
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j=0; j<MAXMACROS; j++) {
+ macroLaunch[i][j] = NO_EVENT;
+ macroEvents[i][j][0] = NO_EVENT;
+ macroInterval[i][j][0] = 0;
+ }
+ macroActive[i] = -1;
+ macroIndex[i] = 0;
+ macroNext[i] = 0;
+ }
+}
+
+long PADinit(long flags) {
+ int i,j;
+
+ init_macros();
+ initPadtime();
+ for (i = 0; i < MAXDEVICES; i++) {
+ maxzero[i] = 250;
+ minzero[i] = -250;
+
+ for (j = 0; j < MAXAXES; j++) {
+ axestatus[i][j] = AXESTS_UNKNOWN;
+ }
+ }
+ loadConfig();
+
+ return 0;
+}
+
+long PADshutdown(void) {
+ return 0;
+}
+
+long PADopen(unsigned long *Disp) {
+ int i,j;
+ int res;
+ PadJoyEvent *pje;
+
+ if (init_done) {
+// fprintf(stderr, "DFInput warning: device already initialized.\n");
+ return 0;
+ }
+
+ Dsp = (Display *)*Disp;
+ XkbSetDetectableAutoRepeat(Dsp, 1, NULL);
+
+ // TODO: find a way to grab the window, and set protocol WM_DELETE_WINDOW if not already set by the video plugin
+ wmprotocols = XInternAtom(Dsp,"WM_PROTOCOLS",0);
+ wmdelwindow = XInternAtom(Dsp,"WM_DELETE_WINDOW",0);
+ //XSetWMProtocols(Dsp, window, &wmdelwindow, 1); //need window!
+
+ joydevice_open = 0;
+
+#ifdef __linux__
+ for (i = 0; i < MAXDEVICES; i++) {
+ if (devicefilename[i][0]) {
+ devicefile[i] = open(devicefilename[i], O_RDONLY);
+ if (devicefile[i] == -1) {
+ fprintf(stderr, "DFInput error: could not open device %s!\n", devicefilename[i]);
+ }
+ else {
+ joydevice_open = 1;
+ }
+ }
+ else {
+ devicefile [i] = -1;
+ }
+ }
+#endif
+
+ for (i = 0; i < MAXDEVICES; i++) {
+ for (j = 0; j < MAXAXES; j++) {
+ axestatus[i][j] = AXESTS_UNUSED;
+ }
+ }
+
+ for (i=0; i<MAXDEVICES; i++) {
+ for (j = 0; j < MAXPSXBUTTONS; j++) {
+ pje = EventCode2PadJoyEvent(PadButtons[i][j]);
+
+ if (pje->event_type == EVENTTYPE_AXISPLUS || pje->event_type == EVENTTYPE_AXISMINUS) {
+ axestatus[pje->pad][pje->no] = AXESTS_UNKNOWN;
+ }
+#ifdef __linux__
+ else if (pje->event_type == EVENTTYPE_ANALOG && use_analog) {
+ axestatus[pje->pad][pje->no] = AXESTS_ANALOG;
+ }
+#endif
+ }
+ }
+
+#ifdef __linux__
+ if (use_threads) {
+ die_thread_die = 0;
+ if (joydevice_open) {
+ fprintf(stderr, "DFInput: starting thread...\n");
+ sleep(1);
+ res = pthread_create(&joy_thread, NULL, thread_check_joydevice, (void *) NULL);
+
+ if (res!=0) {
+ fprintf(stderr, "DFInput warning: thread failure, switching to polling!\n");
+ use_threads = 0;
+ }
+ }
+ }
+#endif
+
+ init_done = 1;
+
+ return 0;
+}
+
+long PADclose(void) {
+ int i;
+
+#ifdef __linux__
+ for (i=0; i<2; i++) {
+ if (devicefile[i] > -1) {
+ close (devicefile[i]);
+ }
+ }
+
+ if (use_threads) {
+ die_thread_die = 1;
+ if (joydevice_open) {
+ pthread_join(joy_thread, (void **) NULL);
+ }
+ }
+#endif
+
+ init_done=0;
+
+ XAutoRepeatOn(Dsp);
+
+ return 0;
+}
+
+long PADquery(void) {
+ return 3; // both pads
+}
+
+static long firstsecond = 0;
+
+static void initPadtime() {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ firstsecond = tv.tv_sec;
+}
+
+// construct a time on our own
+long getPadtime() {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (tv.tv_sec-firstsecond)*10000+tv.tv_usec/100;
+}
+
+// get pending events
+static int getPendingEvents(int millisecondstowait, EventCode *events, int maxevents, int checkJoydevice, int checkXKeyboard, long *timing) {
+ fd_set rfds;
+ int retval;
+ int i;
+ int md;
+ int eventsread=0;
+ XEvent xe;
+ XClientMessageEvent *xce;
+ int cntopen;
+ struct timeval tv;
+ int oldstatus;
+
+#ifdef __linux__
+ struct js_event je;
+
+ if (checkJoydevice) {
+ FD_ZERO(&rfds);
+ md = -1;
+ cntopen=0;
+ for (i=0; i<MAXDEVICES; i++) {
+ if (devicefile[i] > -1) {
+ FD_SET(devicefile[i], &rfds);
+ cntopen++;
+ }
+ if (devicefile[i] > md) md = devicefile[i];
+ }
+ tv.tv_sec = millisecondstowait / 1000;
+ tv.tv_usec = 1000 * (millisecondstowait % 1000);
+
+ retval = select(md + 1, &rfds, NULL, NULL, &tv);
+
+ while (retval && eventsread < maxevents - 2 * checkXKeyboard) {
+ for (i = 0; i < MAXDEVICES; i++) {
+ if (devicefile[i] > -1 && FD_ISSET(devicefile[i], &rfds)) {
+ read (devicefile[i], &je, 8);
+
+ if (je.type == JS_EVENT_AXIS && je.number < MAXAXES) {
+ if (axestatus[i][je.number] == AXESTS_ANALOG) {
+ /* this axe should be reported analog */
+ events[eventsread++] = ANALOGAXIS_EVENT(i,je.number, (je.value + 32768) >> 8);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+
+ }
+ else if (je.value > maxzero[i]) {
+ if (axestatus[i][je.number] != AXESTS_PLUS &&
+ axestatus[i][je.number] != AXESTS_UNUSED) {
+
+ oldstatus = axestatus[i][je.number];
+
+ axestatus[i][je.number] = AXESTS_PLUS;
+
+ events[eventsread++] = AXISPLUS_EVENT(i, je.number);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread==maxevents) return eventsread;
+
+ if (oldstatus == AXESTS_MINUS) {
+ events[eventsread++] = RELEASE_EVENT + AXISMINUS_EVENT(i, je.number);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ }
+
+ }
+ }
+ else if (je.value < minzero[i]) {
+ if (axestatus[i][je.number] != AXESTS_MINUS &&
+ axestatus[i][je.number] != AXESTS_UNUSED) {
+
+ oldstatus = axestatus[i][je.number];
+
+ axestatus[i][je.number] = AXESTS_MINUS;
+
+ events[eventsread++] = AXISMINUS_EVENT(i, je.number);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+
+ if (oldstatus == AXESTS_PLUS) {
+ events[eventsread++] = RELEASE_EVENT+AXISPLUS_EVENT(i, je.number);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ }
+ }
+ }
+ else {
+ if (axestatus[i][je.number] != AXESTS_CENTER &&
+ axestatus[i][je.number] != AXESTS_UNUSED) {
+
+ oldstatus = axestatus[i][je.number];
+
+ axestatus[i][je.number] = AXESTS_CENTER;
+
+ if (oldstatus == AXESTS_PLUS) {
+ events[eventsread++] = RELEASE_EVENT+AXISPLUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ }
+ else if (oldstatus == AXESTS_MINUS) {
+ events[eventsread++] = RELEASE_EVENT+AXISMINUS_EVENT(i,je.number);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ }
+ }
+ }
+ }
+ else if (je.type == JS_EVENT_BUTTON && je.number<MAXBUTTONS) {
+ events[eventsread++] = (je.value ? 0 : RELEASE_EVENT) + BUTTON_EVENT(i, je.number);
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ }
+ }
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ retval = select(md + 1, &rfds, NULL, NULL, &tv);
+ }
+
+ }
+#endif
+
+ if (checkXKeyboard) {
+ while ((i = XPending(Dsp))) {
+ while (i--) {
+ XNextEvent(Dsp, &xe);
+ switch (xe.type) {
+ case KeyPress:
+ events[eventsread++] = KEY_EVENT(XLookupKeysym((XKeyEvent *)&xe, 0));
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ break;
+ case KeyRelease:
+ events[eventsread++] = RELEASE_EVENT + KEY_EVENT(XLookupKeysym((XKeyEvent *)&xe, 0));
+ if (timing) {
+ (*timing) = getPadtime();
+ timing++;
+ }
+ if (eventsread == maxevents) return eventsread;
+ break;
+ case ClientMessage:
+ xce = (XClientMessageEvent *)&xe;
+ if (xce->message_type == wmprotocols && (Atom)xce->data.l[0] == wmdelwindow) {
+ events[eventsread++] = KEY_EVENT(XK_Escape);
+ if (eventsread == maxevents) return eventsread;
+ }
+ break;
+/*
+ case FocusIn:
+ XAutoRepeatOff(Dsp);
+ break;
+ case FocusOut:
+ XAutoRepeatOn(Dsp);
+ break;
+*/
+ }
+ }
+ }
+ }
+
+ return eventsread;
+}
+
+// Key Event not used...
+static EventCode keyLeftOver = NO_EVENT;
+
+static void CheckPads(int checkJoydevice, int checkXKeyboard, int blocking) {
+ EventCode events[MAXCNT];
+ int cnt;
+ int release;
+ EventCode e;
+ int i,j,k,l;
+ int notfound;
+ long now;
+ int v;
+
+ if (checkJoydevice || checkXKeyboard) {
+ cnt = getPendingEvents(blocking<<8, events, MAXCNT, checkJoydevice, checkXKeyboard, NULL);
+ }
+ else {
+ cnt = 0;
+ }
+
+ // more events come from the macros
+ // only process makros when blocking is not set, since
+ // this cannot be done by the joy device thread
+
+ if (!blocking) {
+ now= -1;
+ for (j = 0; j < MAXDEVICES; j++) {
+ if (macroActive[j] > -1) {
+ if (now < 0) {
+ now = getPadtime();
+ }
+
+ while (now >= macroNext[j] && cnt < MAXCNT && macroActive[j] > -1) {
+ events[cnt++]=macroEvents[j][macroActive[j]][macroIndex[j]];
+ macroIndex[j]++;
+ if (macroIndex[j] == MAXMACROLENGTH || macroEvents[j][macroActive[j]][macroIndex[j]] == NO_EVENT) {
+ macroActive[j] = -1;
+ }
+ else {
+ macroNext[j] += macroInterval[j][macroActive[j]][macroIndex[j]];
+ }
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < cnt; i++) {
+ e = events[i];
+ if (e >= RELEASE_EVENT) {
+ release = 1;
+ e -= RELEASE_EVENT;
+ }
+ else {
+ release = 0;
+ }
+
+ notfound = 1;
+ if (e >= FIRST_ANALOG_EVENT) {
+ v = e & 0xff;
+ e -= v;
+ for (j = 0; j < MAXDEVICES && notfound; j++) {
+ for (k = 16; k < MAXPSXBUTTONS && notfound; k++) {
+ if (PadButtons[j][k] == e) {
+ AnalogValue[j][k - 16] = v;
+ notfound = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (j=0; j<MAXDEVICES && notfound; j++) {
+ for (k=0; k<MAXPSXBUTTONS && notfound; k++) {
+ if (PadButtons[j][k] == e) {
+ notfound = 0;
+ if (release) {
+ PadStat[j]|=(1<<k);
+ }
+ else {
+ PadStat[j]&=~(1<<k);
+ }
+ }
+ }
+ for (k=0; k<MAXMACROS && notfound; k++) {
+ if (macroLaunch[j][k] == e) {
+ notfound=0;
+ if (release) {
+ // release all buttons pressed by the macro
+ for (l=macroIndex[j]; l<MAXMACROLENGTH && macroEvents[j][macroActive[j]][l] != NO_EVENT; l++) {
+ if (macroEvents[j][macroActive[j]][l] >= RELEASE_EVENT) {
+ if (cnt<MAXCNT) {
+ events[cnt++]=macroEvents[j][macroActive[j]][l];
+ }
+ }
+
+ }
+
+ macroActive[j]= -1; // stop Makro from running
+ }
+ else {
+ macroActive[j]=k;
+ macroIndex[j]=0;
+ macroNext[j]=getPadtime();
+ }
+ }
+ }
+ }
+ }
+ if (notfound && e < FIRST_JOY_EVENT) {
+ keyLeftOver = e + (release << 30);
+ }
+ }
+}
+
+
+long PADreadPort1(PadDataS *pad) {
+ if (!use_threads) {
+ CheckPads(joydevice_open, 1, 0);
+ }
+ else {
+ CheckPads(0, 1, 0);
+ }
+
+ pad->buttonStatus = PadStat[0];
+#ifdef __linux__
+ if (use_analog) {
+ pad->controllerType = 7; // analog Pad
+ pad->leftJoyX = AnalogValue[0][0];
+ pad->leftJoyY = AnalogValue[0][1];
+ pad->rightJoyX = AnalogValue[0][2];
+ pad->rightJoyY = AnalogValue[0][3];
+ }
+ else {
+#endif
+ pad->controllerType = 4; // standard
+#ifdef __linux__
+ }
+#endif
+ // ePSXe different from pcsx, swap bytes
+ pad->buttonStatus = (pad->buttonStatus>>8)|(pad->buttonStatus<<8);
+
+ return 0;
+}
+
+long PADreadPort2(PadDataS *pad) {
+ if (!use_threads) {
+ CheckPads(joydevice_open, 1, 0);
+ }
+ else {
+ CheckPads(0, 1, 0);
+ }
+
+ pad->buttonStatus = PadStat[1];
+#ifdef __linux__
+ if (use_analog) {
+ pad->controllerType = 7; // analog Pad
+ pad->leftJoyX = AnalogValue[1][0];
+ pad->leftJoyY = AnalogValue[1][1];
+ pad->rightJoyX = AnalogValue[1][2];
+ pad->rightJoyY = AnalogValue[1][3];
+ }
+ else {
+#endif
+ pad->controllerType = 4; // standard
+#ifdef __linux__
+ }
+#endif
+
+ // ePSXe different from pcsx, swap bytes
+ pad->buttonStatus = (pad->buttonStatus>>8)|(pad->buttonStatus<<8);
+
+ return 0;
+}
+
+long PADkeypressed(void) {
+ int ksym;
+
+ CheckPads(0, 1, 1);
+
+ if (keyLeftOver == NO_EVENT) return 0;
+
+ ksym = keyLeftOver-FIRST_KEY_EVENT;
+ keyLeftOver = NO_EVENT;
+
+ return ksym;
+}
+
+#ifdef __linux__
+
+static void *thread_check_joydevice(void *arg) {
+ while (!die_thread_die) {
+ CheckPads(1, 0, 1);
+ }
+ return NULL;
+}
+
+#endif
+
+// analyse Eventcode
+static PadJoyEvent *EventCode2PadJoyEvent(EventCode p_e) {
+ static PadJoyEvent event;
+ EventCode e;
+ int i,p;
+
+ event.event_type = EVENTTYPE_NONE;
+ event.pad = 0;
+ event.no = 0;
+ event.value = 0;
+
+ if (!p_e) {
+ return &event;
+ }
+
+ e = p_e;
+
+ if (e > RELEASE_EVENT) {
+ event.value = 0;
+ e -= RELEASE_EVENT;
+ }
+ else {
+ event.value = 1;
+ }
+
+ if (e && e<FIRST_JOY_EVENT) {
+ event.event_type = EVENTTYPE_KEY;
+ event.no = e;
+ return &event;
+ }
+
+ if (e >= FIRST_ANALOG_EVENT) {
+ event.event_type = EVENTTYPE_ANALOG;
+ event.pad = (e-FIRST_ANALOG_EVENT)/(256*MAXAXES);
+ event.no = (e-ANALOGAXIS_EVENT(event.pad,0,0))/256;
+ event.value = e & 0xff;
+ return &event;
+ }
+
+
+ for (p=0; p<MAXDEVICES; p++) {
+ for (i=0; i<MAXAXES; i++) {
+ if (e == AXISPLUS_EVENT(p,i)) {
+ event.event_type = EVENTTYPE_AXISPLUS;
+ event.pad = p;
+ event.no = i;
+ return &event;
+ }
+ if (e == AXISMINUS_EVENT(p,i)) {
+ event.event_type = EVENTTYPE_AXISMINUS;
+ event.pad = p;
+ event.no = i;
+ return &event;
+ }
+ }
+
+ for (i=0; i<MAXBUTTONS; i++) {
+ if (e == BUTTON_EVENT(p,i)) {
+ event.event_type = EVENTTYPE_BUTTON;
+ event.pad = p;
+ event.no = i;
+ return &event;
+ }
+ }
+ }
+
+ return &event;
+}
+
+
+// reversal of EventCode2String
+static EventCode String2EventCode(char *s) {
+ static char buffer[256];
+ int i,p;
+ char *q;
+ char push_release;
+ EventCode e;
+
+ if (s[0] >= '0' && s[0] <= '9') return atoi(s); // allow numeric input
+
+ e=0;
+ push_release = 'P';
+
+ switch(s[0]) {
+ case 'K':
+ push_release = s[1];
+ strncpy(buffer, s + 3, 255);
+ q=buffer;
+ i=1;
+ while (*q) {
+ if (*q=='"') i = !i;
+ if (*q==' ' && !i)
+ *q='\0';
+ else
+ q++;
+ }
+ if (s[2]=='"' && buffer[0] && buffer[strlen(buffer)-1]=='"') {
+ buffer[strlen(buffer)-1] = '\0';
+ e = KEY_EVENT(XStringToKeysym(buffer));
+ }
+ break;
+ case 'A':
+ if (s[1] >= '0' && s[1] <= '1' && strlen(s) >= 5) {
+ p = s[1] - '0';
+ push_release = s[2];
+ i = atoi(s+3);
+ q=s+3;
+ while (*q && *q != '+' && *q != '-') q++;
+ if (*q == '+')
+ e = AXISPLUS_EVENT(p,i);
+ else if (*q == '-')
+ e = AXISMINUS_EVENT(p,i);
+ }
+ break;
+ case 'B':
+ if (s[1] >= '0' && s[1] <= '1' && strlen(s) >= 4) {
+ p = s[1] - '0';
+ push_release = s[2];
+ i = atoi(s + 3);
+ e = BUTTON_EVENT(p, i);
+ }
+ break;
+ case 'X':
+ if (s[1] >= '0' && s[1] <= '1' && strlen(s) >= 5) {
+ p = s[1] - '0';
+ i = atoi(s + 3);
+ q = s + 3;
+ while (*q && *q != 'v') q++;
+ if (*q == 'v')
+ e = ANALOGAXIS_EVENT(p,i,atoi(q + 1));
+ }
+ break;
+ }
+
+ if (push_release == 'R')
+ return e + RELEASE_EVENT;
+ else
+ return e;
+}
+
+static void loadConfig() {
+ FILE *f;
+ int i;
+ char line[FILENAME_MAX+30];
+ int pad=0;
+ int macronr=0;
+ char *val;
+
+ f = fopen("dfinput.cfg", "r");
+ if (f == NULL) {
+// fprintf(stderr, "DFInput warning: config file not found.\n");
+ return;
+ }
+
+ while(!feof(f)) {
+ fgets(line, FILENAME_MAX+29, f);
+ i=strlen(line)-1;
+ while (i>0 && line[i]<32) line[i--]='\0';
+
+ val=NULL;
+ while(i>0) {
+ if (line[i]=='=') val = line+(i+1);
+ i--;
+ }
+ if (val) {
+ while (*val==' ') val++;
+ }
+
+ if (!strcmp(line, "[general]")) {
+ // nothing to do
+ }
+ else if (!strncmp(line, "use_threads", 11)) {
+ use_threads = atoi(val);
+ }
+ else if (!strncmp(line, "use_analog", 10)) {
+ use_analog = atoi(val);
+ }
+
+ else if (!strcmp(line, "[pad 1]")) {
+ pad = 0;
+ }
+ else if (!strcmp(line, "[pad 2]")) {
+ pad = 1;
+ }
+ else if (!strncmp(line, "[macro ", 7)) {
+ macronr = atoi(line+7)-1;
+ if (macronr<0 || macronr>=MAXMACROS) macronr=0;
+ }
+ else if (!strncmp(line, "devicefilename", 14)) {
+ strcpy(devicefilename[pad], val);
+ }
+ else if (!strncmp(line, "minzero", 7)) {
+ minzero[pad] = atoi(val);
+ }
+ else if (!strncmp(line, "maxzero", 7)) {
+ maxzero[pad] = atoi(val);
+ }
+ else if (!strncmp(line, "event_l2", 8)) PadButtons[pad][0] = String2EventCode(val);
+ else if (!strncmp(line, "event_r2", 8)) PadButtons[pad][1] = String2EventCode(val);
+ else if (!strncmp(line, "event_l1", 8)) PadButtons[pad][2] = String2EventCode(val);
+ else if (!strncmp(line, "event_r1", 8)) PadButtons[pad][3] = String2EventCode(val);
+ else if (!strncmp(line, "event_triangle", 14)) PadButtons[pad][4] = String2EventCode(val);
+ else if (!strncmp(line, "event_circle", 12)) PadButtons[pad][5] = String2EventCode(val);
+ else if (!strncmp(line, "event_cross", 11)) PadButtons[pad][6] = String2EventCode(val);
+ else if (!strncmp(line, "event_square", 12)) PadButtons[pad][7] = String2EventCode(val);
+ else if (!strncmp(line, "event_select", 12)) PadButtons[pad][8] = String2EventCode(val);
+ else if (!strncmp(line, "event_lanalog", 13)) PadButtons[pad][9] = String2EventCode(val);
+ else if (!strncmp(line, "event_ranalog", 13)) PadButtons[pad][10] = String2EventCode(val);
+ else if (!strncmp(line, "event_start", 11)) PadButtons[pad][11] = String2EventCode(val);
+ else if (!strncmp(line, "event_up", 8)) PadButtons[pad][12] = String2EventCode(val);
+ else if (!strncmp(line, "event_right", 11)) PadButtons[pad][13] = String2EventCode(val);
+ else if (!strncmp(line, "event_down", 10)) PadButtons[pad][14] = String2EventCode(val);
+ else if (!strncmp(line, "event_left", 10)) PadButtons[pad][15] = String2EventCode(val);
+ else if (!strncmp(line, "event_lanax", 11)) PadButtons[pad][16] = String2EventCode(val);
+ else if (!strncmp(line, "event_lanay", 11)) PadButtons[pad][17] = String2EventCode(val);
+ else if (!strncmp(line, "event_ranax", 11)) PadButtons[pad][18] = String2EventCode(val);
+ else if (!strncmp(line, "event_ranay", 11)) PadButtons[pad][19] = String2EventCode(val);
+ else if (!strncmp(line, "event_launch", 12)) macroLaunch[pad][macronr] = String2EventCode(val);
+ else if (!strncmp(line, "events", 6)) {
+ i=0;
+ while (*val) {
+ macroEvents[pad][macronr][i++]=String2EventCode(val);
+ while (*val && *val!=' ') val++;
+ if (*val==' ') val++;
+ }
+ macroEvents[pad][macronr][i]=NO_EVENT;
+ }
+ else if (!strncmp(line, "interval", 8)) {
+ i=0;
+ while (*val) {
+ macroInterval[pad][macronr][i++]=atol(val);
+ while (*val && *val!=' ') val++;
+ if (*val==' ') val++;
+ }
+ }
+// else fprintf(stderr, "DFInput error: can't interpret %s\n", line);
+ }
+}
+
+long PADconfigure(void) {
+ system("cfg/cfgDFInput");
+ return 0;
+}
+
+
+/*---------------------------------------------------------------------*/
+/* About dialogue stuff */
+/*---------------------------------------------------------------------*/
+
+
+void PADabout(void) {
+ system("cfg/cfgDFInput -about");
+}
+
+#ifdef __linux__
+
+long PADtest(void) {
+ int i;
+ int f;
+
+ int r=1;
+
+ loadConfig();
+ for (i=0; i<2; i++) {
+ if (devicefilename[i][0]) {
+ r = 0;
+ f = open(devicefilename[i], O_RDONLY);
+ if (f == -1) {
+ return -1;
+ }
+ close (f);
+ }
+ }
+
+ return r;
+}
+
+#endif
diff --git a/plugins/dfinput/padjoy.h b/plugins/dfinput/padjoy.h
new file mode 100644
index 00000000..e51f2db4
--- /dev/null
+++ b/plugins/dfinput/padjoy.h
@@ -0,0 +1,82 @@
+#ifndef _PADJOY_H_
+
+#define _PADJOY_H_
+
+#define DEBUG(x) fprintf(stderr, "DFInput: %s\n", x);
+
+// Maximum number of joy devices
+#define MAXDEVICES 2
+// Maximum number of supported axis (per device, a normal joystick has 2)
+#define MAXAXES 20
+// Maximum number of supported buttons (per device)
+#define MAXBUTTONS 32
+// Number of PSX-Buttons (including analog axis)
+#define MAXPSXBUTTONS 20
+
+// Status of digital Axes (avoids repeated events of the same type on an analog pad)
+#define AXESTS_UNUSED -1
+#define AXESTS_UNKNOWN 0
+#define AXESTS_CENTER 1
+#define AXESTS_PLUS 2
+#define AXESTS_MINUS 3
+#define AXESTS_ANALOG 4
+
+// every kind of supported event is coded into a long int
+typedef int32_t EventCode;
+
+// Position of directional buttons in PadButtons
+#define PSXBTN_UP 12
+#define PSXBTN_RIGHT 13
+#define PSXBTN_DOWN 14
+#define PSXBTN_LEFT 15
+
+// macros to define Eventcodes
+// this may look like I make it too complicated, but it keeps things open for future improvements
+#define NO_EVENT 0
+#define FIRST_KEY_EVENT 0
+#define FIRST_JOY_EVENT (1<<16)
+#define RELEASE_EVENT (1<<30)
+#define FIRST_ANALOG_EVENT (1<<20)
+
+#define KEY_EVENT(n) (FIRST_KEY_EVENT+(n))
+#define AXISPLUS_EVENT(p,n) (FIRST_JOY_EVENT+2*(n)+(p)*(2*MAXAXES+MAXBUTTONS))
+#define AXISMINUS_EVENT(p,n) (FIRST_JOY_EVENT+2*(n)+1+(p)*(2*MAXAXES+MAXBUTTONS))
+#define BUTTON_EVENT(p,n) (FIRST_JOY_EVENT+2*MAXAXES+(n)+(p)*(2*MAXAXES+MAXBUTTONS))
+#define ANALOGAXIS_EVENT(p,n,v) (FIRST_ANALOG_EVENT+256*(n)+(v)+(p)*(256*MAXAXES))
+
+// Makro Definitions etc.
+#define MAXMACROS 3
+#define MAXMACROLENGTH 100
+
+typedef struct
+{
+ unsigned char controllerType;
+ unsigned short buttonStatus;
+ unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY;
+ unsigned char moveX, moveY;
+ unsigned char reserved[91];
+} PadDataS;
+
+// Number of events to fetch at once...
+#define MAXCNT 100
+
+/* number of buttons required for configuration */
+#define CONFIGBUTTONCOUNT 20
+
+#define EVENTTYPE_NONE -1
+#define EVENTTYPE_KEY 0
+#define EVENTTYPE_BUTTON 1
+#define EVENTTYPE_AXISPLUS 2
+#define EVENTTYPE_AXISMINUS 3
+#define EVENTTYPE_ANALOG 4
+
+// The following struct is used in the config part only
+typedef struct
+{
+ unsigned int event_type; // Button, Axe, AnalogAxe
+ unsigned int pad;
+ unsigned int no; // Keycode in case of key event
+ int value; // 0=release, 1=press, or analog value in case of EVENTTYPE_ANALOG
+} PadJoyEvent;
+
+#endif